From 7683d6ce699185291fc50abebdd2b55e15d7c89c Mon Sep 17 00:00:00 2001 From: Aram Sargsyan Date: Thu, 7 Apr 2022 09:23:49 +0000 Subject: [PATCH] Unify dig +nssearch next query starting code for TCP and UDP protocols 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. (cherry picked from commit b944bf41208c648d96fdb58ff74a9e90a0c7a4ab) --- bin/dig/dighost.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 939fd6690a..d5a1835807 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -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); @@ -2658,7 +2661,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); @@ -2668,7 +2673,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(); @@ -2852,23 +2861,6 @@ 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); - } - } } static void