]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Synchronize dns_request_createraw() and dns_request_create() UDP timeout
authorAram Sargsyan <aram@isc.org>
Mon, 12 Dec 2022 11:55:09 +0000 (11:55 +0000)
committerArаm Sаrgsyаn <aram@isc.org>
Mon, 3 Apr 2023 15:21:43 +0000 (15:21 +0000)
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

index f78a57d7a32df1461bca899c680e802e064bf2fa..977b2ebaad59c623fd577613c7ac0a10df44c59d 100644 (file)
@@ -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);