*/
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
*/
setsockopt(socket, level, name, &(int){ 1 }, sizeof(int))
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.
*/
- 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
+ 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)
- struct sockaddr_in sockfd;
-
- if (getsockname(fd, (struct sockaddr *)&sockfd,
- &(socklen_t){ sizeof(sockfd) }) == -1)
- {
- return (ISC_R_FAILURE);
- }
+ if (sa_family == AF_INET) {
#if defined(IP_BINDANY)
- if (sockfd.sin_family == AF_INET) {
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 (sockfd.sin_family == AF_INET6) {
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(handle);
- result = ISC_R_NOTIMPLEMENTED;
+ UNUSED(fd);
+ UNUSED(sa_family);
+ return (ISC_R_NOTIMPLEMENTED);
#endif
- return (result);
}
isc_result_t
isc_nmsocket_t *sock = ievent->sock;
struct sockaddr_storage sname;
int r, flags = 0, snamelen = sizeof(sname);
+ sa_family_t sa_family;
+ uv_os_fd_t fd;
REQUIRE(isc__nm_in_netthread());
REQUIRE(sock->type == isc_nm_tcplistener);
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;
}
r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa,
flags);
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
isc_nmsocket_t *sock = ievent->sock;
int r, uv_bind_flags = 0;
int uv_init_flags = 0;
+ sa_family_t sa_family;
REQUIRE(sock->type == isc_nm_udpsocket);
REQUIRE(sock->iface != NULL);
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;
}
r = uv_udp_bind(&sock->uv_handle.udp,
&sock->parent->iface->addr.type.sa, uv_bind_flags);
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