mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.20] fix: usr: Fix rare assertion failure when shutting down incoming transfer
A very rare assertion failure can be triggered when the incoming transfer is either forcefully shut down or it is finished during printing the details about the statistics channel. This has been fixed. Closes #4860 Backport of MR !9336 Merge branch 'backport-4860-destroy-xfrin-timers-on-the-loop-9.20' into 'bind-9.20' See merge request isc-projects/bind9!9377
This commit is contained in:
commit
02d4755cc3
1 changed files with 36 additions and 23 deletions
|
|
@ -898,8 +898,6 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
|
|||
|
||||
xfr->done = done;
|
||||
|
||||
isc_refcount_init(&xfr->references, 1);
|
||||
|
||||
/*
|
||||
* Set *xfrp now, before calling xfrin_start(), otherwise it's
|
||||
* possible the 'done' callback could be run before *xfrp
|
||||
|
|
@ -909,9 +907,8 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype,
|
|||
|
||||
result = xfrin_start(xfr);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&xfr->shuttingdown, true);
|
||||
xfr->shutdown_result = result;
|
||||
xfrin_log(xfr, ISC_LOG_ERROR, "zone transfer setup failed");
|
||||
xfr->done = NULL;
|
||||
xfrin_fail(xfr, result, "zone transfer setup failed");
|
||||
dns_xfrin_detach(xfrp);
|
||||
}
|
||||
|
||||
|
|
@ -1166,6 +1163,7 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
|
|||
.soa_transport_type = soa_transport_type,
|
||||
.firstsoa = DNS_RDATA_INIT,
|
||||
.edns = true,
|
||||
.references = 1,
|
||||
.magic = XFRIN_MAGIC,
|
||||
};
|
||||
|
||||
|
|
@ -1214,11 +1212,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop,
|
|||
|
||||
isc_tlsctx_cache_attach(tlsctx_cache, &xfr->tlsctx_cache);
|
||||
|
||||
isc_timer_create(dns_zone_getloop(zone), xfrin_timedout, xfr,
|
||||
&xfr->max_time_timer);
|
||||
isc_timer_create(dns_zone_getloop(zone), xfrin_idledout, xfr,
|
||||
&xfr->max_idle_timer);
|
||||
|
||||
dns_zone_name(xfr->zone, xfr->info, sizeof(xfr->info));
|
||||
|
||||
*xfrp = xfr;
|
||||
|
|
@ -1268,14 +1261,6 @@ xfrin_start(dns_xfrin_t *xfr) {
|
|||
dns_xfrin_gettransporttype(xfr));
|
||||
}
|
||||
|
||||
/* Set the maximum timer */
|
||||
isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
|
||||
isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);
|
||||
|
||||
/* Set the idle timer */
|
||||
isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
|
||||
isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
|
||||
|
||||
/*
|
||||
* XXX: timeouts are hard-coded to 30 seconds; this needs to be
|
||||
* configurable.
|
||||
|
|
@ -1285,6 +1270,27 @@ xfrin_start(dns_xfrin_t *xfr) {
|
|||
xfr->tlsctx_cache, xfrin_connect_done,
|
||||
xfrin_send_done, xfrin_recv_done, xfr, &xfr->id,
|
||||
&xfr->dispentry));
|
||||
|
||||
/* Set the maximum timer */
|
||||
if (xfr->max_time_timer == NULL) {
|
||||
isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_timedout,
|
||||
xfr, &xfr->max_time_timer);
|
||||
}
|
||||
isc_interval_set(&interval, dns_zone_getmaxxfrin(xfr->zone), 0);
|
||||
isc_timer_start(xfr->max_time_timer, isc_timertype_once, &interval);
|
||||
|
||||
/* Set the idle timer */
|
||||
if (xfr->max_idle_timer == NULL) {
|
||||
isc_timer_create(dns_zone_getloop(xfr->zone), xfrin_idledout,
|
||||
xfr, &xfr->max_idle_timer);
|
||||
}
|
||||
isc_interval_set(&interval, dns_zone_getidlein(xfr->zone), 0);
|
||||
isc_timer_start(xfr->max_idle_timer, isc_timertype_once, &interval);
|
||||
|
||||
/*
|
||||
* The connect has to be the last thing that is called before returning,
|
||||
* as it can end synchronously and destroy the xfr object.
|
||||
*/
|
||||
CHECK(dns_dispatch_connect(xfr->dispentry));
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
|
|
@ -1399,7 +1405,7 @@ failure:
|
|||
}
|
||||
|
||||
detach:
|
||||
dns_xfrin_unref(xfr);
|
||||
dns_xfrin_detach(&xfr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1670,8 +1676,15 @@ xfrin_end(dns_xfrin_t *xfr, isc_result_t result) {
|
|||
}
|
||||
|
||||
atomic_store(&xfr->shuttingdown, true);
|
||||
isc_timer_stop(xfr->max_time_timer);
|
||||
isc_timer_stop(xfr->max_idle_timer);
|
||||
|
||||
if (xfr->max_time_timer != NULL) {
|
||||
isc_timer_stop(xfr->max_time_timer);
|
||||
isc_timer_destroy(&xfr->max_time_timer);
|
||||
}
|
||||
if (xfr->max_idle_timer != NULL) {
|
||||
isc_timer_stop(xfr->max_idle_timer);
|
||||
isc_timer_destroy(&xfr->max_idle_timer);
|
||||
}
|
||||
|
||||
if (xfr->shutdown_result == ISC_R_UNSET) {
|
||||
xfr->shutdown_result = result;
|
||||
|
|
@ -2103,8 +2116,8 @@ xfrin_destroy(dns_xfrin_t *xfr) {
|
|||
isc_tlsctx_cache_detach(&xfr->tlsctx_cache);
|
||||
}
|
||||
|
||||
isc_timer_destroy(&xfr->max_idle_timer);
|
||||
isc_timer_destroy(&xfr->max_time_timer);
|
||||
INSIST(xfr->max_time_timer == NULL);
|
||||
INSIST(xfr->max_idle_timer == NULL);
|
||||
|
||||
isc_loop_detach(&xfr->loop);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue