2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Convert dispatch to netmgr

The flow of operations in dispatch is changing and will now be similar
for both UDP and TCP queries:

1) Call dns_dispatch_addresponse() to assign a query ID and register
   that we'll be listening for a response with that ID soon. the
   parameters for this function include callback functions to inform the
   caller when the socket is connected and when the message has been
   sent, as well as a task action that will be sent when the response
   arrives. (later this could become a netmgr callback, but at this
   stage to minimize disruption to the calling code, we continue to use
   isc_task for the response event.) on successful completion of this
   function, a dispatch entry object will be instantiated.

2) Call dns_dispatch_connect() on the dispatch entry. this runs
   isc_nm_udpconnect() or isc_nm_tcpdnsconnect(), as needed, and begins
   listening for responses. the caller is informed via a callback
   function when the connection is established.

3) Call dns_dispatch_send() on the dispatch entry. this runs
   isc_nm_send() to send a request.

4) Call dns_dispatch_removeresponse() to terminate listening and close
   the connection.

Implementation comments below:

- As we will be using netmgr buffers now.  code to send the length in
  TCP queries has also been removed as that is handled by the netmgr.

- TCP dispatches can be used by multiple simultaneous queries, so
  dns_dispatch_connect() now checks whether the dispatch is already
  connected before calling isc_nm_tcpdnsconnect() again.

- Running dns_dispatch_getnext() from a non-network thread caused a
  crash due to assertions in the netmgr read functions that appear to be
  unnecessary now. the assertions have been removed.

- fctx->nqueries was formerly incremented when the connection was
  successful, but is now incremented when the query is started and
  decremented if the connection fails.

- It's no longer necessary for each dispatch to have a pool of tasks, so
  there's now a single task per dispatch.

- Dispatch code to avoid UDP ports already in use has been removed.

- dns_resolver and dns_request have been modified to use netmgr callback
  functions instead of task events. some additional changes were needed
  to handle shutdown processing correctly.

- Timeout processing is not yet fully converted to use netmgr timeouts.

- Fixed a lock order cycle reported by TSAN (view -> zone-> adb -> view)
  by by calling dns_zt functions without holding the view lock.
This commit is contained in:
Evan Hunt
2021-01-14 13:02:57 -08:00
parent 9ee60e7a17
commit 308bc46a59
28 changed files with 924 additions and 1606 deletions

View File

@@ -634,6 +634,7 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
dns_zone_t *mkzone = NULL, *rdzone = NULL;
isc_refcount_destroy(&view->references);
if (!RESSHUTDOWN(view)) {
dns_resolver_shutdown(view->resolver);
}
@@ -643,14 +644,14 @@ view_flushanddetach(dns_view_t **viewp, bool flush) {
if (!REQSHUTDOWN(view)) {
dns_requestmgr_shutdown(view->requestmgr);
}
LOCK(&view->lock);
if (view->zonetable != NULL) {
if (view->flush) {
dns_zt_flushanddetach(&view->zonetable);
} else {
dns_zt_detach(&view->zonetable);
}
if (view->zonetable != NULL && view->flush) {
dns_zt_flushanddetach(&view->zonetable);
} else if (view->zonetable != NULL) {
dns_zt_detach(&view->zonetable);
}
LOCK(&view->lock);
if (view->managed_keys != NULL) {
mkzone = view->managed_keys;
view->managed_keys = NULL;
@@ -796,9 +797,9 @@ dns_view_createzonetable(dns_view_t *view) {
isc_result_t
dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
unsigned int ntasks, unsigned int ndisp,
isc_socketmgr_t *socketmgr, isc_timermgr_t *timermgr,
unsigned int options, dns_dispatchmgr_t *dispatchmgr,
unsigned int ntasks, unsigned int ndisp, isc_nm_t *nm,
isc_timermgr_t *timermgr, unsigned int options,
dns_dispatchmgr_t *dispatchmgr,
dns_dispatch_t *dispatchv4,
dns_dispatch_t *dispatchv6) {
isc_result_t result;
@@ -815,8 +816,8 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
}
isc_task_setname(view->task, "view", view);
result = dns_resolver_create(view, taskmgr, ntasks, ndisp, socketmgr,
timermgr, options, dispatchmgr, dispatchv4,
result = dns_resolver_create(view, taskmgr, ntasks, ndisp, nm, timermgr,
options, dispatchmgr, dispatchv4,
dispatchv6, &view->resolver);
if (result != ISC_R_SUCCESS) {
isc_task_detach(&view->task);
@@ -841,11 +842,10 @@ dns_view_createresolver(dns_view_t *view, isc_taskmgr_t *taskmgr,
atomic_fetch_and(&view->attributes, ~DNS_VIEWATTR_ADBSHUTDOWN);
isc_refcount_increment(&view->weakrefs);
result = dns_requestmgr_create(view->mctx, timermgr, socketmgr,
dns_resolver_taskmgr(view->resolver),
dns_resolver_dispatchmgr(view->resolver),
dispatchv4, dispatchv6,
&view->requestmgr);
result = dns_requestmgr_create(
view->mctx, dns_resolver_taskmgr(view->resolver),
dns_resolver_dispatchmgr(view->resolver), dispatchv4,
dispatchv6, &view->requestmgr);
if (result != ISC_R_SUCCESS) {
dns_adb_shutdown(view->adb);
dns_resolver_shutdown(view->resolver);
@@ -2502,12 +2502,12 @@ dns_view_setviewcommit(dns_view_t *view) {
if (view->managed_keys != NULL) {
dns_zone_attach(view->managed_keys, &managed_keys);
}
if (view->zonetable != NULL) {
dns_zt_setviewcommit(view->zonetable);
}
UNLOCK(&view->lock);
if (view->zonetable != NULL) {
dns_zt_setviewcommit(view->zonetable);
}
if (redirect != NULL) {
dns_zone_setviewcommit(redirect);
dns_zone_detach(&redirect);