From e011521ef163779a8ec885ab630cb694a446e95e Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Mon, 9 Nov 2020 12:33:37 -0800 Subject: [PATCH] address some possible shutdown races in xfrin there were two failures during observed in testing, both occurring when 'rndc halt' was run rather than 'rndc stop' - the latter dumps zone contents to disk and presumably introduced enough delay to prevent the races: - a failure when the zone was shut down and called dns_xfrin_detach() before the xfrin had finished connecting; the connect timeout terminated without detaching its handle - a failure when the tcpdns socket timer fired after the outerhandle had already been cleared. this commit incidentally addresses a failure observed in mutexatomic due to a variable having been initialized incorrectly. --- bin/named/server.c | 2 +- lib/dns/xfrin.c | 5 +++-- lib/isc/netmgr/tcpdns.c | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index be731815ba..af3ea26442 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -10004,7 +10004,7 @@ named_server_create(isc_mem_t *mctx, named_server_t **serverp) { &server->in_roothints), "setting up root hints"); - atomic_store(&server->reload_status, NAMED_RELOAD_IN_PROGRESS); + atomic_init(&server->reload_status, NAMED_RELOAD_IN_PROGRESS); /* * Setup the server task, which is responsible for coordinating diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 497318472c..71a5eab2ef 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -937,7 +937,7 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { TIME_NOW(&now); dns_zonemgr_unreachableadd(zmgr, &xfr->masteraddr, &xfr->sourceaddr, &now); - goto failure; + CHECK(result); } else { dns_zonemgr_unreachabledel(zmgr, &xfr->masteraddr, &xfr->sourceaddr); @@ -959,9 +959,10 @@ xfrin_connect_done(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { signer); CHECK(xfrin_send_request(xfr)); - isc_nmhandle_detach(&handle); failure: + isc_nmhandle_detach(&handle); + if (result != ISC_R_SUCCESS && result != ISC_R_SHUTTINGDOWN) { xfrin_fail(xfr, result, "failed to connect"); } diff --git a/lib/isc/netmgr/tcpdns.c b/lib/isc/netmgr/tcpdns.c index b06d56415d..aa2003ea79 100644 --- a/lib/isc/netmgr/tcpdns.c +++ b/lib/isc/netmgr/tcpdns.c @@ -98,7 +98,9 @@ dnstcp_readtimeout(uv_timer_t *timer) { REQUIRE(sock->tid == isc_nm_tid()); /* Close the TCP connection; its closure should fire ours. */ - isc_nmhandle_detach(&sock->outerhandle); + if (sock->outerhandle != NULL) { + isc_nmhandle_detach(&sock->outerhandle); + } } /*