Is there a way to handle getaddrinfo() output with a single loop and IPv6 socket?
I would like to be able to loop through a list which is a result of the getaddrinfo()
function and call connect()
using every element of that list until connect()
is successful. Unfortu开发者_JAVA百科nately, even when I specify the AI_ALL | AI_V4MAPPED
flags, and an AF_INET6
family, the results are mixed. The first part of the list contains sockaddr_in6
structures, and the second part sockaddr_in
structures, so i can't use them with an AF_INET6
socket.
I know i can create two sockets. I would like to know whether it's possible to do it with just the AF_INET6
socket.
Here's the operating system:
> uname -a
> Linux debian 2.6.32-5-amd64 #1 SMP Wed Jan 12 03:40:32 UTC 2011 x86_64 GNU/Linux
You don't have to worry if it's an AF_INET or AF_INET6 socket you are creating. Simply pass the data from the getaddrinfo() call to the socket() call.
e.g.
/* returns -1 on error, or a connected socket descriptor*/
int opensock(const char *hostname, const char *service)
{
struct addrinfo hint, *host, *res = NULL;
int tcp_sd = -1, error;
memset(&hint, '\0', sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
hint.ai_family = PF_UNSPEC;
error = getaddrinfo(hostname, service, &hint, &res);
if(error){
syslog(LOG_DEBUG,"getaddrinfo failed. Cant find host %s: %m",hostname);
return tcp_sd;
}
for (host = res; host; host = host->ai_next) {
tcp_sd = socket(host->ai_family, host->ai_socktype, host->ai_protocol);
if (tcp_sd < 0) {
continue;
}
if (connect(tcp_sd, host->ai_addr, host->ai_addrlen) < 0) {
close(tcp_sd);
tcp_sd = -1;
continue;
}
break; /* okay we got one */
}
freeaddrinfo(res);
return tcp_sd;
}
精彩评论