Question

I wanted to add IPv6 support for my program and came across odd error. I want to open socket which accepts connections. Here is my scenario:

First I use getaddrinfo() to find socket configuration:

struct addrinfo hint, *info = NULL;

memset((void *)&hint, 0, sizeof(hint));
hint.ai_family = AF_INET6;
hint.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
hint.ai_socktype = SOCK_STREAM;

if ((error = getaddrinfo(NULL, "1234", &hint, &info))) {
    /* some error handling */
}

I gen non-NULL result in info. Then I want to create socket:

socket(info->ai_family, info->ai_socktype, info->ai_protocol)

Here I get -1

strerror(errno)

returns Address family not supported by protocol

I thought that getaddrinfo() returns only addresses that can be bound and I would expect it to return NULL in this case. What am I missing?

I want to add that my eth0 does not have IPv6 address right now. I am using uClibc 0.9.32

Was it helpful?

Solution

You need to add AI_ADDRCONFIG to ai_flags to make sure it doesn't return address families unsupported by the kernel. I pretty much always add that flag nowadays.

If you want to support kernels without IPv6 you'll have to avoid setting ai_family to AF_INET6. Instead you have to listen on all the returned addresses, and make sure to set IPV6_V6ONLY on the AF_INET6 ones. There's no guarantee that the AF_INET6 address will be returned first, unfortunately.

OTHER TIPS

getaddrinfo returns a linked list of struct addrinfo objects, which you can traverse using the ai_next member. You should try each returned addrinfo object in turn until you get a connection (or hit NULL/end of list).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top