2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 05:57:52 +00:00

Merge branch '4600-call-dispatch-connect-callbacks-asynchronously' into 'main'

Pin the xfr to a specific loop

Closes #4600

See merge request isc-projects/bind9!8821
This commit is contained in:
Ondřej Surý 2024-03-04 15:34:51 +00:00
commit 470bfcaa19
3 changed files with 37 additions and 30 deletions

View File

@ -19,6 +19,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <isc/async.h>
#include <isc/hash.h>
#include <isc/hashmap.h>
#include <isc/loop.h>
@ -1776,6 +1777,16 @@ tcp_startrecv(dns_dispatch_t *disp, dns_dispentry_t *resp) {
disp->reading = true;
}
static void
resp_connected(void *arg) {
dns_dispentry_t *resp = arg;
dispentry_log(resp, ISC_LOG_DEBUG(90), "connect callback: %s",
isc_result_totext(resp->result));
resp->connected(resp->result, NULL, resp->arg);
dns_dispentry_detach(&resp); /* DISPENTRY005 */
}
static void
tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
dns_dispatch_t *disp = (dns_dispatch_t *)arg;
@ -1846,10 +1857,7 @@ tcp_connected(isc_nmhandle_t *handle, isc_result_t eresult, void *arg) {
next = ISC_LIST_NEXT(resp, rlink);
ISC_LIST_UNLINK(resps, resp, rlink);
dispentry_log(resp, ISC_LOG_DEBUG(90), "connect callback: %s",
isc_result_totext(resp->result));
resp->connected(resp->result, NULL, resp->arg);
dns_dispentry_detach(&resp); /* DISPENTRY005 */
resp_connected(resp);
}
dns_dispatch_detach(&disp); /* DISPATCH003 */
@ -1999,10 +2007,9 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
tcp_startrecv(disp, resp);
}
/* We are already connected; call the connected cb */
dispentry_log(resp, ISC_LOG_DEBUG(90), "connect callback: %s",
isc_result_totext(ISC_R_SUCCESS));
resp->connected(ISC_R_SUCCESS, NULL, resp->arg);
/* Already connected; call the connected cb asynchronously */
dns_dispentry_ref(resp); /* DISPENTRY005 */
isc_async_run(resp->loop, resp_connected, resp);
break;
default:

View File

@ -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));
}

View File

@ -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);