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

Reply via email to