]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
use isc_loop_now() for dispentry timeouts
authorEvan Hunt <each@isc.org>
Sun, 28 May 2023 02:20:47 +0000 (19:20 -0700)
committerOndřej Surý <ondrej@isc.org>
Wed, 19 Jul 2023 13:32:21 +0000 (15:32 +0200)
store a pointer to the running loop when creating a dispatch entry
with dns_dispatch_add(), and use isc_loop_now() to get the timestamp for
the current event loop tick when we initialize the dispentry start time
and check for timeouts.

lib/dns/dispatch.c
lib/dns/include/dns/dispatch.h
lib/dns/request.c
lib/dns/resolver.c
lib/dns/xfrin.c
tests/dns/dispatch_test.c

index 3c9f8f55aca42fa3d9f06f8c00113c93f0174470..6b222eab60586d9f3639f6f4b40adb4341bdc53a 100644 (file)
@@ -20,6 +20,7 @@
 #include <unistd.h>
 
 #include <isc/atomic.h>
+#include <isc/loop.h>
 #include <isc/mem.h>
 #include <isc/mutex.h>
 #include <isc/net.h>
@@ -83,6 +84,7 @@ struct dns_dispentry {
        unsigned int magic;
        isc_refcount_t references;
        dns_dispatch_t *disp;
+       isc_loop_t *loop;
        isc_nmhandle_t *handle; /*%< netmgr handle for UDP connection */
        dns_dispatchstate_t state;
        dns_transport_t *transport;
@@ -630,7 +632,7 @@ next:
         * This is the wrong response.  Check whether there is still enough
         * time to wait for the correct one to arrive before the timeout fires.
         */
-       now = isc_time_now();
+       now = isc_loop_now(resp->loop);
        timeout = resp->timeout - dispentry_runtime(resp, &now);
        if (timeout <= 0) {
                /*
@@ -803,7 +805,7 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
        char buf[ISC_SOCKADDR_FORMATSIZE];
        isc_sockaddr_t peer;
        dns_displist_t resps = ISC_LIST_INITIALIZER;
-       isc_time_t now = isc_time_now();
+       isc_time_t now;
        int timeout;
 
        REQUIRE(VALID_DISPATCH(disp));
@@ -860,14 +862,19 @@ tcp_recv(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region,
         * have been timed out out already, but non-matching TCP reads have
         * prevented this.
         */
-       dns_dispentry_t *next = NULL;
-       for (resp = ISC_LIST_HEAD(disp->active); resp != NULL; resp = next) {
-               next = ISC_LIST_NEXT(resp, alink);
+       resp = ISC_LIST_HEAD(disp->active);
+       if (resp != NULL) {
+               now = isc_loop_now(resp->loop);
+       }
+       while (resp != NULL) {
+               dns_dispentry_t *next = ISC_LIST_NEXT(resp, alink);
 
                timeout = resp->timeout - dispentry_runtime(resp, &now);
                if (timeout <= 0) {
                        tcp_recv_add(&resps, resp, ISC_R_TIMEDOUT);
                }
+
+               resp = next;
        }
 
        /*
@@ -1437,7 +1444,7 @@ ISC_REFCOUNT_IMPL(dns_dispatch, dispatch_destroy);
 #endif
 
 isc_result_t
-dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
+dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options,
                 unsigned int timeout, const isc_sockaddr_t *dest,
                 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
                 dispatch_cb_t connected, dispatch_cb_t sent,
@@ -1460,6 +1467,7 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
        REQUIRE(connected != NULL);
        REQUIRE(response != NULL);
        REQUIRE(sent != NULL);
+       REQUIRE(loop != NULL);
 
        LOCK(&disp->lock);
 
@@ -1477,6 +1485,7 @@ dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
                .port = localport,
                .timeout = timeout,
                .peer = *dest,
+               .loop = loop,
                .connected = connected,
                .sent = sent,
                .response = response,
@@ -1581,7 +1590,7 @@ dns_dispatch_getnext(dns_dispentry_t *resp) {
 
        dispentry_log(resp, LVL(90), "getnext for QID %d", resp->id);
 
-       isc_time_t now = isc_time_now();
+       isc_time_t now = isc_loop_now(resp->loop);
        timeout = resp->timeout - dispentry_runtime(resp, &now);
        if (timeout <= 0) {
                return (ISC_R_TIMEDOUT);
@@ -1975,7 +1984,7 @@ static void
 udp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
        LOCK(&disp->lock);
        resp->state = DNS_DISPATCHSTATE_CONNECTING;
-       resp->start = isc_time_now();
+       resp->start = isc_loop_now(resp->loop);
        dns_dispentry_ref(resp); /* DISPENTRY004 */
        ISC_LIST_APPEND(disp->pending, resp, plink);
        UNLOCK(&disp->lock);
@@ -2014,7 +2023,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
                /* First connection, continue with connecting */
                disp->state = DNS_DISPATCHSTATE_CONNECTING;
                resp->state = DNS_DISPATCHSTATE_CONNECTING;
-               resp->start = isc_time_now();
+               resp->start = isc_loop_now(resp->loop);
                dns_dispentry_ref(resp); /* DISPENTRY005 */
                ISC_LIST_APPEND(disp->pending, resp, plink);
                UNLOCK(&disp->lock);
@@ -2040,7 +2049,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
        case DNS_DISPATCHSTATE_CONNECTING:
                /* Connection pending; add resp to the list */
                resp->state = DNS_DISPATCHSTATE_CONNECTING;
-               resp->start = isc_time_now();
+               resp->start = isc_loop_now(resp->loop);
                dns_dispentry_ref(resp); /* DISPENTRY005 */
                ISC_LIST_APPEND(disp->pending, resp, plink);
                UNLOCK(&disp->lock);
@@ -2048,7 +2057,7 @@ tcp_dispatch_connect(dns_dispatch_t *disp, dns_dispentry_t *resp) {
 
        case DNS_DISPATCHSTATE_CONNECTED:
                resp->state = DNS_DISPATCHSTATE_CONNECTED;
-               resp->start = isc_time_now();
+               resp->start = isc_loop_now(resp->loop);
 
                /* Add the resp to the reading list */
                ISC_LIST_APPEND(disp->active, resp, alink);
index 254fda8e32a88eca3b94fbd5f0eb513b9118c7d3..d5caf9af78916164682922cb07f007cf301bd010 100644 (file)
@@ -263,7 +263,7 @@ typedef void (*dispatch_cb_t)(isc_result_t eresult, isc_region_t *region,
                              void *cbarg);
 
 isc_result_t
-dns_dispatch_add(dns_dispatch_t *disp, unsigned int options,
+dns_dispatch_add(dns_dispatch_t *disp, isc_loop_t *loop, unsigned int options,
                 unsigned int timeout, const isc_sockaddr_t *dest,
                 dns_transport_t *transport, isc_tlsctx_cache_t *tlsctx_cache,
                 dispatch_cb_t connected, dispatch_cb_t sent,
index 3c1bda28db81a777c839a1510678b5967d3d4419..f5d4ed25cfcf13f88e540206f40c263da331a2e4 100644 (file)
@@ -492,10 +492,10 @@ again:
                dispopt |= DNS_DISPATCHOPT_FIXEDID;
        }
 
-       result = dns_dispatch_add(request->dispatch, dispopt, request->timeout,
-                                 destaddr, transport, tlsctx_cache,
-                                 req_connected, req_senddone, req_response,
-                                 request, &id, &request->dispentry);
+       result = dns_dispatch_add(
+               request->dispatch, loop, dispopt, request->timeout, destaddr,
+               transport, tlsctx_cache, req_connected, req_senddone,
+               req_response, request, &id, &request->dispentry);
        if (result != ISC_R_SUCCESS) {
                if ((options & DNS_REQUESTOPT_FIXEDID) != 0 && !newtcp) {
                        newtcp = true;
@@ -635,7 +635,7 @@ again:
                goto detach;
        }
 
-       result = dns_dispatch_add(request->dispatch, 0, request->timeout,
+       result = dns_dispatch_add(request->dispatch, loop, 0, request->timeout,
                                  destaddr, transport, tlsctx_cache,
                                  req_connected, req_senddone, req_response,
                                  request, &id, &request->dispentry);
index 17bc36260101fd58efdfee3caa7f55d3146cf2eb..201979df61bc79294b6751daf9a9c0917a336357 100644 (file)
@@ -2125,10 +2125,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
 
        /* Set up the dispatch and set the query ID */
        result = dns_dispatch_add(
-               query->dispatch, 0, isc_interval_ms(&fctx->interval),
-               &query->addrinfo->sockaddr, addrinfo->transport, tlsctx_cache,
-               resquery_connected, resquery_senddone, resquery_response, query,
-               &query->id, &query->dispentry);
+               query->dispatch, fctx->loop, 0,
+               isc_interval_ms(&fctx->interval), &query->addrinfo->sockaddr,
+               addrinfo->transport, tlsctx_cache, resquery_connected,
+               resquery_senddone, resquery_response, query, &query->id,
+               &query->dispentry);
        if (result != ISC_R_SUCCESS) {
                goto cleanup_udpfetch;
        }
index 46e39bf34e81fe49e6fb7e366aacff0a98617f75..bf3460169a041d7ca781184a38ec5c76fac95f19 100644 (file)
@@ -955,10 +955,11 @@ 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, 0, 30000, &xfr->primaryaddr, xfr->transport,
-               xfr->tlsctx_cache, xfrin_connect_done, xfrin_send_done,
-               xfrin_recv_done, xfr, &xfr->id, &xfr->dispentry));
+       CHECK(dns_dispatch_add(xfr->disp, dns_zone_getloop(xfr->zone), 0, 30000,
+                              &xfr->primaryaddr, xfr->transport,
+                              xfr->tlsctx_cache, xfrin_connect_done,
+                              xfrin_send_done, xfrin_recv_done, xfr, &xfr->id,
+                              &xfr->dispentry));
        CHECK(dns_dispatch_connect(xfr->dispentry));
 
        return (ISC_R_SUCCESS);
index afd3e54b57d044079043f7f1549bbcfadcb3be3b..0780003bab8c4fbf8d1534ff8980a1b8fcd78e08 100644 (file)
@@ -459,10 +459,11 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_connect) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(
-               dispatch, 0, T_CLIENT_CONNECT, &tcp_server_addr, NULL, NULL,
-               timeout_connected, client_senddone, response_timeout,
-               &testdata.region, &id, &dispentry);
+       result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0,
+                                 T_CLIENT_CONNECT, &tcp_server_addr, NULL,
+                                 NULL, timeout_connected, client_senddone,
+                                 response_timeout, &testdata.region, &id,
+                                 &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);
 
@@ -503,10 +504,10 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_tcp_response) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
-                                 &tcp_server_addr, NULL, NULL, connected,
-                                 client_senddone, response_timeout,
-                                 &testdata.region, &id, &dispentry);
+       result = dns_dispatch_add(
+               dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT,
+               &tcp_server_addr, NULL, NULL, connected, client_senddone,
+               response_timeout, &testdata.region, &id, &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);
 
