2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

Merge branch '3168-3-separate-all-recursions' into 'main'

[3/5] Separate all recursions

See merge request isc-projects/bind9!5884
This commit is contained in:
Michał Kępień
2022-06-14 11:42:21 +00:00
4 changed files with 47 additions and 36 deletions

View File

@@ -174,7 +174,6 @@ struct ns_client {
isc_nmhandle_t *sendhandle; /* Waiting for send callback */ isc_nmhandle_t *sendhandle; /* Waiting for send callback */
isc_nmhandle_t *reqhandle; /* Waiting for request callback isc_nmhandle_t *reqhandle; /* Waiting for request callback
(query, update, notify) */ (query, update, notify) */
isc_nmhandle_t *fetchhandle; /* Waiting for recursive fetch */
isc_nmhandle_t *updatehandle; /* Waiting for update callback */ isc_nmhandle_t *updatehandle; /* Waiting for update callback */
unsigned char *tcpbuf; unsigned char *tcpbuf;
dns_message_t *message; dns_message_t *message;

View File

@@ -43,8 +43,10 @@ typedef struct ns_dbversion {
* allows common code paths to differentiate between them * allows common code paths to differentiate between them
*/ */
typedef enum { typedef enum {
RECTYPE_NORMAL,
RECTYPE_PREFETCH, RECTYPE_PREFETCH,
RECTYPE_RPZ, RECTYPE_RPZ,
RECTYPE_HOOK,
RECTYPE_COUNT, RECTYPE_COUNT,
} ns_query_rectype_t; } ns_query_rectype_t;
@@ -52,19 +54,27 @@ typedef enum {
* Helper macros for accessing isc_nmhandle_t pointers for a specific recursion * Helper macros for accessing isc_nmhandle_t pointers for a specific recursion
* a given client is associated with. * a given client is associated with.
*/ */
#define HANDLE_RECTYPE_NORMAL(client) \
((client)->query.recursions[RECTYPE_NORMAL].handle)
#define HANDLE_RECTYPE_PREFETCH(client) \ #define HANDLE_RECTYPE_PREFETCH(client) \
((client)->query.recursions[RECTYPE_PREFETCH].handle) ((client)->query.recursions[RECTYPE_PREFETCH].handle)
#define HANDLE_RECTYPE_RPZ(client) \ #define HANDLE_RECTYPE_RPZ(client) \
((client)->query.recursions[RECTYPE_RPZ].handle) ((client)->query.recursions[RECTYPE_RPZ].handle)
#define HANDLE_RECTYPE_HOOK(client) \
((client)->query.recursions[RECTYPE_HOOK].handle)
/*% /*%
* Helper macros for accessing dns_fetch_t pointers for a specific recursion a * Helper macros for accessing dns_fetch_t pointers for a specific recursion a
* given client is associated with. * given client is associated with.
*/ */
#define FETCH_RECTYPE_NORMAL(client) \
((client)->query.recursions[RECTYPE_NORMAL].fetch)
#define FETCH_RECTYPE_PREFETCH(client) \ #define FETCH_RECTYPE_PREFETCH(client) \
((client)->query.recursions[RECTYPE_PREFETCH].fetch) ((client)->query.recursions[RECTYPE_PREFETCH].fetch)
#define FETCH_RECTYPE_RPZ(client) \ #define FETCH_RECTYPE_RPZ(client) \
((client)->query.recursions[RECTYPE_RPZ].fetch) ((client)->query.recursions[RECTYPE_RPZ].fetch)
#define FETCH_RECTYPE_HOOK(client) \
((client)->query.recursions[RECTYPE_HOOK].fetch)
/*% /*%
* nameserver recursion parameters, to uniquely identify a recursion * nameserver recursion parameters, to uniquely identify a recursion
@@ -94,7 +104,6 @@ struct ns_query {
bool authdbset; bool authdbset;
bool isreferral; bool isreferral;
isc_mutex_t fetchlock; isc_mutex_t fetchlock;
dns_fetch_t *fetch;
ns_hookasync_t *hookactx; ns_hookasync_t *hookactx;
dns_rpz_st_t *rpz_st; dns_rpz_st_t *rpz_st;
isc_bufferlist_t namebufs; isc_bufferlist_t namebufs;

View File

@@ -660,10 +660,12 @@ ns_query_cancel(ns_client_t *client) {
REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(NS_CLIENT_VALID(client));
LOCK(&client->query.fetchlock); LOCK(&client->query.fetchlock);
if (client->query.fetch != NULL) { for (int i = 0; i < RECTYPE_COUNT; i++) {
dns_resolver_cancelfetch(client->query.fetch); dns_fetch_t **fetchp = &client->query.recursions[i].fetch;
if (*fetchp != NULL) {
client->query.fetch = NULL; dns_resolver_cancelfetch(*fetchp);
*fetchp = NULL;
}
} }
if (client->query.hookactx != NULL) { if (client->query.hookactx != NULL) {
client->query.hookactx->cancel(client->query.hookactx); client->query.hookactx->cancel(client->query.hookactx);
@@ -5961,9 +5963,11 @@ query_lookup(query_ctx_t *qctx) {
qctx->client->query.dboptions &= qctx->client->query.dboptions &=
~DNS_DBFIND_STALETIMEOUT; ~DNS_DBFIND_STALETIMEOUT;
qctx->options &= ~DNS_GETDB_STALEFIRST; qctx->options &= ~DNS_GETDB_STALEFIRST;
if (qctx->client->query.fetch != NULL) { if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL)
{
dns_resolver_destroyfetch( dns_resolver_destroyfetch(
&qctx->client->query.fetch); &FETCH_RECTYPE_NORMAL(
qctx->client));
} }
return (query_lookup(qctx)); return (query_lookup(qctx));
} else { } else {
@@ -6163,22 +6167,22 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
client->nodetach = false; client->nodetach = false;
LOCK(&client->query.fetchlock); LOCK(&client->query.fetchlock);
INSIST(client->query.fetch == devent->fetch || INSIST(FETCH_RECTYPE_NORMAL(client) == devent->fetch ||
client->query.fetch == NULL); FETCH_RECTYPE_NORMAL(client) == NULL);
if (QUERY_STALEPENDING(&client->query)) { if (QUERY_STALEPENDING(&client->query)) {
/* /*
* We've gotten an authoritative answer to a query that * We've gotten an authoritative answer to a query that
* was left pending after a stale timeout. We don't need * was left pending after a stale timeout. We don't need
* to do anything with it; free all the data and go home. * to do anything with it; free all the data and go home.
*/ */
client->query.fetch = NULL; FETCH_RECTYPE_NORMAL(client) = NULL;
fetch_answered = true; fetch_answered = true;
} else if (client->query.fetch != NULL) { } else if (FETCH_RECTYPE_NORMAL(client) != NULL) {
/* /*
* This is the fetch we've been waiting for. * This is the fetch we've been waiting for.
*/ */
INSIST(devent->fetch == client->query.fetch); INSIST(FETCH_RECTYPE_NORMAL(client) == devent->fetch);
client->query.fetch = NULL; FETCH_RECTYPE_NORMAL(client) = NULL;
/* /*
* Update client->now. * Update client->now.
@@ -6208,7 +6212,7 @@ fetch_callback(isc_task_t *task, isc_event_t *event) {
} }
UNLOCK(&client->manager->reclock); UNLOCK(&client->manager->reclock);
isc_nmhandle_detach(&client->fetchhandle); isc_nmhandle_detach(&HANDLE_RECTYPE_NORMAL(client));
client->query.attributes &= ~NS_QUERYATTR_RECURSING; client->query.attributes &= ~NS_QUERYATTR_RECURSING;
client->state = NS_CLIENTSTATE_WORKING; client->state = NS_CLIENTSTATE_WORKING;
@@ -6419,7 +6423,7 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
* Invoke the resolver. * Invoke the resolver.
*/ */
REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns); REQUIRE(nameservers == NULL || nameservers->type == dns_rdatatype_ns);
REQUIRE(client->query.fetch == NULL); REQUIRE(FETCH_RECTYPE_NORMAL(client) == NULL);
rdataset = ns_client_newrdataset(client); rdataset = ns_client_newrdataset(client);
@@ -6444,14 +6448,14 @@ ns_query_recurse(ns_client_t *client, dns_rdatatype_t qtype, dns_name_t *qname,
client->query.fetchoptions |= DNS_FETCHOPT_TRYSTALE_ONTIMEOUT; client->query.fetchoptions |= DNS_FETCHOPT_TRYSTALE_ONTIMEOUT;
} }
isc_nmhandle_attach(client->handle, &client->fetchhandle); isc_nmhandle_attach(client->handle, &HANDLE_RECTYPE_NORMAL(client));
result = dns_resolver_createfetch( result = dns_resolver_createfetch(
client->view->resolver, qname, qtype, qdomain, nameservers, client->view->resolver, qname, qtype, qdomain, nameservers,
NULL, peeraddr, client->message->id, client->query.fetchoptions, NULL, peeraddr, client->message->id, client->query.fetchoptions,
0, NULL, client->manager->task, fetch_callback, client, 0, NULL, client->manager->task, fetch_callback, client,
rdataset, sigrdataset, &client->query.fetch); rdataset, sigrdataset, &FETCH_RECTYPE_NORMAL(client));
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
isc_nmhandle_detach(&client->fetchhandle); isc_nmhandle_detach(&HANDLE_RECTYPE_NORMAL(client));
ns_client_putrdataset(client, &rdataset); ns_client_putrdataset(client, &rdataset);
if (sigrdataset != NULL) { if (sigrdataset != NULL) {
ns_client_putrdataset(client, &sigrdataset); ns_client_putrdataset(client, &sigrdataset);
@@ -6692,12 +6696,11 @@ query_hookresume(isc_task_t *task, isc_event_t *event) {
UNLOCK(&client->manager->reclock); UNLOCK(&client->manager->reclock);
/* /*
* This event is running under a client task, so it's safe to detach * The fetch handle should be detached before resuming query processing
* the fetch handle. And it should be done before resuming query * below, since that may trigger another recursion or asynchronous hook
* processing below, since that may trigger another recursion or * event.
* asynchronous hook event.
*/ */
isc_nmhandle_detach(&client->fetchhandle); isc_nmhandle_detach(&HANDLE_RECTYPE_HOOK(client));
client->state = NS_CLIENTSTATE_WORKING; client->state = NS_CLIENTSTATE_WORKING;
@@ -6813,7 +6816,7 @@ ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync,
REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(NS_CLIENT_VALID(client));
REQUIRE(client->query.hookactx == NULL); REQUIRE(client->query.hookactx == NULL);
REQUIRE(client->query.fetch == NULL); REQUIRE(FETCH_RECTYPE_NORMAL(client) == NULL);
result = check_recursionquota(client); result = check_recursionquota(client);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
@@ -6836,12 +6839,11 @@ ns_query_hookasync(query_ctx_t *qctx, ns_query_starthookasync_t runasync,
* attribute won't be checked anywhere. * attribute won't be checked anywhere.
* *
* Hook-based asynchronous processing cannot coincide with normal * Hook-based asynchronous processing cannot coincide with normal
* recursion, so we can safely use fetchhandle here. Unlike in * recursion. Unlike in ns_query_recurse(), we attach to the handle
* ns_query_recurse(), we attach to the handle only if 'runasync' * only if 'runasync' succeeds. It should be safe since we're either in
* succeeds. It should be safe since we're either in the client * the client task or pausing it.
* task or pausing it.
*/ */
isc_nmhandle_attach(client->handle, &client->fetchhandle); isc_nmhandle_attach(client->handle, &HANDLE_RECTYPE_HOOK(client));
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
cleanup: cleanup:
@@ -7495,8 +7497,9 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
dns_db_attach(qctx->client->view->cachedb, &qctx->db); dns_db_attach(qctx->client->view->cachedb, &qctx->db);
qctx->version = NULL; qctx->version = NULL;
qctx->client->query.dboptions |= DNS_DBFIND_STALEOK; qctx->client->query.dboptions |= DNS_DBFIND_STALEOK;
if (qctx->client->query.fetch != NULL) { if (FETCH_RECTYPE_NORMAL(qctx->client) != NULL) {
dns_resolver_destroyfetch(&qctx->client->query.fetch); dns_resolver_destroyfetch(
&FETCH_RECTYPE_NORMAL(qctx->client));
} }
/* /*

View File

@@ -709,11 +709,11 @@ hook_async_common(void *arg, void *data, isc_result_t *resultp,
} }
} else { } else {
/* /*
* Resume from the completion of async event. * Resume from the completion of async event. The fetch handle
* fetchhandle should have been detached so that we can start * should have been detached so that we can start another async
* another async event or DNS recursive resolution. * event or DNS recursive resolution.
*/ */
INSIST(qctx->client->fetchhandle == NULL); INSIST(HANDLE_RECTYPE_HOOK(qctx->client) == NULL);
asdata->async = false; asdata->async = false;
switch (hookpoint) { switch (hookpoint) {
case NS_QUERY_GOT_ANSWER_BEGIN: case NS_QUERY_GOT_ANSWER_BEGIN: