[ds6-devel] nc6/src Makefile.am,1.8,1.9 filter.c,1.13,1.14 filter.h,1.6,1.7 network.c,1.25,1.26 rt_config.c,1.4,NONE rt_config.h,1.2,NONE

chris@deepspace6.net chris@deepspace6.net
Wed Jan 1 14:03:47 2003


Update of /cvs/nc6/src

Modified Files:
	Makefile.am filter.c filter.h network.c 
Removed Files:
	rt_config.c rt_config.h 
Log Message:
Added recommendation for double bind resolution.
Also added check to skip ipv4 mapped results from getaddrinfo.


Index: Makefile.am
===================================================================
RCS file: /cvs/nc6/src/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Makefile.am	29 Dec 2002 14:21:15 -0000	1.8
+++ Makefile.am	1 Jan 2003 14:03:45 -0000	1.9
@@ -7,7 +7,6 @@
   netsupport.h \
   parser.h \
   readwrite.h \
-  rt_config.h \
   io_stream.h \
   connection.h
 
@@ -20,7 +19,6 @@
   netsupport.c \
   parser.c \
   readwrite.c \
-  rt_config.c \
   io_stream.c \
   connection.c
 
Index: filter.c
===================================================================
RCS file: /cvs/nc6/src/filter.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- filter.c	30 Dec 2002 22:35:47 -0000	1.13
+++ filter.c	1 Jan 2003 14:03:45 -0000	1.14
@@ -52,7 +52,7 @@
 
 #ifdef ENABLE_IPV6
 /* returns TRUE if a represents an ipv4-mapped address */
-inline static bool is_address_ipv4_mapped(const struct sockaddr *a)
+bool is_address_ipv4_mapped(const struct sockaddr *a)
 {
 	bool ret = FALSE;
 	
Index: filter.h
===================================================================
RCS file: /cvs/nc6/src/filter.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- filter.h	30 Dec 2002 22:35:47 -0000	1.6
+++ filter.h	1 Jan 2003 14:03:45 -0000	1.7
@@ -27,6 +27,10 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 
+#ifdef ENABLE_IPV6
+bool is_address_ipv4_mapped(const struct sockaddr *a);
+#endif
+
 bool is_allowed(const struct sockaddr *sa, const address *addr,
 		const connection_attributes* attrs);
 
Index: network.c
===================================================================
RCS file: /cvs/nc6/src/network.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- network.c	30 Dec 2002 22:35:47 -0000	1.25
+++ network.c	1 Jan 2003 14:03:45 -0000	1.26
@@ -32,7 +32,6 @@
 #include "network.h"
 #include "parser.h"
 #include "filter.h"
-#include "rt_config.h"
 #include "netsupport.h"
 
 RCSID("@(#) $Header$");
@@ -101,11 +100,20 @@
 		    ptr->ai_socktype != SOCK_DGRAM) 
 			continue;
 
-#if defined(PF_INET6) && !defined(ENABLE_IPV6)
+#ifdef ENABLE_IPV6
+		/* skip IPv4 mapped addresses returned from getaddrinfo,
+		 * for security reasons:
+ http://playground.iijlab.net/i-d/draft-itojun-ipv6-transition-abuse-01.txt
+ 		 */
+		if (is_address_ipv4_mapped(ptr->ai_addr))
+			continue;
+#else
+#ifdef PF_INET6
 		/* skip IPv6 if disabled */
 		if (ptr->ai_family == PF_INET6)
 			continue;
 #endif
+#endif
 
 		/* we are going to try to connect to this address */
 		connect_attempted = TRUE;
@@ -332,6 +340,10 @@
 	bool verbose_mode      = FALSE;
 	bool dont_reuse_addr   = FALSE;
 	bool disable_nagle     = FALSE;
+#ifdef ENABLE_IPV6
+	bool set_ipv6_only     = FALSE;
+	bool bound_ipv6_any    = FALSE;
+#endif
 	struct bound_socket_t* bound_sockets = NULL;
 	fd_set accept_fdset;
 
@@ -368,7 +380,8 @@
 	/* get the IP address of the local end of the connection */
 	err = getaddrinfo(local->address, local->service, &hints, &res);
 	if (err != 0) 
-		fatal("forward host lookup failed for local endpoint %s (%s): %s",
+		fatal("forward host lookup failed "
+		      "for local endpoint %s (%s): %s",
 		      local->address? local->address : "[unspecified]",
 		      local->service, gai_strerror(err));
 		
@@ -376,18 +389,31 @@
 	assert(res != NULL);
 
 #ifdef ENABLE_IPV6
-	/* Some systems (eg. linux) will bind to both ipv6 AND ipv4 when
-	 * listening.  Connections will still be accepted from either ipv6 or
-	 * ipv4 clients (ipv4 will be mapped into ipv6).  However, this means
-	 * that we MUST bind the ipv6 address ONLY for these hosts.
+	/* Some systems have a shared stack for ipv6 and ipv4 (eg. linux),
+	 * which means that binding an ipv6 socket to ADDR_ANY will also
+	 * listen for, and accept, ipv4 addresses.  These are returned as ipv4
+	 * mapped ipv6 addresses from accept(2).
 	 *
-	 * TODO: until we add a configure check to determine if the current
-	 * host does this double binding, we will just ensure that ipv6
-	 * sockets are bound first and then attempt to bind the ipv4 ones.  On
-	 * systems that double bind ipv6/ipv4 the ipv4 bind will simply fail.
+	 * However, getaddrinfo will still return results for both ipv6 AND
+	 * ipv4, but the bind to ipv4 will fail (as it is already held by the
+	 * ipv6 bind).
+	 *
+	 * The following algorithm is used to work around this error to some
+	 * degree:
+	 *
+	 * Ensure binds to IPv6 addresses are attempted before IPv4 addresses.
+	 * On systems where IPV6_V6ONLY is not defined or the setsockopt
+	 * fails:
+	 *   - Keep track of whether an IPv6 socket
+	 *     has been bound to in6_addr_any.
+	 *   - If a bind to IPv4 fails with EADDRINUSE and an IPv6 socket
+	 *     has been bound, then just ignore the error.
 	 */
-	if (is_ipv6_enabled() == TRUE && is_double_binding_sane() == FALSE)
-		res = order_ipv6_first(res);
+
+	/* TODO: instead of reordering the results, just loop through the
+	 * results twice - once for ipv6 then for the rest.
+	 */
+	res = order_ipv6_first(res);
 #endif
 
[...106 lines suppressed...]
--- rt_config.c DELETED ---
--- rt_config.h DELETED ---



More information about the ds6-devel mailing list