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