mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
1773. [bug] Fast retry on host / net unreachable. [RT #13153]
This commit is contained in:
2
CHANGES
2
CHANGES
@@ -16,7 +16,7 @@
|
|||||||
1774. [port] Aix: Silence compiler warnings / build failures.
|
1774. [port] Aix: Silence compiler warnings / build failures.
|
||||||
[RT #13154]
|
[RT #13154]
|
||||||
|
|
||||||
1773. [placeholder] rt13153
|
1773. [bug] Fast retry on host / net unreachable. [RT #13153]
|
||||||
|
|
||||||
1772. [placeholder]
|
1772. [placeholder]
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* 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>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -762,6 +762,9 @@ static void
|
|||||||
resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
||||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||||
resquery_t *query = event->ev_arg;
|
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);
|
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));
|
INSIST(RESQUERY_SENDING(query));
|
||||||
|
|
||||||
query->sends--;
|
query->sends--;
|
||||||
|
fctx = query->fctx;
|
||||||
|
|
||||||
if (RESQUERY_CANCELED(query)) {
|
if (RESQUERY_CANCELED(query)) {
|
||||||
if (query->sends == 0) {
|
if (query->sends == 0) {
|
||||||
@@ -791,16 +795,43 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_socket_detach(&query->tcpsocket);
|
isc_socket_detach(&query->tcpsocket);
|
||||||
resquery_destroy(&query);
|
resquery_destroy(&query);
|
||||||
}
|
}
|
||||||
} else if (sevent->result == ISC_R_HOSTUNREACH ||
|
} else
|
||||||
sevent->result == ISC_R_NETUNREACH)
|
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.
|
* No route to remote.
|
||||||
*/
|
*/
|
||||||
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
||||||
else if (sevent->result != ISC_R_SUCCESS)
|
retry = ISC_TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
isc_event_free(&event);
|
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
|
static inline isc_result_t
|
||||||
@@ -1317,7 +1348,10 @@ static void
|
|||||||
resquery_connected(isc_task_t *task, isc_event_t *event) {
|
resquery_connected(isc_task_t *task, isc_event_t *event) {
|
||||||
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
|
||||||
resquery_t *query = event->ev_arg;
|
resquery_t *query = event->ev_arg;
|
||||||
|
isc_boolean_t retry = ISC_FALSE;
|
||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
|
unsigned int attrs;
|
||||||
|
fetchctx_t *fctx;
|
||||||
|
|
||||||
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
|
REQUIRE(event->ev_type == ISC_SOCKEVENT_CONNECT);
|
||||||
REQUIRE(VALID_QUERY(query));
|
REQUIRE(VALID_QUERY(query));
|
||||||
@@ -1335,6 +1369,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
query->connects--;
|
query->connects--;
|
||||||
|
fctx = query->fctx;
|
||||||
|
|
||||||
if (RESQUERY_CANCELED(query)) {
|
if (RESQUERY_CANCELED(query)) {
|
||||||
/*
|
/*
|
||||||
@@ -1344,9 +1379,8 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
|||||||
isc_socket_detach(&query->tcpsocket);
|
isc_socket_detach(&query->tcpsocket);
|
||||||
resquery_destroy(&query);
|
resquery_destroy(&query);
|
||||||
} else {
|
} else {
|
||||||
if (sevent->result == ISC_R_SUCCESS) {
|
switch (sevent->result) {
|
||||||
unsigned int attrs;
|
case ISC_R_SUCCESS:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We are connected. Create a dispatcher and
|
* We are connected. Create a dispatcher and
|
||||||
* send the query.
|
* send the query.
|
||||||
@@ -1379,25 +1413,46 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
|
|||||||
result = resquery_send(query);
|
result = resquery_send(query);
|
||||||
|
|
||||||
if (result != ISC_R_SUCCESS) {
|
if (result != ISC_R_SUCCESS) {
|
||||||
fetchctx_t *fctx = query->fctx;
|
|
||||||
fctx_cancelquery(&query, NULL, NULL,
|
fctx_cancelquery(&query, NULL, NULL,
|
||||||
ISC_FALSE);
|
ISC_FALSE);
|
||||||
fctx_done(fctx, result);
|
fctx_done(fctx, result);
|
||||||
}
|
}
|
||||||
} else if (sevent->result == ISC_R_HOSTUNREACH ||
|
break;
|
||||||
sevent->result == ISC_R_NETUNREACH) {
|
|
||||||
|
case ISC_R_NETUNREACH:
|
||||||
|
case ISC_R_HOSTUNREACH:
|
||||||
|
case ISC_R_CONNREFUSED:
|
||||||
|
case ISC_R_NOPERM:
|
||||||
|
case ISC_R_ADDRNOTAVAIL:
|
||||||
/*
|
/*
|
||||||
* No route to remote.
|
* No route to remote.
|
||||||
*/
|
*/
|
||||||
isc_socket_detach(&query->tcpsocket);
|
isc_socket_detach(&query->tcpsocket);
|
||||||
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
fctx_cancelquery(&query, NULL, NULL, ISC_TRUE);
|
||||||
} else {
|
retry = ISC_TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
isc_socket_detach(&query->tcpsocket);
|
isc_socket_detach(&query->tcpsocket);
|
||||||
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_event_free(&event);
|
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
|
static void
|
||||||
|
Reference in New Issue
Block a user