>From b694830a330906e63a036513c7a6cdde997d19e4 Mon Sep 17 00:00:00 2001 From: Collin Funk Date: Wed, 26 Jun 2024 20:43:41 -0700 Subject: [PATCH] ping, ping6: Modernize time functions. * bootstrap.conf (gnulib_modules): Add timespec-add. * ping/Makefile.am (LDADD): Add $(CLOCK_TIME_LIB), $(PTHREAD_SIGMASK_LIB), and $(SELECT_LIB). * ping/libping.c (ping_init): Use current_timespec instead of gettimeofday. * ping/ping_common.c (tvsub): Remove function. (ping_timeout_p): Return a bool. Use timespec_sub and current_timespec. * ping/ping_common.h (PING_SET_INTERVAL): Expect a timespec instead of a timeval. (struct ping_data): Store the start time in a timespec instead of a timeval. (tvsub): Remove declaration. (ping_timeout_p): Adjust prototype. * ping/ping.c (send_echo): Use current_timespec. (ping_init): Likewise. (ping_run): Likewise. Use pselect. * ping/ping6.c (send_echo): Use current_timespec. (print_echo): Likewise. (ping_init): Likewise. (ping_run): Likewise. Use pselect. * ping/ping_echo.c (print_echo): Use current_timespec. --- bootstrap.conf | 1 + ping/Makefile.am | 5 ++- ping/libping.c | 4 ++- ping/ping.c | 53 ++++++++++--------------------- ping/ping6.c | 79 ++++++++++++++++++---------------------------- ping/ping_common.c | 34 ++++---------------- ping/ping_common.h | 7 ++-- ping/ping_echo.c | 25 ++++++++------- 8 files changed, 77 insertions(+), 131 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 7a572c96..9026eccc 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -104,6 +104,7 @@ sys_types sysexits termios timespec +timespec-add timespec-sub unistd-safer update-copyright diff --git a/ping/Makefile.am b/ping/Makefile.am index 93d4fa17..085255bc 100644 --- a/ping/Makefile.am +++ b/ping/Makefile.am @@ -23,7 +23,10 @@ AM_CPPFLAGS = \ LDADD = \ $(iu_LIBRARIES) \ - $(LIBIDN) + $(LIBIDN) \ + $(CLOCK_TIME_LIB) \ + $(PTHREAD_SIGMASK_LIB) \ + $(SELECT_LIB) bin_PROGRAMS = $(ping_BUILD) $(ping6_BUILD) diff --git a/ping/libping.c b/ping/libping.c index 1e22a58a..0991d3b2 100644 --- a/ping/libping.c +++ b/ping/libping.c @@ -38,6 +38,8 @@ # include #endif +#include + #include "ping.h" static int useless_ident = 0; /* Relevant at least for Linux. */ @@ -119,7 +121,7 @@ ping_init (int type, int ident) /* Make sure we use only 16 bits in this field, id for icmp is a unsigned short. */ p->ping_ident = ident & 0xFFFF; p->ping_cktab_size = PING_CKTABSIZE; - gettimeofday (&p->ping_start_time, NULL); + p->ping_start_time = current_timespec (); return p; } diff --git a/ping/ping.c b/ping/ping.c index 6c7dbd9a..1f2f6702 100644 --- a/ping/ping.c +++ b/ping/ping.c @@ -47,6 +47,7 @@ #include #include +#include #include #include "ping_impl.h" #include "libinetutils.h" @@ -386,9 +387,9 @@ ping_run (PING *ping, int (*finish) (void)) { fd_set fdset; int fdmax; - struct timeval resp_time; - struct timeval last, intvl, now; - struct timeval *t = NULL; + struct timespec resp_time; + struct timespec last, intvl, now; + struct timespec *t = NULL; int finishing = 0; size_t nresp = 0; size_t i; @@ -397,26 +398,18 @@ ping_run (PING *ping, int (*finish) (void)) fdmax = ping->ping_fd + 1; - /* Some systems use `struct timeval' of size 16. As these are - * not initialising `timeval' properly by assignment alone, let - * us play safely here. gettimeofday() is always sufficient. - */ - memset (&resp_time, 0, sizeof (resp_time)); - memset (&intvl, 0, sizeof (intvl)); - memset (&now, 0, sizeof (now)); - for (i = 0; i < preload; i++) send_echo (ping); if (options & OPT_FLOOD) { intvl.tv_sec = 0; - intvl.tv_usec = 10000; + intvl.tv_nsec = 1e7; } else PING_SET_INTERVAL (intvl, ping->ping_interval); - gettimeofday (&last, NULL); + last = current_timespec (); send_echo (ping); while (!stop) @@ -425,29 +418,14 @@ ping_run (PING *ping, int (*finish) (void)) FD_ZERO (&fdset); FD_SET (ping->ping_fd, &fdset); - gettimeofday (&now, NULL); - resp_time.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; - resp_time.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; - - while (resp_time.tv_usec < 0) - { - resp_time.tv_usec += 1000000; - resp_time.tv_sec--; - } - while (resp_time.tv_usec >= 1000000) - { - resp_time.tv_usec -= 1000000; - resp_time.tv_sec++; - } - - if (resp_time.tv_sec < 0) - resp_time.tv_sec = resp_time.tv_usec = 0; + now = current_timespec (); + resp_time = timespec_sub (timespec_add (last, intvl), now); - n = select (fdmax, &fdset, NULL, NULL, &resp_time); + n = pselect (fdmax, &fdset, NULL, NULL, &resp_time, NULL); if (n < 0) { if (errno != EINTR) - error (EXIT_FAILURE, errno, "select failed"); + error (EXIT_FAILURE, errno, "pselect failed"); continue; } else if (n == 1) @@ -456,7 +434,7 @@ ping_run (PING *ping, int (*finish) (void)) nresp++; if (t == 0) { - gettimeofday (&now, NULL); + now = current_timespec (); t = &now; } @@ -485,7 +463,7 @@ ping_run (PING *ping, int (*finish) (void)) intvl.tv_sec = linger; } - gettimeofday (&last, NULL); + last = current_timespec (); } } @@ -504,8 +482,11 @@ send_echo (PING *ping) if (PING_TIMING (data_length)) { - struct timeval tv; - gettimeofday (&tv, NULL); + struct timespec now = current_timespec (); + /* *INDENT-OFF* */ + struct timeval tv = { .tv_sec = now.tv_sec, + .tv_usec = now.tv_nsec / 1000 }; + /* *INDENT-ON* */ ping_set_data (ping, &tv, 0, sizeof (tv), USE_IPV6); off += sizeof (tv); } diff --git a/ping/ping6.c b/ping/ping6.c index 9cf03eb1..2ac47aa0 100644 --- a/ping/ping6.c +++ b/ping/ping6.c @@ -52,6 +52,7 @@ #include #include +#include #include "ping6.h" #include "libinetutils.h" @@ -329,9 +330,9 @@ ping_run (PING *ping, int (*finish) (void)) { fd_set fdset; int fdmax; - struct timeval resp_time; - struct timeval last, intvl, now; - struct timeval *t = NULL; + struct timespec resp_time; + struct timespec last, intvl, now; + struct timespec *t = NULL; int finishing = 0; size_t nresp = 0; unsigned long i; @@ -340,26 +341,18 @@ ping_run (PING *ping, int (*finish) (void)) fdmax = ping->ping_fd + 1; - /* Some systems use `struct timeval' of size 16. As these are - * not initialising `timeval' properly by assignment alone, let - * us play safely here. gettimeofday() is always sufficient. - */ - memset (&resp_time, 0, sizeof (resp_time)); - memset (&intvl, 0, sizeof (intvl)); - memset (&now, 0, sizeof (now)); - for (i = 0; i < preload; i++) send_echo (ping); if (options & OPT_FLOOD) { intvl.tv_sec = 0; - intvl.tv_usec = 10000; + intvl.tv_nsec = 1e7; } else PING_SET_INTERVAL (intvl, ping->ping_interval); - gettimeofday (&last, NULL); + last = current_timespec (); send_echo (ping); while (!stop) @@ -369,29 +362,14 @@ ping_run (PING *ping, int (*finish) (void)) FD_ZERO (&fdset); FD_SET (ping->ping_fd, &fdset); - gettimeofday (&now, NULL); - resp_time.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; - resp_time.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; - - while (resp_time.tv_usec < 0) - { - resp_time.tv_usec += 1000000; - resp_time.tv_sec--; - } - while (resp_time.tv_usec >= 1000000) - { - resp_time.tv_usec -= 1000000; - resp_time.tv_sec++; - } - - if (resp_time.tv_sec < 0) - resp_time.tv_sec = resp_time.tv_usec = 0; + now = current_timespec (); + resp_time = timespec_sub (timespec_add (last, intvl), now); - n = select (fdmax, &fdset, NULL, NULL, &resp_time); + n = pselect (fdmax, &fdset, NULL, NULL, &resp_time, NULL); if (n < 0) { if (errno != EINTR) - error (EXIT_FAILURE, errno, "select failed"); + error (EXIT_FAILURE, errno, "pselect failed"); continue; } else if (n == 1) @@ -400,7 +378,7 @@ ping_run (PING *ping, int (*finish) (void)) nresp++; if (t == 0) { - gettimeofday (&now, NULL); + now = current_timespec (); t = &now; } @@ -431,7 +409,7 @@ ping_run (PING *ping, int (*finish) (void)) intvl.tv_sec = MAXWAIT; } - gettimeofday (&last, NULL); + last = current_timespec (); } } @@ -450,8 +428,11 @@ send_echo (PING *ping) if (PING_TIMING (data_length)) { - struct timeval tv; - gettimeofday (&tv, NULL); + struct timespec now = current_timespec (); + /* *INDENT-OFF* */ + struct timeval tv = { .tv_sec = now.tv_sec, + .tv_usec = now.tv_nsec / 1000 }; + /* *INDENT-ON* */ ping_set_data (ping, &tv, 0, sizeof (tv), USE_IPV6); off += sizeof (tv); } @@ -560,26 +541,26 @@ print_echo (int dupflag, int hops, struct ping_stat *ping_stat, { int err; char buf[256]; - struct timeval tv; - int timing = 0; + bool timing = false; double triptime = 0.0; - gettimeofday (&tv, NULL); - /* Do timing */ if (PING_TIMING (datalen - sizeof (struct icmp6_hdr))) { - struct timeval tv1, *tp; + struct timeval tv; + struct timespec ts; - timing++; - tp = (struct timeval *) (icmp6 + 1); + timing = true; - /* Avoid unaligned data: */ - memcpy (&tv1, tp, sizeof (tv1)); - tvsub (&tv, &tv1); + /* Avoid unaligned data. */ + memcpy (&tv, icmp6 + 1, sizeof (tv)); + /* *INDENT-OFF* */ + ts = timespec_sub (current_timespec (), + (struct timespec) { .tv_sec = tv.tv_sec, + .tv_nsec = tv.tv_usec * 1000 }); + /* *INDENT-ON* */ - triptime = ((double) tv.tv_sec) * 1000.0 + - ((double) tv.tv_usec) / 1000.0; + triptime = timespectod (ts) * 1000.0; ping_stat->tsum += triptime; ping_stat->tsumsq += triptime * triptime; if (triptime < ping_stat->tmin) @@ -890,7 +871,7 @@ ping_init (int type MAYBE_UNUSED, int ident) /* Make sure we use only 16 bits in this field, id for icmp is a unsigned short. */ p->ping_ident = ident & 0xFFFF; p->ping_cktab_size = PING_CKTABSIZE; - gettimeofday (&p->ping_start_time, NULL); + p->ping_start_time = current_timespec (); return p; } diff --git a/ping/ping_common.c b/ping/ping_common.c index c755e438..a4455d2b 100644 --- a/ping/ping_common.c +++ b/ping/ping_common.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "ping_common.h" @@ -102,23 +103,6 @@ decode_pattern (const char *text, int *pattern_len, *pattern_len = i; } - -/* - * tvsub -- - * Subtract 2 timeval structs: out = out - in. Out is assumed to - * be >= in. - */ -void -tvsub (struct timeval *out, struct timeval *in) -{ - if ((out->tv_usec -= in->tv_usec) < 0) - { - --out->tv_sec; - out->tv_usec += 1000000; - } - out->tv_sec -= in->tv_sec; -} - double nabs (double a) { @@ -241,18 +225,12 @@ ping_unset_data (PING *p) _ping_freebuf (p); } -int -ping_timeout_p (struct timeval *start_time, int timeout) +bool +ping_timeout_p (struct timespec *start_time, int timeout) { - struct timeval now; - gettimeofday (&now, NULL); - if (timeout != -1) - { - tvsub (&now, start_time); - if (now.tv_sec >= timeout) - return 1; - } - return 0; + if (timeout == -1) + return false; + return timespec_sub (current_timespec (), *start_time).tv_sec >= timeout; } char * diff --git a/ping/ping_common.h b/ping/ping_common.h index 46f7b4b2..66e69d6d 100644 --- a/ping/ping_common.h +++ b/ping/ping_common.h @@ -70,7 +70,7 @@ struct ping_stat #define PING_SET_INTERVAL(t,i) do {\ (t).tv_sec = (i)/PING_PRECISION;\ - (t).tv_usec = ((i)%PING_PRECISION)*(1000000/PING_PRECISION) ;\ + (t).tv_nsec = ((i)%PING_PRECISION)*(1e9/PING_PRECISION) ;\ } while (0) @@ -109,7 +109,7 @@ struct ping_data int ping_fd; /* Raw socket descriptor */ int ping_type; /* Type of packets to send */ size_t ping_count; /* Number of packets to send */ - struct timeval ping_start_time; /* Start time */ + struct timespec ping_start_time; /* Start time */ size_t ping_interval; /* Number of seconds to wait between sending pkts */ union ping_address ping_dest; /* whom to ping */ char *ping_hostname; /* Printable hostname */ @@ -153,7 +153,6 @@ struct ping_data (_C_BIT (p, _C_IND (p,bit)) & _C_MASK (_C_IND (p,bit))) -void tvsub (struct timeval *out, struct timeval *in); double nabs (double a); double nsqrt (double a, double prec); @@ -172,7 +171,7 @@ void ping_set_count (PING * ping, size_t count); void ping_set_sockopt (PING * ping, int opt, void *val, int valsize); void ping_set_interval (PING * ping, size_t interval); void ping_unset_data (PING * p); -int ping_timeout_p (struct timeval *start_time, int timeout); +bool ping_timeout_p (struct timespec *start_time, int timeout); char *ipaddr2str (struct sockaddr *from, socklen_t fromlen); char *sinaddr2str (struct in_addr ina); diff --git a/ping/ping_echo.c b/ping/ping_echo.c index 0f41b1bd..1aa69585 100644 --- a/ping/ping_echo.c +++ b/ping/ping_echo.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "ping_impl.h" @@ -177,12 +178,9 @@ print_echo (int dupflag, struct ping_stat *ping_stat, struct ip *ip, icmphdr_t *icmp, int datalen) { int hlen; - struct timeval tv; - int timing = 0; + bool timing = false; double triptime = 0.0; - gettimeofday (&tv, NULL); - /* Length of IP header */ hlen = ip->ip_hl << 2; @@ -192,17 +190,20 @@ print_echo (int dupflag, struct ping_stat *ping_stat, /* Do timing */ if (PING_TIMING (datalen - PING_HEADER_LEN)) { - struct timeval tv1, *tp; + struct timeval tv; + struct timespec ts; - timing++; - tp = (struct timeval *) icmp->icmp_data; + timing = true; - /* Avoid unaligned data: */ - memcpy (&tv1, tp, sizeof (tv1)); - tvsub (&tv, &tv1); + /* Avoid unaligned data. */ + memcpy (&tv, icmp->icmp_data, sizeof (tv)); + /* *INDENT-OFF* */ + ts = timespec_sub (current_timespec (), + (struct timespec) { .tv_sec = tv.tv_sec, + .tv_nsec = tv.tv_usec * 1000 }); + /* *INDENT-ON* */ - triptime = ((double) tv.tv_sec) * 1000.0 + - ((double) tv.tv_usec) / 1000.0; + triptime = timespectod (ts) * 1000.0; ping_stat->tsum += triptime; ping_stat->tsumsq += triptime * triptime; if (triptime < ping_stat->tmin) -- 2.45.2