OK, so I have started doing some socket programming, I am trying to simultaneously learn how to do things using the standard BSD implementation and also how that translates into the Winsock API on Windows. I am setting my self up a Winsock utility library header that can be included in future projects that incorporate networking. I want my library to be IPv4/6 agnostic in that it has functions that work with both IPv4 and IPv6.
The problem I am having is that I do not have access to internet service anywhere apparently cannot connect to any of the IPv6 internet. I know that the World IPv6 day is coming up in June, so maybe this will change. I doubt it though.. Anyway, I am unable to test any of the functions I write that work particularly on IPv6 addresses or hosts.
Here is an example:
I have this function that is supposed to take a hostname as a string, resolve it and then return a presentable IP address as a string. I have a version [ip_string()] that returns the first good IP address it can get in the address family AF_INET or AF_INET6. The second version [ip4_string()] will only return an IPv6 address and the same with [ip6_string()] returning an IPv6 address.
char *ip_string(const char hostname[])
{
char *buffer = new char[INET6_ADDRSTRLEN];
struct addrinfo hints, *res, *ptr;
void *addr = NULL; // void pointer to be set to sin_addr or sin6_addr
/** Initialize hints structure */
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_UNSPEC; // ipv4 or ipv6 address family
hints.ai_socktype = SOCK_STREAM;
/** Function getaddrinfo returns non-zero if there's a problem */
if (getaddrinfo(hostname, "http", &hints, &res) != 0)
throw WinsockException("getaddrinfo()");
/** Loop through list of address structures till we find a valid IP */
const int MAX_ATTEMPTS = 15;
int i = 0;
for (ptr = res; (ptr != NULL); ptr = ptr->ai_next)
{
if (i++ <= MAX_ATTEMPTS)
{
if (ptr->ai_family == AF_INET)
{ // Cast appropriately for ipv4
addr = &(((struct sockaddr_in *)ptr->ai_addr)->sin_addr);
inet_ntop(ptr->ai_family, (in_addr*) addr, buffer, INET_ADDRSTRLEN);
}
else if (ptr->ai_family == AF_INET6)
{ // Cast appropraitely for ipv6
addr = &(((struct sockaddr_in6 *)ptr->ai_addr)->sin6_addr);
inet_ntop(ptr->ai_family, (in6_addr*) addr, buffer, INET6_ADDRSTRLEN);
}
}
}
freeaddrinfo(res); // free list of address structures
if (addr == NULL)
{
delete [] buffer;
return NULL;
}
return buffer;
}
The problem I'm having (I'm assuming), is because I do not have a usable IPv6 connection, (which I confirmed using test-ipv6.com), anytime any of these functions calls getaddrinfo() on a ipv6 host the function seems to not return at all.
Is this normal? Is there anyway to check the connection to see if ipv6 is enabled through the Winsock API? Is there any good way for me to test ipv6 enabled code on a non-ipv6 connection?
You could set up your own little IPv6 internetwork to test this, but it'll be much easier to just get yourself an IPv6 tunnel.
Even if your provider doesn't offer IPv6 access (you should yell at them for that!) you can still get a usable IPv6 connection. Look at Hurricane Electric for example.
Your immediate problem might be as simple as what Karoly said. Just get rid of the first if() statement just inside the for loop. It's redundant anyway (other that that the extra i++ breaks things!).