From 56cef1495f2b72100996fc042277dc52c3328aef Mon Sep 17 00:00:00 2001 From: Patrick McLean Date: Fri, 19 Mar 2021 22:50:51 -0700 Subject: [PATCH] dig: Use high resolution clocks when microsecond accuracy is requested The TIME_NOW macro calls isc_time_now which uses CLOCK_REALTIME_COARSE for getting the current time. This is perfectly fine for millisecond, however when the user request microsecond resolutiuon, they are going to get very inaccurate results. This is especially true on a server class machine where the clock ticks may be set to 100HZ. This changes dig to use the new TIME_NOW_HIRES macro that uses the CLOCK_MONOTONIC_RAW that is more expensive, but gets the *actual* current time rather than the at the last kernel time tick. --- bin/dig/dighost.c | 19 ++++++++++++++++--- bin/dig/host.c | 6 +++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 54bb63e5d1..178c241708 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -2866,7 +2866,11 @@ send_udp(dig_query_t *query) { isc_buffer_usedregion(&query->sendbuf, &r); debug("sending a request"); - TIME_NOW(&query->time_sent); + if (query->lookup->use_usec) { + TIME_NOW_HIRES(&query->time_sent); + } else { + TIME_NOW(&query->time_sent); + } isc_nmhandle_attach(query->handle, &query->sendhandle); @@ -3172,7 +3176,12 @@ launch_next_query(dig_query_t *query) { if (!query->first_soa_rcvd) { dig_query_t *sendquery = NULL; debug("sending a request in launch_next_query"); - TIME_NOW(&query->time_sent); + if (query->lookup->use_usec) { + TIME_NOW_HIRES(&query->time_sent); + } else { + TIME_NOW(&query->time_sent); + } + query_attach(query, &sendquery); isc_buffer_usedregion(&query->sendbuf, &r); if (keep != NULL) { @@ -3584,7 +3593,11 @@ recv_done(isc_nmhandle_t *handle, isc_result_t eresult, isc_region_t *region, goto detach_query; } - TIME_NOW(&query->time_recv); + if (query->lookup->use_usec) { + TIME_NOW_HIRES(&query->time_recv); + } else { + TIME_NOW(&query->time_recv); + } if (eresult == ISC_R_TIMEDOUT && !l->tcp_mode && l->retries > 1) { dig_query_t *newq = NULL; diff --git a/bin/dig/host.c b/bin/dig/host.c index 02d9ce0f48..b3ddc52f1a 100644 --- a/bin/dig/host.c +++ b/bin/dig/host.c @@ -151,7 +151,11 @@ received(unsigned int bytes, isc_sockaddr_t *from, dig_query_t *query) { if (!short_form) { char fromtext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(from, fromtext, sizeof(fromtext)); - TIME_NOW(&now); + if (query->lookup->use_usec) { + TIME_NOW_HIRES(&now); + } else { + TIME_NOW(&now); + } diff = (int)isc_time_microdiff(&now, &query->time_sent); printf("Received %u bytes from %s in %d ms\n", bytes, fromtext, diff / 1000);