Browse Source

Set IPV6_V6ONLY on listener sockets bound to IPv6 addresses.

If we don't do this, [::] can be interpreted to mean all v4 and all
v6 addresses.  Found by dcf.  Fixes bug 4760.  See RFC 3493 section
5.3 for more info.
Nick Mathewson 12 years ago
parent
commit
dd68d596cd
2 changed files with 23 additions and 0 deletions
  1. 4 0
      changes/bug4760
  2. 19 0
      src/or/connection.c

+ 4 - 0
changes/bug4760

@@ -0,0 +1,4 @@
+  o Minor bugfixes:
+    - When binding to an IPv6 address, set the IPV6_V6ONLY socket
+      option, so that the IP stack doesn't decide to use it for IPv4
+      too. Fixes bug 4760; bugfix on 0.2.3.9-alpha.

+ 19 - 0
src/or/connection.c

@@ -902,6 +902,25 @@ connection_listener_new(const struct sockaddr *listensockaddr,
 
     make_socket_reuseable(s);
 
+#ifdef IPV6_V6ONLY
+    if (listensockaddr->sa_family == AF_INET6) {
+#ifdef _WIN32
+      /* In Redmond, this kind of thing passes for standards-conformance. */
+      DWORD one = 1;
+#else
+      int one = 1;
+#endif
+      /* We need to set IPV6_V6ONLY so that this socket can't get used for
+       * IPv4 connections. */
+      if (setsockopt(s,IPPROTO_IPV6, IPV6_V6ONLY, (void*)&one, sizeof(one))<0) {
+        int e = tor_socket_errno(s);
+        log_warn(LD_NET, "Error setting IPV6_V6ONLY flag: %s",
+                 tor_socket_strerror(e));
+        /* Keep going; probably not harmful. */
+      }
+    }
+#endif
+
     if (bind(s,listensockaddr,socklen) < 0) {
       const char *helpfulhint = "";
       int e = tor_socket_errno(s);