isc_socketmgr_t *sockmgr,
const isc_sockaddr_t *localaddr,
isc_socket_t **sockp,
- isc_socket_t *dup_socket);
+ isc_socket_t *dup_socket,
+ bool duponly);
static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr,
isc_socketmgr_t *sockmgr,
isc_taskmgr_t *taskmgr,
static isc_result_t open_socket(isc_socketmgr_t *mgr,
const isc_sockaddr_t *local,
unsigned int options, isc_socket_t **sockp,
- isc_socket_t *dup_socket);
+ isc_socket_t *dup_socket, bool duponly);
static bool portavailable(dns_dispatchmgr_t *mgr, isc_socket_t *sock,
isc_sockaddr_t *sockaddrp);
if (portentry != NULL)
bindoptions |= ISC_SOCKET_REUSEADDRESS;
result = open_socket(sockmgr, &localaddr, bindoptions, &sock,
- NULL);
+ NULL, false);
if (result == ISC_R_SUCCESS) {
if (portentry == NULL) {
portentry = new_portentry(disp, port);
static isc_result_t
open_socket(isc_socketmgr_t *mgr, const isc_sockaddr_t *local,
unsigned int options, isc_socket_t **sockp,
- isc_socket_t *dup_socket)
+ isc_socket_t *dup_socket, bool duponly)
{
isc_socket_t *sock;
isc_result_t result;
result = isc_socket_open(sock);
if (result != ISC_R_SUCCESS)
return (result);
- } else if (dup_socket != NULL && !isc_socket_hasreuseport()) {
+ } else if (dup_socket != NULL && (!isc_socket_hasreuseport() || duponly)) {
result = isc_socket_dup(dup_socket, &sock);
if (result != ISC_R_SUCCESS)
return (result);
static isc_result_t
get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
isc_socketmgr_t *sockmgr, const isc_sockaddr_t *localaddr,
- isc_socket_t **sockp, isc_socket_t *dup_socket)
+ isc_socket_t **sockp, isc_socket_t *dup_socket, bool duponly)
{
unsigned int i, j;
isc_socket_t *held[DNS_DISPATCH_HELD];
prt = ports[isc_random_uniform(nports)];
isc_sockaddr_setport(&localaddr_bound, prt);
result = open_socket(sockmgr, &localaddr_bound,
- 0, &sock, NULL);
+ 0, &sock, NULL, false);
/*
* Continue if the port choosen is already in use
* or the OS has reserved it.
/* Allow to reuse address for non-random ports. */
result = open_socket(sockmgr, localaddr,
ISC_SOCKET_REUSEADDRESS, &sock,
- dup_socket);
+ dup_socket, duponly);
if (result == ISC_R_SUCCESS)
*sockp = sock;
i = 0;
for (j = 0; j < 0xffffU; j++) {
- result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
+ result = open_socket(sockmgr, localaddr, 0, &sock, NULL, false);
if (result != ISC_R_SUCCESS)
goto end;
else if (portavailable(mgr, sock, NULL))
isc_socket_t *sock = NULL;
int i = 0;
+ bool duponly = ((attributes & DNS_DISPATCHATTR_CANREUSE) == 0);
+ /* This is an attribute needed only at creation time */
+ attributes &= ~DNS_DISPATCHATTR_CANREUSE;
/*
* dispatch_allocate() checks mgr for us.
*/
if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) {
result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock,
- dup_socket);
+ dup_socket, duponly);
if (result != ISC_R_SUCCESS)
goto deallocate_dispatch;
*/
isc_sockaddr_anyofpf(&sa_any, isc_sockaddr_pf(localaddr));
if (!isc_sockaddr_eqaddr(&sa_any, localaddr)) {
- result = open_socket(sockmgr, localaddr, 0, &sock, NULL);
+ result = open_socket(sockmgr, localaddr, 0, &sock, NULL, false);
if (sock != NULL)
isc_socket_detach(&sock);
if (result != ISC_R_SUCCESS)