IPv6 address literals in --bind_address (1.19_rc4)

Ivan Nejgebauer <[email protected]>
Newsgroups gmane.mail.perdition.user
Message-ID <[email protected]>
Each server in the --bind_address option list passes through the function 
user_server_port_strn_assign() (in perdition/server_port.c) which 
separates the user, server and port components. This function does not 
recognize IPv6 address literals as documented in RFC 3986 (i.e., IPv6 
addresses enclosed in brackets.)

For example, address literal [2001:db8:1000:1::2] will be separated into 
"server" [2001:db8:1000:1: and "port" 2] , which are syntactically 
incorrect and will produce an error in getaddrinfo(). The enclosed patch 
adds IPv6 literal handling.

(A workaround is to use a "naked" IPv6 address with the port 
specification, e.g., 2001:db8:1000:1::2:110 , but this is a) ugly and b) 
not standards-compliant.)

i.

______________________________________________
Perdition-users mailing list
[email protected]
http://lists.vergenet.net/listinfo/perdition-users
ipv6-literal.patch (text/x-diff, 2.1 KB)
--- perdition/server_port.h.orig	2010-09-29 10:42:01.000000000 +0200
+++ perdition/server_port.h	2010-09-29 10:45:13.000000000 +0200
@@ -32,6 +32,8 @@
 #include "str.h"
 
 #define SERVER_PORT_DELIMITER ':'
+#define IPV6_LITERAL_RIGHT_DELIMITER ']'
+#define IPV6_LITERAL_LEFT_DELIMITER '['
 
 /* #defines to destroy and duplicate strings */
 #define DESTROY_SP   user_server_port_destroy_cb
--- perdition/server_port.c.orig	2010-09-29 10:41:54.000000000 +0200
+++ perdition/server_port.c	2010-09-29 11:37:53.000000000 +0200
@@ -99,6 +99,15 @@
 	return user_server_port_strn_assign(usp, str, strlen(str));
 }
 
+#define FIX_IPV6_LITERAL \
+do {									\
+	char *l;							\
+	if (*(*usp)->server != IPV6_LITERAL_LEFT_DELIMITER)		\
+		break;							\
+	l = strchr((*usp)->server, IPV6_LITERAL_RIGHT_DELIMITER);	\
+	(*usp)->server++;						\
+	*l = '\0';							\
+} while(0);
 
 /**********************************************************************
  * user_server_port_strn_assign
@@ -119,6 +128,7 @@
 		size_t str_len)
 {
 	int alloced = 0;
+	int ipv6_literal = 0;
 
 	if(!*usp) {
 		*usp = user_server_port_create();
@@ -139,7 +149,19 @@
 	memset((*usp)->server, 0, str_len + 1);
 	strncpy((*usp)->server, str, str_len);
 
-	(*usp)->port = strrchr((*usp)->server, SERVER_PORT_DELIMITER);
+	(*usp)->port = strrchr((*usp)->server, IPV6_LITERAL_RIGHT_DELIMITER);
+	if((*usp)->port) {
+		char *l;
+
+		l = strchr((*usp)->server, IPV6_LITERAL_LEFT_DELIMITER);
+		if (l && (*usp)->port - l > 2) {	/* at least [::] */
+			ipv6_literal = 1;
+			if (*++(*usp)->port != SERVER_PORT_DELIMITER)
+				(*usp)->port = NULL;
+		}
+	}
+	if (!ipv6_literal)
+		(*usp)->port = strrchr((*usp)->server, SERVER_PORT_DELIMITER);
 	if((*usp)->port) {
 		*(*usp)->port = '\0';
 		(*usp)->port++;
@@ -154,6 +176,8 @@
 	if((*usp)->server) {
 		*(*usp)->server = '\0';
 		(*usp)->server += strlen(opt.domain_delimiter);
+		if (ipv6_literal)
+			FIX_IPV6_LITERAL;
 		(*usp)->server = strdup((*usp)->server);
 		if(!(*usp)->server) {
 			goto strdup_fail;
@@ -161,6 +185,8 @@
 	}
 	else {
 		(*usp)->server = (*usp)->user;
+		if (ipv6_literal)
+			FIX_IPV6_LITERAL;
 		(*usp)->user = NULL;
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.