From 98d59bdf62db8be585683c800250dd11860d8b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Mon, 4 Mar 2024 13:21:35 +0100 Subject: [PATCH] Pin the xfr to a specific loop Instead of getting the loop from the zone every time, attach the xfrin directly to the loop. This also allows to remove the extra safety tid checks from the dns_xfrin unit. --- lib/dns/xfrin.c | 40 +++++++++++++++++++++------------------- lib/dns/zone.c | 4 +--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 9ac923f5e7..8b5d41233f 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -186,6 +186,8 @@ struct dns_xfrin { isc_tlsctx_cache_t *tlsctx_cache; + isc_loop_t *loop; + isc_timer_t *max_time_timer; isc_timer_t *max_idle_timer; @@ -206,7 +208,7 @@ typedef struct xfrin_work { */ static void -xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, +xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop, dns_name_t *zonename, dns_rdataclass_t rdclass, dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr, const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey, @@ -404,8 +406,7 @@ axfr_commit(dns_xfrin_t *xfr) { .result = ISC_R_UNSET, }; xfr->diff_running = true; - isc_work_enqueue(dns_zone_getloop(xfr->zone), axfr_apply, - axfr_apply_done, work); + isc_work_enqueue(xfr->loop, axfr_apply, axfr_apply_done, work); } static isc_result_t @@ -587,8 +588,7 @@ ixfr_apply_done(void *arg) { /* Reschedule */ if (!cds_wfcq_empty(&xfr->diff_head, &xfr->diff_tail)) { - isc_work_enqueue(dns_zone_getloop(xfr->zone), ixfr_apply, - ixfr_apply_done, work); + isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work); return; } @@ -642,8 +642,7 @@ ixfr_commit(dns_xfrin_t *xfr) { .result = ISC_R_UNSET, }; xfr->diff_running = true; - isc_work_enqueue(dns_zone_getloop(xfr->zone), ixfr_apply, - ixfr_apply_done, work); + isc_work_enqueue(xfr->loop, ixfr_apply, ixfr_apply_done, work); } failure: @@ -886,13 +885,15 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, dns_xfrin_t *xfr = NULL; isc_result_t result; dns_db_t *db = NULL; + isc_loop_t *loop = NULL; REQUIRE(xfrp != NULL && *xfrp == NULL); REQUIRE(done != NULL); REQUIRE(isc_sockaddr_getport(primaryaddr) != 0); REQUIRE(zone != NULL); REQUIRE(dns_zone_getview(zone) != NULL); - REQUIRE(dns_zone_gettid(zone) == isc_tid()); + + loop = dns_zone_getloop(zone); (void)dns_zone_getdb(zone, &db); @@ -900,9 +901,9 @@ dns_xfrin_create(dns_zone_t *zone, dns_rdatatype_t xfrtype, REQUIRE(db != NULL); } - xfrin_create(mctx, zone, db, zonename, dns_zone_getclass(zone), xfrtype, - primaryaddr, sourceaddr, tsigkey, soa_transport_type, - transport, tlsctx_cache, &xfr); + xfrin_create(mctx, zone, db, loop, zonename, dns_zone_getclass(zone), + xfrtype, primaryaddr, sourceaddr, tsigkey, + soa_transport_type, transport, tlsctx_cache, &xfr); if (db != NULL) { xfr->zone_had_db = true; @@ -1064,7 +1065,6 @@ dns_xfrin_gettsigkeyname(const dns_xfrin_t *xfr) { void dns_xfrin_shutdown(dns_xfrin_t *xfr) { REQUIRE(VALID_XFRIN(xfr)); - REQUIRE(dns_zone_gettid(xfr->zone) == isc_tid()); xfrin_fail(xfr, ISC_R_CANCELED, "shut down"); } @@ -1112,15 +1112,14 @@ xfrin_reset(dns_xfrin_t *xfr) { static void xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) { + REQUIRE(VALID_XFRIN(xfr)); + dns_xfrin_ref(xfr); /* Make sure only the first xfrin_fail() trumps */ if (atomic_compare_exchange_strong(&xfr->shuttingdown, &(bool){ false }, true)) { - isc_timer_stop(xfr->max_time_timer); - isc_timer_stop(xfr->max_idle_timer); - if (result != DNS_R_UPTODATE && result != DNS_R_TOOMANYRECORDS) { xfrin_log(xfr, ISC_LOG_ERROR, "%s: %s", msg, @@ -1142,7 +1141,7 @@ xfrin_fail(dns_xfrin_t *xfr, isc_result_t result, const char *msg) { } static void -xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, +xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, isc_loop_t *loop, dns_name_t *zonename, dns_rdataclass_t rdclass, dns_rdatatype_t reqtype, const isc_sockaddr_t *primaryaddr, const isc_sockaddr_t *sourceaddr, dns_tsigkey_t *tsigkey, @@ -1165,6 +1164,7 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, .magic = XFRIN_MAGIC, }; + isc_loop_attach(loop, &xfr->loop); isc_mem_attach(mctx, &xfr->mctx); dns_zone_iattach(zone, &xfr->zone); dns_view_weakattach(dns_zone_getview(zone), &xfr->view); @@ -1172,7 +1172,6 @@ xfrin_create(isc_mem_t *mctx, dns_zone_t *zone, dns_db_t *db, __cds_wfcq_init(&xfr->diff_head, &xfr->diff_tail); - atomic_init(&xfr->shuttingdown, false); atomic_init(&xfr->is_ixfr, false); if (db != NULL) { @@ -1276,7 +1275,7 @@ xfrin_start(dns_xfrin_t *xfr) { * XXX: timeouts are hard-coded to 30 seconds; this needs to be * configurable. */ - CHECK(dns_dispatch_add(xfr->disp, dns_zone_getloop(xfr->zone), 0, 30000, + CHECK(dns_dispatch_add(xfr->disp, xfr->loop, 0, 30000, &xfr->primaryaddr, xfr->transport, xfr->tlsctx_cache, xfrin_connect_done, xfrin_send_done, xfrin_recv_done, xfr, &xfr->id, @@ -1667,6 +1666,8 @@ 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->shutdown_result == ISC_R_UNSET) { xfr->shutdown_result = result; } @@ -1984,7 +1985,6 @@ xfrin_destroy(dns_xfrin_t *xfr) { isc_time_t now = isc_time_now(); REQUIRE(VALID_XFRIN(xfr)); - REQUIRE(dns_zone_gettid(xfr->zone) == isc_tid()); /* Safe-guards */ REQUIRE(atomic_load(&xfr->shuttingdown)); @@ -2101,6 +2101,8 @@ xfrin_destroy(dns_xfrin_t *xfr) { isc_timer_destroy(&xfr->max_idle_timer); isc_timer_destroy(&xfr->max_time_timer); + isc_loop_detach(&xfr->loop); + isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr)); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 3dbf5ff06d..7d98ae4741 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -18152,7 +18152,6 @@ got_transfer_quota(void *arg) { const char *soa_before = ""; bool loaded; isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL; - dns_xfrin_t *xfr = NULL; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { zone_xfrdone(zone, NULL, ISC_R_CANCELED); @@ -18303,7 +18302,7 @@ got_transfer_quota(void *arg) { result = dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr, zone->tsigkey, soa_transport_type, zone->transport, zmgr_tlsctx_cache, - zone->mctx, zone_xfrdone, &xfr); + zone->mctx, zone_xfrdone, &zone->xfr); isc_tlsctx_cache_detach(&zmgr_tlsctx_cache); @@ -18318,7 +18317,6 @@ got_transfer_quota(void *arg) { } LOCK_ZONE(zone); - zone->xfr = xfr; if (xfrtype == dns_rdatatype_axfr) { if (isc_sockaddr_pf(&primaryaddr) == PF_INET) { inc_stats(zone, dns_zonestatscounter_axfrreqv4);