From 5508e253769fd17e713a96e14750b8ee7ccd32d8 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Thu, 2 Feb 2023 12:16:49 -0800 Subject: [PATCH] use configured source ports for UDP requests the optional 'port' option, when used with notify-source, transfer-source, etc, is used to set up UDP dispatches with a particular source port, but when the actual UDP connection was established the port would be overridden with a random one. this has been fixed. (configuring source ports is deprecated in 9.20 and slated for removal in 9.22, but should still work correctly until then.) (cherry picked from commit 4d50c912ba78ac6a98b3f0e01e2d7563ea5aefd7) --- lib/dns/dispatch.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 7bcf2e840a..b529a4ae8f 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -366,7 +366,7 @@ setup_socket(dns_dispatch_t *disp, dns_dispentry_t *resp, dns_dispatchmgr_t *mgr = disp->mgr; unsigned int nports; in_port_t *ports = NULL; - in_port_t port; + in_port_t port = *portp; if (resp->retries++ > 5) { return (ISC_R_FAILURE); @@ -386,12 +386,13 @@ setup_socket(dns_dispatch_t *disp, dns_dispentry_t *resp, resp->local = disp->local; resp->peer = *dest; - port = ports[isc_random_uniform(nports)]; - isc_sockaddr_setport(&resp->local, port); + if (port == 0) { + port = ports[isc_random_uniform(nports)]; + isc_sockaddr_setport(&resp->local, port); + *portp = port; + } resp->port = port; - *portp = port; - return (ISC_R_SUCCESS); } @@ -1421,7 +1422,7 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, dns_dispentry_t **respp) { dns_dispentry_t *resp = NULL; dns_qid_t *qid = NULL; - in_port_t localport = 0; + in_port_t dispport, localport = 0; dns_messageid_t id; unsigned int bucket; bool ok = false; @@ -1446,8 +1447,12 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options, qid = disp->mgr->qid; - resp = isc_mem_get(disp->mgr->mctx, sizeof(*resp)); + dispport = isc_sockaddr_getport(&disp->local); + if (dispport != 0) { + localport = dispport; + } + resp = isc_mem_get(disp->mgr->mctx, sizeof(*resp)); *resp = (dns_dispentry_t){ .port = localport, .timeout = timeout,