]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Unify dig +nssearch next query starting code for TCP and UDP protocols
authorAram Sargsyan <aram@isc.org>
Thu, 7 Apr 2022 09:23:49 +0000 (09:23 +0000)
committerAram Sargsyan <aram@isc.org>
Thu, 14 Apr 2022 09:34:40 +0000 (09:34 +0000)
In `+nssearch` mode `dig` starts the next query of the followup lookup
using `start_udp()` or `start_tcp()` calls without waiting for the
previous query to complete.

In UDP mode that happens in the `send_done()` callback of the previous
query, but in TCP mode that happens in the `start_tcp()` call of the
previous query (recursion) which doesn't work because `start_tcp()`
attaches the `lookup->current_query` to the query it is starting, so a
recursive call will result in an assertion failure.

Make the TCP mode to start the next query in `send_done()`, just like in
the UDP mode. During that time the `lookup->current_query` is already
detached by the `tcp_connected()`/`udp_ready()` callbacks.

bin/dig/dighost.c

index 57ccf415e4a33edf338742b245e8dc9310d22a2d..0c09f3f59056ea932e64ca3db8228654c714f55d 100644 (file)
@@ -231,6 +231,9 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
 static void
 start_udp(dig_query_t *query);
 
+static void
+start_tcp(dig_query_t *query);
+
 static void
 force_next(dig_query_t *query);
 
@@ -2709,7 +2712,9 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                return;
        }
 
-       if (l->ns_search_only && !l->trace_root && !l->tcp_mode) {
+       if (l->ns_search_only && !l->trace_root) {
+               bool tcp_mode = l->tcp_mode;
+
                debug("sending next, since searching");
                next = ISC_LIST_NEXT(query, link);
 
@@ -2719,7 +2724,11 @@ send_done(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
                if (next == NULL) {
                        clear_current_lookup();
                } else {
-                       start_udp(next);
+                       if (tcp_mode) {
+                               start_tcp(next);
+                       } else {
+                               start_udp(next);
+                       }
                }
 
                check_if_done();
@@ -3009,24 +3018,8 @@ start_tcp(dig_query_t *query) {
                /* XXX: set DSCP */
        }
 
-       /*
-        * If we're at the endgame of a nameserver search, we need to
-        * immediately bring up all the queries.  Do it here.
-        */
-       if (query->lookup->ns_search_only && !query->lookup->trace_root) {
-               debug("sending next, since searching");
-               if (ISC_LINK_LINKED(query, link)) {
-                       next = ISC_LIST_NEXT(query, link);
-                       ISC_LIST_DEQUEUE(query->lookup->q, query, link);
-               } else {
-                       next = NULL;
-               }
-               if (next != NULL) {
-                       start_tcp(next);
-               }
-       }
-
        return;
+
 failure_tls:
        if (query->lookup->tls_key_file_set != query->lookup->tls_cert_file_set)
        {