Blob Blame History Raw
diff -urp dnsmasq-2.63-orig/src/dhcp6.c dnsmasq-2.63/src/dhcp6.c
--- dnsmasq-2.63-orig/src/dhcp6.c	2012-08-16 09:04:05.000000000 -0400
+++ dnsmasq-2.63/src/dhcp6.c	2012-11-03 07:55:39.293006824 -0400
@@ -36,15 +36,31 @@ void dhcp6_init(void)
 #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
   int class = IPTOS_CLASS_CS6;
 #endif
-  
+  int oneopt = 1;
+
   if ((fd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1 ||
 #if defined(IPV6_TCLASS) && defined(IPTOS_CLASS_CS6)
       setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &class, sizeof(class)) == -1 ||
 #endif
+      setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &oneopt, sizeof(oneopt)) == -1 ||
       !fix_fd(fd) ||
       !set_ipv6pktinfo(fd))
     die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
   
+  /* When bind-interfaces is set, there might be more than one dnmsasq
+     instance binding port 547. That's OK if they serve different networks.
+     Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
+  if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
+    {
+#ifdef SO_REUSEPORT
+      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
+#else
+      int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
+#endif
+      if (rc == -1)
+	die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
+    }
+  
   memset(&saddr, 0, sizeof(saddr));
 #ifdef HAVE_SOCKADDR_SA_LEN
   saddr.sin6_len = sizeof(struct sockaddr_in6);