[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