From: Ondřej Surý Date: Wed, 27 Apr 2022 15:41:47 +0000 (+0200) Subject: Move socket related functions to netmgr/socket.c X-Git-Tag: v9.19.1~15^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=24c38796754521844eb77f0bacd7dd53a34b10e1;p=thirdparty%2Fbind9.git Move socket related functions to netmgr/socket.c Move the netmgr socket related functions from netmgr/netmgr.c and netmgr/uv-compat.c to netmgr/socket.c, so they are all present all in the same place. Adjust the names of couple interal functions accordingly. --- diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index c0bb69fa4ab..7ac556adaab 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -103,6 +103,7 @@ libisc_la_SOURCES = \ $(libisc_la_HEADERS) \ netmgr/netmgr-int.h \ netmgr/netmgr.c \ + netmgr/socket.c \ netmgr/tcp.c \ netmgr/tcpdns.c \ netmgr/timer.c \ diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 10c56514af5..0594faa5f60 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -1875,12 +1875,6 @@ isc__nm_closesocket(uv_os_sock_t sock); * Platform independent closesocket() version */ -isc_result_t -isc__nm_socket_freebind(uv_os_sock_t fd, sa_family_t sa_family); -/*%< - * Set the IP_FREEBIND (or equivalent) socket option on the uv_handle - */ - isc_result_t isc__nm_socket_reuse(uv_os_sock_t fd); /*%< @@ -2160,3 +2154,15 @@ isc__nmsocket_writetimeout_cb(void *data, isc_result_t eresult); isc_error_fatal(__FILE__, __LINE__, "%s failed: %s", #func, \ uv_strerror(ret)); \ } + +/* + * Bind to the socket, but allow binding to IPv6 tentative addresses reported by + * the route socket by setting IP_FREEBIND (or equivalent). + */ +int +isc__nm_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr, + unsigned int flags); + +int +isc__nm_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr, + unsigned int flags); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index f7444630c86..0b250fe1dc8 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -2978,213 +2978,6 @@ isc__nm_decstats(isc_nmsocket_t *sock, isc__nm_statid_t id) { } } -isc_result_t -isc__nm_socket(int domain, int type, int protocol, uv_os_sock_t *sockp) { - int sock = socket(domain, type, protocol); - if (sock < 0) { - return (isc_errno_toresult(errno)); - } - - *sockp = (uv_os_sock_t)sock; - return (ISC_R_SUCCESS); -} - -void -isc__nm_closesocket(uv_os_sock_t sock) { - close(sock); -} - -#define setsockopt_on(socket, level, name) \ - setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) - -#define setsockopt_off(socket, level, name) \ - setsockopt(socket, level, name, &(int){ 0 }, sizeof(int)) - -isc_result_t -isc__nm_socket_freebind(uv_os_sock_t fd, sa_family_t sa_family) { - /* - * Set the IP_FREEBIND (or equivalent option) on the uv_handle. - */ -#ifdef IP_FREEBIND - UNUSED(sa_family); - if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#elif defined(IP_BINDANY) || defined(IPV6_BINDANY) - if (sa_family == AF_INET) { -#if defined(IP_BINDANY) - if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#endif - } else if (sa_family == AF_INET6) { -#if defined(IPV6_BINDANY) - if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#endif - } - return (ISC_R_NOTIMPLEMENTED); -#elif defined(SO_BINDANY) - UNUSED(sa_family); - if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#else - UNUSED(fd); - UNUSED(sa_family); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -isc__nm_socket_reuse(uv_os_sock_t fd) { - /* - * Generally, the SO_REUSEADDR socket option allows reuse of - * local addresses. - * - * On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some - * additional refinements for programs that use multicast. - * - * On Linux, SO_REUSEPORT has different semantics: it _shares_ the port - * rather than steal it from the current listener, so we don't use it - * here, but rather in isc__nm_socket_reuse_lb(). - * - * On Windows, it also allows a socket to forcibly bind to a port in use - * by another socket. - */ - -#if defined(SO_REUSEPORT) && !defined(__linux__) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#elif defined(SO_REUSEADDR) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEADDR) == -1) { - return (ISC_R_FAILURE); - } - return (ISC_R_SUCCESS); -#else - UNUSED(fd); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -isc__nm_socket_reuse_lb(uv_os_sock_t fd) { - /* - * On FreeBSD 12+, SO_REUSEPORT_LB socket option allows sockets to be - * bound to an identical socket address. For UDP sockets, the use of - * this option can provide better distribution of incoming datagrams to - * multiple processes (or threads) as compared to the traditional - * technique of having multiple processes compete to receive datagrams - * on the same socket. - * - * On Linux, the same thing is achieved simply with SO_REUSEPORT. - */ -#if defined(SO_REUSEPORT_LB) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT_LB) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#elif defined(SO_REUSEPORT) && defined(__linux__) - if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); - return (ISC_R_NOTIMPLEMENTED); -#endif -} - -isc_result_t -isc__nm_socket_incoming_cpu(uv_os_sock_t fd) { -#ifdef SO_INCOMING_CPU - if (setsockopt_on(fd, SOL_SOCKET, SO_INCOMING_CPU) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); -#endif - return (ISC_R_NOTIMPLEMENTED); -} - -isc_result_t -isc__nm_socket_disable_pmtud(uv_os_sock_t fd, sa_family_t sa_family) { - /* - * Disable the Path MTU Discovery on IP packets - */ - if (sa_family == AF_INET6) { -#if defined(IPV6_DONTFRAG) - if (setsockopt_off(fd, IPPROTO_IPV6, IPV6_DONTFRAG) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#elif defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT) - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, - &(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1) - { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); -#endif - } else if (sa_family == AF_INET) { -#if defined(IP_DONTFRAG) - if (setsockopt_off(fd, IPPROTO_IP, IP_DONTFRAG) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT) - if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, - &(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1) - { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); -#endif - } else { - return (ISC_R_FAMILYNOSUPPORT); - } - - return (ISC_R_NOTIMPLEMENTED); -} - -isc_result_t -isc__nm_socket_v6only(uv_os_sock_t fd, sa_family_t sa_family) { - /* - * Enable the IPv6-only option on IPv6 sockets - */ - if (sa_family == AF_INET6) { -#if defined(IPV6_V6ONLY) - if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_V6ONLY) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); -#endif - } - return (ISC_R_NOTIMPLEMENTED); -} - isc_result_t isc_nm_checkaddr(const isc_sockaddr_t *addr, isc_socktype_t type) { int proto, pf, addrlen, fd, r; @@ -3242,81 +3035,6 @@ isc_nm_checkaddr(const isc_sockaddr_t *addr, isc_socktype_t type) { #define TIMEOUT_OPTNAME TCP_KEEPINIT #endif -isc_result_t -isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms) { -#if defined(TIMEOUT_OPTNAME) - TIMEOUT_TYPE timeout = timeout_ms / TIMEOUT_DIV; - - if (timeout == 0) { - timeout = 1; - } - - if (setsockopt(fd, IPPROTO_TCP, TIMEOUT_OPTNAME, &timeout, - sizeof(timeout)) == -1) - { - return (ISC_R_FAILURE); - } - - return (ISC_R_SUCCESS); -#else - UNUSED(fd); - UNUSED(timeout_ms); - - return (ISC_R_SUCCESS); -#endif -} - -isc_result_t -isc__nm_socket_tcp_nodelay(uv_os_sock_t fd) { -#ifdef TCP_NODELAY - if (setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) == -1) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); - return (ISC_R_SUCCESS); -#endif -} - -isc_result_t -isc__nm_socket_tcp_maxseg(uv_os_sock_t fd, int size) { -#ifdef TCP_MAXSEG - if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (void *)&size, - sizeof(size))) { - return (ISC_R_FAILURE); - } else { - return (ISC_R_SUCCESS); - } -#else - UNUSED(fd); - UNUSED(size); - return (ISC_R_SUCCESS); -#endif -} - -isc_result_t -isc__nm_socket_min_mtu(uv_os_sock_t fd, sa_family_t sa_family) { - if (sa_family != AF_INET6) { - return (ISC_R_SUCCESS); - } -#ifdef IPV6_USE_MIN_MTU - if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU) == -1) { - return (ISC_R_FAILURE); - } -#elif defined(IPV6_MTU) - if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &(int){ 1280 }, - sizeof(int)) == -1) { - return (ISC_R_FAILURE); - } -#else - UNUSED(fd); -#endif - - return (ISC_R_SUCCESS); -} - void isc__nm_set_network_buffers(isc_nm_t *nm, uv_handle_t *handle) { int32_t recv_buffer_size = 0; diff --git a/lib/isc/netmgr/socket.c b/lib/isc/netmgr/socket.c new file mode 100644 index 00000000000..291ac99fa26 --- /dev/null +++ b/lib/isc/netmgr/socket.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include + +#include "netmgr-int.h" +#include "uv-compat.h" + +#define setsockopt_on(socket, level, name) \ + setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) + +#define setsockopt_off(socket, level, name) \ + setsockopt(socket, level, name, &(int){ 0 }, sizeof(int)) + +static isc_result_t +socket_freebind(uv_os_sock_t fd, sa_family_t sa_family) { + /* + * Set the IP_FREEBIND (or equivalent option) on the uv_handle. + */ +#ifdef IP_FREEBIND + UNUSED(sa_family); + if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#elif defined(IP_BINDANY) || defined(IPV6_BINDANY) + if (sa_family == AF_INET) { +#if defined(IP_BINDANY) + if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#endif + } else if (sa_family == AF_INET6) { +#if defined(IPV6_BINDANY) + if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#endif + } + return (ISC_R_NOTIMPLEMENTED); +#elif defined(SO_BINDANY) + UNUSED(sa_family); + if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#else + UNUSED(fd); + UNUSED(sa_family); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +int +isc__nm_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr, + unsigned int flags) { + int r; + uv_os_sock_t fd; + + r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd); + if (r < 0) { + return (r); + } + + r = uv_udp_bind(handle, addr, flags); + if (r == UV_EADDRNOTAVAIL && + socket_freebind(fd, addr->sa_family) == ISC_R_SUCCESS) + { + /* + * Retry binding with IP_FREEBIND (or equivalent option) if the + * address is not available. This helps with IPv6 tentative + * addresses which are reported by the route socket, although + * named is not yet able to properly bind to them. + */ + r = uv_udp_bind(handle, addr, flags); + } + + return (r); +} + +static int +tcp_bind_now(uv_tcp_t *handle, const struct sockaddr *addr, + unsigned int flags) { + int r; + struct sockaddr_storage sname; + int snamelen = sizeof(sname); + + r = uv_tcp_bind(handle, addr, flags); + if (r < 0) { + return (r); + } + + /* + * uv_tcp_bind() uses a delayed error, initially returning + * success even if bind() fails. By calling uv_tcp_getsockname() + * here we can find out whether the bind() call was successful. + */ + r = uv_tcp_getsockname(handle, (struct sockaddr *)&sname, &snamelen); + if (r < 0) { + return (r); + } + + return (0); +} + +int +isc__nm_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr, + unsigned int flags) { + int r; + uv_os_sock_t fd; + + r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd); + if (r < 0) { + return (r); + } + + r = tcp_bind_now(handle, addr, flags); + if (r == UV_EADDRNOTAVAIL && + socket_freebind(fd, addr->sa_family) == ISC_R_SUCCESS) + { + /* + * Retry binding with IP_FREEBIND (or equivalent option) if the + * address is not available. This helps with IPv6 tentative + * addresses which are reported by the route socket, although + * named is not yet able to properly bind to them. + */ + r = tcp_bind_now(handle, addr, flags); + } + + return (r); +} + +isc_result_t +isc__nm_socket(int domain, int type, int protocol, uv_os_sock_t *sockp) { + int sock = socket(domain, type, protocol); + if (sock < 0) { + return (isc_errno_toresult(errno)); + } + + *sockp = (uv_os_sock_t)sock; + return (ISC_R_SUCCESS); +} + +void +isc__nm_closesocket(uv_os_sock_t sock) { + close(sock); +} + +isc_result_t +isc__nm_socket_reuse(uv_os_sock_t fd) { + /* + * Generally, the SO_REUSEADDR socket option allows reuse of + * local addresses. + * + * On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some + * additional refinements for programs that use multicast. + * + * On Linux, SO_REUSEPORT has different semantics: it _shares_ the port + * rather than steal it from the current listener, so we don't use it + * here, but rather in isc__nm_socket_reuse_lb(). + * + * On Windows, it also allows a socket to forcibly bind to a port in use + * by another socket. + */ + +#if defined(SO_REUSEPORT) && !defined(__linux__) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#elif defined(SO_REUSEADDR) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEADDR) == -1) { + return (ISC_R_FAILURE); + } + return (ISC_R_SUCCESS); +#else + UNUSED(fd); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +isc_result_t +isc__nm_socket_reuse_lb(uv_os_sock_t fd) { + /* + * On FreeBSD 12+, SO_REUSEPORT_LB socket option allows sockets to be + * bound to an identical socket address. For UDP sockets, the use of + * this option can provide better distribution of incoming datagrams to + * multiple processes (or threads) as compared to the traditional + * technique of having multiple processes compete to receive datagrams + * on the same socket. + * + * On Linux, the same thing is achieved simply with SO_REUSEPORT. + */ +#if defined(SO_REUSEPORT_LB) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT_LB) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(SO_REUSEPORT) && defined(__linux__) + if (setsockopt_on(fd, SOL_SOCKET, SO_REUSEPORT) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); + return (ISC_R_NOTIMPLEMENTED); +#endif +} + +isc_result_t +isc__nm_socket_incoming_cpu(uv_os_sock_t fd) { +#ifdef SO_INCOMING_CPU + if (setsockopt_on(fd, SOL_SOCKET, SO_INCOMING_CPU) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + return (ISC_R_NOTIMPLEMENTED); +} + +isc_result_t +isc__nm_socket_disable_pmtud(uv_os_sock_t fd, sa_family_t sa_family) { + /* + * Disable the Path MTU Discovery on IP packets + */ + if (sa_family == AF_INET6) { +#if defined(IPV6_DONTFRAG) + if (setsockopt_off(fd, IPPROTO_IPV6, IPV6_DONTFRAG) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1) + { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + } else if (sa_family == AF_INET) { +#if defined(IP_DONTFRAG) + if (setsockopt_off(fd, IPPROTO_IP, IP_DONTFRAG) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT) + if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, + &(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1) + { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + } else { + return (ISC_R_FAMILYNOSUPPORT); + } + + return (ISC_R_NOTIMPLEMENTED); +} + +isc_result_t +isc__nm_socket_v6only(uv_os_sock_t fd, sa_family_t sa_family) { + /* + * Enable the IPv6-only option on IPv6 sockets + */ + if (sa_family == AF_INET6) { +#if defined(IPV6_V6ONLY) + if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_V6ONLY) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); +#endif + } + return (ISC_R_NOTIMPLEMENTED); +} + +isc_result_t +isc__nm_socket_connectiontimeout(uv_os_sock_t fd, int timeout_ms) { +#if defined(TIMEOUT_OPTNAME) + TIMEOUT_TYPE timeout = timeout_ms / TIMEOUT_DIV; + + if (timeout == 0) { + timeout = 1; + } + + if (setsockopt(fd, IPPROTO_TCP, TIMEOUT_OPTNAME, &timeout, + sizeof(timeout)) == -1) + { + return (ISC_R_FAILURE); + } + + return (ISC_R_SUCCESS); +#else + UNUSED(fd); + UNUSED(timeout_ms); + + return (ISC_R_SUCCESS); +#endif +} + +isc_result_t +isc__nm_socket_tcp_nodelay(uv_os_sock_t fd) { +#ifdef TCP_NODELAY + if (setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) == -1) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); + return (ISC_R_SUCCESS); +#endif +} + +isc_result_t +isc__nm_socket_tcp_maxseg(uv_os_sock_t fd, int size) { +#ifdef TCP_MAXSEG + if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, (void *)&size, + sizeof(size))) { + return (ISC_R_FAILURE); + } else { + return (ISC_R_SUCCESS); + } +#else + UNUSED(fd); + UNUSED(size); + return (ISC_R_SUCCESS); +#endif +} + +isc_result_t +isc__nm_socket_min_mtu(uv_os_sock_t fd, sa_family_t sa_family) { + if (sa_family != AF_INET6) { + return (ISC_R_SUCCESS); + } +#ifdef IPV6_USE_MIN_MTU + if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU) == -1) { + return (ISC_R_FAILURE); + } +#elif defined(IPV6_MTU) + if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &(int){ 1280 }, + sizeof(int)) == -1) { + return (ISC_R_FAILURE); + } +#else + UNUSED(fd); +#endif + + return (ISC_R_SUCCESS); +} diff --git a/lib/isc/netmgr/tcp.c b/lib/isc/netmgr/tcp.c index e7eb77feb56..1ef80d4e2ec 100644 --- a/lib/isc/netmgr/tcp.c +++ b/lib/isc/netmgr/tcp.c @@ -550,16 +550,16 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { } if (mgr->load_balance_sockets) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; } } else { if (sock->parent->fd == -1) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index 73753742eaf..0d928069abe 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -516,16 +516,16 @@ isc__nm_async_tcpdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) { } if (mgr->load_balance_sockets) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; } } else { if (sock->parent->fd == -1) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; diff --git a/lib/isc/netmgr/tlsdns.c b/lib/isc/netmgr/tlsdns.c index 68fbca67fe2..3529c356160 100644 --- a/lib/isc/netmgr/tlsdns.c +++ b/lib/isc/netmgr/tlsdns.c @@ -603,16 +603,16 @@ isc__nm_async_tlsdnslisten(isc__networker_t *worker, isc__netievent_t *ev0) { } if (mgr->load_balance_sockets) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; } } else { if (sock->parent->fd == -1) { - r = isc_uv_tcp_freebind(&sock->uv_handle.tcp, - &sock->iface.type.sa, flags); + r = isc__nm_tcp_freebind(&sock->uv_handle.tcp, + &sock->iface.type.sa, flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; diff --git a/lib/isc/netmgr/udp.c b/lib/isc/netmgr/udp.c index 29a603a0dd2..df4312fba25 100644 --- a/lib/isc/netmgr/udp.c +++ b/lib/isc/netmgr/udp.c @@ -463,9 +463,9 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { } if (mgr->load_balance_sockets) { - r = isc_uv_udp_freebind(&sock->uv_handle.udp, - &sock->parent->iface.type.sa, - uv_bind_flags); + r = isc__nm_udp_freebind(&sock->uv_handle.udp, + &sock->parent->iface.type.sa, + uv_bind_flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; @@ -473,9 +473,9 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { } else { if (sock->parent->fd == -1) { /* This thread is first, bind the socket */ - r = isc_uv_udp_freebind(&sock->uv_handle.udp, - &sock->parent->iface.type.sa, - uv_bind_flags); + r = isc__nm_udp_freebind(&sock->uv_handle.udp, + &sock->parent->iface.type.sa, + uv_bind_flags); if (r < 0) { isc__nm_incstats(sock, STATID_BINDFAIL); goto done; diff --git a/lib/isc/netmgr/uv-compat.c b/lib/isc/netmgr/uv-compat.c index b7c0f7b0e29..39ec0cfed2f 100644 --- a/lib/isc/netmgr/uv-compat.c +++ b/lib/isc/netmgr/uv-compat.c @@ -59,82 +59,3 @@ uv_tcp_close_reset(uv_tcp_t *handle, uv_close_cb close_cb) { return (0); } #endif /* UV_VERSION_HEX < UV_VERSION(1, 32, 0) */ - -int -isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr, - unsigned int flags) { - int r; - uv_os_sock_t fd; - - r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd); - if (r < 0) { - return (r); - } - - r = uv_udp_bind(handle, addr, flags); - if (r == UV_EADDRNOTAVAIL && - isc__nm_socket_freebind(fd, addr->sa_family) == ISC_R_SUCCESS) - { - /* - * Retry binding with IP_FREEBIND (or equivalent option) if the - * address is not available. This helps with IPv6 tentative - * addresses which are reported by the route socket, although - * named is not yet able to properly bind to them. - */ - r = uv_udp_bind(handle, addr, flags); - } - - return (r); -} - -static int -isc__uv_tcp_bind_now(uv_tcp_t *handle, const struct sockaddr *addr, - unsigned int flags) { - int r; - struct sockaddr_storage sname; - int snamelen = sizeof(sname); - - r = uv_tcp_bind(handle, addr, flags); - if (r < 0) { - return (r); - } - - /* - * uv_tcp_bind() uses a delayed error, initially returning - * success even if bind() fails. By calling uv_tcp_getsockname() - * here we can find out whether the bind() call was successful. - */ - r = uv_tcp_getsockname(handle, (struct sockaddr *)&sname, &snamelen); - if (r < 0) { - return (r); - } - - return (0); -} - -int -isc_uv_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr, - unsigned int flags) { - int r; - uv_os_sock_t fd; - - r = uv_fileno((const uv_handle_t *)handle, (uv_os_fd_t *)&fd); - if (r < 0) { - return (r); - } - - r = isc__uv_tcp_bind_now(handle, addr, flags); - if (r == UV_EADDRNOTAVAIL && - isc__nm_socket_freebind(fd, addr->sa_family) == ISC_R_SUCCESS) - { - /* - * Retry binding with IP_FREEBIND (or equivalent option) if the - * address is not available. This helps with IPv6 tentative - * addresses which are reported by the route socket, although - * named is not yet able to properly bind to them. - */ - r = isc__uv_tcp_bind_now(handle, addr, flags); - } - - return (r); -} diff --git a/lib/isc/netmgr/uv-compat.h b/lib/isc/netmgr/uv-compat.h index 3a103874e4a..91e5d2c107c 100644 --- a/lib/isc/netmgr/uv-compat.h +++ b/lib/isc/netmgr/uv-compat.h @@ -116,11 +116,3 @@ uv_os_getenv(const char *name, char *buffer, size_t *size) { #define uv_os_setenv(name, value) setenv(name, value, 0) #endif /* UV_VERSION_HEX < UV_VERSION(1, 12, 0) */ - -int -isc_uv_udp_freebind(uv_udp_t *handle, const struct sockaddr *addr, - unsigned int flags); - -int -isc_uv_tcp_freebind(uv_tcp_t *handle, const struct sockaddr *addr, - unsigned int flags); diff --git a/lib/isc/tests/doh_test.c b/lib/isc/tests/doh_test.c index 2d7907d5006..a2625a0a97a 100644 --- a/lib/isc/tests/doh_test.c +++ b/lib/isc/tests/doh_test.c @@ -43,6 +43,7 @@ #include "../netmgr/http.c" #include "../netmgr/netmgr-int.h" +#include "../netmgr/socket.c" #include "../netmgr/uv-compat.c" #include "../netmgr/uv-compat.h" #include "../netmgr_p.h" diff --git a/lib/isc/tests/netmgr_test.c b/lib/isc/tests/netmgr_test.c index 62353dd0b74..c9c6a7504d6 100644 --- a/lib/isc/tests/netmgr_test.c +++ b/lib/isc/tests/netmgr_test.c @@ -35,6 +35,7 @@ #define KEEP_BEFORE #include "../netmgr/netmgr-int.h" +#include "../netmgr/socket.c" #include "../netmgr/udp.c" #include "../netmgr/uv-compat.c" #include "../netmgr/uv-compat.h"