@@ -537,10 +538,10 @@ ISC_LOOP_TEST_IMPL(dispatch_tcp_response) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
-                                 &tcp_server_addr, NULL, NULL, connected,
-                                 client_senddone, response, &testdata.region,
-                                 &id, &dispentry);
+       result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0,
+                                 T_CLIENT_CONNECT, &tcp_server_addr, NULL,
+                                 NULL, connected, client_senddone, response,
+                                 &testdata.region, &id, &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);
 
@@ -574,10 +575,11 @@ ISC_LOOP_TEST_IMPL(dispatch_tls_response) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(
-               dispatch, 0, T_CLIENT_CONNECT, &tls_server_addr, tls_transport,
-               tls_tlsctx_client_cache, connected, client_senddone, response,
-               &testdata.region, &id, &dispentry);
+       result = dns_dispatch_add(dispatch, isc_loop_main(loopmgr), 0,
+                                 T_CLIENT_CONNECT, &tls_server_addr,
+                                 tls_transport, tls_tlsctx_client_cache,
+                                 connected, client_senddone, response,
+                                 &testdata.region, &id, &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);
 
@@ -608,10 +610,10 @@ ISC_LOOP_TEST_IMPL(dispatch_timeout_udp_response) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
-                                 &udp_server_addr, NULL, NULL, connected,
-                                 client_senddone, response_timeout,
-                                 &testdata.region, &id, &dispentry);
+       result = dns_dispatch_add(
+               dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT,
+               &udp_server_addr, NULL, NULL, connected, client_senddone,
+               response_timeout, &testdata.region, &id, &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);
 
@@ -642,10 +644,10 @@ ISC_LOOP_TEST_IMPL(dispatch_getnext) {
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatchmgr_detach(&dispatchmgr);
 
-       result = dns_dispatch_add(dispatch, 0, T_CLIENT_CONNECT,
-                                 &udp_server_addr, NULL, NULL, connected,
-                                 client_senddone, response_getnext,
-                                 &testdata.region, &id, &dispentry);
+       result = dns_dispatch_add(
+               dispatch, isc_loop_main(loopmgr), 0, T_CLIENT_CONNECT,
+               &udp_server_addr, NULL, NULL, connected, client_senddone,
+               response_getnext, &testdata.region, &id, &dispentry);
        assert_int_equal(result, ISC_R_SUCCESS);
        dns_dispatch_detach(&dispatch);