diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index d45734ecc7..c7f721b2a0 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -1321,7 +1321,7 @@ isc__nm_closesocket(uv_os_sock_t sock); */ isc_result_t -isc__nm_socket_reuse(uv_os_sock_t fd); +isc__nm_socket_reuse(uv_os_sock_t fd, int val); /*%< * Set the SO_REUSEADDR or SO_REUSEPORT (or equivalent) socket option on the fd */ diff --git a/lib/isc/netmgr/socket.c b/lib/isc/netmgr/socket.c index 7440c0b855..8f02dc848d 100644 --- a/lib/isc/netmgr/socket.c +++ b/lib/isc/netmgr/socket.c @@ -159,7 +159,7 @@ isc__nm_closesocket(uv_os_sock_t sock) { } isc_result_t -isc__nm_socket_reuse(uv_os_sock_t fd) { +isc__nm_socket_reuse(uv_os_sock_t fd, int val) { /* * Generally, the SO_REUSEADDR socket option allows reuse of * local addresses. @@ -173,12 +173,12 @@ isc__nm_socket_reuse(uv_os_sock_t fd) { */ #if defined(SO_REUSEPORT) && !defined(__linux__) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)) == -1) { return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); #elif defined(SO_REUSEADDR) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEADDR) == -1) { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) { return (ISC_R_FAILURE); } return (ISC_R_SUCCESS); diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index f43b1118b0..1916b79998 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -289,7 +289,7 @@ isc__nm_tcp_lb_socket(isc_nm_t *mgr, sa_family_t sa_family) { /* FIXME: set mss */ - result = isc__nm_socket_reuse(sock); + result = isc__nm_socket_reuse(sock, 1); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (mgr->load_balance_sockets) { diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 82f99a61c8..4da1db8519 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -78,7 +78,7 @@ isc__nm_udp_lb_socket(isc_nm_t *mgr, sa_family_t sa_family) { (void)isc__nm_socket_disable_pmtud(sock, sa_family); (void)isc__nm_socket_v6only(sock, sa_family); - result = isc__nm_socket_reuse(sock); + result = isc__nm_socket_reuse(sock, 1); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (mgr->load_balance_sockets) { @@ -752,9 +752,10 @@ fail: static isc_result_t udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { - int uv_bind_flags = UV_UDP_REUSEADDR; + int uv_bind_flags = 0; int r; isc__networker_t *worker = sock->worker; + isc_result_t result; r = uv_udp_init(&worker->loop->loop, &sock->uv_handle.udp); UV_RUNTIME_CHECK(uv_udp_init, r); @@ -771,6 +772,12 @@ udp_connect_direct(isc_nmsocket_t *sock, isc__nm_uvreq_t *req) { } isc__nm_incstats(sock, STATID_OPEN); + /* + * uv_udp_open() enables REUSE_ADDR, we need to disable it again. + */ + result = isc__nm_socket_reuse(sock->fd, 0); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + if (sock->iface.type.sa.sa_family == AF_INET6) { uv_bind_flags |= UV_UDP_IPV6ONLY; } @@ -846,9 +853,6 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, sock->client = true; sock->fd = fd; - result = isc__nm_socket_reuse(sock->fd); - RUNTIME_CHECK(result == ISC_R_SUCCESS || - result == ISC_R_NOTIMPLEMENTED); (void)isc__nm_socket_disable_pmtud(sock->fd, sa_family); diff --git a/tests/isc/doh_test.c b/tests/isc/doh_test.c index 072816cf24..c8240281f9 100644 --- a/tests/isc/doh_test.c +++ b/tests/isc/doh_test.c @@ -247,7 +247,7 @@ setup_ephemeral_port(isc_sockaddr_t *addr, sa_family_t family) { return (r); } - result = isc__nm_socket_reuse(fd); + result = isc__nm_socket_reuse(fd, 1); if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { fprintf(stderr, "setup_ephemeral_port: isc__nm_socket_reuse(): %s",