tags 336658 + patch, ipv6 thanks The attached patch should bring IPv6 support to gnutls-{cli{,debug},serv}. I'm not patching the regression tests as they are not used within Debian.
Sincerely, -- Rémi Denis-Courmont http://www.simphalempin.com/home/
diff -ru gnutls13-1.3.5.orig/src/cli.c gnutls13-1.3.5/src/cli.c --- gnutls13-1.3.5.orig/src/cli.c 2006-04-16 12:46:13.000000000 +0200 +++ gnutls13-1.3.5/src/cli.c 2006-04-16 15:37:29.000000000 +0200 @@ -485,7 +485,6 @@ { int err, ret; int sd, ii, i; - struct sockaddr_in sa; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; @@ -494,8 +493,8 @@ fd_set rset; int maxfd; struct timeval tv; - int user_term = 0, port; - struct hostent *server_host; + int user_term = 0; + struct addrinfo hints, *res, *ptr; socket_st hd; gaa_parser (argc, argv); @@ -516,38 +515,47 @@ printf ("Resolving '%s'...\n", hostname); /* get server name */ - server_host = gethostbyname (hostname); - if (server_host == NULL) + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + if ((err = getaddrinfo (hostname, service, &hints, &res))) { - fprintf (stderr, "Cannot resolve %s\n", hostname); + fprintf (stderr, "Cannot resolve %s:%s: %s\n", hostname, service, + gai_strerror (err)); exit (1); } - sd = socket (AF_INET, SOCK_STREAM, 0); - ERR (sd, "socket"); - - port = service_to_port (service); - if (port == -1) + sd = -1; + for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { - fprintf (stderr, "Unknown service\n"); - return -1; - } + char portname[6]; + sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + if (sd == -1) continue; + + if ((err = getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, + portname, sizeof (portname), NI_NUMERICHOST)) != 0) + { + fprintf (stderr, "getnameinfo(): %s\n", gai_strerror (err)); + freeaddrinfo (res); + return (1); + } + + printf ("Connecting to '%s:%s'...\n", buffer, portname); - memset (&sa, '\0', sizeof (sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons (port); + err = connect (sd, ptr->ai_addr, ptr->ai_addrlen); + if (err < 0) + { + close (sd); + sd = -1; + continue; + } - sa.sin_addr.s_addr = *((unsigned int *) server_host->h_addr); + break; + } - if (inet_ntop (AF_INET, &sa.sin_addr, buffer, MAX_BUF) == NULL) + if (sd == -1) { - perror ("inet_ntop()"); - return (1); + ERR (err, "connect"); } - printf ("Connecting to '%s:%d'...\n", buffer, port); - - err = connect (sd, (SA *) & sa, sizeof (sa)); - ERR (err, "connect"); hd.secure = 0; hd.fd = sd; @@ -608,10 +616,10 @@ printf ("\n\n- Connecting again- trying to resume previous session\n"); - sd = socket (AF_INET, SOCK_STREAM, 0); + sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); ERR (sd, "socket"); - err = connect (sd, (SA *) & sa, sizeof (sa)); + err = connect (sd, ptr->ai_addr, ptr->ai_addrlen); ERR (err, "connect"); hd.fd = sd; @@ -623,6 +631,8 @@ } } + freeaddrinfo (res); + after_handshake: diff -ru gnutls13-1.3.5.orig/src/serv.c gnutls13-1.3.5/src/serv.c --- gnutls13-1.3.5.orig/src/serv.c 2006-04-16 12:46:13.000000000 +0200 +++ gnutls13-1.3.5/src/serv.c 2006-04-16 15:33:43.000000000 +0200 @@ -507,41 +507,62 @@ static int listen_socket (const char *name, int listen_port) { - struct sockaddr_in a; + struct addrinfo hints, *res, *ptr; + char portname[6]; int s; int yes; - if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) - { - perror ("socket() failed"); - return -1; - } - yes = 1; + snprintf (portname, sizeof (portname), "%d", listen_port); + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; - if (setsockopt - (s, SOL_SOCKET, SO_REUSEADDR, (const void *) &yes, sizeof (yes)) < 0) + if ((s = getaddrinfo (NULL, portname, &hints, &res)) != 0) { - perror ("setsockopt() failed"); - failed: - close (s); + fprintf (stderr, "getaddrinfo() failed: %s\n", gai_strerror (s)); return -1; } - memset (&a, 0, sizeof (a)); - a.sin_port = htons (listen_port); - a.sin_family = AF_INET; - if (bind (s, (struct sockaddr *) &a, sizeof (a)) < 0) + s = -1; + + for (ptr = res; (ptr != NULL) && (s == -1); ptr = ptr->ai_next) { - perror ("bind() failed"); - goto failed; + if ((s = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) < 0) + { + perror ("socket() failed"); + continue; + } + + yes = 1; + if (setsockopt + (s, SOL_SOCKET, SO_REUSEADDR, (const void *) &yes, sizeof (yes)) < 0) + { + perror ("setsockopt() failed"); + failed: + close (s); + s = -1; + continue; + } + + if (bind (s, res->ai_addr, res->ai_addrlen) < 0) + { + perror ("bind() failed"); + goto failed; + } + + if (listen (s, 10) < 0) + { + perror ("listen() failed"); + goto failed; + } } - if (listen (s, 10) < 0) + freeaddrinfo (res); + if (s == -1) { - perror ("listen() failed"); - goto failed; + return -1; } - printf ("%s ready. Listening to port '%d'.\n\n", name, listen_port); + printf ("%s ready. Listening to port '%s'.\n\n", name, portname); return s; } @@ -618,6 +639,28 @@ static void gaa_parser (int argc, char **argv); +static int get_port (const struct sockaddr_storage *addr) +{ + switch (addr->ss_family) + { + case AF_INET6: + return ntohs (((const struct sockaddr_in6 *)addr)->sin6_port); + case AF_INET: + return ntohs (((const struct sockaddr_in *)addr)->sin_port); + } + return -1; +} + +static const char *addr_ntop (const struct sockaddr *sa, socklen_t salen, + char *buf, size_t buflen) +{ + if (getnameinfo (sa, salen, buf, buflen, NULL, 0, NI_NUMERICHOST) == 0) + { + return buf; + } + return NULL; +} + int main (int argc, char **argv) { @@ -625,7 +668,8 @@ char topbuf[512]; char name[256]; int accept_fd; - struct sockaddr_in client_address; + struct sockaddr_storage client_address; + socklen_t calen; #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); @@ -879,14 +923,13 @@ /* a new connection has arrived */ if (FD_ISSET (h, &rd)) { - unsigned int l; gnutls_session tls_session; tls_session = initialize_session (); - l = sizeof (client_address); - memset (&client_address, 0, l); - accept_fd = accept (h, (struct sockaddr *) &client_address, &l); + calen = sizeof (client_address); + memset (&client_address, 0, calen); + accept_fd = accept (h, (struct sockaddr *) &client_address, &calen); if (accept_fd < 0) { @@ -965,10 +1008,9 @@ if (verbose == 0) { printf ("\n* connection from %s, port %d\n", - inet_ntop (AF_INET, - &client_address.sin_addr, + addr_ntop ((struct sockaddr *)&client_address, calen, topbuf, sizeof (topbuf)), - ntohs (client_address.sin_port)); + get_port (&client_address)); print_info (j->tls_session, NULL); } j->handshake_ok = 1; @@ -1062,10 +1104,9 @@ if (verbose == 0) { printf ("- connection from %s, port %d\n", - inet_ntop (AF_INET, - &client_address.sin_addr, + addr_ntop ((struct sockaddr*) &client_address, calen, topbuf, sizeof (topbuf)), - ntohs (client_address.sin_port)); + get_port (&client_address)); print_info (j->tls_session, NULL); } diff -ru gnutls13-1.3.5.orig/src/tls_test.c gnutls13-1.3.5/src/tls_test.c --- gnutls13-1.3.5.orig/src/tls_test.c 2006-04-16 12:46:13.000000000 +0200 +++ gnutls13-1.3.5/src/tls_test.c 2006-04-16 15:41:21.000000000 +0200 @@ -155,18 +155,6 @@ static int tt = 0; const char *ip; -#define CONNECT() \ - sd = socket(AF_INET, SOCK_STREAM, 0); \ - ERR(sd, "socket"); \ - memset(&sa, '\0', sizeof(sa)); \ - sa.sin_family = AF_INET; \ - sa.sin_port = htons(port); \ - sa.sin_addr.s_addr = *((unsigned int *) server_host->h_addr); \ - ip = inet_ntop(AF_INET, &sa.sin_addr, buffer, MAX_BUF); \ - if (tt++ == 0) printf("Connecting to '%s:%d'...\n", ip, port); \ - err = connect(sd, (SA *) & sa, sizeof(sa)); \ - ERR(err, "connect") - static void gaa_parser (int argc, char **argv); int @@ -174,10 +162,10 @@ { int err, ret; int sd, i; - struct sockaddr_in sa; gnutls_session state; char buffer[MAX_BUF + 1]; - struct hostent *server_host; + char portname[6]; + struct addrinfo hints, *res, *ptr; gaa_parser (argc, argv); @@ -204,10 +192,14 @@ printf ("Resolving '%s'...\n", hostname); /* get server name */ - server_host = gethostbyname (hostname); - if (server_host == NULL) + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICSERV; + snprintf (portname, sizeof (portname), "%d", port); + if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0) { - fprintf (stderr, "Cannot resolve %s\n", hostname); + fprintf (stderr, "Cannot resolve %s: %s\n", hostname, + gai_strerror (err)); exit (1); } @@ -253,7 +245,27 @@ break; } - CONNECT (); + sd = -1; + for (ptr = res; ptr != NULL; ptr = ptr->ai_next) + { + sd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + if (sd == -1) + { + continue; + } + + getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, + NULL, 0, NI_NUMERICHOST); + if (tt++ == 0) printf("Connecting to '%s:%d'...\n", buffer, port); + if ((err = connect(sd, ptr->ai_addr, ptr->ai_addrlen)) != 0) + { + close (sd); + sd = -1; + continue; + } + } + ERR(err, "connect") + gnutls_init (&state, GNUTLS_CLIENT); gnutls_transport_set_ptr (state, (gnutls_transport_ptr) sd); @@ -286,6 +298,8 @@ } while (1); + freeaddrinfo (res); + #ifdef ENABLE_SRP gnutls_srp_free_client_credentials (srp_cred); #endif