2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

2048. [bug] It was possible to loop forever when using

avoid-v4-udp-ports / avoid-v6-udp-ports when
                        the OS always returned the same local port.
                        [RT #16182]
This commit is contained in:
Mark Andrews
2006-07-19 00:42:13 +00:00
parent ce9cfc26a1
commit 7076f000ea
2 changed files with 37 additions and 9 deletions

View File

@@ -1,3 +1,8 @@
2048. [bug] It was possible to loop forever when using
avoid-v4-udp-ports / avoid-v6-udp-ports when
the OS always returned the same local port.
[RT #16182]
2047. [bug] Failed to initialise the interface flags to zero. 2047. [bug] Failed to initialise the interface flags to zero.
[RT #16245] [RT #16245]

View File

@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * PERFORMANCE OF THIS SOFTWARE.
*/ */
/* $Id: dispatch.c,v 1.126 2006/01/06 00:01:44 marka Exp $ */ /* $Id: dispatch.c,v 1.127 2006/07/19 00:42:13 marka Exp $ */
/*! \file */ /*! \file */
@@ -1735,6 +1735,11 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
/* /*
* mgr should be locked. * mgr should be locked.
*/ */
#ifndef DNS_DISPATCH_HELD
#define DNS_DISPATCH_HELD 20U
#endif
static isc_result_t static isc_result_t
dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr, isc_taskmgr_t *taskmgr,
@@ -1745,7 +1750,9 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
{ {
isc_result_t result; isc_result_t result;
dns_dispatch_t *disp; dns_dispatch_t *disp;
isc_socket_t *sock; isc_socket_t *sock = NULL;
isc_socket_t *held[DNS_DISPATCH_HELD];
unsigned int i = 0, j = 0;
/* /*
* dispatch_allocate() checks mgr for us. * dispatch_allocate() checks mgr for us.
@@ -1756,17 +1763,30 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
return (result); return (result);
/* /*
* This assumes that the IP stack will *not* quickly reallocate * Try to allocate a socket that is not on the blacklist.
* the same port. If it does continually reallocate the same port * Hold up to DNS_DISPATCH_HELD sockets to prevent the OS
* then we need a mechanism to hold all the blacklisted sockets * from returning the same port to us too quickly.
* until we find a usable socket.
*/ */
memset(held, 0, sizeof(held));
getsocket: getsocket:
result = create_socket(sockmgr, localaddr, &sock); result = create_socket(sockmgr, localaddr, &sock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto deallocate_dispatch; goto deallocate_dispatch;
if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) { if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) {
isc_socket_detach(&sock); if (held[i] != NULL)
isc_socket_detach(&held[i]);
held[i++] = sock;
sock = NULL;
if (i == DNS_DISPATCH_HELD)
i = 0;
if (j++ == 0xffffU) {
mgr_log(mgr, ISC_LOG_ERROR, "avoid-v%s-udp-ports: "
"unable to allocate a non-blacklisted port",
isc_sockaddr_pf(localaddr) == AF_INET ?
"4" : "6");
result = ISC_R_FAILURE;
goto deallocate_dispatch;
}
goto getsocket; goto getsocket;
} }
@@ -1803,7 +1823,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
*dispp = disp; *dispp = disp;
return (ISC_R_SUCCESS); goto cleanheld;
/* /*
* Error returns. * Error returns.
@@ -1814,7 +1834,10 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_socket_detach(&disp->socket); isc_socket_detach(&disp->socket);
deallocate_dispatch: deallocate_dispatch:
dispatch_free(&disp); dispatch_free(&disp);
cleanheld:
for (i = 0; i < DNS_DISPATCH_HELD; i++)
if (held[i] != NULL)
isc_socket_detach(&held[i]);
return (result); return (result);
} }