2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

refactor dispatch cancellation

Renamed some functions for clarity and readability:

- dns_dispatch_addresponse() -> dns_dispatch_add()
- dns_dispatch_removeresponse() -> dns_dispatch_done()

The dns_dispatch_cancel() function now calls dns_dispatch_done()
directly, so it is no longer ever necessary to call both functions.

dns_dispatch_cancel() is used to terminate dispatch connections
that are still pending, while dns_dispatch_done() is used when they
are complete.
This commit is contained in:
Evan Hunt 2021-10-03 15:15:50 -07:00
parent 2653800e0b
commit 24dbf9849e
5 changed files with 126 additions and 108 deletions

View File

@ -1288,11 +1288,11 @@ dns_dispatch_detach(dns_dispatch_t **dispp) {
}
isc_result_t
dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
unsigned int timeout, const isc_sockaddr_t *dest,
dispatch_cb_t connected, dispatch_cb_t sent,
dispatch_cb_t response, void *arg,
dns_messageid_t *idp, dns_dispentry_t **resp) {
dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
unsigned int timeout, const isc_sockaddr_t *dest,
dispatch_cb_t connected, dispatch_cb_t sent,
dispatch_cb_t response, void *arg, dns_messageid_t *idp,
dns_dispentry_t **resp) {
dns_dispentry_t *res = NULL;
dns_qid_t *qid = NULL;
in_port_t localport = 0;
@ -1476,7 +1476,65 @@ dns_dispatch_getnext(dns_dispentry_t *resp) {
}
void
dns_dispatch_removeresponse(dns_dispentry_t **respp) {
dns_dispatch_cancel(dns_dispentry_t **respp) {
dns_dispentry_t *resp = NULL;
REQUIRE(respp != NULL);
resp = *respp;
REQUIRE(VALID_RESPONSE(resp));
resp->canceled = true;
/* Connected UDP. */
if (resp->handle != NULL) {
isc_nm_cancelread(resp->handle);
goto done;
}
/* TCP pending connection. */
if (ISC_LINK_LINKED(resp, plink)) {
dns_dispentry_t *copy = resp;
ISC_LIST_UNLINK(resp->disp->pending, resp, plink);
if (resp->connected != NULL) {
resp->connected(ISC_R_CANCELED, NULL, resp->arg);
}
/*
* We need to detach twice if we were pending
* connection - once to take the place of the
* detach in tcp_connected() or udp_connected()
* that we won't reach, and again later in
* dns_dispatch_done().
*/
dispentry_detach(&copy);
goto done;
}
/*
* Connected TCP, or unconnected UDP.
*
* If TCP, we don't want to cancel the dispatch
* unless this is the last resp waiting.
*/
if (ISC_LINK_LINKED(resp, alink)) {
ISC_LIST_UNLINK(resp->disp->active, resp, alink);
if (ISC_LIST_EMPTY(resp->disp->active) &&
resp->disp->handle != NULL) {
isc_nm_cancelread(resp->disp->handle);
} else if (resp->response != NULL) {
resp->response(ISC_R_CANCELED, NULL, resp->arg);
}
}
done:
dns_dispatch_done(respp);
}
void
dns_dispatch_done(dns_dispentry_t **respp) {
dns_dispatchmgr_t *mgr = NULL;
dns_dispatch_t *disp = NULL;
dns_dispentry_t *resp = NULL;
@ -1762,45 +1820,6 @@ dns_dispatch_send(dns_dispentry_t *resp, isc_region_t *r, isc_dscp_t dscp) {
isc_nm_send(handle, r, send_done, resp);
}
void
dns_dispatch_cancel(dns_dispentry_t *resp) {
REQUIRE(VALID_RESPONSE(resp));
resp->canceled = true;
/* Connected UDP */
if (resp->handle != NULL) {
isc_nm_cancelread(resp->handle);
return;
}
/* TCP pending connection. */
if (ISC_LINK_LINKED(resp, plink)) {
ISC_LIST_UNLINK(resp->disp->pending, resp, plink);
if (resp->connected != NULL) {
resp->connected(ISC_R_CANCELED, NULL, resp->arg);
dispentry_detach(&resp);
}
return;
}
/*
* Connected TCP, or unconnected UDP.
*
* If TCP, we don't want to cancel the dispatch
* unless this is the last resp waiting.
*/
if (ISC_LINK_LINKED(resp, alink)) {
ISC_LIST_UNLINK(resp->disp->active, resp, alink);
if (ISC_LIST_EMPTY(resp->disp->active) &&
resp->disp->handle != NULL) {
isc_nm_cancelread(resp->disp->handle);
} else if (resp->response != NULL) {
resp->response(ISC_R_CANCELED, NULL, resp->arg);
}
}
}
isc_result_t
dns_dispatch_getlocaladdress(dns_dispatch_t *disp, isc_sockaddr_t *addrp) {
REQUIRE(VALID_DISPATCH(disp));

View File

@ -25,7 +25,7 @@
* MP:
*
*\li All locking is performed internally to each dispatch.
* Restrictions apply to dns_dispatch_removeresponse().
* Restrictions apply to dns_dispatch_done().
*
* Reliability:
*
@ -225,17 +225,7 @@ isc_result_t
dns_dispatch_connect(dns_dispentry_t *resp);
/*%<
* Connect to the remote server configured in 'resp' and run the
* connect callback that was set up via dns_dispatch_addresponse().
*
* Requires:
*\li 'resp' is valid.
*/
void
dns_dispatch_cancel(dns_dispentry_t *resp);
/*%<
* Cancel pending connects in 'resp', by setting a flag so that
* a read is not started when the connect handler runs.
* connect callback that was set up via dns_dispatch_add().
*
* Requires:
*\li 'resp' is valid.
@ -274,11 +264,11 @@ typedef void (*dispatch_cb_t)(isc_result_t eresult, isc_region_t *region,
void *cbarg);
isc_result_t
dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
unsigned int timeout, const isc_sockaddr_t *dest,
dispatch_cb_t connected, dispatch_cb_t sent,
dispatch_cb_t response, void *arg,
dns_messageid_t *idp, dns_dispentry_t **resp);
dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
unsigned int timeout, const isc_sockaddr_t *dest,
dispatch_cb_t connected, dispatch_cb_t sent,
dispatch_cb_t response, void *arg, dns_messageid_t *idp,
dns_dispentry_t **resp);
/*%<
* Add a response entry for this dispatch.
*
@ -316,13 +306,27 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, unsigned int options,
*/
void
dns_dispatch_removeresponse(dns_dispentry_t **resp);
dns_dispatch_done(dns_dispentry_t **respp);
/*%<
* Stops the flow of responses for the provided id and destination.
* Disconnects a dispatch response entry from its dispatch and shuts it
* down. This is called when the dispatch is complete; use
* dns_dispatch_cancel() if it is still pending.
*
* Requires:
*\li "resp" != NULL and "*resp" contain a value previously allocated
* by dns_dispatch_addresponse();
* by dns_dispatch_add();
*/
void
dns_dispatch_cancel(dns_dispentry_t **respp);
/*%<
* Cancel all pending connects and reads in a dispatch entry,
* then call dns_dispatch_done(). This is used when the caller
* cancels a dispatch response before it has completed.
*
* Requires:
*\li "resp" != NULL and "*resp" contain a value previously allocated
* by dns_dispatch_add();
*/
isc_result_t

View File

@ -559,10 +559,10 @@ again:
}
req_attach(request, &rclone);
result = dns_dispatch_addresponse(
request->dispatch, dispopt, request->timeout, destaddr,
req_connected, req_senddone, req_response, request, &id,
&request->dispentry);
result = dns_dispatch_add(request->dispatch, dispopt, request->timeout,
destaddr, req_connected, req_senddone,
req_response, request, &id,
&request->dispentry);
if (result != ISC_R_SUCCESS) {
if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
newtcp = true;
@ -722,7 +722,7 @@ use_tcp:
}
req_attach(request, &rclone);
result = dns_dispatch_addresponse(
result = dns_dispatch_add(
request->dispatch, 0, request->timeout, destaddr, req_connected,
req_senddone, req_response, request, &id, &request->dispentry);
if (result != ISC_R_SUCCESS) {
@ -737,7 +737,7 @@ use_tcp:
*/
req_detach(&rclone);
dns_message_renderreset(message);
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_done(&request->dispentry);
dns_dispatch_detach(&request->dispatch);
options |= DNS_REQUESTOPT_TCP;
tcp = true;
@ -901,8 +901,7 @@ request_cancel(dns_request_t *request) {
request->flags &= ~DNS_REQUEST_F_CONNECTING;
if (request->dispentry != NULL) {
dns_dispatch_cancel(request->dispentry);
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_cancel(&request->dispentry);
}
dns_dispatch_detach(&request->dispatch);
@ -977,8 +976,6 @@ dns_request_destroy(dns_request_t **requestp) {
LOCK(&request->requestmgr->lock);
LOCK(&request->requestmgr->locks[request->hash]);
ISC_LIST_UNLINK(request->requestmgr->requests, request, link);
INSIST(!DNS_REQUEST_CONNECTING(request));
INSIST(!DNS_REQUEST_SENDING(request));
UNLOCK(&request->requestmgr->locks[request->hash]);
UNLOCK(&request->requestmgr->lock);
@ -986,7 +983,6 @@ dns_request_destroy(dns_request_t **requestp) {
* These should have been cleaned up before the completion
* event was sent.
*/
INSIST(!ISC_LINK_LINKED(request, link));
INSIST(request->dispentry == NULL);
INSIST(request->dispatch == NULL);
@ -1010,7 +1006,7 @@ req_connected(isc_result_t eresult, isc_region_t *region, void *arg) {
request->flags &= ~DNS_REQUEST_F_CONNECTING;
if (eresult == ISC_R_TIMEDOUT) {
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_done(&request->dispentry);
dns_dispatch_detach(&request->dispatch);
req_sendevent(request, eresult);
} else if (DNS_REQUEST_CANCELED(request)) {
@ -1103,7 +1099,7 @@ done:
* Cleanup.
*/
if (request->dispentry != NULL) {
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_done(&request->dispentry);
}
request_cancel(request);
@ -1192,7 +1188,7 @@ req_destroy(dns_request_t *request) {
isc_event_free((isc_event_t **)&request->event);
}
if (request->dispentry != NULL) {
dns_dispatch_removeresponse(&request->dispentry);
dns_dispatch_done(&request->dispentry);
}
if (request->dispatch != NULL) {
dns_dispatch_detach(&request->dispatch);

View File

@ -1142,7 +1142,7 @@ resquery_destroy(resquery_t *query) {
}
if (query->dispentry != NULL) {
dns_dispatch_removeresponse(&query->dispentry);
dns_dispatch_done(&query->dispentry);
}
if (query->dispatch != NULL) {
@ -1229,12 +1229,12 @@ fctx_cancelquery(resquery_t **queryp, isc_time_t *finish, bool no_response,
query = *queryp;
fctx = query->fctx;
FCTXTRACE("cancelquery");
if (RESQUERY_CANCELED(query)) {
return;
}
FCTXTRACE("cancelquery");
query->attributes |= RESQUERY_ATTR_CANCELED;
/*
@ -1397,8 +1397,7 @@ fctx_cancelquery(resquery_t **queryp, isc_time_t *finish, bool no_response,
* exist, cancel them.
*/
if (query->dispentry != NULL) {
dns_dispatch_cancel(query->dispentry);
dns_dispatch_removeresponse(&query->dispentry);
dns_dispatch_cancel(&query->dispentry);
}
if (ISC_LINK_LINKED(query, link)) {
@ -2126,7 +2125,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
UNLOCK(&res->buckets[fctx->bucketnum].lock);
/* Set up the dispatch and set the query ID */
result = dns_dispatch_addresponse(
result = dns_dispatch_add(
query->dispatch, 0, isc_interval_ms(&fctx->interval),
&query->addrinfo->sockaddr, resquery_connected,
resquery_senddone, resquery_response, query, &query->id,
@ -2733,7 +2732,7 @@ cleanup_message:
/*
* Stop the dispatcher from listening.
*/
dns_dispatch_removeresponse(&query->dispentry);
dns_dispatch_done(&query->dispentry);
cleanup_temps:
if (qname != NULL) {
@ -4390,7 +4389,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) {
fctx_cleanup(fctx);
LOCK(&res->buckets[bucketnum].lock);
fctx_decreference(fctx);
RUNTIME_CHECK(!fctx_decreference(fctx));
FCTX_ATTR_SET(fctx, FCTX_ATTR_SHUTTINGDOWN);

View File

@ -456,10 +456,10 @@ dispatch_timeout_tcp_connect(void **state) {
region.base = rbuf;
region.length = sizeof(rbuf);
result = dns_dispatch_addresponse(dispatch, 0, T_CLIENT_CONNECT,
&tcp_server_addr, timeout_connected,
client_senddone, response, &region,
&id, &dispentry);
result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
&tcp_server_addr, timeout_connected,
client_senddone, response, &region, &id,
&dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -473,7 +473,7 @@ dispatch_timeout_tcp_connect(void **state) {
uv_sem_wait(&sem);
dns_dispatch_removeresponse(&dispentry);
dns_dispatch_done(&dispentry);
dns_dispatch_detach(&dispatch);
dns_dispatchmgr_detach(&dispatchmgr);
@ -517,9 +517,9 @@ dispatch_timeout_tcp_response(void **state __attribute__((unused))) {
region.base = rbuf;
region.length = sizeof(rbuf);
result = dns_dispatch_addresponse(
dispatch, 0, T_CLIENT_CONNECT, &tcp_server_addr, connected,
client_senddone, response_timeout, &region, &id, &dispentry);
result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
&tcp_server_addr, connected, client_senddone,
response_timeout, &region, &id, &dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -539,7 +539,7 @@ dispatch_timeout_tcp_response(void **state __attribute__((unused))) {
isc_nmsocket_close(&sock);
assert_null(sock);
dns_dispatch_removeresponse(&dispentry);
dns_dispatch_done(&dispentry);
dns_dispatch_detach(&dispatch);
dns_dispatchmgr_detach(&dispatchmgr);
@ -573,9 +573,9 @@ dispatch_tcp_response(void **state __attribute__((unused))) {
region.base = rbuf;
region.length = sizeof(rbuf);
result = dns_dispatch_addresponse(
dispatch, 0, T_CLIENT_CONNECT, &tcp_server_addr, connected,
client_senddone, response, &region, &id, &dispentry);
result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
&tcp_server_addr, connected, client_senddone,
response, &region, &id, &dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -598,7 +598,7 @@ dispatch_tcp_response(void **state __attribute__((unused))) {
isc_nmsocket_close(&sock);
assert_null(sock);
dns_dispatch_removeresponse(&dispentry);
dns_dispatch_done(&dispentry);
dns_dispatch_detach(&dispatch);
dns_dispatchmgr_detach(&dispatchmgr);
@ -632,9 +632,9 @@ dispatch_timeout_udp_response(void **state __attribute__((unused))) {
region.base = rbuf;
region.length = sizeof(rbuf);
result = dns_dispatch_addresponse(
dispatch, 0, T_CLIENT_CONNECT, &udp_server_addr, connected,
client_senddone, response_timeout, &region, &id, &dispentry);
result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
&udp_server_addr, connected, client_senddone,
response_timeout, &region, &id, &dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -654,7 +654,7 @@ dispatch_timeout_udp_response(void **state __attribute__((unused))) {
isc_nmsocket_close(&sock);
assert_null(sock);
dns_dispatch_removeresponse(&dispentry);
dns_dispatch_done(&dispentry);
dns_dispatch_detach(&dispatch);
dns_dispatchmgr_detach(&dispatchmgr);
@ -688,9 +688,9 @@ dispatch_getnext(void **state) {
region.base = rbuf;
region.length = sizeof(rbuf);
result = dns_dispatch_addresponse(
dispatch, 0, T_CLIENT_CONNECT, &udp_server_addr, connected,
client_senddone, response_getnext, &region, &id, &dispentry);
result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
&udp_server_addr, connected, client_senddone,
response_getnext, &region, &id, &dispentry);
assert_int_equal(result, ISC_R_SUCCESS);
memset(message, 0, sizeof(message));
@ -711,7 +711,7 @@ dispatch_getnext(void **state) {
isc_nmsocket_close(&sock);
assert_null(sock);
dns_dispatch_removeresponse(&dispentry);
dns_dispatch_done(&dispentry);
dns_dispatch_detach(&dispatch);
dns_dispatchmgr_detach(&dispatchmgr);
}