]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Set SO_REUSEADDR so that the wildcard interface and a more specific
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 31 Oct 2013 15:06:11 +0000 (15:06 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 31 Oct 2013 15:06:11 +0000 (15:06 +0000)
  interface port 53 can be used at the same time, and one of the
  daemons is unbound.

git-svn-id: file:///svn/unbound/trunk@2996 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
services/outside_network.c

index 8e168dc04545c3f4403045d7ace647df2ba2aa63..841e93c6a991e8179dab56064243bf6f0f973185 100644 (file)
@@ -1,3 +1,8 @@
+31 Oct 2013: Wouter
+       - Set SO_REUSEADDR so that the wildcard interface and a more specific
+         interface port 53 can be used at the same time, and one of the
+         daemons is unbound.
+
 22 Oct 2013: Wouter
        - Patch from Neel Goyal: Add an API call to set an event base on an
          existing ub_ctx.  This basically just destroys the current worker and
index 368faaea42119c6dc9c5f46a428dc2085503f889..6eeedb75e5d900c45b5159c504cee3c6a3b4a331 100644 (file)
@@ -91,10 +91,10 @@ verbose_print_addr(struct addrinfo *addr)
 int
 create_udp_sock(int family, int socktype, struct sockaddr* addr,
         socklen_t addrlen, int v6only, int* inuse, int* noproto,
-       int rcv, int snd)
+       int rcv, int snd, int listen)
 {
        int s;
-#if defined(IPV6_USE_MIN_MTU)
+#if defined(SO_REUSEADDR) || defined(IPV6_USE_MIN_MTU)
        int on=1;
 #endif
 #ifdef IPV6_MTU
@@ -129,6 +129,25 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
                *noproto = 0;
                return -1;
        }
+       if(listen) {
+#ifdef SO_REUSEADDR
+               if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, 
+                       (socklen_t)sizeof(on)) < 0) {
+#ifndef USE_WINSOCK
+                       log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+                               strerror(errno));
+                       close(s);
+#else
+                       log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+                               wsa_strerror(WSAGetLastError()));
+                       closesocket(s);
+#endif
+                       *noproto = 0;
+                       *inuse = 0;
+                       return -1;
+               }
+#endif /* SO_REUSEADDR */
+       }
        if(rcv) {
 #ifdef SO_RCVBUF
                int got;
@@ -526,7 +545,7 @@ make_sock(int stype, const char* ifname, const char* port,
                verbose_print_addr(res);
                s = create_udp_sock(res->ai_family, res->ai_socktype,
                        (struct sockaddr*)res->ai_addr, res->ai_addrlen,
-                       v6only, &inuse, &noproto, (int)rcv, (int)snd);
+                       v6only, &inuse, &noproto, (int)rcv, (int)snd, 1);
                if(s == -1 && inuse) {
                        log_err("bind: address already in use");
                } else if(s == -1 && noproto && hints->ai_family == AF_INET6){
index 4d37aca5eee476897ffaa47cf372af73de680892..451a64abcd890ce3de1c3e4122d70ed5159cfc68 100644 (file)
@@ -178,11 +178,13 @@ void listen_start_accept(struct listen_dnsport* listen);
        IPv6 proto (family) is not available.
  * @param rcv: set size on rcvbuf with socket option, if 0 it is not set.
  * @param snd: set size on sndbuf with socket option, if 0 it is not set.
+ * @param listen: if true, this is a listening UDP port, eg port 53, and 
+ *     set SO_REUSEADDR on it.
  * @return: the socket. -1 on error.
  */
 int create_udp_sock(int family, int socktype, struct sockaddr* addr, 
        socklen_t addrlen, int v6only, int* inuse, int* noproto, int rcv,
-       int snd);
+       int snd, int listen);
 
 /**
  * Create and bind TCP listening socket
index 373d8f3536882b0d44c2dbf93181be5a717d3f7b..ece59098a72d7f4c1a912e004486350a2aefd2d6 100644 (file)
@@ -849,13 +849,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
                sa->sin6_port = (in_port_t)htons((uint16_t)port);
                fd = create_udp_sock(AF_INET6, SOCK_DGRAM, 
                        (struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
-                       0, 0);
+                       0, 0, 0);
        } else {
                struct sockaddr_in* sa = (struct sockaddr_in*)addr;
                sa->sin_port = (in_port_t)htons((uint16_t)port);
                fd = create_udp_sock(AF_INET, SOCK_DGRAM, 
                        (struct sockaddr*)addr, addrlen, 1, inuse, &noproto,
-                       0, 0);
+                       0, 0, 0);
        }
        return fd;
 }