--- tcp.c.orig 2010-10-12 16:51:18.000000000 +0200 +++ tcp.c 2010-10-12 17:23:49.000000000 +0200 @@ -25,13 +25,18 @@ #include "axel.h" +#include + /* Get a TCP connection */ int tcp_connect( char *hostname, int port, char *local_if ) { - struct hostent *host = NULL; - struct sockaddr_in addr; + struct addrinfo hints; + struct addrinfo *ai, *rp; + char portbuf[8]; + snprintf(portbuf, 8, "%d", port); + struct sockaddr_in local; - int fd; + int fd = -1; #ifdef DEBUG socklen_t i = sizeof( local ); @@ -39,20 +44,34 @@ fprintf( stderr, "tcp_connect( %s, %i ) = ", hostname, port ); #endif - /* Why this loop? Because the call might return an empty record. - At least it very rarely does, on my system... */ - for( fd = 0; fd < 5; fd ++ ) - { - if( ( host = gethostbyname( hostname ) ) == NULL ) - return( -1 ); - if( *host->h_name ) break; - } - if( !host || !host->h_name || !*host->h_name ) - return( -1 ); - - if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) - return( -1 ); - + { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = 0; + hints.ai_protocol = 0; + if (getaddrinfo(hostname, portbuf, &hints, &ai) != 0) + { + fd = -1; + } else { + for (rp = ai; rp != NULL; rp->ai_next) + { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd < 0) continue; + if (connect(fd, rp->ai_addr, rp->ai_addrlen) >= 0) + { + break; + } + close(fd); + } + } + freeaddrinfo(ai); + } + if (fd < 0) + { + return( -1 ); + } + if( local_if && *local_if ) { local.sin_family = AF_INET; @@ -64,17 +83,7 @@ return( -1 ); } } - - addr.sin_family = AF_INET; - addr.sin_port = htons( port ); - addr.sin_addr = *( (struct in_addr *) host->h_addr ); - - if( connect( fd, (struct sockaddr *) &addr, sizeof( struct sockaddr_in ) ) == -1 ) - { - close( fd ); - return( -1 ); - } - + #ifdef DEBUG getsockname( fd, &local, &i ); fprintf( stderr, "%i\n", ntohs( local.sin_port ) );