diff options
Diffstat (limited to 'lib/dns/dispatch.c')
-rw-r--r-- | lib/dns/dispatch.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 129895431ddf4..1c113eccb235f 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -3038,6 +3038,8 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, if (result != ISC_R_SUCCESS) return (result); + disp->socktype = isc_sockettype_udp; + if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) { result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock, dup_socket); @@ -3087,7 +3089,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_mempool_setname(disp->portpool, "disp_portpool"); isc_mempool_setfreemax(disp->portpool, 128); } - disp->socktype = isc_sockettype_udp; disp->socket = sock; disp->local = *localaddr; @@ -3233,6 +3234,17 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, dns_messageid_t *idp, dns_dispentry_t **resp, isc_socketmgr_t *sockmgr) { + return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, + idp, resp, sockmgr)); +} + +isc_result_t +dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options, + isc_sockaddr_t *dest, isc_task_t *task, + isc_taskaction_t action, void *arg, + dns_messageid_t *idp, dns_dispentry_t **resp, + isc_socketmgr_t *sockmgr) +{ dns_dispentry_t *res; unsigned int bucket; in_port_t localport = 0; @@ -3320,10 +3332,14 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, } /* - * Try somewhat hard to find an unique ID. + * Try somewhat hard to find an unique ID unless FIXEDID is set + * in which case we use the id passed in via *idp. */ LOCK(&qid->lock); - id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp)); + if ((options & DNS_DISPATCHOPT_FIXEDID) != 0) + id = *idp; + else + id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp)); ok = ISC_FALSE; i = 0; do { @@ -3332,6 +3348,8 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest, ok = ISC_TRUE; break; } + if ((disp->attributes & DNS_DISPATCHATTR_FIXEDID) != 0) + break; id += qid->qid_increment; id &= 0x0000ffff; } while (i++ < 64); @@ -3419,7 +3437,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest, REQUIRE(VALID_DISPATCH(disp)); REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0); - return (dns_dispatch_addresponse2(disp, dest, task, action, arg, + return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg, idp, resp, NULL)); } |