From: Ondřej Surý Date: Mon, 4 Mar 2024 11:58:56 +0000 (+0100) Subject: Always call the TCP dispatch connected callbacks asynchronously X-Git-Tag: v9.19.22~12^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e74c7dcf51cf623c6500146aa7c140c01ed637eb;p=thirdparty%2Fbind9.git Always call the TCP dispatch connected callbacks asynchronously The TCP dispatch connected callbacks could be called synchronously which in turn could destroy xfrin before we return from dns_xfrin_create(). Delay the calling the callback called from tcp_dispatch_connect() by calling it always asynchronously. --- diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index 603add2ba35..e5412abe9eb 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -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: