2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

Merge branch '4096-uv-now' into 'main'

add isc_loop_now() to get consistent time

Closes #4096

See merge request isc-projects/bind9!7989
This commit is contained in:
Ondřej Surý
2023-07-19 13:32:47 +00:00
8 changed files with 86 additions and 49 deletions

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

View 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,

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

View 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;
}

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

View File

@@ -205,4 +205,14 @@ isc_loop_getloopmgr(isc_loop_t *loop);
* Requires:
*\li 'loop' is a valid loop.
*/
isc_time_t
isc_loop_now(isc_loop_t *loop);
/*%<
* Returns the start time of the current loop tick.
*
* Requires:
*
* \li 'loop' is a valid loop.
*/
ISC_LANG_ENDDECLS

View File

@@ -32,6 +32,7 @@
#include <isc/strerr.h>
#include <isc/thread.h>
#include <isc/tid.h>
#include <isc/time.h>
#include <isc/urcu.h>
#include <isc/util.h>
#include <isc/uv.h>
@@ -598,3 +599,16 @@ isc_loop_getloopmgr(isc_loop_t *loop) {
return (loop->loopmgr);
}
isc_time_t
isc_loop_now(isc_loop_t *loop) {
REQUIRE(VALID_LOOP(loop));
uint64_t msec = uv_now(&loop->loop);
isc_time_t t = {
.seconds = msec / MS_PER_SEC,
.nanoseconds = (msec % MS_PER_SEC) * NS_PER_MS,
};
return (t);
}

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