In my program, I am trying to implement support for dual-stack operation (both IPv4 and IPv6 sockets).
In the case of IPv4, everything is working fine. But in the IPv6 case, accept()
is returning a -1
value (an error).
Can anyone suggest the possible reasons, and how to fix it?
When accept()
returns -1
, errno
will be set to indicate what specific error occurred. Please call perror("accept")
for an easy way to see what the error was, and update your question with the results.
Also, please note that accept()
must be called on a socket that has been:
socket()
call. (you should pass PF_INET6
for the first argument of your socket to create an IPv6 protocol family socket)bind()
using a struct sockaddr_in6
parameter as the 2nd parameter (with its sin6_family
set to AF_INET6
for IPv6 to indicate you will be binding to an IPv6 address). Remember to zero out the sin6_zero
field first. One strategy would be to zero the entire sockaddr structure, which would set the IPv6 address to IN6ADDR_ANY, which means you would just have to set the port and the address family.listen()
If you are still having trouble, post the code you have so far.
If I had to guess (since you haven't posted any code), I think if it works with IPv4 and gets to the point where it can accept()
a connection, but IPv6 connection accept()
calls return -1
, I think it's likely that you aren't passing accept()
a large enough struct sockaddr
for it to work.
For example, the following code:
printf("sizeof(struct sockaddr_in) = %ld\n", sizeof(struct sockaddr_in));
printf("sizeof(struct sockaddr_in6) = %ld\n", sizeof(struct sockaddr_in6));
Prints (on my system):
sizeof(struct sockaddr_in) = 16
sizeof(struct sockaddr_in6) = 28
If you are only giving accept()
enough room to write out an IPv4 address, it will fail when it accepts an IPv6 connection. Make sure you allocate either a struct sockaddr_in6
or a struct sockaddr_storage
, and ensure the size argument is correct.