]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add runtime detection of SO_REUSEPORT, use it instead of dup() if available.
authorWitold Kręcicki <wpk@isc.org>
Thu, 23 Aug 2018 07:42:30 +0000 (09:42 +0200)
committerWitold Kręcicki <wpk@isc.org>
Tue, 6 Nov 2018 11:25:09 +0000 (11:25 +0000)
lib/dns/dispatch.c
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/libisc.def.in
lib/isc/win32/socket.c

index 9c440d370e9cd8406aee32db5ff1b3ccc05b1392..a3e27e62c30edb9ae36f56c2a7ce60622909ddd7 100644 (file)
@@ -1677,7 +1677,7 @@ open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
                result = isc_socket_open(sock);
                if (result != ISC_R_SUCCESS)
                        return (result);
-       } else if (dup_socket != NULL) {
+       } else if (dup_socket != NULL && !isc_socket_hasreuseport()) {
                result = isc_socket_dup(dup_socket, &sock);
                if (result != ISC_R_SUCCESS)
                        return (result);
index d9738af4f64b0b4fb8178709607d3151bb7981ee..98fa51bfd6ceb72b3d8f8471ddbb3c08103843b2 100644 (file)
@@ -1010,6 +1010,12 @@ isc_socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
  * Test interface. Drop UDP packet > 'maxudp'.
  */
 
+bool
+isc_socket_hasreuseport(void);
+/*%<
+ * Return true if there is SO_REUSEPORT support
+ */
+
 #ifdef HAVE_LIBXML2
 int
 isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
index 400d87244d1fe9cdd053692d0138b4269701341a..e3952ba372021d1fd069171b0c73686d26fab39e 100644 (file)
@@ -4580,13 +4580,21 @@ isc_socket_bind(isc_socket_t *sock0, const isc_sockaddr_t *sockaddr,
                goto bind_socket;
 #endif
        if ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
-           isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
-           setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
+           isc_sockaddr_getport(sockaddr) != (in_port_t)0) {
+               if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
                       sizeof(on)) < 0) {
-               UNEXPECTED_ERROR(__FILE__, __LINE__,
+                       UNEXPECTED_ERROR(__FILE__, __LINE__,
                                 "setsockopt(%d) %s", sock->fd,
                                 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
                                                ISC_MSG_FAILED, "failed"));
+               }
+               if (setsockopt(sock->fd, SOL_SOCKET, SO_REUSEPORT, (void *)&on,
+                      sizeof(on)) < 0) {
+                       UNEXPECTED_ERROR(__FILE__, __LINE__,
+                                "setsockopt(%d) %s", sock->fd,
+                                isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+                                               ISC_MSG_FAILED, "failed"));
+               }
                /* Press on... */
        }
 #ifdef AF_UNIX
@@ -5445,6 +5453,38 @@ isc_socket_getfd(isc_socket_t *socket0) {
        return ((short) sock->fd);
 }
 
+static isc_once_t      hasreuseport_once = ISC_ONCE_INIT;
+static bool            hasreuseport = false;
+
+static void
+init_hasreuseport() {
+#ifdef SO_REUSEPORT
+       int sock, yes = 1;
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0) {
+               close(sock);
+               return;
+       } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&yes,
+                       sizeof(yes)) < 0) {
+               close(sock);
+               return;
+       } else if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void *)&yes,
+                       sizeof(yes)) < 0) {
+               close(sock);
+               return;
+       }
+       hasreuseport = true;
+#endif
+}
+
+bool
+isc_socket_hasreuseport() {
+       RUNTIME_CHECK(isc_once_do(&hasreuseport_once, init_hasreuseport)
+                     == ISC_R_SUCCESS);
+       return (hasreuseport);
+}
+
+
 #if defined(HAVE_LIBXML2) || defined(HAVE_JSON)
 static const char *
 _socktype(isc_sockettype_t type)
index e323f54d04e30b3af3f7b6aab9f5197980114eae..13d4ba58faecbc1c557c4dcab9409d232711b2e0 100644 (file)
@@ -78,6 +78,7 @@ isc_socket_getpeername
 isc_socket_getsockname
 isc_socket_gettag
 isc_socket_gettype
+isc_socket_hasreuseport
 isc_socket_ipv6only
 isc_socket_listen
 isc_socket_open
index 8be28bfc0da6eff759112e2829fe909f5009d341..026b4da765bacf60757ccd6f239b4bd5bc34e684 100644 (file)
@@ -3691,6 +3691,11 @@ isc_socket_socketevent(isc_mem_t *mctx, void *sender,
        return (allocate_socketevent(mctx, sender, eventtype, action, arg));
 }
 
+bool
+isc_socket_hasreuseport() {
+        return (false);
+}
+
 #ifdef HAVE_LIBXML2
 
 static const char *