]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add runtime detection of SO_REUSEPORT, use it if available (instead of dup)
authorWitold Kręcicki <wpk@isc.org>
Thu, 23 Aug 2018 07:42:30 +0000 (09:42 +0200)
committerWitold Kręcicki <wpk@isc.org>
Wed, 24 Oct 2018 07:10:20 +0000 (07:10 +0000)
bin/tests/system/rpzrecurse/setup.sh
bin/tests/system/rpzrecurse/tests.sh
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 36786a72dee78092ae77f5808009b0f052f4ba21..7deefd8427f5b37233ef01912a9acab40ba9fc37 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/sh -x
 #
 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 #
index 38dead46e237a10e8ae147847eb4f109246e4723..ed1f3143f6c8e8dd231618a8d2efa6c3ffab570f 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/sh -x
 #
 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 #
index 6202a778ec8be90e146033ef59b2ab2170933e9a..670be5a7194c81cb90b4ab0d36d145d9a790fa52 100644 (file)
@@ -1678,7 +1678,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 588a355d59b0efaeb3fe88f3540a8217f1b5ab15..450ee3e16f584de04cd357ce9daf7f7db295f94a 100644 (file)
@@ -1037,6 +1037,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 aa2ba8c5f2ba60bf8253cbb6a3e52b4fba91fb6a..8c831334586d6527cb0118569ab30abaddae5c7c 100644 (file)
@@ -4802,13 +4802,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
@@ -5667,6 +5675,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 e15bdacd2bcc5884e8095fb8262acb370b6c196f..6c74f62c899b0ff26df2a0b01b79847a4c8b2524 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 8e568268a85e402687877f26af83c66d58e5016a..a64f11d9ebe021babbae862f0c9fd25af79cc8a8 100644 (file)
@@ -3941,6 +3941,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 *