Commit 9dc01a63 authored by Ondřej Surý's avatar Ondřej Surý Committed by Ondřej Surý
Browse files

Refactor isc__nm_socket_freebind() to take fd and sa_family as args

The isc__nm_socket_freebind() has been refactored to match other
isc__nm_socket_...() helper functions and take uv_os_fd_t and
sa_family_t as function arguments.
parent d685bbc8
...@@ -834,7 +834,7 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid); ...@@ -834,7 +834,7 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid);
*/ */
isc_result_t isc_result_t
isc__nm_socket_freebind(const uv_handle_t *handle); isc__nm_socket_freebind(uv_os_fd_t fd, sa_family_t sa_family);
/*%< /*%<
* Set the IP_FREEBIND (or equivalent) socket option on the uv_handle * Set the IP_FREEBIND (or equivalent) socket option on the uv_handle
*/ */
......
...@@ -1584,50 +1584,44 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid) { ...@@ -1584,50 +1584,44 @@ isc__nm_decstats(isc_nm_t *mgr, isc_statscounter_t counterid) {
setsockopt(socket, level, name, &(int){ 1 }, sizeof(int)) setsockopt(socket, level, name, &(int){ 1 }, sizeof(int))
isc_result_t isc_result_t
isc__nm_socket_freebind(const uv_handle_t *handle) { isc__nm_socket_freebind(uv_os_fd_t fd, sa_family_t sa_family) {
/* /*
* Set the IP_FREEBIND (or equivalent option) on the uv_handle. * Set the IP_FREEBIND (or equivalent option) on the uv_handle.
*/ */
isc_result_t result = ISC_R_SUCCESS;
uv_os_fd_t fd;
if (uv_fileno(handle, &fd) != 0) {
return (ISC_R_FAILURE);
}
#ifdef IP_FREEBIND #ifdef IP_FREEBIND
UNUSED(sa_family);
if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) { if (setsockopt_on(fd, IPPROTO_IP, IP_FREEBIND) == -1) {
return (ISC_R_FAILURE); return (ISC_R_FAILURE);
} }
return (ISC_R_SUCCESS);
#elif defined(IP_BINDANY) || defined(IPV6_BINDANY) #elif defined(IP_BINDANY) || defined(IPV6_BINDANY)
struct sockaddr_in sockfd; if (sa_family == AF_INET) {
if (getsockname(fd, (struct sockaddr *)&sockfd,
&(socklen_t){ sizeof(sockfd) }) == -1)
{
return (ISC_R_FAILURE);
}
#if defined(IP_BINDANY) #if defined(IP_BINDANY)
if (sockfd.sin_family == AF_INET) {
if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) { if (setsockopt_on(fd, IPPROTO_IP, IP_BINDANY) == -1) {
return (ISC_R_FAILURE); return (ISC_R_FAILURE);
} }
} return (ISC_R_SUCCESS);
#endif #endif
} else if (sa_family == AF_INET6) {
#if defined(IPV6_BINDANY) #if defined(IPV6_BINDANY)
if (sockfd.sin_family == AF_INET6) {
if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) { if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_BINDANY) == -1) {
return (ISC_R_FAILURE); return (ISC_R_FAILURE);
} }
} return (ISC_R_SUCCESS);
#endif #endif
}
return (ISC_R_NOTIMPLEMENTED);
#elif defined(SO_BINDANY) #elif defined(SO_BINDANY)
UNUSED(sa_family);
if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) { if (setsockopt_on(fd, SOL_SOCKET, SO_BINDANY) == -1) {
return (ISC_R_FAILURE); return (ISC_R_FAILURE);
} }
return (ISC_R_SUCCESS);
#else #else
UNUSED(handle); UNUSED(fd);
result = ISC_R_NOTIMPLEMENTED; UNUSED(sa_family);
return (ISC_R_NOTIMPLEMENTED);
#endif #endif
return (result);
} }
isc_result_t isc_result_t
......
...@@ -318,6 +318,8 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { ...@@ -318,6 +318,8 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
isc_nmsocket_t *sock = ievent->sock; isc_nmsocket_t *sock = ievent->sock;
struct sockaddr_storage sname; struct sockaddr_storage sname;
int r, flags = 0, snamelen = sizeof(sname); int r, flags = 0, snamelen = sizeof(sname);
sa_family_t sa_family;
uv_os_fd_t fd;
REQUIRE(isc__nm_in_netthread()); REQUIRE(isc__nm_in_netthread());
REQUIRE(sock->type == isc_nm_tcplistener); REQUIRE(sock->type == isc_nm_tcplistener);
...@@ -334,14 +336,16 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) { ...@@ -334,14 +336,16 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]); isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPEN]);
if (sock->iface->addr.type.sa.sa_family == AF_INET6) { sa_family = sock->iface->addr.type.sa.sa_family;
if (sa_family == AF_INET6) {
flags = UV_TCP_IPV6ONLY; flags = UV_TCP_IPV6ONLY;
} }
r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa,
flags); flags);
if (r == UV_EADDRNOTAVAIL && if (r == UV_EADDRNOTAVAIL &&
isc__nm_socket_freebind(&sock->uv_handle.handle) == ISC_R_SUCCESS) uv_fileno(&sock->uv_handle.handle, &fd) == 0 &&
isc__nm_socket_freebind(fd, sa_family) == ISC_R_SUCCESS)
{ {
/* /*
* Retry binding with IP_FREEBIND (or equivalent option) if the * Retry binding with IP_FREEBIND (or equivalent option) if the
......
...@@ -137,6 +137,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { ...@@ -137,6 +137,7 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
isc_nmsocket_t *sock = ievent->sock; isc_nmsocket_t *sock = ievent->sock;
int r, uv_bind_flags = 0; int r, uv_bind_flags = 0;
int uv_init_flags = 0; int uv_init_flags = 0;
sa_family_t sa_family;
REQUIRE(sock->type == isc_nm_udpsocket); REQUIRE(sock->type == isc_nm_udpsocket);
REQUIRE(sock->iface != NULL); REQUIRE(sock->iface != NULL);
...@@ -158,14 +159,15 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) { ...@@ -158,14 +159,15 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]); isc__nm_incstats(sock->mgr, sock->statsindex[STATID_OPENFAIL]);
} }
if (sock->iface->addr.type.sa.sa_family == AF_INET6) { sa_family = sock->iface->addr.type.sa.sa_family;
if (sa_family == AF_INET6) {
uv_bind_flags |= UV_UDP_IPV6ONLY; uv_bind_flags |= UV_UDP_IPV6ONLY;
} }
r = uv_udp_bind(&sock->uv_handle.udp, r = uv_udp_bind(&sock->uv_handle.udp,
&sock->parent->iface->addr.type.sa, uv_bind_flags); &sock->parent->iface->addr.type.sa, uv_bind_flags);
if (r == UV_EADDRNOTAVAIL && if (r == UV_EADDRNOTAVAIL &&
isc__nm_socket_freebind(&sock->uv_handle.handle) == ISC_R_SUCCESS) isc__nm_socket_freebind(sock->fd, sa_family) == ISC_R_SUCCESS)
{ {
/* /*
* Retry binding with IP_FREEBIND (or equivalent option) if the * Retry binding with IP_FREEBIND (or equivalent option) if the
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment