Skip to content
Advertisement

IPv6 example program fails on connect()

IPv6 example program fails on connect()

JavaScript

I arranged the server argument to be evaluated by inet_pton() if numeric, otherwise, it goes through getaddrinfo(). inet_pton() sets up the address and it works. getaddrinfo() does not, apparently, it dies in connect (hangs up). The example program is a simple web page fetch and print (not https). I used the www.example.com server to test it.

Note in the following example run that I use the same address getaddrinfo()gives me in a numeric example, then that works fine.

What am I doing wrong here?

The compile is simply gcc socket.c -o socket.

JavaScript

I did find a similar post where they recommend adding the interface name to the server name, like www.example.com%enp2s0, but that was just rejected as invalid by getaddrinfo().

Advertisement

Answer

The main problem is that you are not populating serv_addr correctly.

When calling getadr(), your call to memcpy() for the result does not copy enough bytes for a complete sockaddr_in6 (sizeof(sockaddr) is less thansizeof(sockaddr_in6)). Also, you are not askinggetaddrinfo()to output a port number, so thesin6_port` of the result will not be 80 as you are expecting.

That is why connect() fails when you use getaddrinfo() instead of inet_pton().

There are other problems with your code, too.

When using memset(), you need to use an integer 0 rather than a character '0'. They are not the same value. Unused sockaddr_in6 fields need to be zeroed out properly.

Your getadr() function leaks memory, and it is inefficient in general. Use the hints parameter of getaddrinfo() to limit the results it outputs so you don’t have to go hunting for them. And you need to free the output with freeaddrinfo() when you are done using it.

isdigit() is not the correct way to differentiate a numeric IP from a hostname. And besides, you don’t really need to do this differentiation manually, as getaddrinfo() can parse a numeric IP string. But if you do differentiate manually, call inet_pton() unconditionally and then call getaddrinfo() if inet_pton() fails.

With that said, try something more like this instead:

JavaScript

That said, getaddrinfo() outputs a linked list of IP addresses. It is possible for a hostname to resolve to multiple IPs, not all of which may be reachable from your machine. You should loop through the entire list connect()‘ing to each IP until one of them succeeds or the list is exhausted. For example:

JavaScript
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement