From 643abfbba7fe9eb7e2000ee3015c7e680cc590a2 Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Mon, 12 Dec 2022 11:55:09 +0000 Subject: [PATCH] Synchronize dns_request_createraw() and dns_request_create() UDP timeout The dns_request_createraw() function, unlike dns_request_create(), when calculating the UDP timeout value, doesn't check that 'udpretries' is not zero, and that is the more logical behavior, because the calculation formula uses division to 'udpretries + 1', where '1' is the first try. Change the dns_request_create() function to remove the 'udpretries != 0' condition. Add a 'REQUIRE(udpretries != UINT_MAX)' check to protect from a division by zero. Make the 'request->udpcount' field to represent the number of tries, instead of the number of retries. --- lib/dns/request.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/dns/request.c b/lib/dns/request.c index f78a57d7a3..977b2ebaad 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -421,6 +421,8 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, REQUIRE(cb != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); + REQUIRE(udpretries != UINT_MAX); + if (srcaddr != NULL) { REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr)); } @@ -447,7 +449,7 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, request->cb = cb; request->arg = arg; request->result = ISC_R_FAILURE; - request->udpcount = udpretries; + request->udpcount = udpretries + 1; isc_buffer_usedregion(msgbuf, &r); if (r.length < DNS_MESSAGE_HEADERLEN || r.length > 65535) { @@ -460,7 +462,7 @@ dns_request_createraw(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, request->timeout = timeout * 1000; } else { if (udptimeout == 0) { - udptimeout = timeout / (udpretries + 1); + udptimeout = timeout / request->udpcount; } if (udptimeout == 0) { udptimeout = 1; @@ -569,6 +571,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, REQUIRE(cb != NULL); REQUIRE(requestp != NULL && *requestp == NULL); REQUIRE(timeout > 0); + REQUIRE(udpretries != UINT_MAX); mctx = requestmgr->mctx; @@ -598,9 +601,7 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, request->cb = cb; request->arg = arg; request->result = ISC_R_FAILURE; - request->udpcount = udpretries; - - request->udpcount = udpretries; + request->udpcount = udpretries + 1; if (key != NULL) { dns_tsigkey_attach(key, &request->tsigkey); @@ -615,8 +616,8 @@ dns_request_create(dns_requestmgr_t *requestmgr, dns_message_t *message, tcp = true; request->timeout = timeout * 1000; } else { - if (udptimeout == 0 && udpretries != 0) { - udptimeout = timeout / (udpretries + 1); + if (udptimeout == 0) { + udptimeout = timeout / request->udpcount; } if (udptimeout == 0) { udptimeout = 1; @@ -973,7 +974,7 @@ req_response(isc_result_t result, isc_region_t *region, void *arg) { if (result == ISC_R_TIMEDOUT) { LOCK(&request->requestmgr->locks[request->hash]); - if (request->udpcount != 0) { + if (request->udpcount > 1) { request->udpcount -= 1; dns_dispatch_resume(request->dispentry, request->timeout);