]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
dig: prevent query from being detached if udpconnect fails on first attempt
authorEvan Hunt <each@isc.org>
Thu, 5 Nov 2020 22:15:14 +0000 (14:15 -0800)
committerOndřej Surý <ondrej@sury.org>
Sat, 7 Nov 2020 20:11:58 +0000 (21:11 +0100)
FreeBSD sometimes returns spurious errors in UDP connect() attempts,
so we try a few times before giving up. However, each failed attempt
triggers a call to udp_ready() in dighost.c, and that was causing
the query object to be detached prematurely.

bin/dig/dighost.c
bin/dig/dighost.h

index 081518cb17325078a0421d6f040b467981944ab6..d7b04c02ea9ca1d3eb6e019802653a21b76f5ee8 100644 (file)
@@ -2897,7 +2897,9 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                        debug("udp setup failed: %s",
                              isc_result_totext(eresult));
                }
-               query_detach(&query);
+               if (query->tries == 0) {
+                       query_detach(&query);
+               }
                return;
        }
 
@@ -2933,7 +2935,6 @@ static void
 start_udp(dig_query_t *query) {
        isc_result_t result;
        dig_query_t *next = NULL;
-       int i = 0;
 
        REQUIRE(DIG_VALID_QUERY(query));
 
@@ -2985,6 +2986,7 @@ start_udp(dig_query_t *query) {
                }
        }
 
+       query->tries = 3;
        do {
                int local_timeout = timeout * 1000;
                if (local_timeout == 0) {
@@ -2996,11 +2998,11 @@ start_udp(dig_query_t *query) {
                 * in a spurious transient EADDRINUSE. Try a few more times
                 * before giving up.
                 */
-               debug("isc_nm_udpconnect(): try %d", i + 1);
+               debug("isc_nm_udpconnect(): %d tries left", --query->tries);
                result = isc_nm_udpconnect(netmgr, (isc_nmiface_t *)&localaddr,
                                           (isc_nmiface_t *)&query->sockaddr,
                                           udp_ready, query, local_timeout, 0);
-       } while (result != ISC_R_SUCCESS && i++ < 2);
+       } while (result != ISC_R_SUCCESS && query->tries > 0);
        check_result(result, "isc_nm_udpconnect");
 }
 
index 6a30b5ef8546feb8f98dadb7e08b3c7e389c0f82..81cc2750a1e2b99927d0c5d43a6747a36c8980db 100644 (file)
@@ -199,6 +199,7 @@ struct dig_query {
        isc_time_t time_recv;
        uint64_t byte_count;
        isc_timer_t *timer;
+       uint8_t tries;
 };
 
 struct dig_server {