mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-30 05:57:52 +00:00
1773. [bug] Fast retry on host / net unreachable. [RT #13153]
This commit is contained in:
parent
cf74c9cc6a
commit
c202b9f4dd
2
CHANGES
2
CHANGES
@ -16,7 +16,7 @@
|
||||
1774. [port] Aix: Silence compiler warnings / build failures.
|
||||
[RT #13154]
|
||||
|
||||
1773. [placeholder] rt13153
|
||||
1773. [bug] Fast retry on host / net unreachable. [RT #13153]
|
||||
|
||||
1772. [placeholder]
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: resolver.c,v 1.298 2004/11/10 21:57:46 marka Exp $ */
|
||||
/* $Id: resolver.c,v 1.299 2004/12/03 01:59:28 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -762,6 +762,9 @@ static void
|
||||
resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||
resquery_t *query = event->ev_arg;
|
||||
isc_boolean_t retry = ISC_FALSE;
|
||||
isc_result_t result;
|
||||
fetchctx_t *fctx;
|
||||
|
||||
REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE);
|
||||
|
||||
@ -780,6 +783,7 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
||||
INSIST(RESQUERY_SENDING(query));
|
||||
|
||||
query->sends--;
|
||||
fctx = query->fctx;
|
||||
|
||||
if (RESQUERY_CANCELED(query)) {
|
||||
if (query->sends == 0) {
|
||||
@ -791,16 +795,43 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socket_detach(&query->tcpsocket);
|
||||
resquery_destroy(&query);
|
||||
}
|
||||
} else if (sevent->result == ISC_R_HOSTUNREACH ||
|
||||
sevent->result == ISC_R_NETUNREACH)
|
||||
/*
|
||||
* No route to remote.
|
||||
*/
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
||||
else if (sevent->result != ISC_R_SUCCESS)
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||
} else
|
||||
switch (sevent->result) {
|
||||
case ISC_R_SUCCESS:
|
||||
break;
|
||||
|
||||
case ISC_R_HOSTUNREACH:
|
||||
case ISC_R_NETUNREACH:
|
||||
case ISC_R_NOPERM:
|
||||
case ISC_R_ADDRNOTAVAIL:
|
||||
case ISC_R_CONNREFUSED:
|
||||
|
||||
/*
|
||||
* No route to remote.
|
||||
*/
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
||||
retry = ISC_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (retry) {
|
||||
/*
|
||||
* Behave as if the idle timer has expired. For TCP
|
||||
* this may not actually reflect the latest timer.
|
||||
*/
|
||||
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
|
||||
result = fctx_stopidletimer(fctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
else
|
||||
fctx_try(fctx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
@ -1317,7 +1348,10 @@ static void
|
||||
resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||
resquery_t *query = event->ev_arg;
|
||||
isc_boolean_t retry = ISC_FALSE;
|
||||
isc_result_t result;
|
||||
unsigned int attrs;
|
||||
fetchctx_t *fctx;
|
||||
|
||||
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
|
||||
REQUIRE(VALID_QUERY(query));
|
||||
@ -1335,6 +1369,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
|
||||
query->connects--;
|
||||
fctx = query->fctx;
|
||||
|
||||
if (RESQUERY_CANCELED(query)) {
|
||||
/*
|
||||
@ -1344,9 +1379,8 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
isc_socket_detach(&query->tcpsocket);
|
||||
resquery_destroy(&query);
|
||||
} else {
|
||||
if (sevent->result == ISC_R_SUCCESS) {
|
||||
unsigned int attrs;
|
||||
|
||||
switch (sevent->result) {
|
||||
case ISC_R_SUCCESS:
|
||||
/*
|
||||
* We are connected. Create a dispatcher and
|
||||
* send the query.
|
||||
@ -1379,25 +1413,46 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||
result = resquery_send(query);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
fetchctx_t *fctx = query->fctx;
|
||||
fctx_cancelquery(&query, NULL, NULL,
|
||||
ISC_FALSE);
|
||||
fctx_done(fctx, result);
|
||||
}
|
||||
} else if (sevent->result == ISC_R_HOSTUNREACH ||
|
||||
sevent->result == ISC_R_NETUNREACH) {
|
||||
break;
|
||||
|
||||
case ISC_R_NETUNREACH:
|
||||
case ISC_R_HOSTUNREACH:
|
||||
case ISC_R_CONNREFUSED:
|
||||
case ISC_R_NOPERM:
|
||||
case ISC_R_ADDRNOTAVAIL:
|
||||
/*
|
||||
* No route to remote.
|
||||
*/
|
||||
isc_socket_detach(&query->tcpsocket);
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
||||
} else {
|
||||
retry = ISC_TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
isc_socket_detach(&query->tcpsocket);
|
||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
isc_event_free(&event);
|
||||
|
||||
if (retry) {
|
||||
/*
|
||||
* Behave as if the idle timer has expired. For TCP
|
||||
* connections this may not actually reflect the latest timer.
|
||||
*/
|
||||
fctx->attributes &= ~FCTX_ATTR_ADDRWAIT;
|
||||
result = fctx_stopidletimer(fctx);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
fctx_done(fctx, result);
|
||||
else
|
||||
fctx_try(fctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
x
Reference in New Issue
Block a user