implement a 10 minute bitstring-reverse-query avoidance if we tried once and
it failed with ISC_R_FAILURE, DNS_R_SERVFAIL, or DNS_R_FORMERR. This makes it so we don't try the bitstring lookup when it will most likely fail.
This commit is contained in:
@@ -333,6 +333,7 @@ client_initialize(client_t *client, clientmgr_t *cmgr)
|
||||
|
||||
client->options = 0;
|
||||
client->byaddr = NULL;
|
||||
client->addrinfo = NULL;
|
||||
|
||||
ISC_LIST_APPEND(cmgr->idle, client, link);
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ struct client_s {
|
||||
dns_byaddr_t *byaddr;
|
||||
unsigned int options;
|
||||
isc_netaddr_t na;
|
||||
dns_adbaddrinfo_t *addrinfo;
|
||||
|
||||
/*
|
||||
* Alias and address info. This is copied up to the gabn/gnba
|
||||
|
||||
@@ -43,6 +43,7 @@ static void
|
||||
byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
{
|
||||
client_t *client;
|
||||
clientmgr_t *cm;
|
||||
dns_byaddrevent_t *bevent;
|
||||
int lwres;
|
||||
lwres_buffer_t lwb;
|
||||
@@ -52,11 +53,13 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
isc_buffer_t b;
|
||||
lwres_gnbaresponse_t *gnba;
|
||||
isc_uint16_t naliases;
|
||||
isc_stdtime_t now;
|
||||
|
||||
(void)task;
|
||||
|
||||
lwb.base = NULL;
|
||||
client = event->arg;
|
||||
cm = client->clientmgr;
|
||||
INSIST(client->byaddr == event->sender);
|
||||
|
||||
bevent = (dns_byaddrevent_t *)event;
|
||||
@@ -65,15 +68,33 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
DP(50, "byaddr event result = %s",
|
||||
isc_result_totext(bevent->result));
|
||||
|
||||
if (bevent->result != ISC_R_SUCCESS) {
|
||||
result = bevent->result;
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_byaddr_destroy(&client->byaddr);
|
||||
isc_event_free(&event);
|
||||
bevent = NULL;
|
||||
|
||||
/*
|
||||
* Were we trying bitstring or nibble mode? If bitstring,
|
||||
* and we got FORMERROR or SERVFAIL, set the flag to
|
||||
* avoid bitstring lables for 10 minutes. If we got any
|
||||
* other error (NXDOMAIN, etc) just try again without
|
||||
* bitstrings, and let our cache handle the negative answer
|
||||
* for bitstrings.
|
||||
*/
|
||||
if ((client->options & DNS_BYADDROPT_IPV6NIBBLE) != 0) {
|
||||
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
|
||||
error_pkt_send(client, LWRES_R_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
isc_stdtime_get(&now);
|
||||
if (result == DNS_R_FORMERR ||
|
||||
result == DNS_R_SERVFAIL ||
|
||||
result == ISC_R_FAILURE)
|
||||
dns_adb_setavoidbitstring(cm->view->adb,
|
||||
client->addrinfo, now + 600);
|
||||
|
||||
/*
|
||||
* Fall back to nibble reverse if the default of bitstrings
|
||||
* fails.
|
||||
@@ -110,6 +131,7 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
}
|
||||
|
||||
dns_byaddr_destroy(&client->byaddr);
|
||||
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
|
||||
isc_event_free(&event);
|
||||
|
||||
/*
|
||||
@@ -120,7 +142,7 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
client->pkt.authlength = 0;
|
||||
client->pkt.result = LWRES_R_SUCCESS;
|
||||
|
||||
lwres = lwres_gnbaresponse_render(client->clientmgr->lwctx,
|
||||
lwres = lwres_gnbaresponse_render(cm->lwctx,
|
||||
gnba, &client->pkt, &lwb);
|
||||
if (lwres != LWRES_R_SUCCESS)
|
||||
goto out;
|
||||
@@ -131,8 +153,8 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
r.length = lwb.used;
|
||||
client->sendbuf = r.base;
|
||||
client->sendlength = r.length;
|
||||
result = isc_socket_sendto(client->clientmgr->sock, &r,
|
||||
client->clientmgr->task, client_send,
|
||||
result = isc_socket_sendto(cm->sock, &r,
|
||||
cm->task, client_send,
|
||||
client, &client->address, NULL);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto out;
|
||||
@@ -144,9 +166,10 @@ byaddr_done(isc_task_t *task, isc_event_t *event)
|
||||
out:
|
||||
if (client->byaddr != NULL)
|
||||
dns_byaddr_destroy(&client->byaddr);
|
||||
|
||||
if (client->addrinfo != NULL)
|
||||
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
|
||||
if (lwb.base != NULL)
|
||||
lwres_context_freemem(client->clientmgr->lwctx,
|
||||
lwres_context_freemem(cm->lwctx,
|
||||
lwb.base, lwb.length);
|
||||
|
||||
isc_event_free(&event);
|
||||
@@ -166,6 +189,7 @@ start_byaddr(client_t *client)
|
||||
client->options, cm->task, byaddr_done,
|
||||
client, &client->byaddr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_adb_freeaddrinfo(cm->view->adb, &client->addrinfo);
|
||||
error_pkt_send(client, LWRES_R_FAILURE);
|
||||
return;
|
||||
}
|
||||
@@ -176,13 +200,16 @@ process_gnba(client_t *client, lwres_buffer_t *b)
|
||||
{
|
||||
lwres_gnbarequest_t *req;
|
||||
isc_result_t result;
|
||||
isc_sockaddr_t sa;
|
||||
clientmgr_t *cm;
|
||||
|
||||
REQUIRE(CLIENT_ISRECVDONE(client));
|
||||
INSIST(client->byaddr == NULL);
|
||||
|
||||
cm = client->clientmgr;
|
||||
req = NULL;
|
||||
|
||||
result = lwres_gnbarequest_parse(client->clientmgr->lwctx,
|
||||
result = lwres_gnbarequest_parse(cm->lwctx,
|
||||
b, &client->pkt, &req);
|
||||
if (result != LWRES_R_SUCCESS)
|
||||
goto out;
|
||||
@@ -203,6 +230,7 @@ process_gnba(client_t *client, lwres_buffer_t *b)
|
||||
} else {
|
||||
goto out;
|
||||
}
|
||||
isc_sockaddr_fromnetaddr(&sa, &client->na, 53);
|
||||
|
||||
DP(50, "Client %p looking for addrtype %08x",
|
||||
client, req->addr.family);
|
||||
@@ -210,18 +238,30 @@ process_gnba(client_t *client, lwres_buffer_t *b)
|
||||
/*
|
||||
* We no longer need to keep this around.
|
||||
*/
|
||||
lwres_gnbarequest_free(client->clientmgr->lwctx, &req);
|
||||
lwres_gnbarequest_free(cm->lwctx, &req);
|
||||
|
||||
/*
|
||||
* Initialize the real name and alias arrays in the reply we're
|
||||
* going to build up.
|
||||
*/
|
||||
client_init_gnba(client);
|
||||
client->options = 0;
|
||||
|
||||
/*
|
||||
* See if we should skip the byaddr bit.
|
||||
*/
|
||||
INSIST(client->addrinfo == NULL);
|
||||
result = dns_adb_findaddrinfo(cm->view->adb, &sa,
|
||||
&client->addrinfo, 0);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (client->addrinfo->avoid_bitstring > 0)
|
||||
client->options |= DNS_BYADDROPT_IPV6NIBBLE;
|
||||
|
||||
/*
|
||||
* Start the find.
|
||||
*/
|
||||
client->options = 0;
|
||||
start_byaddr(client);
|
||||
|
||||
return;
|
||||
@@ -231,7 +271,7 @@ process_gnba(client_t *client, lwres_buffer_t *b)
|
||||
*/
|
||||
out:
|
||||
if (req != NULL)
|
||||
lwres_gnbarequest_free(client->clientmgr->lwctx, &req);
|
||||
lwres_gnbarequest_free(cm->lwctx, &req);
|
||||
|
||||
error_pkt_send(client, LWRES_R_FAILURE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user