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 b944bf4120)
This commit is contained in:
Aram Sargsyan 2022-04-07 09:23:49 +00:00
parent da30a638a2
commit 7683d6ce69

View 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);
@ -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