2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

Merge branch '3145-dig-+nssearch-does-not-exit-until-interrupted' into 'main'

Fix "dig +nssearch" indefinitely hanging issue

Closes #3145

See merge request isc-projects/bind9!6007
This commit is contained in:
Arаm Sаrgsyаn
2022-04-01 11:51:17 +00:00
3 changed files with 54 additions and 4 deletions

View File

@@ -1,3 +1,6 @@
5844. [bug] dig +nssearch was hanging until manually interrupted.
[GL #3145]
5843. [bug] When an UPDATE targets a zone that is not configured, 5843. [bug] When an UPDATE targets a zone that is not configured,
the requested zone name is now logged in the "not the requested zone name is now logged in the "not
authoritative" error message, so that it is easier to authoritative" error message, so that it is easier to

View File

@@ -1551,6 +1551,30 @@ check_if_done(void) {
} }
} }
/*%
* Check if we're done with all the queries in the lookup, except for
* the `except_q` query (can be NULL if no exception is required).
* Expects `l` to be a valid and locked lookup.
*/
static bool
check_if_queries_done(dig_lookup_t *l, dig_query_t *except_q) {
dig_query_t *q = ISC_LIST_HEAD(l->q);
debug("check_if_queries_done(%p)", l);
while (q != NULL) {
if (!q->started || isc_refcount_current(&q->references) > 1) {
if (!q->canceled && q != except_q) {
debug("there is a pending query %p", q);
return (false);
}
}
q = ISC_LIST_NEXT(q, link);
}
return (true);
}
static void static void
_destroy_lookup(dig_lookup_t *lookup) { _destroy_lookup(dig_lookup_t *lookup) {
dig_server_t *s; dig_server_t *s;
@@ -2126,7 +2150,6 @@ _new_query(dig_lookup_t *lookup, char *servname, char *userarg,
*query = (dig_query_t){ .sendbuf = lookup->renderbuf, *query = (dig_query_t){ .sendbuf = lookup->renderbuf,
.servname = servname, .servname = servname,
.userarg = userarg, .userarg = userarg,
.first_pass = true,
.warn_id = true, .warn_id = true,
.recvspace = isc_mem_get(mctx, COMMSIZE), .recvspace = isc_mem_get(mctx, COMMSIZE),
.tmpsendspace = isc_mem_get(mctx, COMMSIZE) }; .tmpsendspace = isc_mem_get(mctx, COMMSIZE) };
@@ -3074,6 +3097,22 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
dig_query_t *readquery = NULL; dig_query_t *readquery = NULL;
int local_timeout = timeout * 1000; int local_timeout = timeout * 1000;
REQUIRE(DIG_VALID_QUERY(query));
REQUIRE(query->handle == NULL);
debug("udp_ready()");
query->started = true;
if (atomic_load(&cancel_now)) {
return;
}
INSIST(!free_now);
debug("udp_ready(%p, %s, %p)", handle, isc_result_totext(eresult),
query);
if (eresult == ISC_R_CANCELED || query->canceled) { if (eresult == ISC_R_CANCELED || query->canceled) {
dig_lookup_t *l = query->lookup; dig_lookup_t *l = query->lookup;
@@ -3413,14 +3452,17 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
char sockstr[ISC_SOCKADDR_FORMATSIZE]; char sockstr[ISC_SOCKADDR_FORMATSIZE];
dig_lookup_t *l = NULL; dig_lookup_t *l = NULL;
REQUIRE(DIG_VALID_QUERY(query));
REQUIRE(query->handle == NULL);
debug("tcp_connected()"); debug("tcp_connected()");
query->started = true;
if (atomic_load(&cancel_now)) { if (atomic_load(&cancel_now)) {
return; return;
} }
REQUIRE(DIG_VALID_QUERY(query));
REQUIRE(query->handle == NULL);
INSIST(!free_now); INSIST(!free_now);
debug("tcp_connected(%p, %s, %p)", handle, isc_result_totext(eresult), debug("tcp_connected(%p, %s, %p)", handle, isc_result_totext(eresult),
@@ -4310,7 +4352,12 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region,
l->trace_root = false; l->trace_root = false;
usesearch = false; usesearch = false;
} else { } else {
/*
* This is a query in the followup lookup
*/
dighost_printmessage(query, &b, msg, true); dighost_printmessage(query, &b, msg, true);
docancel = check_if_queries_done(l, query);
} }
} }
} }

View File

@@ -194,7 +194,7 @@ struct dig_lookup {
struct dig_query { struct dig_query {
unsigned int magic; unsigned int magic;
dig_lookup_t *lookup; dig_lookup_t *lookup;
bool first_pass; bool started;
bool first_soa_rcvd; bool first_soa_rcvd;
bool second_rr_rcvd; bool second_rr_rcvd;
bool first_repeat_rcvd; bool first_repeat_rcvd;