summaryrefslogtreecommitdiff
path: root/lib/dns/dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/dispatch.c')
-rw-r--r--lib/dns/dispatch.c28
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));
}