mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
Fix DiG UDP query retry and fail-over bug
When the `udp_ready()` callback function gets called with a failure result code, DiG erroneously cancels the lookup. Copy the logic behind `tcp_connected()` callback function into `udp_ready()` so that DiG will now retry the failed query (if retries are enabled) and then, if it fails again, it will fail-over to the next server in the list, which synchronizes the behavior between TCP and UDP modes. Also, `udp_ready()` was calling `lookup_detach()` without calling `lookup_attach()` first, but the issue was masked behind the fact that `clear_current_lookup()` wasn't being called when needed, and `lookup_detach()` was compensating for that. This also has been fixed. (cherry picked from commit 3f3108552577c326b4dab6c3b631c51cf0040144)
This commit is contained in:
parent
c003127717
commit
be8ec6ef18
1 changed files with 43 additions and 5 deletions
|
|
@ -3112,6 +3112,9 @@ send_udp(dig_query_t *query) {
|
|||
static void
|
||||
udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
||||
dig_query_t *query = (dig_query_t *)arg;
|
||||
dig_query_t *next = NULL;
|
||||
char sockstr[ISC_SOCKADDR_FORMATSIZE];
|
||||
dig_lookup_t *l = NULL;
|
||||
dig_query_t *readquery = NULL;
|
||||
int local_timeout = timeout * 1000;
|
||||
|
||||
|
|
@ -3132,30 +3135,63 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
debug("udp_ready(%p, %s, %p)", handle, isc_result_totext(eresult),
|
||||
query);
|
||||
|
||||
if (eresult == ISC_R_CANCELED || query->canceled) {
|
||||
dig_lookup_t *l = query->lookup;
|
||||
LOCK_LOOKUP;
|
||||
lookup_attach(query->lookup, &l);
|
||||
|
||||
if (eresult == ISC_R_CANCELED || query->canceled) {
|
||||
debug("in cancel handler");
|
||||
if (!query->canceled) {
|
||||
cancel_lookup(l);
|
||||
}
|
||||
query_detach(&query);
|
||||
lookup_detach(&l);
|
||||
clear_current_lookup();
|
||||
UNLOCK_LOOKUP;
|
||||
return;
|
||||
} else if (eresult != ISC_R_SUCCESS) {
|
||||
dig_lookup_t *l = query->lookup;
|
||||
|
||||
debug("udp setup failed: %s", isc_result_totext(eresult));
|
||||
isc_sockaddr_format(&query->sockaddr, sockstr, sizeof(sockstr));
|
||||
dighost_warning("UDP setup with %s(%s) for %s failed: %s.",
|
||||
sockstr, query->servname, l->textname,
|
||||
isc_result_totext(eresult));
|
||||
|
||||
if (exitcode < 9) {
|
||||
exitcode = 9;
|
||||
}
|
||||
|
||||
if (l->retries > 1) {
|
||||
l->retries--;
|
||||
debug("making new UDP request, %d tries left",
|
||||
l->retries);
|
||||
requeue_lookup(l, true);
|
||||
next = NULL;
|
||||
} else if ((l->current_query != NULL) &&
|
||||
(ISC_LINK_LINKED(l->current_query, link)))
|
||||
{
|
||||
next = ISC_LIST_NEXT(l->current_query, link);
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
query_detach(&query);
|
||||
cancel_lookup(l);
|
||||
if (next == NULL) {
|
||||
cancel_lookup(l);
|
||||
}
|
||||
lookup_detach(&l);
|
||||
|
||||
if (next != NULL) {
|
||||
start_udp(next);
|
||||
} else {
|
||||
clear_current_lookup();
|
||||
}
|
||||
|
||||
check_if_done();
|
||||
UNLOCK_LOOKUP;
|
||||
return;
|
||||
}
|
||||
|
||||
exitcode = 0;
|
||||
|
||||
query_attach(query, &readquery);
|
||||
|
||||
debug("recving with lookup=%p, query=%p, handle=%p", query->lookup,
|
||||
|
|
@ -3177,6 +3213,8 @@ udp_ready(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
|
|||
send_udp(readquery);
|
||||
|
||||
query_detach(&query);
|
||||
lookup_detach(&l);
|
||||
UNLOCK_LOOKUP;
|
||||
}
|
||||
|
||||
/*%
|
||||
|
|
|
|||
Loading…
Reference in a new issue