From: Arran Cudbard-Bell Date: Fri, 24 Sep 2021 19:11:00 +0000 (-0500) Subject: Wrap fr_time_delta_t and fr_unix_time_t in structs X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6f74f2f37b786dcd70086c2579e203ffe33710d;p=thirdparty%2Ffreeradius-server.git Wrap fr_time_delta_t and fr_unix_time_t in structs Fix invalid timeouts passed to redis and memcached --- diff --git a/src/bin/dhcpclient.c b/src/bin/dhcpclient.c index b32ed6859b..38b04928d0 100644 --- a/src/bin/dhcpclient.c +++ b/src/bin/dhcpclient.c @@ -269,12 +269,10 @@ static fr_radius_packet_t *fr_dhcpv4_recv_raw_loop(int lsockfd, our_timeout = timeout; /* Loop waiting for DHCP replies until timer expires */ - while (our_timeout) { + while (fr_time_delta_ispos(our_timeout)) { if ((!found) || (reply)) { // only debug at start and each time we get a valid DHCP reply on raw socket - DEBUG("Waiting for %s DHCP replies for: %d.%06d", - (nb_reply > 0) ? " additional ":" ", - (int)(our_timeout / NSEC), - (int)(our_timeout % NSEC)); + DEBUG("Waiting for %s DHCP replies for: %.6f", + (nb_reply > 0) ? " additional ":" ", fr_time_delta_unwrap(our_timeout) / (double)NSEC); } reply = NULL; @@ -299,7 +297,7 @@ static fr_radius_packet_t *fr_dhcpv4_recv_raw_loop(int lsockfd, # endif #endif } else { - our_timeout = 0; + our_timeout = fr_time_delta_wrap(0); } if (reply) { diff --git a/src/bin/radclient.c b/src/bin/radclient.c index 512f115f86..58ed629d46 100644 --- a/src/bin/radclient.c +++ b/src/bin/radclient.c @@ -51,8 +51,8 @@ typedef struct request_s request_t; /* to shut up warnings about mschap.h */ #define reply_pairs reply_list static int retries = 3; -static fr_time_delta_t timeout = ((fr_time_delta_t) 5) * NSEC; -static fr_time_delta_t sleep_time = -1; +static fr_time_delta_t timeout = fr_time_delta_wrap(5 * NSEC); /* 5 seconds */ +static fr_time_delta_t sleep_time = fr_time_delta_wrap(-1); static char *secret = NULL; static bool do_output = true; @@ -769,7 +769,9 @@ static int send_one_packet(rc_request_t *request) * Remember when we have to wake up, to re-send the * request, of we didn't receive a reply. */ - if ((sleep_time == -1) || (sleep_time > timeout)) sleep_time = timeout; + if ((fr_time_delta_eq(sleep_time, fr_time_delta_wrap(-1)) || (fr_time_delta_gt(sleep_time, timeout)))) { + sleep_time = timeout; + } /* * Haven't sent the packet yet. Initialize it. @@ -882,14 +884,14 @@ static int send_one_packet(rc_request_t *request) /* * Not time for a retry, do so. */ - if (fr_time_sub(now, request->timestamp) < timeout) { + if (fr_time_delta_lt(fr_time_sub(now, request->timestamp), timeout)) { /* * When we walk over the tree sending * packets, we update the minimum time * required to sleep. */ - if ((sleep_time == -1) || - (sleep_time > fr_time_sub(now, request->timestamp))) { + if (fr_time_delta_eq(sleep_time, fr_time_delta_wrap(-1)) || + fr_time_delta_gt(sleep_time, fr_time_sub(now, request->timestamp))) { sleep_time = fr_time_sub(now, request->timestamp); } return 0; @@ -961,7 +963,7 @@ static int recv_one_packet(fr_time_delta_t wait_time) max_fd = fr_packet_list_fd_set(packet_list, &set); if (max_fd < 0) fr_exit_now(1); /* no sockets to listen on! */ - our_wait_time = wait_time <= 0 ? fr_time_delta_from_sec(0) : wait_time; + our_wait_time = !fr_time_delta_ispos(wait_time) ? fr_time_delta_from_sec(0) : wait_time; /* * No packet was received. @@ -1507,7 +1509,7 @@ int main(int argc, char **argv) char const *filename = NULL; done = true; - sleep_time = -1; + sleep_time = fr_time_delta_wrap(-1); /* * Walk over the packets, sending them. @@ -1521,7 +1523,7 @@ int main(int argc, char **argv) * receive it, but don't wait for a * packet. */ - recv_one_packet(0); + recv_one_packet(fr_time_delta_wrap(0)); /* * This packet is done. Delete it. @@ -1563,12 +1565,12 @@ int main(int argc, char **argv) if (persec) { fr_time_delta_t psec; - psec = (persec == 1) ? fr_time_delta_from_sec(1) : (1000000 / persec); + psec = (persec == 1) ? fr_time_delta_from_sec(1) : fr_time_delta_wrap(1000000 / persec); /* * Don't sleep elsewhere. */ - sleep_time = 0; + sleep_time = fr_time_delta_wrap(0); /* @@ -1591,7 +1593,7 @@ int main(int argc, char **argv) int i; done = false; - sleep_time = 0; + sleep_time = fr_time_delta_wrap(0); for (i = 0; i < 4; i++) { ((uint32_t *) this->packet->vector)[i] = fr_rand(); @@ -1610,7 +1612,7 @@ int main(int argc, char **argv) if (fr_packet_list_num_elements(packet_list) > 0) { done = false; } else { - sleep_time = 0; + sleep_time = fr_time_delta_wrap(0); } /* @@ -1620,7 +1622,7 @@ int main(int argc, char **argv) * sending more packets (if necessary), and updating * the sleep time. */ - if (!done && (sleep_time > 0)) { + if (!done && fr_time_delta_ispos(sleep_time)) { recv_one_packet(sleep_time); } } while (!done); diff --git a/src/bin/radiusd.c b/src/bin/radiusd.c index 669f2fbc8f..e5603e07d2 100644 --- a/src/bin/radiusd.c +++ b/src/bin/radiusd.c @@ -155,7 +155,7 @@ static fr_event_timer_t const *fr_time_sync_ev = NULL; static void fr_time_sync_event(fr_event_list_t *el, UNUSED fr_time_t now, UNUSED void *uctx) { - fr_time_delta_t when = NSEC; + fr_time_delta_t when = fr_time_delta_from_sec(1); (void) fr_event_timer_in(el, el, &fr_time_sync_ev, when, fr_time_sync_event, NULL); (void) fr_time_sync(); @@ -216,7 +216,7 @@ int main(int argc, char *argv[]) dl_module_loader_t *dl_modules = NULL; #ifndef NDEBUG - fr_time_delta_t exit_after = 0; + fr_time_delta_t exit_after = fr_time_delta_wrap(0); #endif /* * Must be called first, so the handler is called last @@ -346,7 +346,7 @@ int main(int argc, char *argv[]) #ifndef NDEBUG case 'e': - exit_after = (fr_time_delta_t)atoi(optarg) * NSEC; + exit_after = fr_time_delta_from_sec(atoi(optarg)); break; #endif @@ -921,7 +921,7 @@ int main(int argc, char *argv[]) fr_time_sync_event(main_loop_event_list(), fr_time(), NULL); #ifndef NDEBUG - if (exit_after > 0) fr_exit_after(main_loop_event_list(), fr_time_wrap(0), &exit_after); + if (fr_time_delta_ispos(exit_after)) fr_exit_after(main_loop_event_list(), fr_time_wrap(0), &exit_after); #endif /* * Process requests until HUP or exit. diff --git a/src/bin/radsniff.c b/src/bin/radsniff.c index 05d7bce394..352c9071d2 100644 --- a/src/bin/radsniff.c +++ b/src/bin/radsniff.c @@ -1875,7 +1875,7 @@ static void rs_got_packet(fr_event_list_t *el, int fd, UNUSED int flags, void *c * event ourselves. */ now_real = fr_time(); - if (fr_time_sub(now_real, last_sync) > fr_time_delta_from_sec(1)) { + if (fr_time_delta_gt(fr_time_sub(now_real, last_sync), fr_time_delta_from_sec(1))) { fr_time_sync(); last_sync = now_real; } diff --git a/src/include/build.h b/src/include/build.h index 1b352bfe9c..4c969abc51 100644 --- a/src/include/build.h +++ b/src/include/build.h @@ -114,6 +114,13 @@ do { \ */ #define UNCONST(_type, _ptr) ((_type)((uintptr_t)(_ptr))) +/** Typeof field + * + * @param[in] _type struct type containing the field. + * @param[in] _field to return the type of. + */ +#define typeof_field(_type, _field) __typeof__(((_type *)NULL)->_field) + /** HEX concatenation macros * */ diff --git a/src/lib/eap/session.c b/src/lib/eap/session.c index bfd7235e94..74966f362f 100644 --- a/src/lib/eap/session.c +++ b/src/lib/eap/session.c @@ -50,7 +50,7 @@ static int _eap_session_free(eap_session_t *eap_session) * retransmit which nukes our ID, and therefore our state. */ if (((request && RDEBUG_ENABLED) || (!request && DEBUG_ENABLED)) && - (eap_session->tls && !eap_session->finished && (fr_time_sub(fr_time(), eap_session->updated) > fr_time_delta_from_sec(3)))) { + (eap_session->tls && !eap_session->finished && fr_time_delta_gt(fr_time_sub(fr_time(), eap_session->updated), fr_time_delta_from_sec(3)))) { ROPTIONAL(RWDEBUG, WARN, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); ROPTIONAL(RWDEBUG, WARN, "!! EAP session %016" PRIxPTR " did not finish! !!", (uintptr_t)eap_session); diff --git a/src/lib/io/channel.c b/src/lib/io/channel.c index ec23e4efd3..b7df5c377c 100644 --- a/src/lib/io/channel.c +++ b/src/lib/io/channel.c @@ -289,7 +289,7 @@ static int fr_channel_data_ready(fr_channel_t *ch, fr_time_t when, fr_channel_en } #define IALPHA (8) -#define RTT(_old, _new) ((_new + ((IALPHA - 1) * _old)) / IALPHA) +#define RTT(_old, _new) fr_time_delta_wrap((fr_time_delta_unwrap(_new) + (fr_time_delta_unwrap(_old) * (IALPHA - 1))) / IALPHA) /** Send a request message into the channel * @@ -341,7 +341,7 @@ int fr_channel_send_request(fr_channel_t *ch, fr_channel_data_t *cd) requestor->sequence = sequence; message_interval = fr_time_sub(when, requestor->stats.last_write); - if (!requestor->stats.message_interval) { + if (fr_time_delta_ispos(requestor->stats.message_interval)) { requestor->stats.message_interval = message_interval; } else { requestor->stats.message_interval = RTT(requestor->stats.message_interval, message_interval); @@ -435,7 +435,7 @@ bool fr_channel_recv_reply(fr_channel_t *ch) * NAKs have zero processing time, so we ignore them for * the purpose of RTT. */ - if (cd->reply.processing_time) { + if (fr_time_delta_ispos(cd->reply.processing_time)) { ch->processing_time = RTT(ch->processing_time, cd->reply.processing_time); } ch->cpu_time = cd->reply.cpu_time; @@ -968,7 +968,7 @@ void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char cons fr_log(log, L_INFO, file, line, "\tkevents checked = %" PRIu64 "\n", ch->end[TO_RESPONDER].stats.kevents); fr_log(log, L_INFO, file, line, "\toutstanding = %" PRIu64 "\n", ch->end[TO_RESPONDER].stats.outstanding); fr_log(log, L_INFO, file, line, "\tpackets processed = %" PRIu64 "\n", ch->end[TO_RESPONDER].stats.packets); - fr_log(log, L_INFO, file, line, "\tmessage interval (RTT) = %" PRIu64 "\n", ch->end[TO_RESPONDER].stats.message_interval); + fr_log(log, L_INFO, file, line, "\tmessage interval (RTT) = %" PRIu64 "\n", fr_time_delta_unwrap(ch->end[TO_RESPONDER].stats.message_interval)); fr_log(log, L_INFO, file, line, "\tlast write = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_RESPONDER].stats.last_read_other)); fr_log(log, L_INFO, file, line, "\tlast read other end = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_RESPONDER].stats.last_read_other)); fr_log(log, L_INFO, file, line, "\tlast signal other = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_RESPONDER].stats.last_sent_signal)); @@ -977,7 +977,7 @@ void fr_channel_stats_log(fr_channel_t const *ch, fr_log_t const *log, char cons fr_log(log, L_INFO, file, line, "\tsignals sent = %" PRIu64"\n", ch->end[TO_REQUESTOR].stats.signals); fr_log(log, L_INFO, file, line, "\tkevents checked = %" PRIu64 "\n", ch->end[TO_REQUESTOR].stats.kevents); fr_log(log, L_INFO, file, line, "\tpackets processed = %" PRIu64 "\n", ch->end[TO_REQUESTOR].stats.packets); - fr_log(log, L_INFO, file, line, "\tmessage interval (RTT) = %" PRIu64 "\n", ch->end[TO_REQUESTOR].stats.message_interval); + fr_log(log, L_INFO, file, line, "\tmessage interval (RTT) = %" PRIu64 "\n", fr_time_delta_unwrap(ch->end[TO_REQUESTOR].stats.message_interval)); fr_log(log, L_INFO, file, line, "\tlast write = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_REQUESTOR].stats.last_read_other)); fr_log(log, L_INFO, file, line, "\tlast read other end = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_REQUESTOR].stats.last_read_other)); fr_log(log, L_INFO, file, line, "\tlast signal other = %" PRIu64 "\n", fr_time_unwrap(ch->end[TO_REQUESTOR].stats.last_sent_signal)); diff --git a/src/lib/io/load.c b/src/lib/io/load.c index 0eeaba29a0..c268491f9d 100644 --- a/src/lib/io/load.c +++ b/src/lib/io/load.c @@ -37,9 +37,23 @@ RCSID("$Id$") #define IBETA (4) #define IALPHA (8) -#define DIFF(_rtt, _t) (_rtt < _t ? (_t - _rtt) : (_rtt - _t)) -#define RTTVAR(_rtt, _rttvar, _t) ((((IBETA - 1) * _rttvar) + DIFF(_rtt, _t)) / IBETA) -#define RTT(_old, _new) ((_new + ((IALPHA - 1) * _old)) / IALPHA) +#define DIFF(_rtt, _t) \ + (\ + fr_time_delta_lt(_rtt, _t) ? \ + fr_time_delta_sub(_t, _rtt) : \ + fr_time_delta_sub(_rtt, _t)\ + ) + +#define RTTVAR(_rtt, _rttvar, _t) \ + fr_time_delta_div(\ + fr_time_delta_add(\ + fr_time_delta_mul(_rttvar, fr_time_delta_wrap(IBETA - 1)), \ + DIFF(_rtt, _t)\ + ), \ + fr_time_delta_wrap(IBETA)\ + ) + +#define RTT(_old, _new) fr_time_delta_wrap((fr_time_delta_unwrap(_new) + (fr_time_delta_unwrap(_old) * (IALPHA - 1))) / IALPHA) typedef enum { FR_LOAD_STATE_INIT = 0, @@ -135,7 +149,7 @@ static void load_timer(fr_event_list_t *el, fr_time_t now, void *uctx) l->pps += l->config->step; l->stats.pps = l->pps; l->stats.skipped = 0; - l->delta = fr_time_delta_from_sec(l->config->parallel) / l->pps; + l->delta = fr_time_delta_div(fr_time_delta_from_sec(l->config->parallel), fr_time_delta_wrap(l->pps)); /* * Stop at max PPS, if it's set. Otherwise @@ -223,7 +237,7 @@ int fr_load_generator_start(fr_load_t *l) l->stats.pps = l->pps; l->count = l->config->parallel; - l->delta = (NSEC * ((uint64_t) l->config->parallel)) / l->pps; + l->delta = fr_time_delta_div(fr_time_delta_from_sec(l->config->parallel), fr_time_delta_wrap(l->pps)); l->next = fr_time_add(l->step_start, l->delta); load_timer(l->el, l->step_start, l); @@ -267,19 +281,19 @@ fr_load_reply_t fr_load_generator_have_reply(fr_load_t *l, fr_time_t request_tim /* * t is in nanoseconds. */ - if (t < 1000) { + if (fr_time_delta_lt(t, fr_time_delta_wrap(1000))) { l->stats.times[0]++; /* < microseconds */ - } else if (t < 10000) { + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(10000))) { l->stats.times[1]++; /* microseconds */ - } else if (t < 100000) { + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(100000))) { l->stats.times[2]++; /* 10s of microseconds */ - } else if (t < 1000000) { - l->stats.times[3]++; /* 100s of microiseconds */ - } else if (t < 10000000) { + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(1000000))) { + l->stats.times[3]++; /* 100s of microseconds */ + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(10000000))) { l->stats.times[4]++; /* milliseconds */ - } else if (t < 100000000) { + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(100000000))) { l->stats.times[5]++; /* 10s of milliseconds */ - } else if (t < NSEC) { + } else if (fr_time_delta_lt(t, fr_time_delta_wrap(NSEC))) { l->stats.times[6]++; /* 100s of milliseconds */ } else { l->stats.times[7]++; /* seconds */ @@ -334,11 +348,9 @@ size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, } - now_f = fr_time_sub(now, l->stats.start); - now_f /= NSEC; + now_f = fr_time_delta_unwrap(fr_time_sub(now, l->stats.start)) / (double)NSEC; - last_send_f = fr_time_sub(l->stats.last_send, l->stats.start); - last_send_f /= NSEC; + last_send_f = fr_time_delta_unwrap(fr_time_sub(l->stats.last_send, l->stats.start)) / (double)NSEC; /* * Track packets/s. Since times are in nanoseconds, we @@ -347,7 +359,11 @@ size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, * numbers, and then converted to a final 32-bit counter. */ if (fr_time_gt(now, l->step_start)) { - l->stats.pps_accepted = fr_time_delta_from_sec(l->stats.received - l->step_received) / fr_time_sub(now, l->step_start); + l->stats.pps_accepted = + fr_time_delta_unwrap( + fr_time_delta_div(fr_time_delta_from_sec(l->stats.received - l->step_received), + fr_time_sub(now, l->step_start)) + ); } return snprintf(buffer, buflen, @@ -359,7 +375,7 @@ size_t fr_load_generator_stats_sprint(fr_load_t *l, fr_time_t now, char *buffer, "%d,%d,%d,%d,%d,%d,%d,%d," "%d\n", now_f, last_send_f, - l->stats.rtt, l->stats.rttvar, + fr_time_delta_unwrap(l->stats.rtt), fr_time_delta_unwrap(l->stats.rttvar), l->stats.pps, l->stats.pps_accepted, l->stats.sent, l->stats.received, l->stats.backlog, l->stats.max_backlog, diff --git a/src/lib/io/master.c b/src/lib/io/master.c index f131f003fd..caa38407a1 100644 --- a/src/lib/io/master.c +++ b/src/lib/io/master.c @@ -1853,9 +1853,7 @@ static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, void *nr) * No dynamic clients AND no packet cleanups? We don't * need timers. */ - if (!inst->dynamic_clients && !inst->cleanup_delay) { - return; - } + if (inst->dynamic_clients && !fr_time_delta_ispos(inst->cleanup_delay)) return; /* * Set event list and network side for this socket. @@ -1904,7 +1902,8 @@ static void client_expiry_timer(fr_event_list_t *el, fr_time_t now, void *uctx) case PR_CLIENT_DYNAMIC: delay = inst->idle_timeout; - if (client->radclient->limit.idle_timeout && (client->radclient->limit.idle_timeout < inst->idle_timeout)) { + if (fr_time_delta_ispos(client->radclient->limit.idle_timeout) && + (fr_time_delta_lt(client->radclient->limit.idle_timeout, inst->idle_timeout))) { delay = client->radclient->limit.idle_timeout; } break; @@ -2084,7 +2083,7 @@ static void packet_expiry_timer(fr_event_list_t *el, fr_time_t now, void *uctx) * On duplicates this also extends the expiry timer. */ if (fr_time_eq(now, fr_time_wrap(0)) && !track->discard && inst->app_io->track_duplicates) { - fr_assert(inst->cleanup_delay > 0); + fr_assert(fr_time_delta_ispos(inst->cleanup_delay)); fr_assert(track->do_not_respond || track->reply_len); track->expires = fr_time_add(fr_time(), inst->cleanup_delay); @@ -2096,8 +2095,8 @@ static void packet_expiry_timer(fr_event_list_t *el, fr_time_t now, void *uctx) */ if (fr_event_timer_at(track, el, &track->ev, track->expires, packet_expiry_timer, track) == 0) { - DEBUG("proto_%s - cleaning up request in %d.%06ds", inst->app_io->name, - (int) (inst->cleanup_delay / NSEC), (int) (inst->cleanup_delay % NSEC)); + DEBUG("proto_%s - cleaning up request in %.6fs", inst->app_io->name, + fr_time_delta_unwrap(inst->cleanup_delay) / (double)NSEC); return; } @@ -2566,7 +2565,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *cs) * If we are tracking duplicates, then we must have a non-zero cleanup delay. */ if (!inst->app_io->track_duplicates) { - inst->cleanup_delay = 0; + inst->cleanup_delay = fr_time_delta_wrap(0); } else { FR_TIME_DELTA_BOUND_CHECK("cleanup_delay", inst->cleanup_delay, >=, fr_time_delta_from_sec(1)); diff --git a/src/lib/io/network.c b/src/lib/io/network.c index fb37a88609..771d979bbc 100644 --- a/src/lib/io/network.c +++ b/src/lib/io/network.c @@ -427,7 +427,7 @@ static void fr_network_unsuspend(fr_network_t *nr) } #define IALPHA (8) -#define RTT(_old, _new) ((_new + ((IALPHA - 1) * _old)) / IALPHA) +#define RTT(_old, _new) fr_time_delta_wrap((fr_time_delta_unwrap(_new) + (fr_time_delta_unwrap(_old) * (IALPHA - 1))) / IALPHA) /** Callback which handles a message being received on the network side. * @@ -448,7 +448,7 @@ static void fr_network_recv_reply(void *ctx, fr_channel_t *ch, fr_channel_data_t worker = fr_channel_requestor_uctx_get(ch); worker->stats.out++; worker->cpu_time = cd->reply.cpu_time; - if (worker->predicted == 0) { + if (!fr_time_delta_ispos(worker->predicted)) { worker->predicted = cd->reply.processing_time; } else { worker->predicted = RTT(worker->predicted, cd->reply.processing_time); @@ -574,14 +574,14 @@ retry: two = fr_rand() % nr->num_workers; } while (two == one); - if (nr->workers[one]->cpu_time < nr->workers[two]->cpu_time) { + if (fr_time_delta_lt(nr->workers[one]->cpu_time, nr->workers[two]->cpu_time)) { worker = nr->workers[one]; } else { worker = nr->workers[two]; } } else { int i; - fr_time_delta_t cpu_time = ~((fr_time_delta_t) 0); + fr_time_delta_t cpu_time = fr_time_delta_max(); fr_network_worker_t *found = NULL; /* @@ -592,7 +592,7 @@ retry: worker = nr->workers[i]; if (worker->blocked) continue; - if (worker->cpu_time < cpu_time) { + if (fr_time_delta_lt(worker->cpu_time, cpu_time)) { found = worker; } } @@ -652,7 +652,7 @@ retry: * updated with a more accurate number when we receive a * reply from this channel. */ - worker->cpu_time += worker->predicted; + worker->cpu_time = fr_time_delta_add(worker->cpu_time, worker->predicted); return 0; } diff --git a/src/lib/io/schedule.c b/src/lib/io/schedule.c index 127b7f1ea9..0faf3b08df 100644 --- a/src/lib/io/schedule.c +++ b/src/lib/io/schedule.c @@ -328,8 +328,9 @@ static void *fr_schedule_network_thread(void *arg) /* * Print out statistics for this network IO handler. */ - if (sc->config->stats_interval) (void) fr_event_timer_in(sn, el, &sn->ev, sn->sc->config->stats_interval, stats_timer, sn); - + if (fr_time_delta_ispos(sc->config->stats_interval)) { + (void) fr_event_timer_in(sn, el, &sn->ev, sn->sc->config->stats_interval, stats_timer, sn); + } /* * Call the main event processing loop of the network * thread Will not return until the worker is about diff --git a/src/lib/io/time_tracking.h b/src/lib/io/time_tracking.h index 18fe784965..952ab08e21 100644 --- a/src/lib/io/time_tracking.h +++ b/src/lib/io/time_tracking.h @@ -112,7 +112,7 @@ do { \ for (_parent = (_tt)->parent; _parent; _parent = _parent->parent) { \ _parent->_event = _now; \ _parent->last_changed = _now; \ - _parent->running_total += _run_time; \ + _parent->running_total = fr_time_delta_add(_parent->running_total, _run_time); \ } \ } while (0) @@ -125,7 +125,7 @@ do { \ for (_parent = (_tt)->parent; _parent; _parent = _parent->parent){ \ _parent->_event = _now; \ _parent->last_changed = _now; \ - _parent->waiting_total += _wait_time; \ + _parent->waiting_total = fr_time_delta_add(_parent->waiting_total, _wait_time); \ } \ } while (0) @@ -199,7 +199,7 @@ static inline CC_HINT(nonnull) void fr_time_tracking_pop(fr_time_tracking_t *tt, run_time = fr_time_sub(now, tt->last_changed); tt->last_changed = tt->parent->ended = now; - tt->running_total += run_time; + tt->running_total = fr_time_delta_add(tt->running_total, run_time); UPDATE_PARENT_RUN_TIME(tt, run_time, last_changed, now); tt->parent = tt->parent->parent; @@ -221,7 +221,7 @@ static inline CC_HINT(nonnull) void fr_time_tracking_yield(fr_time_tracking_t *t tt->last_yielded = tt->last_changed = now; run_time = fr_time_sub(now, tt->last_resumed); - tt->running_total += run_time; + tt->running_total = fr_time_delta_add(tt->running_total, run_time); UPDATE_PARENT_RUN_TIME(tt, run_time, last_yielded, now); } @@ -241,12 +241,12 @@ static inline CC_HINT(nonnull) void fr_time_tracking_resume(fr_time_tracking_t * tt->last_resumed = tt->last_changed = now; wait_time = fr_time_sub(now, tt->last_yielded); - tt->waiting_total += wait_time; + tt->waiting_total = fr_time_delta_add(tt->waiting_total, wait_time); UPDATE_PARENT_WAIT_TIME(tt, wait_time, last_resumed, now); } #define IALPHA (8) -#define RTT(_old, _new) ((_new + ((IALPHA - 1) * _old)) / IALPHA) +#define RTT(_old, _new) fr_time_delta_wrap((fr_time_delta_unwrap(_new) + (fr_time_delta_unwrap(_old) * (IALPHA - 1))) / IALPHA) /** End time tracking for this entity * @@ -266,10 +266,13 @@ static inline void fr_time_tracking_end(fr_time_delta_t *predicted, tt->ended = tt->last_changed = now; run_time = fr_time_sub(now, tt->last_resumed); - tt->running_total += run_time; + tt->running_total = fr_time_delta_add(tt->running_total, run_time); UPDATE_PARENT_RUN_TIME(tt, run_time, ended, now); - if (predicted) *predicted = !(*predicted) ? tt->running_total : RTT((*predicted), tt->running_total); + if (predicted) { + *predicted = !fr_time_delta_ispos(*predicted) ? + tt->running_total : RTT((*predicted), tt->running_total); + } tt->parent = NULL; } @@ -282,7 +285,7 @@ static inline void fr_time_tracking_end(fr_time_delta_t *predicted, static inline CC_HINT(nonnull) void fr_time_tracking_debug(fr_time_tracking_t *tt, FILE *fp) { #define DPRINT_TIME(_x) fprintf(fp, "\t" #_x " = %"PRIu64"\n", fr_time_unwrap(tt->_x)); -#define DPRINT(_x) fprintf(fp, "\t" #_x " = %"PRIu64"\n", tt->_x); +#define DPRINT(_x) fprintf(fp, "\t" #_x " = %"PRIu64"\n", fr_time_delta_unwrap(tt->_x)); DPRINT_TIME(started); DPRINT_TIME(ended); diff --git a/src/lib/io/worker.c b/src/lib/io/worker.c index 275c76b4e8..9d661a66f2 100644 --- a/src/lib/io/worker.c +++ b/src/lib/io/worker.c @@ -338,7 +338,7 @@ static void worker_nak(fr_worker_t *worker, fr_channel_data_t *cd, fr_time_t now */ reply->m.when = now; reply->reply.cpu_time = worker->tracking.running_total; - reply->reply.processing_time = 10; /* @todo - set to something better? */ + reply->reply.processing_time = fr_time_delta_from_sec(10); /* @todo - set to something better? */ reply->reply.request_time = cd->request.recv_time; reply->listen = cd->listen; @@ -1166,7 +1166,7 @@ static inline CC_HINT(always_inline) void worker_run_request(fr_worker_t *worker * event loop fewer times per second, instead of after * every request. */ - while ((fr_time_sub(now, start) < (NSEC / 100000)) && + while (fr_time_delta_lt(fr_time_sub(now, start), fr_time_delta_wrap(NSEC / 100000)) && ((request = fr_heap_pop(worker->runnable)) != NULL)) { REQUEST_VERIFY(request); @@ -1223,12 +1223,18 @@ nomem: if (worker->config._x > _max) worker->config._x = _max; \ } while (0) +#define CHECK_CONFIG_TIME_DELTA(_x, _min, _max) do { \ + if (fr_time_delta_ispos(worker->config._x)) worker->config._x = _min; \ + if (fr_time_delta_lt(worker->config._x, _min)) worker->config._x = _min; \ + if (fr_time_delta_gt(worker->config._x, _max)) worker->config._x = _max; \ + } while (0) + CHECK_CONFIG(max_requests,1024,(1 << 30)); CHECK_CONFIG(max_channels, 64, 1024); CHECK_CONFIG(talloc_pool_size, 4096, 65536); CHECK_CONFIG(message_set_size, 1024, 8192); CHECK_CONFIG(ring_buffer_size, (1 << 17), (1 << 20)); - CHECK_CONFIG(max_request_time, fr_time_delta_from_sec(30), fr_time_delta_from_sec(60)); + CHECK_CONFIG_TIME_DELTA(max_request_time, fr_time_delta_from_sec(30), fr_time_delta_from_sec(60)); worker->channel = talloc_zero_array(worker, fr_channel_t *, worker->config.max_channels); if (!worker->channel) { @@ -1409,9 +1415,9 @@ void fr_worker_debug(fr_worker_t *worker, FILE *fp) fprintf(fp, "\tstats.in = %" PRIu64 "\n", worker->stats.in); fprintf(fp, "\tcalculated (predicted) total CPU time = %" PRIu64 "\n", - worker->predicted * worker->stats.in); + fr_time_delta_unwrap(worker->predicted) * worker->stats.in); fprintf(fp, "\tcalculated (counted) per request time = %" PRIu64 "\n", - worker->tracking.running_total / worker->stats.in); + fr_time_delta_unwrap(worker->tracking.running_total) / worker->stats.in); fr_time_tracking_debug(&worker->tracking, fp); @@ -1519,17 +1525,17 @@ static int cmd_stats_worker(FILE *fp, UNUSED FILE *fp_err, void *ctx, fr_cmd_inf if ((info->argc == 0) || (strcmp(info->argv[0], "cpu") == 0)) { when = worker->predicted; - fprintf(fp, "cpu.request_time_rtt\t\t%u.%09" PRIu64 "\n", (unsigned int) (when / NSEC), when % NSEC); + fprintf(fp, "cpu.request_time_rtt\t\t%.9f\n", fr_time_delta_unwrap(when) / (double)NSEC); when = worker->tracking.running_total; - if (when > 0) when /= (worker->stats.in - worker->stats.dropped); - fprintf(fp, "cpu.average_request_time\t%u.%09" PRIu64 "\n", (unsigned int) (when / NSEC), when % NSEC); + if (fr_time_delta_ispos(when)) when = fr_time_delta_div(when, fr_time_delta_wrap(worker->stats.in - worker->stats.dropped)); + fprintf(fp, "cpu.average_request_time\t%.9f\n", fr_time_delta_unwrap(when) / (double)NSEC); when = worker->tracking.running_total; - fprintf(fp, "cpu.used\t\t\t%u.%06u\n", (unsigned int) (when / NSEC), (unsigned int) (when % NSEC) / 1000); + fprintf(fp, "cpu.used\t\t\t%.6f\n", fr_time_delta_unwrap(when) / (double)NSEC); when = worker->tracking.waiting_total; - fprintf(fp, "cpu.waiting\t\t\t%u.%03u\n", (unsigned int) (when / NSEC), (unsigned int) (when % NSEC) / 1000000); + fprintf(fp, "cpu.waiting\t\t\t%.3f\n", fr_time_delta_unwrap(when) / (double)NSEC); fr_time_elapsed_fprint(fp, &worker->cpu_time, "cpu.requests", 4); fr_time_elapsed_fprint(fp, &worker->wall_clock, "time.requests", 4); diff --git a/src/lib/redis/cluster.c b/src/lib/redis/cluster.c index 4f200cd35f..207d0e1ca2 100644 --- a/src/lib/redis/cluster.c +++ b/src/lib/redis/cluster.c @@ -1889,7 +1889,7 @@ fr_redis_rcode_t fr_redis_cluster_state_next(fr_redis_cluster_state_t *state, fr if (!*conn) *conn = fr_pool_connection_get(state->node->pool, request); - if (cluster->conf->retry_delay) nanosleep(&fr_time_delta_to_timespec(cluster->conf->retry_delay), NULL); + if (fr_time_delta_ispos(cluster->conf->retry_delay)) nanosleep(&fr_time_delta_to_timespec(cluster->conf->retry_delay), NULL); goto try_again; /* diff --git a/src/lib/server/cf_parse.h b/src/lib/server/cf_parse.h index 2b9f5e01b0..9809a28216 100644 --- a/src/lib/server/cf_parse.h +++ b/src/lib/server/cf_parse.h @@ -352,7 +352,7 @@ do {\ #define FR_TIME_DELTA_BOUND_CHECK(_name, _var, _op, _bound)\ do {\ - if (!(_var _op _bound)) { \ + if (!fr_time_delta_cond(_var, _op, _bound)) { \ WARN("Ignoring \"" _name " = %pV\", forcing to \"" _name " = %pV\"",\ fr_box_time_delta(_var),\ fr_box_time_delta(_bound));\ diff --git a/src/lib/server/client.c b/src/lib/server/client.c index 75f2f2e2af..a2a24752a8 100644 --- a/src/lib/server/client.c +++ b/src/lib/server/client.c @@ -860,7 +860,7 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_SECTION *serv * A response_window of zero is OK, and means that it's * ignored by the rest of the server timers. */ - if (c->response_window) { + if (fr_time_delta_ispos(c->response_window)) { FR_TIME_DELTA_BOUND_CHECK("response_window", c->response_window, >=, fr_time_delta_from_usec(1000)); FR_TIME_DELTA_BOUND_CHECK("response_window", c->response_window, <=, fr_time_delta_from_sec(60)); FR_TIME_DELTA_BOUND_CHECK("response_window", c->response_window, <=, main_config->max_request_time); @@ -878,12 +878,12 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, CONF_SECTION *serv #endif if ((c->proto == IPPROTO_TCP) || (c->proto == IPPROTO_IP)) { - if ((c->limit.idle_timeout > 0) && (c->limit.idle_timeout < fr_time_delta_from_sec(5))) + if (fr_time_delta_ispos(c->limit.idle_timeout) && fr_time_delta_lt(c->limit.idle_timeout, fr_time_delta_from_sec(5))) c->limit.idle_timeout = fr_time_delta_from_sec(5); - if ((c->limit.lifetime > 0) && (c->limit.lifetime < fr_time_delta_from_sec(5))) + if (fr_time_delta_ispos(c->limit.lifetime) && (fr_time_delta_lt(c->limit.lifetime, fr_time_delta_from_sec(5)))) c->limit.lifetime = fr_time_delta_from_sec(5); - if ((c->limit.lifetime > 0) && (c->limit.idle_timeout > c->limit.lifetime)) - c->limit.idle_timeout = 0; + if (fr_time_delta_ispos(c->limit.lifetime) && (fr_time_delta_lt(c->limit.idle_timeout, c->limit.lifetime))) + c->limit.idle_timeout = fr_time_delta_wrap(0); } return c; diff --git a/src/lib/server/connection.c b/src/lib/server/connection.c index 14242f01e4..0bcb8db0f3 100644 --- a/src/lib/server/connection.c +++ b/src/lib/server/connection.c @@ -736,7 +736,7 @@ static void connection_state_enter_shutdown(fr_connection_t *conn) * if it doesn't shutdown within the * timeout period. */ - if (conn->connection_timeout) { + if (fr_time_delta_ispos(conn->connection_timeout)) { if (fr_event_timer_in(conn, conn->pub.el, &conn->ev, conn->connection_timeout, _connection_timeout, conn) < 0) { /* @@ -846,7 +846,7 @@ static void connection_state_enter_failed(fr_connection_t *conn) case FR_CONNECTION_STATE_CONNECTED: /* Failed after connecting */ case FR_CONNECTION_STATE_CONNECTING: /* Failed during connecting */ case FR_CONNECTION_STATE_SHUTDOWN: /* Failed during shutdown */ - if (conn->reconnection_delay) { + if (fr_time_delta_ispos(conn->reconnection_delay)) { DEBUG2("Delaying reconnection by %pVs", fr_box_time_delta(conn->reconnection_delay)); if (fr_event_timer_in(conn, conn->pub.el, &conn->ev, conn->reconnection_delay, _reconnect_delay_done, conn) < 0) { @@ -1005,7 +1005,7 @@ static void connection_state_enter_connecting(fr_connection_t *conn) * If there's a connection timeout, * set, then add the timer. */ - if (conn->connection_timeout) { + if (fr_time_delta_ispos(conn->connection_timeout)) { if (fr_event_timer_in(conn, conn->pub.el, &conn->ev, conn->connection_timeout, _connection_timeout, conn) < 0) { PERROR("Failed setting connection_timeout event, failing connection"); diff --git a/src/lib/server/exec.c b/src/lib/server/exec.c index c4aa3401fa..42074794ea 100644 --- a/src/lib/server/exec.c +++ b/src/lib/server/exec.c @@ -994,8 +994,8 @@ int fr_exec_start(TALLOC_CTX *ctx, fr_exec_state_t *exec, request_t *request, /* * Setup event to kill the child process after a period of time. */ - if ((timeout > 0) && fr_event_timer_in(ctx, el, &exec->ev, - timeout, exec_timeout, exec) < 0) goto fail_and_close; + if (fr_time_delta_ispos(timeout) && + (fr_event_timer_in(ctx, el, &exec->ev, timeout, exec_timeout, exec) < 0)) goto fail_and_close; /* * If we need to parse stdout, insert a special IO handler that diff --git a/src/lib/server/exec_legacy.c b/src/lib/server/exec_legacy.c index baa82c7a59..f2a8e4ce71 100644 --- a/src/lib/server/exec_legacy.c +++ b/src/lib/server/exec_legacy.c @@ -391,7 +391,7 @@ int radius_readfrom_program_legacy(int fd, pid_t pid, fr_time_delta_t timeout, c /* * Minimum timeout period is one section */ - if (timeout < NSEC) timeout = fr_time_delta_from_sec(1); + if (fr_time_delta_unwrap(timeout) < NSEC) timeout = fr_time_delta_from_sec(1); /* * Read from the pipe until we doesn't get any more or @@ -407,9 +407,9 @@ int radius_readfrom_program_legacy(int fd, pid_t pid, fr_time_delta_t timeout, c FD_SET(fd, &fds); elapsed = fr_time_sub(fr_time(), start); - if (elapsed >= timeout) goto too_long; + if (fr_time_delta_gteq(elapsed, timeout)) goto too_long; - rcode = select(fd + 1, &fds, NULL, NULL, &fr_time_delta_to_timeval(timeout - elapsed)); + rcode = select(fd + 1, &fds, NULL, NULL, &fr_time_delta_to_timeval(fr_time_delta_sub(timeout, elapsed))); if (rcode == 0) { too_long: DEBUG("Child PID %u is taking too much time: forcing failure and killing child.", pid); diff --git a/src/lib/server/main_loop.c b/src/lib/server/main_loop.c index 2fda34f90d..6faa03b667 100644 --- a/src/lib/server/main_loop.c +++ b/src/lib/server/main_loop.c @@ -122,7 +122,7 @@ static void main_loop_signal_process(int flag) static fr_time_t last_hup = fr_time_wrap(0); when = fr_time(); - if (fr_time_sub(when, last_hup) < fr_time_delta_from_sec(5)) { + if (fr_time_delta_lt(fr_time_sub(when, last_hup), fr_time_delta_from_sec(5))) { INFO("Ignoring HUP (less than 5s since last one)"); return; } @@ -234,7 +234,7 @@ int main_loop_start(void) static int _loop_status(UNUSED fr_time_t now, fr_time_delta_t wake, UNUSED void *ctx) { - if (wake > (NSEC / 10)) DEBUG3("Main loop waking up in %pV seconds", fr_box_time_delta(wake)); + if (fr_time_delta_unwrap(wake) > (NSEC / 10)) DEBUG3("Main loop waking up in %pV seconds", fr_box_time_delta(wake)); return 0; } diff --git a/src/lib/server/paircmp.c b/src/lib/server/paircmp.c index 83cd7e726c..dcfb95adb7 100644 --- a/src/lib/server/paircmp.c +++ b/src/lib/server/paircmp.c @@ -361,17 +361,11 @@ int paircmp_pairs(UNUSED request_t *request, fr_pair_t const *check, fr_pair_t * break; case FR_TYPE_INT32: - if (vp->vp_int32 < check->vp_int32) { - ret = -1; - } else if (vp->vp_int32 > check->vp_int32) { - ret = +1; - } else { - ret = 0; - } + ret = CMP(vp->vp_int32, check->vp_int32); break; case FR_TYPE_DATE: - ret = vp->vp_date - check->vp_date; + ret = fr_unix_time_cmp(vp->vp_date, check->vp_date); break; case FR_TYPE_IPV4_ADDR: diff --git a/src/lib/server/pool.c b/src/lib/server/pool.c index 5f0512a0ef..f40bd2d415 100644 --- a/src/lib/server/pool.c +++ b/src/lib/server/pool.c @@ -363,7 +363,7 @@ static fr_pool_connection_t *connection_spawn(fr_pool_t *pool, request_t *reques fr_time_gt(fr_time_add(pool->state.last_failed, pool->retry_delay), now)) { bool complain = false; - if (fr_time_sub(now, pool->state.last_throttled) >= fr_time_delta_from_sec(1)) { + if (fr_time_delta_gteq(fr_time_sub(now, pool->state.last_throttled), fr_time_delta_from_sec(1))) { complain = true; pool->state.last_throttled = now; @@ -610,14 +610,14 @@ static int connection_manage(fr_pool_t *pool, request_t *request, fr_pool_connec goto do_delete; } - if ((pool->lifetime > 0) && + if (fr_time_delta_ispos(pool->lifetime) && (fr_time_lt(fr_time_add(this->created, pool->lifetime), now))) { ROPTIONAL(RDEBUG2, DEBUG2, "Closing expired connection (%" PRIu64 "): Hit lifetime limit", this->number); goto do_delete; } - if ((pool->idle_timeout > 0) && + if (fr_time_delta_ispos(pool->idle_timeout) && (fr_time_lt(fr_time_add(this->last_released, pool->idle_timeout), now))) { ROPTIONAL(RINFO, INFO, "Closing connection (%" PRIu64 "): Hit idle_timeout, was idle for %pVs", this->number, fr_box_time_delta(fr_time_sub(now, this->last_released))); @@ -648,7 +648,7 @@ static int connection_check(fr_pool_t *pool, request_t *request) fr_time_t now = fr_time(); fr_pool_connection_t *this, *next; - if (fr_time_sub(now, pool->state.last_checked) < fr_time_delta_from_sec(1)) { + if (fr_time_delta_lt(fr_time_sub(now, pool->state.last_checked), fr_time_delta_from_sec(1))) { pthread_mutex_unlock(&pool->mutex); return 1; } @@ -749,9 +749,9 @@ static int connection_check(fr_pool_t *pool, request_t *request) * Decrease the delay for the next time we clean * up. */ - pool->state.next_delay >>= 1; - if (pool->state.next_delay == 0) pool->state.next_delay = 1; - pool->delay_interval += pool->state.next_delay; + pool->state.next_delay = fr_time_delta_wrap(fr_time_delta_unwrap(pool->state.next_delay) >> 1); + if (!fr_time_delta_ispos(pool->state.next_delay)) pool->state.next_delay = fr_time_delta_wrap(1); + pool->delay_interval = fr_time_delta_add(pool->delay_interval, pool->state.next_delay); goto manage_connections; } @@ -852,7 +852,7 @@ static void *connection_get_internal(fr_pool_t *pool, request_t *request, bool s /* * Rate-limit complaints. */ - if (fr_time_sub(now, pool->state.last_at_max) > fr_time_delta_from_sec(1)) { + if (fr_time_delta_gt(fr_time_sub(now, pool->state.last_at_max), fr_time_delta_from_sec(1))) { complain = true; pool->state.last_at_max = now; } @@ -1064,12 +1064,12 @@ fr_pool_t *fr_pool_init(TALLOC_CTX *ctx, FR_INTEGER_BOUND_CHECK("start", pool->start, <=, pool->max); FR_INTEGER_BOUND_CHECK("spare", pool->spare, <=, (pool->max - pool->min)); - if (pool->lifetime > 0) { + if (fr_time_delta_ispos(pool->lifetime)) { FR_TIME_DELTA_COND_CHECK("idle_timeout", pool->idle_timeout, - (pool->idle_timeout <= pool->lifetime), 0); + fr_time_delta_lteq(pool->idle_timeout, pool->lifetime), fr_time_delta_wrap(0)); } - if (pool->idle_timeout > 0) { + if (fr_time_delta_ispos(pool->idle_timeout)) { FR_TIME_DELTA_BOUND_CHECK("cleanup_interval", pool->cleanup_interval, <=, pool->idle_timeout); } @@ -1411,16 +1411,16 @@ void fr_pool_connection_release(fr_pool_t *pool, request_t *request, void *conn) * * These should only fire once per second. */ - if (pool->held_trigger_min && - (held < pool->held_trigger_min) && - (fr_time_sub(this->last_released, pool->state.last_held_min) >= fr_time_delta_from_sec(1))) { + if (fr_time_delta_ispos(pool->held_trigger_min) && + (fr_time_delta_lt(held, pool->held_trigger_min)) && + (fr_time_delta_gteq(fr_time_sub(this->last_released, pool->state.last_held_min), fr_time_delta_from_sec(1)))) { trigger_min = true; pool->state.last_held_min = this->last_released; } - if (pool->held_trigger_min && - (held > pool->held_trigger_max) && - (fr_time_sub(this->last_released, pool->state.last_held_max) >= fr_time_delta_from_sec(1))) { + if (fr_time_delta_ispos(pool->held_trigger_min) && + (fr_time_delta_gt(held, pool->held_trigger_max)) && + (fr_time_delta_gteq(fr_time_sub(this->last_released, pool->state.last_held_max), fr_time_delta_from_sec(1)))) { trigger_max = true; pool->state.last_held_max = this->last_released; } diff --git a/src/lib/server/pool.h b/src/lib/server/pool.h index a47684928a..9ea359f9ff 100644 --- a/src/lib/server/pool.h +++ b/src/lib/server/pool.h @@ -59,7 +59,7 @@ struct fr_pool_state_s { fr_time_t last_held_min; //!< Last time we warned about a low latency event. fr_time_t last_held_max; //!< Last time we warned about a high latency event. - uint32_t next_delay; //!< The next delay time. cleanup. Initialized to + fr_time_delta_t next_delay; //!< The next delay time. cleanup. Initialized to //!< cleanup_interval, and decays from there. uint64_t count; //!< Number of connections spawned over the lifetime diff --git a/src/lib/server/stats.c b/src/lib/server/stats.c index fa386a44a2..684c668198 100644 --- a/src/lib/server/stats.c +++ b/src/lib/server/stats.c @@ -158,7 +158,7 @@ void radius_stats_init(int flag) void radius_stats_ema(fr_stats_ema_t *ema, fr_time_t start, fr_time_t end) { - fr_time_delta_t tdiff; + int64_t tdiff; #ifdef WITH_STATS_DEBUG static int n = 0; #endif @@ -219,7 +219,7 @@ void fr_stats_bins(fr_stats_t *stats, fr_time_t start, fr_time_t end) if (fr_time_lt(end, start)) return; /* bad data */ diff = fr_time_sub(end, start); - if (diff >= fr_time_delta_from_sec(10)) { + if (fr_time_delta_gteq(diff, fr_time_delta_from_sec(10))) { stats->elapsed[7]++; } else { int i; diff --git a/src/lib/server/trunk.c b/src/lib/server/trunk.c index b8ef8327e0..4f44272195 100644 --- a/src/lib/server/trunk.c +++ b/src/lib/server/trunk.c @@ -2243,7 +2243,7 @@ void fr_trunk_request_free(fr_trunk_request_t **treq_to_free) /* * No cleanup delay, means cleanup immediately */ - if (trunk->conf.req_cleanup_delay == 0) { + if (!fr_time_delta_ispos(trunk->conf.req_cleanup_delay)) { treq->pub.state = FR_TRUNK_REQUEST_STATE_INIT; #ifndef NDEBUG @@ -3334,7 +3334,7 @@ static void _trunk_connection_on_connected(UNUSED fr_connection_t *conn, * Insert a timer to reconnect the * connection periodically. */ - if (trunk->conf.lifetime > 0) { + if (fr_time_delta_ispos(trunk->conf.lifetime)) { if (fr_event_timer_in(tconn, trunk->el, &tconn->lifetime_ev, trunk->conf.lifetime, _trunk_connection_lifetime_expire, tconn) < 0) { PERROR("Failed inserting connection reconnection timer event, halting connection"); @@ -3413,7 +3413,7 @@ static void _trunk_connection_on_closed(UNUSED fr_connection_t *conn, /* * Remove the reconnect event */ - if (trunk->conf.lifetime > 0) fr_event_timer_delete(&tconn->lifetime_ev); + if (fr_time_delta_ispos(trunk->conf.lifetime)) fr_event_timer_delete(&tconn->lifetime_ev); /* * Remove the I/O events @@ -4277,7 +4277,7 @@ static void _trunk_timer(fr_event_list_t *el, fr_time_t now, void *uctx) trunk_manage(trunk, now); - if (trunk->conf.manage_interval > 0) { + if (fr_time_delta_ispos(trunk->conf.manage_interval)) { if (fr_event_timer_in(trunk, el, &trunk->manage_ev, trunk->conf.manage_interval, _trunk_timer, trunk) < 0) { PERROR("Failed inserting trunk management event"); @@ -4549,7 +4549,7 @@ int fr_trunk_start(fr_trunk_t *trunk) if (trunk_connection_spawn(trunk, fr_time()) != 0) return -1; } - if (trunk->conf.manage_interval > 0) { + if (fr_time_delta_ispos(trunk->conf.manage_interval)) { /* * Insert the event timer to manage * the interval between managing connections. @@ -4594,7 +4594,7 @@ int fr_trunk_connection_manage_schedule(fr_trunk_t *trunk) { if (!trunk->started || !trunk->managing_connections) return 0; - if (fr_event_timer_in(trunk, trunk->el, &trunk->manage_ev, 0, _trunk_timer, trunk) < 0) { + if (fr_event_timer_in(trunk, trunk->el, &trunk->manage_ev, fr_time_delta_wrap(0), _trunk_timer, trunk) < 0) { PERROR("Failed inserting trunk management event"); return -1; } diff --git a/src/lib/tls/ctx.c b/src/lib/tls/ctx.c index 6963d19bf9..92a922e3b3 100644 --- a/src/lib/tls/ctx.c +++ b/src/lib/tls/ctx.c @@ -235,7 +235,7 @@ static int tls_ctx_load_cert_chain(SSL_CTX *ctx, fr_tls_chain_conf_t *chain) * the chain will next need refreshing. */ { - fr_unix_time_t expires_first = 0; + fr_unix_time_t expires_first = fr_unix_time_wrap(0); int ret; for (ret = SSL_CTX_set_current_cert(ctx, SSL_CERT_SET_FIRST); @@ -281,7 +281,8 @@ static int tls_ctx_load_cert_chain(SSL_CTX *ctx, fr_tls_chain_conf_t *chain) * the chain expires so we can use it for * runtime checks. */ - if ((expires_first == 0) || (expires_first > not_after)) expires_first = not_after; + if (!fr_unix_time_ispos(expires_first) || + (fr_unix_time_gt(expires_first, not_after))) expires_first = not_after; } /* diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index 0f20a5407a..5a0330695f 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -1669,17 +1669,17 @@ bool unlang_compile_actions(unlang_actions_t *actions, CONF_SECTION *action_cs, } if (module_retry) { - if (!actions->retry.irt) { + if (!fr_time_delta_ispos(actions->retry.irt)) { cf_log_err(csi, "initial_rtx_time MUST be non-zero for modules which support retries."); return false; } } else { - if (actions->retry.irt) { + if (fr_time_delta_ispos(actions->retry.irt)) { cf_log_err(csi, "initial_rtx_time MUST be zero, as only max_rtx_count and max_rtx_duration are used."); return false; } - if (!actions->retry.mrc && !actions->retry.mrd) { + if (!actions->retry.mrc && !fr_time_delta_ispos(actions->retry.mrd)) { disallow_retry_action = true; } } @@ -1703,7 +1703,9 @@ bool unlang_compile_actions(unlang_actions_t *actions, CONF_SECTION *action_cs, return false; } - if (!actions->retry.irt && !actions->retry.mrc && !actions->retry.mrd) { + if (!fr_time_delta_ispos(actions->retry.irt) && + !actions->retry.mrc && + !fr_time_delta_ispos(actions->retry.mrd)) { cf_log_err(csi, "Cannot use a '%s = retry' action without a 'retry { ... }' section.", fr_table_str_by_value(mod_rcode_table, i, "???")); return false; @@ -4121,7 +4123,7 @@ void unlang_frame_perf_cleanup(unlang_t const *instruction) t = &unlang_thread_array[instruction->number]; - t->cpu_time += fr_time_sub(fr_time(), t->enter); + t->cpu_time = fr_time_add(t->cpu_time, fr_time_sub(fr_time(), t->enter)); } @@ -4161,7 +4163,8 @@ static void unlang_perf_dump(fr_log_t *log, unlang_t const *instruction, int dep t = &unlang_thread_array[instruction->number]; - fr_log(log, L_DBG, file, line, "count=%" PRIu64 " cpu_time=%" PRIu64 "\n", t->use_count, t->cpu_time); + fr_log(log, L_DBG, file, line, "count=%" PRIu64 " cpu_time=%" PRIu64, + t->use_count, fr_time_delta_unwrap(t->cpu_time)); if (g->children) { unlang_t *child; @@ -4176,7 +4179,7 @@ static void unlang_perf_dump(fr_log_t *log, unlang_t const *instruction, int dep fr_log(log, L_DBG, file, line, "%.*s", depth, unlang_spaces); } - fr_log(log, L_DBG, file, line, "}\n"); + fr_log(log, L_DBG, file, line, "}"); } } diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index aaba2dbc9b..2bf729d7ab 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -282,7 +282,7 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t * timer is automatically freed when the * frame is cleaned up. */ - if (instruction->actions.retry.mrd) { + if (fr_time_delta_ispos(instruction->actions.retry.mrd)) { retry->timeout = fr_time_add(fr_time(), instruction->actions.retry.mrd); if (fr_event_timer_at(retry, unlang_interpret_event_list(request), &retry->ev, retry->timeout, diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index 2998ba5d8f..def90ad2de 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -949,7 +949,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, * If we're doing retries, remember when we started * running the module. */ - if (frame->instruction->actions.retry.irt) now = fr_time(); + if (fr_time_delta_ispos(frame->instruction->actions.retry.irt)) now = fr_time(); caller = request->module; request->module = mc->instance->name; @@ -994,7 +994,7 @@ static unlang_action_t unlang_module(rlm_rcode_t *p_result, request_t *request, /* * If we have retry timers, then start the retries. */ - if (frame->instruction->actions.retry.irt) { + if (fr_time_delta_ispos(frame->instruction->actions.retry.irt)) { fr_assert(fr_time_gt(now, fr_time_wrap(0))); (void) fr_retry_init(&state->retry, now, &frame->instruction->actions.retry); /* can't fail */ diff --git a/src/lib/unlang/subrequest_child.c b/src/lib/unlang/subrequest_child.c index 8eee8ef28b..274a8a327c 100644 --- a/src/lib/unlang/subrequest_child.c +++ b/src/lib/unlang/subrequest_child.c @@ -89,22 +89,22 @@ int unlang_subrequest_lifetime_set(request_t *request) */ vp = fr_pair_find_by_da(&request->control_pairs, request_attr_request_lifetime, 0); if (!vp || (vp->vp_uint32 > 0)) { - fr_time_delta_t when = 0; + fr_time_delta_t when = fr_time_delta_wrap(0); const fr_event_timer_t **ev_p; if (!vp) { - when += fr_time_delta_from_sec(30); /* default to 30s if not set */ + when = fr_time_delta_add(when, fr_time_delta_from_sec(30)); /* default to 30s if not set */ } else if (vp->vp_uint32 > 3600) { RWDEBUG("Request-Timeout can be no more than 3600 seconds"); - when += fr_time_delta_from_sec(3600); + when = fr_time_delta_add(when, fr_time_delta_from_sec(3600)); } else if (vp->vp_uint32 < 5) { RWDEBUG("Request-Timeout can be no less than 5 seconds"); - when += fr_time_delta_from_sec(5); + when = fr_time_delta_add(when ,fr_time_delta_from_sec(5)); } else { - when += fr_time_delta_from_sec(vp->vp_uint32); + when = fr_time_delta_from_sec(vp->vp_uint32); } ev_p = talloc_size(request, sizeof(*ev_p)); diff --git a/src/lib/unlang/tmpl.c b/src/lib/unlang/tmpl.c index 0d0d8c3ebd..3881008f7c 100644 --- a/src/lib/unlang/tmpl.c +++ b/src/lib/unlang/tmpl.c @@ -352,7 +352,7 @@ int unlang_tmpl_push(TALLOC_CTX *ctx, fr_value_box_list_t *out, request_t *reque * Default to something sensible * instead of locking the same indefinitely. */ - if (!state->args.exec.timeout) state->args.exec.timeout = fr_time_delta_from_sec(EXEC_TIMEOUT); + if (!fr_time_delta_ispos(state->args.exec.timeout)) state->args.exec.timeout = fr_time_delta_from_sec(EXEC_TIMEOUT); fr_value_box_list_init(&state->box); diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index 29d3b63449..4befd63fb1 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -50,6 +50,9 @@ fr_table_num_ordered_t const date_precision_table[] = { { L("milliseconds"), FR_TIME_RES_MSEC }, { L("ms"), FR_TIME_RES_MSEC }, + { L("centiseconds"), FR_TIME_RES_CSEC }, + { L("cs"), FR_TIME_RES_CSEC }, + { L("seconds"), FR_TIME_RES_SEC }, { L("s"), FR_TIME_RES_SEC } diff --git a/src/lib/util/event.c b/src/lib/util/event.c index 0c77f38bfb..b6612256df 100644 --- a/src/lib/util/event.c +++ b/src/lib/util/event.c @@ -1823,7 +1823,7 @@ unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t time * is to use a kqueue instance to monitor * for process exit. */ - if ((timeout > 0) && fr_dlist_num_elements(&el->pid_to_reap)) { + if (fr_time_delta_ispos(timeout) && fr_dlist_num_elements(&el->pid_to_reap)) { int status; struct kevent evset; int waiting = 0; @@ -1874,8 +1874,7 @@ unsigned int fr_event_list_reap_signal(fr_event_list_t *el, fr_time_delta_t time struct kevent kev; int ret; - ret = kevent(kq, NULL, 0, &kev, 1, - &fr_time_delta_to_timespec(fr_time_sub(end, now))); + ret = kevent(kq, NULL, 0, &kev, 1, &fr_time_delta_to_timespec(fr_time_sub(end, now))); switch (ret) { default: EVENT_DEBUG("%p - %s - Reaper tmp loop error %s, forcing process reaping", @@ -2183,7 +2182,7 @@ int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait) * By default we wait for 0ns, which means returning * immediately from kevent(). */ - when = 0; + when = fr_time_delta_wrap(0); wake = &when; el->now = now; @@ -2222,9 +2221,9 @@ int fr_event_corral(fr_event_list_t *el, fr_time_t now, bool wait) for (pre = fr_dlist_head(&el->pre_callbacks); pre != NULL; pre = fr_dlist_next(&el->pre_callbacks, pre)) { - if (pre->callback(now, wake ? *wake : 0, pre->uctx) > 0) { + if (pre->callback(now, wake ? *wake : fr_time_delta_wrap(0), pre->uctx) > 0) { wake = &when; - when = 0; + when = fr_time_delta_wrap(0); } } } @@ -2575,7 +2574,7 @@ static int _event_list_free(fr_event_list_t *el) while ((ev = fr_lst_peek(el->times)) != NULL) fr_event_timer_delete(&ev); - fr_event_list_reap_signal(el, 0, SIGKILL); + fr_event_list_reap_signal(el, fr_time_delta_wrap(0), SIGKILL); talloc_free_children(el); diff --git a/src/lib/util/heap_tests.c b/src/lib/util/heap_tests.c index 0a6b839ad8..dec118bdcd 100644 --- a/src/lib/util/heap_tests.c +++ b/src/lib/util/heap_tests.c @@ -271,9 +271,9 @@ static void heap_cycle(void) end = fr_time(); TEST_MSG_ALWAYS("\ncycle size: %d\n", HEAP_CYCLE_SIZE); - TEST_MSG_ALWAYS("insert: %2.2f s\n", fr_time_sub(start_remove, start_insert) / (double)NSEC); - TEST_MSG_ALWAYS("extract: %2.2f s\n", fr_time_sub(start_swap, start_remove)/ (double)NSEC); - TEST_MSG_ALWAYS("swap: %2.2f s\n", fr_time_sub(end, start_swap) / (double)NSEC); + TEST_MSG_ALWAYS("insert: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_remove, start_insert)) / (double)NSEC); + TEST_MSG_ALWAYS("extract: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_swap, start_remove))/ (double)NSEC); + TEST_MSG_ALWAYS("swap: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(end, start_swap)) / (double)NSEC); talloc_free(hp); free(array); diff --git a/src/lib/util/lst_tests.c b/src/lib/util/lst_tests.c index fdd46963c5..aa2eff8db8 100644 --- a/src/lib/util/lst_tests.c +++ b/src/lib/util/lst_tests.c @@ -375,9 +375,9 @@ static void lst_cycle(void) end = fr_time(); TEST_MSG_ALWAYS("\ncycle size: %d\n", LST_CYCLE_SIZE); - TEST_MSG_ALWAYS("insert: %2.2f s\n", fr_time_sub(start_remove, start_insert) / (double)NSEC); - TEST_MSG_ALWAYS("extract: %2.2f s\n", fr_time_sub(start_swap, start_remove) / (double)NSEC); - TEST_MSG_ALWAYS("swap: %2.2f s\n", fr_time_sub(end, start_swap) / (double)NSEC); + TEST_MSG_ALWAYS("insert: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_remove, start_insert)) / (double)NSEC); + TEST_MSG_ALWAYS("extract: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(start_swap, start_remove)) / (double)NSEC); + TEST_MSG_ALWAYS("swap: %.2fs\n", fr_time_delta_unwrap(fr_time_sub(end, start_swap)) / (double)NSEC); talloc_free(lst); free(values); @@ -470,10 +470,10 @@ static void queue_cmp(unsigned int count) end_pop = fr_time(); TEST_MSG_ALWAYS("\nlst size: %u\n", count); - TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_sub(end_alloc, start_alloc) / 1000); - TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_sub(end_insert, start_insert) / 1000); - TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_sub(end_pop_first, start_pop) / 1000); - TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_sub(end_pop, start_pop) / 1000); + TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000); + TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000); + TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000); + TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000); talloc_free(lst); } @@ -506,10 +506,10 @@ static void queue_cmp(unsigned int count) end_pop = fr_time(); TEST_MSG_ALWAYS("\nheap size: %u\n", count); - TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_sub(end_alloc, start_alloc) / 1000); - TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_sub(end_insert, start_insert) / 1000); - TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_sub(end_pop_first, start_pop) / 1000); - TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_sub(end_pop, start_pop) / 1000); + TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000); + TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000); + TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000); + TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000); talloc_free(heap); } @@ -538,10 +538,10 @@ static void queue_cmp(unsigned int count) end_pop = fr_time(); TEST_MSG_ALWAYS("\narray size: %u\n", count); - TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_sub(end_alloc, start_alloc) / 1000); - TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_sub(end_insert, start_insert) / 1000); - TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_sub(end_pop_first, start_pop) / 1000); - TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_sub(end_pop, start_pop) / 1000); + TEST_MSG_ALWAYS("alloc: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_alloc, start_alloc)) / 1000); + TEST_MSG_ALWAYS("insert: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_insert, start_insert)) / 1000); + TEST_MSG_ALWAYS("pop-first: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop_first, start_pop)) / 1000); + TEST_MSG_ALWAYS("pop: %"PRIu64" μs\n", fr_time_delta_unwrap(fr_time_sub(end_pop, start_pop)) / 1000); talloc_free(array); } diff --git a/src/lib/util/misc.c b/src/lib/util/misc.c index 9b50678290..c7d9d55613 100644 --- a/src/lib/util/misc.c +++ b/src/lib/util/misc.c @@ -579,34 +579,35 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re { int i; fr_unix_time_t t; + int64_t tmp; struct tm *tm, s_tm; char buf[64]; char *p; char *f[4]; char *tail = NULL; - fr_time_delta_t gmtoff = 0; + fr_time_delta_t gmtoff = fr_time_delta_wrap(0); /* * Test for unix timestamp, which is just a number and * nothing else. */ - t = strtoul(date_str, &tail, 10); + tmp = strtoul(date_str, &tail, 10); if (*tail == '\0') { switch (hint) { case FR_TIME_RES_SEC: - t = fr_unix_time_from_sec(t); + t = fr_unix_time_from_sec(tmp); break; case FR_TIME_RES_MSEC: - t = fr_unix_time_from_msec(t); + t = fr_unix_time_from_msec(tmp); break; case FR_TIME_RES_USEC: - t = fr_unix_time_from_usec(t); + t = fr_unix_time_from_usec(tmp); break; case FR_TIME_RES_NSEC: - t = fr_unix_time_from_nsec(t); + t = fr_unix_time_from_nsec(tmp); break; default: @@ -632,12 +633,12 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re * Z | (+/-)%H:%M time zone offset * */ - if ((t > 1900) && (t < 3000) && *tail == '-') { + if ((tmp > 1900) && (tmp < 3000) && *tail == '-') { unsigned long subseconds; int tz, tz_hour, tz_min; p = tail + 1; - s_tm.tm_year = t - 1900; /* 'struct tm' starts years in 1900 */ + s_tm.tm_year = tmp - 1900; /* 'struct tm' starts years in 1900 */ if (get_part(&p, &s_tm.tm_mon, 1, 13, '-', "month") < 0) return -1; s_tm.tm_mon--; /* ISO is 1..12, where 'struct tm' is 0..11 */ @@ -716,9 +717,7 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re done: tm->tm_gmtoff = tz; - *date = fr_unix_time_from_tm(tm); - *date += subseconds; - + *date = fr_unix_time_add(fr_unix_time_from_tm(tm), fr_time_delta_wrap(subseconds)); return 0; } @@ -892,7 +891,7 @@ int fr_unix_time_from_str(fr_unix_time_t *date, char const *date_str, fr_time_re tm->tm_min = atoi(f[1]); } - *date = fr_unix_time_from_tm(tm) + gmtoff; + *date = fr_unix_time_add(fr_unix_time_from_tm(tm), gmtoff); return 0; } diff --git a/src/lib/util/pair_list_perf_test.c b/src/lib/util/pair_list_perf_test.c index e504d32120..f4e2e3714e 100644 --- a/src/lib/util/pair_list_perf_test.c +++ b/src/lib/util/pair_list_perf_test.c @@ -305,7 +305,7 @@ static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned unsigned int i, j; fr_pair_t *new_vp; fr_time_t start, end; - fr_time_delta_t used = 0; + fr_time_delta_t used = fr_time_delta_wrap(0); size_t input_count = talloc_array_length(source_vps); fr_pair_list_init(&test_vps); @@ -326,7 +326,7 @@ static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned start = fr_time(); fr_pair_append(&test_vps, new_vp); end = fr_time(); - used += fr_time_sub(end, start); + used = fr_time_delta_add(used, fr_time_sub(end, start)); } TEST_CHECK(fr_pair_list_len(&test_vps) == len); fr_pair_list_free(&test_vps); @@ -334,8 +334,8 @@ static void do_test_fr_pair_append(unsigned int len, unsigned int perc, unsigned TEST_MSG_ALWAYS("repetitions=%d", reps); TEST_MSG_ALWAYS("perc_rep=%d", perc); TEST_MSG_ALWAYS("list_length=%d", len); - TEST_MSG_ALWAYS("used=%"PRId64, used); - TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/((double)used / NSEC)); + TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used)); + TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC)); } static void do_test_fr_pair_find_by_da(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[]) @@ -344,7 +344,7 @@ static void do_test_fr_pair_find_by_da(unsigned int len, unsigned int perc, unsi unsigned int i, j; fr_pair_t *new_vp; fr_time_t start, end; - fr_time_delta_t used = 0; + fr_time_delta_t used = fr_time_delta_wrap(0); fr_dict_attr_t const *da; size_t input_count = talloc_array_length(source_vps); @@ -370,15 +370,15 @@ static void do_test_fr_pair_find_by_da(unsigned int len, unsigned int perc, unsi start = fr_time(); (void) fr_pair_find_by_da(&test_vps, da, 0); end = fr_time(); - used += fr_time_sub(end, start); + used = fr_time_delta_add(used, fr_time_sub(end, start)); } } fr_pair_list_free(&test_vps); TEST_MSG_ALWAYS("repetitions=%d", reps); TEST_MSG_ALWAYS("perc_rep=%d", perc); TEST_MSG_ALWAYS("list_length=%d", len); - TEST_MSG_ALWAYS("used=%"PRId64, used); - TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/((double)used / NSEC)); + TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used)); + TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC)); } static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[]) @@ -387,7 +387,7 @@ static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int r unsigned int i, j, nth_item; fr_pair_t *new_vp; fr_time_t start, end; - fr_time_delta_t used = 0; + fr_time_delta_t used = fr_time_delta_wrap(0); fr_dict_attr_t const *da; size_t input_count = talloc_array_length(source_vps); @@ -416,15 +416,15 @@ static void do_test_find_nth(unsigned int len, unsigned int perc, unsigned int r start = fr_time(); (void) fr_pair_find_by_da(&test_vps, da, nth_item); end = fr_time(); - used += fr_time_sub(end, start); + used = fr_time_delta_add(used, fr_time_sub(end, start)); } } fr_pair_list_free(&test_vps); TEST_MSG_ALWAYS("repetitions=%d", reps); TEST_MSG_ALWAYS("perc_rep=%d", perc); TEST_MSG_ALWAYS("list_length=%d", len); - TEST_MSG_ALWAYS("used=%"PRId64, used); - TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/((double)used / NSEC)); + TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used)); + TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC)); } static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsigned int reps, fr_pair_t *source_vps[]) @@ -433,7 +433,7 @@ static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsig unsigned int i, j; fr_pair_t *new_vp; fr_time_t start, end; - fr_time_delta_t used = 0; + fr_time_delta_t used = fr_time_delta_wrap(0); size_t input_count = talloc_array_length(source_vps); fr_pair_list_init(&test_vps); @@ -448,14 +448,14 @@ static void do_test_fr_pair_list_free(unsigned int len, unsigned int perc, unsig start = fr_time(); fr_pair_list_free(&test_vps); end = fr_time(); - used += fr_time_sub(end, start); + used = fr_time_delta_add(used, fr_time_sub(end, start)); } fr_pair_list_free(&test_vps); TEST_MSG_ALWAYS("repetitions=%d", reps); TEST_MSG_ALWAYS("perc_rep=%d", perc); TEST_MSG_ALWAYS("list_length=%d", len); - TEST_MSG_ALWAYS("used=%"PRId64, used); - TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/((double)used / NSEC)); + TEST_MSG_ALWAYS("used=%"PRId64, fr_time_delta_unwrap(used)); + TEST_MSG_ALWAYS("per_sec=%0.0lf", (reps * len)/(fr_time_delta_unwrap(used) / (double)NSEC)); } #define test_func(_func, _count, _perc, _source_vps) \ diff --git a/src/lib/util/retry.c b/src/lib/util/retry.c index 65f4f3b298..fee9543aa6 100644 --- a/src/lib/util/retry.c +++ b/src/lib/util/retry.c @@ -35,8 +35,9 @@ RCSID("$Id$") */ int fr_retry_init(fr_retry_t *r, fr_time_t now, fr_retry_config_t const *config) { - fr_time_delta_t scale, rt; - uint128_t delay; + uint64_t scale; + fr_time_delta_t rt; + uint128_t delay; memset(r, 0, sizeof(*r)); @@ -52,11 +53,11 @@ int fr_retry_init(fr_retry_t *r, fr_time_t now, fr_retry_config_t const *config) * = IRT * (1 + RAND) */ scale = fr_rand(); - scale += ((fr_time_delta_t) 1) << 32; /* multiple it by 1 * 2^32 */ - scale -= ((fr_time_delta_t) 1) << 31; /* scale it -2^31..+2^31 */ + scale += ((uint64_t) 1) << 32; /* multiple it by 1 * 2^32 */ + scale -= ((uint64_t) 1) << 31; /* scale it -2^31..+2^31 */ - delay = uint128_mul64(scale, r->config->irt); - rt = uint128_to_64(uint128_rshift(delay, 32)); + delay = uint128_mul64(scale, fr_time_delta_unwrap(r->config->irt)); + rt = fr_time_delta_wrap(uint128_to_64(uint128_rshift(delay, 32))); r->rt = rt; r->next = fr_time_add(now, rt); @@ -75,8 +76,9 @@ int fr_retry_init(fr_retry_t *r, fr_time_t now, fr_retry_config_t const *config) */ fr_retry_state_t fr_retry_next(fr_retry_t *r, fr_time_t now) { - fr_time_delta_t scale, rt; - uint128_t delay; + uint64_t scale; + fr_time_delta_t rt; + uint128_t delay; /* * Increment retransmission counter @@ -95,7 +97,7 @@ redo: /* * Cap delay at MRD */ - if (r->config->mrd) { + if (fr_time_delta_ispos(r->config->mrd)) { fr_time_t end; end = fr_time_add(r->start, r->config->mrd); @@ -116,11 +118,11 @@ redo: * = RTprev * (2 + RAND) */ scale = fr_rand(); - scale -= ((fr_time_delta_t) 1) << 31; /* scale it -2^31..+2^31 */ - scale += ((fr_time_delta_t) 1) << 33; /* multiple it by 2 * 2^32 */ + scale -= ((uint64_t) 1) << 31; /* scale it -2^31..+2^31 */ + scale += ((uint64_t) 1) << 33; /* multiple it by 2 * 2^32 */ - delay = uint128_mul64(scale, r->rt); - rt = uint128_to_64(uint128_rshift(delay, 32)); + delay = uint128_mul64(scale, fr_time_delta_unwrap(r->rt)); + rt = fr_time_delta_wrap(uint128_to_64(uint128_rshift(delay, 32))); /* * Cap delay at MRT. @@ -128,13 +130,13 @@ redo: * RT = MRT + RAND * MRT * = MRT * (1 + RAND) */ - if (r->config->mrt && (rt > r->config->mrt)) { + if (fr_time_delta_ispos(r->config->mrt) && (fr_time_delta_gt(rt, r->config->mrt))) { scale = fr_rand(); - scale -= ((fr_time_delta_t) 1) << 31; /* scale it -2^31..+2^31 */ - scale += ((fr_time_delta_t) 1) << 32; /* multiple it by 1 * 2^32 */ + scale -= ((uint64_t) 1) << 31; /* scale it -2^31..+2^31 */ + scale += ((uint64_t) 1) << 32; /* multiple it by 1 * 2^32 */ - delay = uint128_mul64(scale, r->config->mrt); - rt = uint128_to_64(uint128_rshift(delay, 32)); + delay = uint128_mul64(scale, fr_time_delta_unwrap(r->config->mrt)); + rt = fr_time_delta_wrap(uint128_to_64(uint128_rshift(delay, 32))); } /* @@ -158,7 +160,7 @@ redo: * i.e. if we weren't serviced for one event, just skip * it, and go to the next one. */ - if (fr_time_lt(fr_time_add(r->next, (rt / 2)), now)) goto redo; + if (fr_time_lt(fr_time_add(r->next, fr_time_delta_wrap((fr_time_delta_unwrap(rt) / 2))), now)) goto redo; return FR_RETRY_CONTINUE; } diff --git a/src/lib/util/retry.h b/src/lib/util/retry.h index 59b152b3ed..021d380fd6 100644 --- a/src/lib/util/retry.h +++ b/src/lib/util/retry.h @@ -36,7 +36,7 @@ typedef struct { uint32_t mrc; //!< Maximum retransmission count } fr_retry_config_t; -#define RETRY_INIT { 0, 0, 0, 0 } +#define RETRY_INIT { fr_time_delta_wrap(0), fr_time_delta_wrap(0), fr_time_delta_wrap(0), 0 } typedef struct { fr_retry_config_t const *config; //!< master configuration diff --git a/src/lib/util/socket.c b/src/lib/util/socket.c index 1f382177c5..a6c25beeab 100644 --- a/src/lib/util/socket.c +++ b/src/lib/util/socket.c @@ -611,7 +611,7 @@ int fr_socket_wait_for_connect(int sockfd, fr_time_delta_t timeout) return 0; case 0: /* timeout */ - if (!fr_cond_assert(timeout)) return -1; + if (!fr_cond_assert(fr_time_delta_ispos(timeout))) return -1; fr_strerror_printf("Connection timed out after %pVs", fr_box_time_delta(timeout)); return -2; diff --git a/src/lib/util/strerror_tests.c b/src/lib/util/strerror_tests.c index d33e9aa74f..23e6c2d661 100644 --- a/src/lib/util/strerror_tests.c +++ b/src/lib/util/strerror_tests.c @@ -195,7 +195,7 @@ static void strerror_printf_benchmark(void) } stop = fr_time(); - rate = (uint64_t)((float)NSEC / (fr_time_sub(stop, start) / 100000)); + rate = (uint64_t)((float)NSEC / (fr_time_delta_unwrap(fr_time_sub(stop, start)) / 100000)); printf("printf pop rate %" PRIu64 "\n", rate); /* shared runners are terrible for performance tests */ @@ -219,7 +219,7 @@ static void strerror_const_benchmark(void) } stop = fr_time(); - rate = (uint64_t)((float)NSEC / (fr_time_sub(stop, start) / 100000)); + rate = (uint64_t)((float)NSEC / (fr_time_delta_unwrap(fr_time_sub(stop, start)) / 100000)); printf("const pop rate %" PRIu64 "\n", rate); /* shared runners are terrible for performance tests */ diff --git a/src/lib/util/time.c b/src/lib/util/time.c index 699f3ec8a1..9434b7b35c 100644 --- a/src/lib/util/time.c +++ b/src/lib/util/time.c @@ -99,8 +99,8 @@ int fr_time_sync(void) if (clock_gettime(CLOCK_MONOTONIC, &ts_monotime) < 0) return -1; atomic_store_explicit(&our_realtime, - fr_time_delta_from_timespec(&ts_realtime) - - (fr_time_delta_from_timespec(&ts_monotime) - our_epoch), + fr_time_delta_unwrap(fr_time_delta_from_timespec(&ts_realtime)) - + (fr_time_delta_unwrap(fr_time_delta_from_timespec(&ts_monotime)) - our_epoch), memory_order_release); now = ts_realtime.tv_sec; @@ -117,7 +117,7 @@ int fr_time_sync(void) monotime = mach_absolute_time(); atomic_store_explicit(&our_realtime, - fr_time_delta_from_timeval(&tv_realtime) - + fr_time_delta_unwrap(fr_time_delta_from_timeval(&tv_realtime)) - (monotime - our_mach_epoch) * (timebase.numer / timebase.denom, memory_order_release)); @@ -156,7 +156,7 @@ int fr_time_start(void) struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) return -1; - our_epoch = fr_time_delta_from_timespec(&ts); + our_epoch = fr_time_delta_unwrap(fr_time_delta_from_timespec(&ts)); } #else /* __MACH__ is defined */ mach_timebase_info(&timebase); @@ -182,7 +182,7 @@ int fr_time_start(void) */ int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta) { - *delta = 0; + *delta = fr_time_delta_wrap(0); if ((strcmp(tz, "UTC") == 0) || (strcmp(tz, "GMT") == 0)) { @@ -193,12 +193,12 @@ int fr_time_delta_from_time_zone(char const *tz, fr_time_delta_t *delta) * Our local time zone OR time zone with daylight savings. */ if (tz_names[0] && (strcmp(tz, tz_names[0]) == 0)) { - *delta = gmtoff[0]; + *delta = fr_time_delta_wrap(gmtoff[0]); return 0; } if (tz_names[1] && (strcmp(tz, tz_names[1]) == 0)) { - *delta = gmtoff[1]; + *delta = fr_time_delta_wrap(gmtoff[1]); return 0; } @@ -324,17 +324,17 @@ int fr_time_delta_from_str(fr_time_delta_t *out, char const *in, fr_time_res_t h } if ((p[0] == 'm') && !p[1]) { - *out = sec * 60 * NSEC; + *out = fr_time_delta_from_sec(sec * 60); return 0; } if ((p[0] == 'h') && !p[1]) { - *out = sec * 3600 * NSEC; + *out = fr_time_delta_from_sec(sec * 3600); return 0; } if ((p[0] == 'd') && !p[1]) { - *out = sec * 86400 * NSEC; + *out = fr_time_delta_from_sec(sec * 86400); return 0; } @@ -371,9 +371,9 @@ int fr_time_delta_from_str(fr_time_delta_t *out, char const *in, fr_time_res_t h if (*end) goto failed; if (negative) { - *out = (minutes * 60 - sec) * NSEC; + *out = fr_time_delta_from_sec(minutes * 60 - sec); } else { - *out = (minutes * 60 + sec) * NSEC; + *out = fr_time_delta_from_sec(minutes * 60 + sec); } return 0; @@ -438,7 +438,7 @@ done: sec += subsec; } - *out = sec; + *out = fr_time_delta_wrap(sec); return 0; } @@ -508,30 +508,30 @@ void fr_time_elapsed_update(fr_time_elapsed_t *elapsed, fr_time_t start, fr_time fr_time_delta_t delay; if (fr_time_gteq(start, end)) { - delay = 0; + delay = fr_time_delta_wrap(0); } else { delay = fr_time_sub(end, start); } - if (delay < 1000) { /* microseconds */ + if (fr_time_delta_lt(delay, fr_time_delta_wrap(1000))) { /* microseconds */ elapsed->array[0]++; - } else if (delay < 10000) { + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(10000))) { elapsed->array[1]++; - } else if (delay < 100000) { + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(100000))) { elapsed->array[2]++; - } else if (delay < 1000000) { /* milliseconds */ + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(1000000))) { /* milliseconds */ elapsed->array[3]++; - } else if (delay < 10000000) { + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(10000000))) { elapsed->array[4]++; - } else if (delay < (fr_time_delta_t) 100000000) { + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(100000000))) { elapsed->array[5]++; - } else if (delay < (fr_time_delta_t) 1000000000) { /* seconds */ + } else if (fr_time_delta_lt(delay, fr_time_delta_wrap(1000000000))) { /* seconds */ elapsed->array[6]++; } else { /* tens of seconds or more */ @@ -605,16 +605,19 @@ int64_t fr_time_delta_scale(fr_time_delta_t delta, fr_time_res_t hint) { switch (hint) { case FR_TIME_RES_SEC: - return delta / NSEC; + return fr_time_delta_to_sec(delta); + + case FR_TIME_RES_CSEC: + return fr_time_delta_to_csec(delta); case FR_TIME_RES_MSEC: - return delta / 1000000; + return fr_time_delta_to_msec(delta); case FR_TIME_RES_USEC: - return delta / 1000; + return fr_time_delta_to_usec(delta); case FR_TIME_RES_NSEC: - return delta; + return fr_time_delta_unwrap(delta); default: break; diff --git a/src/lib/util/time.h b/src/lib/util/time.h index 69e30803e1..b63be194ab 100644 --- a/src/lib/util/time.h +++ b/src/lib/util/time.h @@ -54,6 +54,25 @@ typedef struct fr_time_s { ///< entries. } fr_time_t; +#define fr_time_max() (fr_time_t){ .value = INT64_MAX } +#define fr_time_min() (fr_time_t){ .value = INT64_MIN } +#define fr_time_wrap(_time) (fr_time_t){ .value = (_time) } +static inline int64_t fr_time_unwrap(fr_time_t time) { return time.value; } /* func to stop mixing with fr_time_delta_t */ + +/** A time delta, a difference in time measured in nanoseconds. + * + * This is easier to distinguish where server epoch time is being + * used, and where relative time is being used. + */ +typedef struct fr_time_delta_s { + int64_t value; +} fr_time_delta_t; + +#define fr_time_delta_max() (fr_time_delta_t){ .value = INT64_MAX } +#define fr_time_delta_min() (fr_time_delta_t){ .value = INT64_MIN } +#define fr_time_delta_wrap(_time) (fr_time_delta_t){ .value = (_time) } +static inline int64_t fr_time_delta_unwrap(fr_time_delta_t time) { return time.value; } /* func to stop mixing with fr_time_t */ + /** "Unix" time. This is the time in nanoseconds since midnight January 1, 1970 * * Note that it is *unsigned*, as we don't use dates before 1970. Having it @@ -65,24 +84,35 @@ typedef struct fr_time_s { * parties idea of time is correct (or if ours is wrong), so we don't * mangle unix time based on clock skew. */ -typedef uint64_t fr_unix_time_t; +typedef struct fr_unix_time_s { + uint64_t value; +} fr_unix_time_t; -/** A time delta, a difference in time measured in nanoseconds. +#define fr_unix_time_max() (fr_unix_time_t){ .value = UINT64_MAX } +#define fr_unix_time_min() (fr_unix_time_t){ .value = 0 } +#define fr_unix_time_wrap(_time) (fr_unix_time_t){ .value = (_time) } +static inline uint64_t fr_unix_time_unwrap(fr_unix_time_t time) { return time.value; } /* func to stop mixing with fr_time_t */ + +/** @name fr_time_t arithmetic and comparison macros * - * This is easier to distinguish where server epoch time is being - * used, and where relative time is being used. + * We wrap the 64bit signed time value in a struct to prevent misuse. + * + * The macros below allow basic arithmetic and comparisons to be performed. + * @{ */ -typedef int64_t fr_time_delta_t; - -#define fr_time_max() (fr_time_t){ .value = INT64_MAX } -#define fr_time_wrap(_time) (fr_time_t){ .value = (_time) } -#define fr_time_unwrap(_time) (_time).value - /* Don't add fr_time_add_time_time, it's almost always a type error */ -static inline fr_time_t fr_time_add_time_delta(fr_time_t a, fr_time_delta_t b) { return fr_time_wrap(fr_time_unwrap(a) + b); } -static inline fr_time_t fr_time_add_delta_time(fr_time_delta_t a, fr_time_t b) { return fr_time_wrap(a + fr_time_unwrap(b)); } -static inline fr_time_delta_t fr_time_add_delta_delta(fr_time_delta_t a, fr_time_delta_t b) { return a + b; } +static inline fr_time_t fr_time_add_time_delta(fr_time_t a, fr_time_delta_t b) { return fr_time_wrap(fr_time_unwrap(a) + fr_time_delta_unwrap(b)); } +static inline fr_time_t fr_time_add_delta_time(fr_time_delta_t a, fr_time_t b) { return fr_time_wrap(fr_time_delta_unwrap(a) + fr_time_unwrap(b)); } +/** Add a time/time delta together + * + * Types may either be: + * - fr_time_add((fr_time_t), (fr_time_delta_t)) + * - fr_time_add((fr_time_delta_t), (fr_time_delta_t)) + * + * Adding two time values together is most likely an error. + * Adding two time_delta values together can be done with #fr_time_delta_add. + */ #define fr_time_add(_a, _b) \ _Generic(_a, \ fr_time_t : _Generic(_b, \ @@ -90,15 +120,21 @@ static inline fr_time_delta_t fr_time_add_delta_delta(fr_time_delta_t a, fr_time ), \ fr_time_delta_t : _Generic(_b, \ fr_time_t : fr_time_add_delta_time, \ - fr_time_delta_t : fr_time_add_delta_delta \ + fr_time_delta_t : fr_time_delta_add \ ) \ )(_a, _b) -static inline fr_time_delta_t fr_time_sub_time_time(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) - fr_time_unwrap(b); } -static inline fr_time_t fr_time_sub_time_delta(fr_time_t a, fr_time_delta_t b) { return fr_time_wrap(fr_time_unwrap(a) - b); } +static inline fr_time_delta_t fr_time_sub_time_time(fr_time_t a, fr_time_t b) { return fr_time_delta_wrap(fr_time_unwrap(a) - fr_time_unwrap(b)); } +static inline fr_time_t fr_time_sub_time_delta(fr_time_t a, fr_time_delta_t b) { return fr_time_wrap(fr_time_unwrap(a) - fr_time_delta_unwrap(b)); } /** Subtract one time from another * + * Types may either be: + * - fr_time_sub((fr_time_t), (fr_time_t)) - Produces a #fr_time_delta_t + * - fr_time_sub((fr_time_t), (fr_time_delta_t)) - Produces a #fr_time_t + * + * Subtracting time from a delta is most likely an error. + * Subtracting two time_delta values can be done with #fr_time_delta_sub */ #define fr_time_sub(_a, _b) \ _Generic(_a, \ @@ -108,17 +144,107 @@ static inline fr_time_t fr_time_sub_time_delta(fr_time_t a, fr_time_delta_t b) { ) \ )(_a, _b) -static inline bool fr_time_gt(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) > fr_time_unwrap(b); } -static inline bool fr_time_gteq(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) >= fr_time_unwrap(b); } -static inline bool fr_time_lt(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) < fr_time_unwrap(b); } -static inline bool fr_time_lteq(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) <= fr_time_unwrap(b); } -static inline bool fr_time_eq(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) == fr_time_unwrap(b); } -static inline bool fr_time_neq(fr_time_t a, fr_time_t b) { return fr_time_unwrap(a) != fr_time_unwrap(b); } +#define fr_time_gt(_a, _b) (fr_time_unwrap(_a) > fr_time_unwrap(_b)) +#define fr_time_gteq(_a, _b) (fr_time_unwrap(_a) >= fr_time_unwrap(_b)) +#define fr_time_lt(_a, _b) (fr_time_unwrap(_a) < fr_time_unwrap(_b)) +#define fr_time_lteq(_a, _b) (fr_time_unwrap(_a) <= fr_time_unwrap(_b)) +#define fr_time_eq(_a, _b) (fr_time_unwrap(_a) == fr_time_unwrap(_b)) +#define fr_time_neq(_a, _b) (fr_time_unwrap(_a) != fr_time_unwrap(_b)) + +#define fr_time_ispos(_a) (fr_time_unwrap(_a) > 0) +#define fr_time_isneg(_a) (fr_time_unwrap(_a) < 0) +/** @} */ + +/** @name fr_time_delta_t arithmetic and comparison macros + * + * We wrap the 64bit signed time delta value in a struct to prevent misuse. + * + * The macros below allow basic arithmetic and comparisons to be performed. + * @{ + */ +static inline fr_time_delta_t fr_time_delta_add(fr_time_delta_t a, fr_time_delta_t b) { return fr_time_delta_wrap(fr_time_delta_unwrap(a) + fr_time_delta_unwrap(b)); } +static inline fr_time_delta_t fr_time_delta_sub(fr_time_delta_t a, fr_time_delta_t b) { return fr_time_delta_wrap(fr_time_delta_unwrap(a) - fr_time_delta_unwrap(b)); } +static inline fr_time_delta_t fr_time_delta_div(fr_time_delta_t a, fr_time_delta_t b) { return fr_time_delta_wrap(fr_time_delta_unwrap(a) / fr_time_delta_unwrap(b)); } +static inline fr_time_delta_t fr_time_delta_mul(fr_time_delta_t a, fr_time_delta_t b) { return fr_time_delta_wrap(fr_time_delta_unwrap(a) * fr_time_delta_unwrap(b)); } + +#define fr_time_delta_cond(_a, _op, _b) (fr_time_delta_unwrap(_a) _op fr_time_delta_unwrap(_b)) +#define fr_time_delta_gt(_a, _b) (fr_time_delta_unwrap(_a) > fr_time_delta_unwrap(_b)) +#define fr_time_delta_gteq(_a, _b) (fr_time_delta_unwrap(_a) >= fr_time_delta_unwrap(_b)) +#define fr_time_delta_lt(_a, _b) (fr_time_delta_unwrap(_a) < fr_time_delta_unwrap(_b)) +#define fr_time_delta_lteq(_a, _b) (fr_time_delta_unwrap(_a) <= fr_time_delta_unwrap(_b)) +#define fr_time_delta_eq(_a, _b) (fr_time_delta_unwrap(_a) == fr_time_delta_unwrap(_b)) +#define fr_time_delta_neq(_a, _b) (fr_time_delta_unwrap(_a) != fr_time_delta_unwrap(_b)) + +#define fr_time_delta_ispos(_a) (fr_time_delta_unwrap(_a) > 0) +#define fr_time_delta_isneg(_a) (fr_time_delta_unwrap(_a) < 0) +/** @} */ + +/** @name fr_unix_time_t arithmetic and comparison macros + * + * We wrap the 64bit signed time value in a struct to prevent misuse. + * + * The macros below allow basic arithmetic and comparisons to be performed. + * @{ + */ +/* Don't add fr_unix_time_add_time_time, it's almost always a type error */ +static inline fr_unix_time_t fr_unix_time_add_time_delta(fr_unix_time_t a, fr_time_delta_t b) { return fr_unix_time_wrap(fr_unix_time_unwrap(a) + fr_time_delta_unwrap(b)); } +static inline fr_unix_time_t fr_unix_time_add_delta_time(fr_time_delta_t a, fr_unix_time_t b) { return fr_unix_time_wrap(fr_time_delta_unwrap(a) + fr_unix_time_unwrap(b)); } + +/** Add a time/time delta together + * + * Types may either be: + * - fr_unix_time_add((fr_unix_time_t), (fr_time_delta_t)) + * - fr_unix_time_add((fr_time_delta_t), (fr_time_delta_t)) + * + * Adding two time values together is most likely an error. + * Adding two time_delta values together can be done with #fr_time_delta_add. + */ +#define fr_unix_time_add(_a, _b) \ + _Generic(_a, \ + fr_unix_time_t : _Generic(_b, \ + fr_time_delta_t : fr_unix_time_add_time_delta \ + ), \ + fr_time_delta_t : _Generic(_b, \ + fr_unix_time_t : fr_unix_time_add_delta_time, \ + fr_time_delta_t : fr_time_delta_add \ + ) \ + )(_a, _b) + +static inline fr_time_delta_t fr_unix_time_sub_time_time(fr_unix_time_t a, fr_unix_time_t b) { return fr_time_delta_wrap(fr_unix_time_unwrap(a) - fr_unix_time_unwrap(b)); } +static inline fr_unix_time_t fr_unix_time_sub_time_delta(fr_unix_time_t a, fr_time_delta_t b) { return fr_unix_time_wrap(fr_unix_time_unwrap(a) - fr_time_delta_unwrap(b)); } + +/** Subtract one time from another + * + * Types may either be: + * - fr_unix_time_sub((fr_unix_time_t), (fr_unix_time_t)) - Produces a #fr_time_delta_t + * - fr_unix_time_sub((fr_unix_time_t), (fr_time_delta_t)) - Produces a #fr_unix_time_t + * + * Subtracting time from a delta is most likely an error. + * Subtracting two time_delta values can be done with #fr_time_delta_sub + */ +#define fr_unix_time_sub(_a, _b) \ + _Generic(_a, \ + fr_unix_time_t : _Generic(_b, \ + fr_unix_time_t : fr_unix_time_sub_time_time, \ + fr_time_delta_t : fr_unix_time_sub_time_delta \ + ) \ + )(_a, _b) + +#define fr_unix_time_gt(_a, _b) (fr_unix_time_unwrap(_a) > fr_unix_time_unwrap(_b)) +#define fr_unix_time_gteq(_a, _b) (fr_unix_time_unwrap(_a) >= fr_unix_time_unwrap(_b)) +#define fr_unix_time_lt(_a, _b) (fr_unix_time_unwrap(_a) < fr_unix_time_unwrap(_b)) +#define fr_unix_time_lteq(_a, _b) (fr_unix_time_unwrap(_a) <= fr_unix_time_unwrap(_b)) +#define fr_unix_time_eq(_a, _b) (fr_unix_time_unwrap(_a) == fr_unix_time_unwrap(_b)) +#define fr_unix_time_neq(_a, _b) (fr_unix_time_unwrap(_a) != fr_unix_time_unwrap(_b)) + +#define fr_unix_time_ispos(_a) (fr_unix_time_unwrap(_a) > 0) +/** @} */ /** The base resolution for print parse operations */ typedef enum { FR_TIME_RES_SEC = 0, + FR_TIME_RES_CSEC, FR_TIME_RES_MSEC, FR_TIME_RES_USEC, FR_TIME_RES_NSEC @@ -142,14 +268,64 @@ extern mach_timebase_info_data_t timebase; extern uint64_t our_mach_epoch; #endif -/* - * Need cast because of difference in sign +/** @name fr_unix_time_t scale conversion macros/functions + * + * @{ */ -#define fr_unix_time_from_nsec(_x) (fr_unix_time_t)(_x) -#define fr_unix_time_from_usec(_x) (fr_unix_time_t)fr_time_delta_from_usec((fr_time_delta_t)(_x)) -#define fr_unix_time_from_msec(_x) (fr_unix_time_t)fr_time_delta_from_msec((fr_time_delta_t)(_x)) -#define fr_unix_time_from_csec(_x) (fr_unix_time_t)fr_time_delta_from_csec((fr_time_delta_t)(_x)) -#define fr_unix_time_from_sec(_x) (fr_unix_time_t)fr_time_delta_from_sec((fr_time_delta_t)(_x)) +static inline fr_unix_time_t fr_unix_time_from_nsec(int64_t nsec) +{ + return fr_unix_time_wrap(nsec); +} + +static inline fr_unix_time_t fr_unix_time_from_usec(int64_t usec) +{ + return fr_unix_time_wrap(usec * (NSEC / USEC)); +} + +static inline fr_unix_time_t fr_unix_time_from_msec(int64_t msec) +{ + return fr_unix_time_wrap(msec * (NSEC / MSEC)); +} + +static inline fr_unix_time_t fr_unix_time_from_csec(int64_t csec) +{ + return fr_unix_time_wrap(csec * (NSEC / CSEC)); +} + +static inline fr_unix_time_t fr_unix_time_from_sec(int64_t sec) +{ + return fr_unix_time_wrap(sec * NSEC); +} + +static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv) +{ + return fr_unix_time_wrap((((typeof_field(fr_unix_time_t, value)) tv->tv_sec) * NSEC) + (((typeof_field(fr_unix_time_t, value)) tv->tv_usec) * (NSEC / USEC))); +} + +static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timespec(struct timespec const *ts) +{ + return fr_unix_time_wrap((((typeof_field(fr_unix_time_t, value))ts->tv_sec) * NSEC) + ts->tv_nsec); +} + +static inline int64_t fr_unix_time_to_usec(fr_unix_time_t delta) +{ + return fr_unix_time_unwrap(delta) / (NSEC / USEC); +} + +static inline int64_t fr_unix_time_to_msec(fr_unix_time_t delta) +{ + return fr_unix_time_unwrap(delta) / (NSEC / MSEC); +} + +static inline int64_t fr_unix_time_to_csec(fr_unix_time_t delta) +{ + return fr_unix_time_unwrap(delta) / (NSEC / CSEC); +} + +static inline int64_t fr_unix_time_to_sec(fr_unix_time_t delta) +{ + return (fr_unix_time_unwrap(delta) / NSEC); +} /** Covert a time_t into out internal fr_unix_time_t * @@ -163,104 +339,96 @@ extern uint64_t our_mach_epoch; */ static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_time(time_t time) { - if (time < 0) return 0; - - return (time * NSEC); -} + if (time < 0) return fr_unix_time_wrap(0); -#define fr_unix_time_to_nsec(_x) (uint64_t)(_x) -#define fr_unix_time_to_usec(_x) (uint64_t)fr_time_delta_to_usec(_x) -#define fr_unix_time_to_msec(_x) (uint64_t)fr_time_delta_to_msec(_x) -#define fr_unix_time_to_csec(_x) (uint64_t)fr_time_delta_to_csec(_x) -#define fr_unix_time_to_sec(_x) (uint64_t)fr_time_delta_to_sec(_x) - -static inline CC_HINT(nonnull) fr_unix_time_t fr_unix_time_from_timeval(struct timeval const *tv) -{ - return (((fr_unix_time_t) tv->tv_sec) * NSEC) + (((fr_unix_time_t) tv->tv_usec) * (NSEC / USEC)); + return fr_unix_time_wrap(time * NSEC); } +/** @} */ +/** @name fr_time_delta_t scale conversion macros/functions + * + * @{ + */ static inline fr_time_delta_t fr_time_delta_from_nsec(int64_t nsec) { - return nsec; + return fr_time_delta_wrap(nsec); } static inline fr_time_delta_t fr_time_delta_from_usec(int64_t usec) { - return (usec * (NSEC / USEC)); + return fr_time_delta_wrap(usec * (NSEC / USEC)); } static inline fr_time_delta_t fr_time_delta_from_msec(int64_t msec) { - return (msec * (NSEC / MSEC)); + return fr_time_delta_wrap(msec * (NSEC / MSEC)); } static inline fr_time_delta_t fr_time_delta_from_csec(int64_t csec) { - return (csec * (NSEC / CSEC)); + return fr_time_delta_wrap(csec * (NSEC / CSEC)); } static inline fr_time_delta_t fr_time_delta_from_sec(int64_t sec) { - return (sec * NSEC); + return fr_time_delta_wrap(sec * NSEC); } static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timeval(struct timeval const *tv) { - return (((fr_time_delta_t) tv->tv_sec) * NSEC) + (((fr_time_delta_t) tv->tv_usec) * (NSEC / USEC)); + return fr_time_delta_wrap((((typeof_field(fr_time_delta_t, value))tv->tv_sec) * NSEC) + (((typeof_field(fr_time_delta_t, value)) tv->tv_usec) * (NSEC / USEC))); } static inline CC_HINT(nonnull) fr_time_delta_t fr_time_delta_from_timespec(struct timespec const *ts) { - return (((fr_time_delta_t) ts->tv_sec) * NSEC) + ts->tv_nsec; + return fr_time_delta_wrap((((typeof_field(fr_time_delta_t, value))ts->tv_sec) * NSEC) + ts->tv_nsec); } static inline int64_t fr_time_delta_to_usec(fr_time_delta_t delta) { - return delta / (NSEC / USEC); + return fr_time_delta_unwrap(delta) / (NSEC / USEC); } static inline int64_t fr_time_delta_to_msec(fr_time_delta_t delta) { - return (delta / (NSEC / MSEC)); + return fr_time_delta_unwrap(delta) / (NSEC / MSEC); } static inline int64_t fr_time_delta_to_csec(fr_time_delta_t delta) { - return (delta / (NSEC / CSEC)); + return fr_time_delta_unwrap(delta) / (NSEC / CSEC); } static inline int64_t fr_time_delta_to_sec(fr_time_delta_t delta) { - return (delta / NSEC); + return (fr_time_delta_unwrap(delta) / NSEC); } /** Convert a delta to a timeval * - * @param[in] _delta in nanoseconds. + * @param[in] delta in nanoseconds. */ #define fr_time_delta_to_timeval(_delta) \ - (struct timeval){ .tv_sec = (_delta) / NSEC, .tv_usec = ((_delta) % NSEC) / (NSEC / USEC) } +(struct timeval){ \ + .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \ + .tv_usec = (fr_time_delta_unwrap(_delta) % NSEC) / (NSEC / USEC) \ +} /** Convert a delta to a timespec * - * @param[in] _delta in nanoseconds. - */ -#define fr_time_delta_to_timespec(_delta) \ - (struct timespec){ .tv_sec = (_delta) / NSEC, .tv_nsec = ((_delta) % NSEC) } - -/** Convert server epoch time to unix epoch time - * - * @param[in] _when The server epoch time to convert. + * @param[in] delta in nanoseconds. */ -#define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_wallclock_at_last_sync() + fr_time_unwrap(_when)) +#define fr_time_delta_to_timespec(_delta)\ +(struct timespec){ \ + .tv_sec = fr_time_delta_unwrap(_delta) / NSEC, \ + .tv_nsec = (fr_time_delta_unwrap(_delta) % NSEC) \ +} +/** @} */ -/** Convert server epoch time to unix epoch time +/** @name fr_time_delta_t scale conversion macros/functions * - * @param[in] _when The server epoch time to convert. + * @{ */ -#define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_wallclock_at_last_sync() + fr_time_unwrap(_when)) - - /** Nanoseconds since the Unix Epoch the last time we synced internal time with wallclock time * */ @@ -274,7 +442,7 @@ static inline int64_t fr_time_wallclock_at_last_sync(void) */ static inline fr_unix_time_t fr_time_to_unix_time(fr_time_t when) { - return fr_time_unwrap(when) + atomic_load_explicit(&our_realtime, memory_order_consume); + return fr_unix_time_wrap(fr_time_unwrap(when) + atomic_load_explicit(&our_realtime, memory_order_consume)); } /** Convert an fr_time_t (internal time) to number of usec since the unix epoch (wallclock time) @@ -309,31 +477,17 @@ static inline int64_t fr_time_to_sec(fr_time_t when) return ((fr_time_unwrap(when) + atomic_load_explicit(&our_realtime, memory_order_consume)) / NSEC); } -/** Convert a timespec (wallclock time) to a fr_time_t (internal time) +/** Convert server epoch time to unix epoch time * - * @param[in] when_ts The timestamp to convert. - * @return - * - >0 number of nanoseconds since the server started. - * - 0 when the server started. - * - 0 if when_tv occurred before the server started. + * @param[in] _when The server epoch time to convert. */ -static inline CC_HINT(nonnull) fr_time_t fr_time_from_timespec(struct timespec const *when_ts) -{ - return fr_time_wrap(fr_time_delta_from_timespec(when_ts) - atomic_load_explicit(&our_realtime, memory_order_consume)); -} +#define fr_time_to_timeval(_when) fr_time_delta_to_timeval(fr_time_delta_wrap(fr_time_wallclock_at_last_sync() + fr_time_unwrap(_when))) -/** Convert a timeval (wallclock time) to a fr_time_t (internal time) +/** Convert server epoch time to unix epoch time * - * @param[in] when_tv The timestamp to convert. - * @return - * - >0 number of nanoseconds since the server started. - * - 0 when the server started. - * - <0 number of nanoseconds before the server started. + * @param[in] _when The server epoch time to convert. */ -static inline CC_HINT(nonnull) fr_time_t fr_time_from_timeval(struct timeval const *when_tv) -{ - return fr_time_wrap(fr_time_delta_from_timeval(when_tv) - atomic_load_explicit(&our_realtime, memory_order_consume)); -} +#define fr_time_to_timespec(_when) fr_time_delta_to_timespec(fr_time_delta_wrap(fr_time_wallclock_at_last_sync() + fr_time_unwrap(_when))) /** Convert a nsec (wallclock time) to a fr_time_t (internal time) * @@ -400,6 +554,33 @@ static inline fr_time_t fr_time_from_sec(time_t when) return fr_time_wrap((when * NSEC) - atomic_load_explicit(&our_realtime, memory_order_consume)); } +/** Convert a timespec (wallclock time) to a fr_time_t (internal time) + * + * @param[in] when_ts The timestamp to convert. + * @return + * - >0 number of nanoseconds since the server started. + * - 0 when the server started. + * - 0 if when_tv occurred before the server started. + */ +static inline CC_HINT(nonnull) fr_time_t fr_time_from_timespec(struct timespec const *when_ts) +{ + return fr_time_wrap(fr_time_delta_unwrap(fr_time_delta_from_timespec(when_ts)) - atomic_load_explicit(&our_realtime, memory_order_consume)); +} + +/** Convert a timeval (wallclock time) to a fr_time_t (internal time) + * + * @param[in] when_tv The timestamp to convert. + * @return + * - >0 number of nanoseconds since the server started. + * - 0 when the server started. + * - <0 number of nanoseconds before the server started. + */ +static inline CC_HINT(nonnull) fr_time_t fr_time_from_timeval(struct timeval const *when_tv) +{ + return fr_time_wrap(fr_time_delta_unwrap(fr_time_delta_from_timeval(when_tv)) - atomic_load_explicit(&our_realtime, memory_order_consume)); +} +/** @} */ + /** Compare two fr_time_t values * * @param[in] a The first value to compare. @@ -414,6 +595,34 @@ static inline int8_t fr_time_cmp(fr_time_t a, fr_time_t b) return CMP(fr_time_unwrap(a), fr_time_unwrap(b)); } +/** Compare two fr_time_delta_t values + * + * @param[in] a The first value to compare. + * @param[in] b The second value to compare. + * @return + * - +1 if a > b + * - 0 if a == b + * - -1 if a < b + */ +static inline int8_t fr_time_delta_cmp(fr_time_delta_t a, fr_time_delta_t b) +{ + return CMP(fr_time_delta_unwrap(a), fr_time_delta_unwrap(b)); +} + +/** Compare two fr_unix_time_t values + * + * @param[in] a The first value to compare. + * @param[in] b The second value to compare. + * @return + * - +1 if a > b + * - 0 if a == b + * - -1 if a < b + */ +static inline int8_t fr_unix_time_cmp(fr_unix_time_t a, fr_unix_time_t b) +{ + return CMP(fr_unix_time_unwrap(a), fr_unix_time_unwrap(b)); +} + /** Return a relative time since the server our_epoch * * This time is useful for doing time comparisons, deltas, etc. @@ -428,7 +637,7 @@ static inline fr_time_t fr_time(void) #ifdef HAVE_CLOCK_GETTIME struct timespec ts; (void) clock_gettime(CLOCK_MONOTONIC, &ts); - return fr_time_wrap(fr_time_delta_from_timespec(&ts) - our_epoch); + return fr_time_wrap(fr_time_delta_unwrap(fr_time_delta_from_timespec(&ts)) - our_epoch); #else /* __MACH__ is defined */ uint64_t when; diff --git a/src/lib/util/value.c b/src/lib/util/value.c index 54829abf85..979fd9c2ef 100644 --- a/src/lib/util/value.c +++ b/src/lib/util/value.c @@ -593,7 +593,7 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) break; case FR_TYPE_DATE: - CHECK(date); + compare = fr_unix_time_cmp(a->datum.date, b->datum.date); break; case FR_TYPE_UINT8: @@ -633,7 +633,7 @@ int fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b) break; case FR_TYPE_TIME_DELTA: - CHECK(time_delta); + compare = fr_time_delta_cmp(a->datum.time_delta, b->datum.time_delta); break; case FR_TYPE_FLOAT32: @@ -1125,11 +1125,11 @@ int fr_value_box_hton(fr_value_box_t *dst, fr_value_box_t const *src) break; case FR_TYPE_DATE: - dst->vb_date = htonll(src->vb_date); + dst->vb_date = fr_unix_time_wrap(htonll(fr_unix_time_unwrap(src->vb_date))); break; case FR_TYPE_TIME_DELTA: - dst->vb_time_delta = htonll(src->vb_time_delta); + dst->vb_time_delta = fr_time_delta_wrap(htonll(fr_time_delta_unwrap(src->vb_time_delta))); break; case FR_TYPE_FLOAT32: @@ -1361,7 +1361,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) */ case FR_TYPE_DATE: { - uint64_t date; + uint64_t date = 0; if (!value->enumv) { goto date_seconds; @@ -1372,6 +1372,10 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) date = fr_unix_time_to_sec(value->vb_date); break; + case FR_TIME_RES_CSEC: + date = fr_unix_time_to_csec(value->vb_date); + break; + case FR_TIME_RES_MSEC: date = fr_unix_time_to_msec(value->vb_date); break; @@ -1383,9 +1387,6 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) case FR_TIME_RES_NSEC: date = fr_unix_time_to_usec(value->vb_date); break; - - default: - goto unsupported; } if (!value->enumv) { @@ -1416,7 +1417,7 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) case FR_TYPE_TIME_DELTA: { - int64_t date; /* may be negative */ + int64_t date = 0; /* may be negative */ if (!value->enumv) { goto delta_seconds; @@ -1427,6 +1428,10 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) date = fr_time_delta_to_sec(value->vb_time_delta); break; + case FR_TIME_RES_CSEC: + date = fr_time_delta_to_csec(value->vb_time_delta); + break; + case FR_TIME_RES_MSEC: date = fr_time_delta_to_msec(value->vb_time_delta); break; @@ -1436,11 +1441,8 @@ ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value) break; case FR_TIME_RES_NSEC: - date = value->vb_time_delta; + date = fr_time_delta_unwrap(value->vb_time_delta); break; - - default: - goto unsupported; } if (!value->enumv) { @@ -1748,11 +1750,14 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, FR_DBUFF_OUT_UINT64V_RETURN(&date, &work_dbuff, length); switch (precision) { - default: case FR_TIME_RES_SEC: /* external seconds, internal nanoseconds */ date *= NSEC; break; + case FR_TIME_RES_CSEC: + date *= (NSEC / CSEC); + break; + case FR_TIME_RES_MSEC: date *= (NSEC / MSEC); break; @@ -1765,7 +1770,7 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, break; } - dst->vb_date = date; + dst->vb_date = fr_unix_time_wrap(date); } break; @@ -1806,11 +1811,14 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, } switch (precision) { - default: case FR_TIME_RES_SEC: /* external seconds, internal nanoseconds */ dst->vb_time_delta = fr_time_delta_from_sec(date); break; + case FR_TIME_RES_CSEC: + dst->vb_time_delta = fr_time_delta_from_csec(date); + break; + case FR_TIME_RES_MSEC: dst->vb_time_delta = fr_time_delta_from_msec(date); break; @@ -1820,7 +1828,7 @@ ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, break; case FR_TIME_RES_NSEC: - dst->vb_time_delta = date; + dst->vb_time_delta = fr_time_delta_wrap(date); break; } @@ -2711,11 +2719,14 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f if (dst->enumv) { switch (dst->enumv->flags.flag_time_res) { date_src_seconds: - default: case FR_TIME_RES_SEC: tmp = fr_unix_time_to_sec(src->vb_date); break; + case FR_TIME_RES_CSEC: + tmp = fr_unix_time_to_csec(src->vb_date); + break; + case FR_TIME_RES_USEC: tmp = fr_unix_time_to_usec(src->vb_date); break; @@ -2725,7 +2736,7 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f break; case FR_TIME_RES_NSEC: - tmp = src->vb_date; + tmp = fr_unix_time_unwrap(src->vb_date); break; } } else goto date_src_seconds; @@ -2741,11 +2752,14 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f if (dst->enumv) { switch (dst->enumv->flags.flag_time_res) { delta_src_seconds: - default: case FR_TIME_RES_SEC: tmp = (uint64_t)fr_time_delta_to_sec(src->vb_time_delta); break; + case FR_TIME_RES_CSEC: + tmp = (uint64_t)fr_time_delta_to_csec(src->vb_time_delta); + break; + case FR_TIME_RES_USEC: tmp = (uint64_t)fr_time_delta_to_usec(src->vb_time_delta); break; @@ -2755,7 +2769,7 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f break; case FR_TIME_RES_NSEC: - tmp = (uint64_t)src->vb_time_delta; + tmp = (uint64_t)fr_time_delta_unwrap(src->vb_time_delta); break; } } else goto delta_src_seconds; @@ -2804,21 +2818,24 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f if (dst->enumv) { switch (dst->enumv->flags.flag_time_res) { date_dst_seconds: - default: case FR_TIME_RES_SEC: - dst->vb_date = fr_unix_time_from_sec((fr_unix_time_t)tmp); + dst->vb_date = fr_unix_time_from_sec(tmp); + break; + + case FR_TIME_RES_CSEC: + dst->vb_date = fr_unix_time_from_csec(tmp); break; case FR_TIME_RES_USEC: - dst->vb_date = fr_unix_time_from_usec((fr_unix_time_t)tmp); + dst->vb_date = fr_unix_time_from_usec(tmp); break; case FR_TIME_RES_MSEC: - dst->vb_date = fr_unix_time_from_msec((fr_unix_time_t)tmp); + dst->vb_date = fr_unix_time_from_msec(tmp); break; case FR_TIME_RES_NSEC: - dst->vb_date = fr_unix_time_from_nsec((fr_unix_time_t)tmp); + dst->vb_date = fr_unix_time_from_nsec(tmp); break; } } else goto date_dst_seconds; @@ -2828,21 +2845,24 @@ static inline int fr_value_box_cast_integer_to_integer(UNUSED TALLOC_CTX *ctx, f if (dst->enumv) { switch (dst->enumv->flags.flag_time_res) { delta_dst_seconds: - default: case FR_TIME_RES_SEC: - dst->vb_time_delta = fr_time_delta_from_sec((fr_time_delta_t)tmp); + dst->vb_time_delta = fr_time_delta_from_sec(tmp); + break; + + case FR_TIME_RES_CSEC: + dst->vb_time_delta = fr_time_delta_from_csec(tmp); break; case FR_TIME_RES_USEC: - dst->vb_time_delta = fr_time_delta_from_usec((fr_time_delta_t)tmp); + dst->vb_time_delta = fr_time_delta_from_usec(tmp); break; case FR_TIME_RES_MSEC: - dst->vb_time_delta = fr_time_delta_from_msec((fr_time_delta_t)tmp); + dst->vb_time_delta = fr_time_delta_from_msec(tmp); break; case FR_TIME_RES_NSEC: - dst->vb_time_delta = fr_time_delta_from_nsec((fr_time_delta_t)tmp); + dst->vb_time_delta = fr_time_delta_from_nsec(tmp); break; } } else goto delta_dst_seconds; @@ -4895,7 +4915,7 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff len = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &s_tm); FR_SBUFF_IN_BSTRNCPY_RETURN(&our_out, buf, len); - subseconds = data->vb_date % NSEC; + subseconds = fr_unix_time_unwrap(data->vb_date) % NSEC; /* * Use RFC 3339 format, which is a @@ -4904,7 +4924,12 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff * formats. The RFC is much stricter. */ switch (data->enumv->flags.flag_time_res) { - default: + case FR_TIME_RES_SEC: + break; + + case FR_TIME_RES_CSEC: + subseconds /= (NSEC / CSEC); + FR_SBUFF_IN_SPRINTF_RETURN(&our_out, ".%02" PRIi64, subseconds); break; case FR_TIME_RES_MSEC: @@ -4958,24 +4983,28 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff #define MOD(a,b) (((a<0) ? (-a) : (a))%(b)) switch (res) { - default: case FR_TIME_RES_SEC: - lhs = data->datum.time_delta / NSEC; - rhs = MOD(data->datum.time_delta, NSEC); + lhs = fr_time_delta_to_sec(data->datum.time_delta); + rhs = MOD(fr_time_delta_unwrap(data->datum.time_delta), NSEC); + break; + + case FR_TIME_RES_CSEC: + lhs = fr_time_delta_to_csec(data->datum.time_delta); + rhs = MOD(fr_time_delta_unwrap(data->datum.time_delta), (NSEC / CSEC)); break; case FR_TIME_RES_MSEC: - lhs = data->datum.time_delta / 1000000; - rhs = MOD(data->datum.time_delta, 1000000); + lhs = fr_time_delta_to_msec(data->datum.time_delta); + rhs = MOD(fr_time_delta_unwrap(data->datum.time_delta), (NSEC / MSEC)); break; case FR_TIME_RES_USEC: - lhs = data->datum.time_delta / 1000; - rhs = MOD(data->datum.time_delta, 1000); + lhs = fr_time_delta_to_usec(data->datum.time_delta); + rhs = MOD(fr_time_delta_unwrap(data->datum.time_delta), (NSEC / USEC)); break; case FR_TIME_RES_NSEC: - lhs = data->datum.time_delta; + lhs = fr_time_delta_unwrap(data->datum.time_delta); rhs = 0; break; } @@ -4985,15 +5014,13 @@ ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff * 0 is unsigned, but we want to print * "-0.1" if necessary. */ - if ((lhs == 0) && (data->datum.time_delta < 0)) { + if ((lhs == 0) && fr_time_delta_isneg(data->datum.time_delta)) { FR_SBUFF_IN_CHAR_RETURN(&our_out, '-'); } FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "%" PRIi64 ".%09" PRIu64, lhs, rhs); } else { - if (data->datum.time_delta < 0) { - lhs = rhs = 0; - } + if (fr_time_delta_isneg(data->datum.time_delta)) lhs = rhs = 0; FR_SBUFF_IN_SPRINTF_RETURN(&our_out, "%" PRIu64 ".%09" PRIu64, lhs, rhs); } diff --git a/src/lib/util/value.h b/src/lib/util/value.h index 8eac796567..a8a7583f3d 100644 --- a/src/lib/util/value.h +++ b/src/lib/util/value.h @@ -516,7 +516,7 @@ DEF_BOXING_FUNC(int64_t, int64, FR_TYPE_INT64) DEF_BOXING_FUNC(float, float32, FR_TYPE_FLOAT32) DEF_BOXING_FUNC(double, float64, FR_TYPE_FLOAT64) -DEF_BOXING_FUNC(uint64_t, date, FR_TYPE_DATE) +DEF_BOXING_FUNC(fr_unix_time_t, date, FR_TYPE_DATE) /** Automagically fill in a box, determining the value type from the type of the C variable * @@ -606,7 +606,7 @@ DEF_UNBOXING_FUNC(int64_t, int64, FR_TYPE_INT64) DEF_UNBOXING_FUNC(float, float32, FR_TYPE_FLOAT32) DEF_UNBOXING_FUNC(double, float64, FR_TYPE_FLOAT64) -DEF_UNBOXING_FUNC(uint64_t, date, FR_TYPE_DATE) +DEF_UNBOXING_FUNC(fr_unix_time_t, date, FR_TYPE_DATE) /** Unbox simple types peforming type checks * diff --git a/src/listen/detail/proto_detail_file.c b/src/listen/detail/proto_detail_file.c index b7073b6815..cef9187f27 100644 --- a/src/listen/detail/proto_detail_file.c +++ b/src/listen/detail/proto_detail_file.c @@ -260,11 +260,15 @@ static int work_exists(proto_detail_file_thread_t *thread, int fd) * Set the next interval, and ensure that we * don't do massive busy-polling. */ - thread->lock_interval += thread->lock_interval / 2; - if (thread->lock_interval > ((fr_time_delta_t) 30) * NSEC) thread->lock_interval = ((fr_time_delta_t) 30) * NSEC; + thread->lock_interval = fr_time_delta_add(thread->lock_interval, + fr_time_delta_div(thread->lock_interval, + fr_time_delta_wrap(2))); + if (fr_time_delta_gt(thread->lock_interval, fr_time_delta_from_sec(30))) { + thread->lock_interval = fr_time_delta_from_sec(30); + } - DEBUG3("proto_detail (%s): Waiting %d.%06ds for lock on file %s", - thread->name, (int) (delay / NSEC), (int) ((delay % NSEC) / 1000), inst->filename_work); + DEBUG3("proto_detail (%s): Waiting %.6fs for lock on file %s", + thread->name, fr_time_delta_unwrap(delay) / (double)NSEC, inst->filename_work); if (fr_event_timer_in(thread, thread->el, &thread->ev, delay, work_retry_timer, thread) < 0) { @@ -519,7 +523,7 @@ delay: return; } - thread->lock_interval = NSEC / 10; + thread->lock_interval = fr_time_delta_from_msec(100); /* * It exists, go process it! diff --git a/src/listen/detail/proto_detail_work.c b/src/listen/detail/proto_detail_work.c index a4ecec4dc8..fe3a5d4542 100644 --- a/src/listen/detail/proto_detail_work.c +++ b/src/listen/detail/proto_detail_work.c @@ -605,8 +605,8 @@ static ssize_t mod_write(fr_listen_t *li, void *packet_ctx, UNUSED fr_time_t req } } - DEBUG("%s - packet %d failed during processing. Will retransmit in %d.%06ds", - thread->name, track->id, (int) (track->retry.rt / NSEC), (int) ((track->retry.rt % NSEC) / 1000)); + DEBUG("%s - packet %d failed during processing. Will retransmit in %.6fs", + thread->name, track->id, fr_time_delta_unwrap(track->retry.rt) / (double)NSEC); if (fr_event_timer_at(thread, thread->el, &track->ev, track->retry.next, work_retransmit, track) < 0) { diff --git a/src/listen/load/proto_load_step.c b/src/listen/load/proto_load_step.c index 48b547b8df..fa50614847 100644 --- a/src/listen/load/proto_load_step.c +++ b/src/listen/load/proto_load_step.c @@ -243,7 +243,7 @@ static void write_stats(fr_event_list_t *el, fr_time_t now, void *uctx) size_t len; char buffer[1024]; - (void) fr_event_timer_in(thread, el, &thread->ev, NSEC, write_stats, thread); + (void) fr_event_timer_in(thread, el, &thread->ev, fr_time_delta_from_sec(1), write_stats, thread); len = fr_load_generator_stats_sprint(thread->l, now, buffer, sizeof(buffer)); if (write(thread->fd, buffer, len) < 0) { @@ -330,7 +330,7 @@ static void mod_event_list_set(fr_listen_t *li, fr_event_list_t *el, void *nr) return; } - (void) fr_event_timer_in(thread, thread->el, &thread->ev, NSEC, write_stats, thread); + (void) fr_event_timer_in(thread, thread->el, &thread->ev, fr_time_delta_from_sec(1), write_stats, thread); len = fr_load_generator_stats_sprint(thread->l, fr_time(), buffer, sizeof(buffer)); if (write(thread->fd, buffer, len) < 0) { diff --git a/src/modules/rlm_cache/drivers/rlm_cache_memcached/rlm_cache_memcached.c b/src/modules/rlm_cache/drivers/rlm_cache_memcached/rlm_cache_memcached.c index 5d41fd4a9c..4aa96793d7 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_memcached/rlm_cache_memcached.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_memcached/rlm_cache_memcached.c @@ -225,7 +225,7 @@ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config ret = memcached_set(mandle->handle, (char const *)c->key, c->key_len, to_store ? to_store : "", - to_store ? talloc_array_length(to_store) - 1 : 0, c->expires, 0); + to_store ? talloc_array_length(to_store) - 1 : 0, fr_unix_time_to_sec(c->expires), 0); talloc_free(pool); if (ret != MEMCACHED_SUCCESS) { RERROR("Failed storing entry: %s: %s", memcached_strerror(mandle->handle, ret), diff --git a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c index 743fa49434..229d902e63 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_rbtree/rlm_cache_rbtree.c @@ -60,7 +60,7 @@ static int8_t cache_heap_cmp(void const *one, void const *two) { rlm_cache_entry_t const *a = one, *b = two; - return CMP(a->expires, b->expires); + return fr_unix_time_cmp(a->expires, b->expires); } /** Cleanup a cache_rbtree instance @@ -167,7 +167,7 @@ static cache_status_t cache_entry_find(rlm_cache_entry_t **out, * Clear out old entries */ c = fr_heap_peek(driver->heap); - if (c && (c->expires < fr_time_to_unix_time(request->packet->timestamp))) { + if (c && (fr_unix_time_lt(c->expires, fr_time_to_unix_time(request->packet->timestamp)))) { fr_heap_extract(driver->heap, c); fr_rb_delete(driver->cache, c); talloc_free(c); diff --git a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c index cf38a51a4f..dd6546ecea 100644 --- a/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c +++ b/src/modules/rlm_cache/drivers/rlm_cache_redis/rlm_cache_redis.c @@ -366,7 +366,7 @@ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config /* * Start the transaction, as we need to set an expiry time too. */ - if (c->expires > 0) { + if (fr_unix_time_ispos(c->expires)) { RDEBUG3("MULTI"); if (redisAppendCommand(conn->handle, "MULTI") != REDIS_OK) { append_error: @@ -397,7 +397,7 @@ static cache_status_t cache_entry_insert(UNUSED rlm_cache_config_t const *config /* * Set the expiry time and close out the transaction. */ - if (c->expires > 0) { + if (fr_unix_time_ispos(c->expires)) { RDEBUG3("EXPIREAT \"%pV\" %" PRIu64, fr_box_strvalue_len((char const *)c->key, c->key_len), fr_unix_time_to_sec(c->expires)); diff --git a/src/modules/rlm_cache/rlm_cache.c b/src/modules/rlm_cache/rlm_cache.c index a7d89792a8..9270fea691 100644 --- a/src/modules/rlm_cache/rlm_cache.c +++ b/src/modules/rlm_cache/rlm_cache.c @@ -236,11 +236,11 @@ static unlang_action_t cache_find(rlm_rcode_t *p_result, rlm_cache_entry_t **out * Yes, but it expired, OR the "forget all" epoch has * passed. Delete it, and pretend it doesn't exist. */ - if ((c->expires < fr_time_to_unix_time(request->packet->timestamp)) || - (c->created < fr_unix_time_from_sec(inst->config.epoch))) { + if (fr_unix_time_lt(c->expires, fr_time_to_unix_time(request->packet->timestamp)) || + fr_unix_time_lt(c->created, fr_unix_time_from_sec(inst->config.epoch))) { RDEBUG2("Found entry for \"%pV\", but it expired %pV ago. Removing it", fr_box_strvalue_len((char const *)key, key_len), - fr_box_time_delta(fr_time_to_unix_time(request->packet->timestamp) - c->expires)); + fr_box_time_delta(fr_unix_time_sub(fr_time_to_unix_time(request->packet->timestamp), c->expires))); inst->driver->expire(&inst->config, inst->driver_inst->dl_inst->data, request, handle, c->key, c->key_len); cache_free(inst, &c); @@ -322,7 +322,7 @@ static unlang_action_t cache_insert(rlm_rcode_t *p_result, * All in NSEC resolution */ c->created = c->expires = fr_time_to_unix_time(request->packet->timestamp); - c->expires += ttl; + c->expires = fr_unix_time_add(c->expires, ttl); RDEBUG2("Creating new cache entry"); @@ -718,7 +718,7 @@ static unlang_action_t CC_HINT(nonnull) mod_cache_it(rlm_rcode_t *p_result, modu fr_assert(c); - c->expires = fr_time_to_unix_time(request->packet->timestamp) + ttl; + c->expires = fr_unix_time_add(fr_time_to_unix_time(request->packet->timestamp), ttl); cache_set_ttl(&tmp, inst, request, &handle, c); switch (tmp) { @@ -993,7 +993,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) fr_assert(inst->config.key); - if (inst->config.ttl == 0) { + if (!fr_time_delta_ispos(inst->config.ttl)) { cf_log_err(conf, "Must set 'ttl' to non-zero"); return -1; } diff --git a/src/modules/rlm_delay/rlm_delay.c b/src/modules/rlm_delay/rlm_delay.c index 751988fe25..69f3397533 100644 --- a/src/modules/rlm_delay/rlm_delay.c +++ b/src/modules/rlm_delay/rlm_delay.c @@ -89,7 +89,7 @@ static int delay_add(request_t *request, fr_time_t *resume_at, fr_time_t now, /* * Delay is zero (and reschedule is not forced) */ - if (!force_reschedule && (delay == 0)) return 1; + if (!force_reschedule && !fr_time_delta_ispos(delay)) return 1; /* * Process the delay relative to the start of packet processing @@ -151,7 +151,7 @@ static unlang_action_t CC_HINT(nonnull) mod_delay(rlm_rcode_t *p_result, module_ if (tmpl_aexpand_type(request, &delay, FR_TYPE_TIME_DELTA, request, inst->delay, NULL, NULL) < 0) RETURN_MODULE_FAIL; } else { - delay = 0; + delay = fr_time_delta_wrap(0); } /* @@ -248,7 +248,7 @@ static xlat_action_t xlat_delay(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor_t *out * This is very useful for testing. */ if (!delay) { - if (!fr_cond_assert(delay_add(request, &resume_at, *yielded_at, 0, true, true) == 0)) { + if (!fr_cond_assert(delay_add(request, &resume_at, *yielded_at, fr_time_delta_wrap(0), true, true) == 0)) { return XLAT_ACTION_FAIL; } goto yield; diff --git a/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c b/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c index e7e55f5463..c762f72717 100644 --- a/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c +++ b/src/modules/rlm_eap/types/rlm_eap_fast/eap_fast.c @@ -170,7 +170,7 @@ static void eap_fast_send_pac_tunnel(request_t *request, fr_tls_session_t *tls_s pac.info.lifetime.hdr.type = htons(attr_eap_fast_pac_info_pac_lifetime->attr); pac.info.lifetime.hdr.length = htons(sizeof(pac.info.lifetime.data)); - pac.info.lifetime.data = htonl(fr_time_to_sec(request->packet->timestamp) + t->pac_lifetime); + pac.info.lifetime.data = htonl(fr_time_to_sec(fr_time_add(request->packet->timestamp, t->pac_lifetime))); pac.info.a_id.hdr.type = htons(EAP_FAST_TLV_MANDATORY | attr_eap_fast_pac_a_id->attr); pac.info.a_id.hdr.length = htons(sizeof(pac.info.a_id.data)); @@ -944,7 +944,8 @@ fr_radius_packet_code_t eap_fast_process(request_t *request, eap_session_t *eap_ * Send a new pac at 60% of the lifetime, * or if the PAC has expired, or if no lifetime was set. */ - renew = fr_time_add(request->packet->timestamp, ((t->pac_lifetime * 3) / 5)); + renew = fr_time_add(request->packet->timestamp, + fr_time_delta_wrap((fr_time_delta_unwrap(t->pac_lifetime) * 3) / 5)); if (t->pac.expired || fr_time_eq(t->pac.expires, fr_time_wrap(0)) || fr_time_lteq(t->pac.expires, renew)) { diff --git a/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c b/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c index 477b11b76d..3db6e8813e 100644 --- a/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c +++ b/src/modules/rlm_eap/types/rlm_eap_fast/rlm_eap_fast.c @@ -667,7 +667,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *cs) return -1; } - if (!inst->pac_lifetime) { + if (!fr_time_delta_ispos(inst->pac_lifetime)) { cf_log_err_by_child(cs, "pac_lifetime", "must be non-zero"); return -1; } diff --git a/src/modules/rlm_exec/rlm_exec.c b/src/modules/rlm_exec/rlm_exec.c index 703643699d..e2baf3d717 100644 --- a/src/modules/rlm_exec/rlm_exec.c +++ b/src/modules/rlm_exec/rlm_exec.c @@ -207,16 +207,16 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) return -1; } - if (!inst->timeout_is_set || !inst->timeout) { + if (!inst->timeout_is_set || !fr_time_delta_ispos(inst->timeout)) { /* * Pick the shorter one */ - inst->timeout = main_config->max_request_time > fr_time_delta_from_sec(EXEC_TIMEOUT) ? + inst->timeout = fr_time_delta_gt(main_config->max_request_time, fr_time_delta_from_sec(EXEC_TIMEOUT)) ? fr_time_delta_from_sec(EXEC_TIMEOUT): main_config->max_request_time; } else { - if (inst->timeout < fr_time_delta_from_sec(1)) { + if (fr_time_delta_lt(inst->timeout, fr_time_delta_from_sec(1))) { cf_log_err(conf, "Timeout '%pVs' is too small (minimum: 1s)", fr_box_time_delta(inst->timeout)); return -1; } @@ -224,7 +224,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) /* * Blocking a request longer than max_request_time isn't going to help anyone. */ - if (inst->timeout > main_config->max_request_time) { + if (fr_time_delta_gt(inst->timeout, main_config->max_request_time)) { cf_log_err(conf, "Timeout '%pVs' is too large (maximum: %pVs)", fr_box_time_delta(inst->timeout), fr_box_time_delta(main_config->max_request_time)); return -1; @@ -466,7 +466,7 @@ static unlang_action_t CC_HINT(nonnull) mod_exec_dispatch(rlm_rcode_t *p_result, fr_value_box_list_init(&m->box); return unlang_module_yield_to_tmpl(m, &m->box, request, inst->tmpl, - TMPL_ARGS_EXEC(env_pairs, 0, true, &m->status), + TMPL_ARGS_EXEC(env_pairs, fr_time_delta_wrap(0), true, &m->status), mod_exec_wait_resume, NULL, &m->box); } diff --git a/src/modules/rlm_krb5/rlm_krb5.c b/src/modules/rlm_krb5/rlm_krb5.c index 29b37b9885..5c824ea17f 100644 --- a/src/modules/rlm_krb5/rlm_krb5.c +++ b/src/modules/rlm_krb5/rlm_krb5.c @@ -229,7 +229,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) inst->pool = module_connection_pool_init(conf, inst, krb5_mod_conn_create, NULL, NULL, NULL, NULL); if (!inst->pool) return -1; #else - inst->conn = krb5_mod_conn_create(inst, inst, 0); + inst->conn = krb5_mod_conn_create(inst, inst, fr_time_delta_wrap(0)); if (!inst->conn) return -1; #endif return 0; diff --git a/src/modules/rlm_linelog/rlm_linelog.c b/src/modules/rlm_linelog/rlm_linelog.c index bdf6cf0518..bdf5cb1024 100644 --- a/src/modules/rlm_linelog/rlm_linelog.c +++ b/src/modules/rlm_linelog/rlm_linelog.c @@ -241,7 +241,7 @@ static void *mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t ti } if (errno == EINPROGRESS) { - if (timeout) { + if (fr_time_delta_ispos(timeout)) { DEBUG2("Waiting for connection to complete..."); } else { DEBUG2("Blocking until connection complete..."); @@ -257,7 +257,7 @@ static void *mod_conn_create(TALLOC_CTX *ctx, void *instance, fr_time_delta_t ti /* * Set blocking operation as we have no timeout set */ - if (!timeout && (fr_blocking(sockfd) < 0)) { + if (!fr_time_delta_ispos(timeout) && (fr_blocking(sockfd) < 0)) { ERROR("Failed setting nonblock flag on fd"); close(sockfd); return NULL; @@ -451,7 +451,7 @@ static unlang_action_t CC_HINT(nonnull) mod_do_linelog(rlm_rcode_t *p_result, mo { rlm_linelog_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_linelog_t); linelog_conn_t *conn; - fr_time_delta_t timeout = 0; + fr_time_delta_t timeout = fr_time_delta_wrap(0); char buff[4096]; char *p = buff; @@ -689,13 +689,13 @@ build_vector: break; case LINELOG_DST_UNIX: - if (inst->unix_sock.timeout) { + if (fr_time_delta_ispos(inst->unix_sock.timeout)) { timeout = inst->unix_sock.timeout; } goto do_write; case LINELOG_DST_UDP: - if (inst->udp.timeout) { + if (fr_time_delta_ispos(inst->udp.timeout)) { timeout = inst->udp.timeout; } goto do_write; @@ -703,7 +703,7 @@ build_vector: case LINELOG_DST_TCP: { int i, num; - if (inst->tcp.timeout) { + if (fr_time_delta_ispos(inst->tcp.timeout)) { timeout = inst->tcp.timeout; } diff --git a/src/modules/rlm_logintime/rlm_logintime.c b/src/modules/rlm_logintime/rlm_logintime.c index 1e66405529..d70e5fbb4b 100644 --- a/src/modules/rlm_logintime/rlm_logintime.c +++ b/src/modules/rlm_logintime/rlm_logintime.c @@ -83,7 +83,7 @@ static int timecmp(UNUSED void *instance, request_t *request, UNUSED fr_pair_lis /* * If there's a request, use that timestamp. */ - if (timestr_match(check->vp_strvalue, request->packet->timestamp) >= 0) return 0; + if (fr_time_delta_gteq(timestr_match(check->vp_strvalue, request->packet->timestamp), fr_time_delta_wrap(0))) return 0; return -1; } @@ -167,12 +167,12 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod * Compare the time the request was received with the current Login-Time value */ left = timestr_match(ends->vp_strvalue, request->packet->timestamp); - if (left < 0) RETURN_MODULE_DISALLOW; /* outside of the allowed time */ + if (fr_time_delta_isneg(left)) RETURN_MODULE_DISALLOW; /* outside of the allowed time */ /* * Do nothing, login time is not controlled (unendsed). */ - if (left == 0) RETURN_MODULE_OK; + if (fr_time_delta_eq(left, fr_time_delta_wrap(0))) RETURN_MODULE_OK; /* * The min_time setting is to deal with NAS that won't allow Session-vp values below a certain value @@ -180,7 +180,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod * * We don't know were going to get another chance to lock out the user, so we need to do it now. */ - if (left < inst->min_time) { + if (fr_time_delta_lt(left, inst->min_time)) { REDEBUG("Login outside of allowed time-slot (session end %s, with lockout %i seconds before)", ends->vp_strvalue, (int) fr_time_delta_to_sec(inst->min_time)); @@ -231,7 +231,7 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) { rlm_logintime_t *inst = instance; - if (inst->min_time == 0) { + if (!fr_time_delta_ispos(inst->min_time)) { cf_log_err(conf, "Invalid value '0' for minimum_timeout"); return -1; } diff --git a/src/modules/rlm_logintime/timestr.c b/src/modules/rlm_logintime/timestr.c index 068bf96aa3..6ff54ed053 100644 --- a/src/modules/rlm_logintime/timestr.c +++ b/src/modules/rlm_logintime/timestr.c @@ -245,9 +245,9 @@ fr_time_delta_t timestr_match(char const *tmstr, fr_time_t when) break; } - if (!tot) return -1; + if (!tot) return fr_time_delta_wrap(-1); - if (i == now) return 0; + if (i == now) return fr_time_delta_wrap(0); return fr_time_delta_from_sec(tot); } diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 93cadcfc8d..c189ff8ac4 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -2245,15 +2245,15 @@ static int mod_instantiate(void *instance, CONF_SECTION *conf) /* * Check ntlm_auth_timeout is sane */ - if (!inst->ntlm_auth_timeout) { + if (!fr_time_delta_ispos(inst->ntlm_auth_timeout)) { inst->ntlm_auth_timeout = fr_time_delta_from_sec(EXEC_TIMEOUT); } - if (inst->ntlm_auth_timeout < fr_time_delta_from_sec(1)) { + if (fr_time_delta_lt(inst->ntlm_auth_timeout, fr_time_delta_from_sec(1))) { cf_log_err(conf, "ntml_auth_timeout '%pVs' is too small (minimum: 1s)", fr_box_time_delta(inst->ntlm_auth_timeout)); return -1; } - if (inst->ntlm_auth_timeout > fr_time_delta_from_sec(10)) { + if (fr_time_delta_gt(inst->ntlm_auth_timeout, fr_time_delta_from_sec(10))) { cf_log_err(conf, "ntlm_auth_timeout '%pVs' is too large (maximum: 10s)", fr_box_time_delta(inst->ntlm_auth_timeout)); return -1; diff --git a/src/modules/rlm_radius/rlm_radius.c b/src/modules/rlm_radius/rlm_radius.c index 3c00bf65aa..bec7af337f 100644 --- a/src/modules/rlm_radius/rlm_radius.c +++ b/src/modules/rlm_radius/rlm_radius.c @@ -456,7 +456,7 @@ static unlang_action_t CC_HINT(nonnull) mod_process(rlm_rcode_t *p_result, modul } if ((request->packet->code >= FR_RADIUS_CODE_MAX) || - !inst->retry[request->packet->code].irt) { /* can't be zero */ + !fr_time_delta_ispos(inst->retry[request->packet->code].irt)) { /* can't be zero */ REDEBUG("Invalid packet code %d", request->packet->code); RETURN_MODULE_FAIL; } diff --git a/src/modules/rlm_radius/rlm_radius_udp.c b/src/modules/rlm_radius/rlm_radius_udp.c index 97cd8f260a..8047696f4d 100644 --- a/src/modules/rlm_radius/rlm_radius_udp.c +++ b/src/modules/rlm_radius/rlm_radius_udp.c @@ -1831,7 +1831,7 @@ static void request_mux(fr_event_list_t *el, */ if (fr_time_eq(u->retry.start, fr_time_wrap(0))) { (void) fr_retry_init(&u->retry, fr_time(), &h->inst->parent->retry[u->code]); - fr_assert(u->retry.rt > 0); + fr_assert(fr_time_delta_ispos(u->retry.rt)); fr_assert(fr_time_gt(u->retry.next, fr_time_wrap(0))); } diff --git a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c index b8ac3e4e71..744a2b038d 100644 --- a/src/modules/rlm_redis_ippool/rlm_redis_ippool.c +++ b/src/modules/rlm_redis_ippool/rlm_redis_ippool.c @@ -466,7 +466,7 @@ static void ippool_action_print(request_t *request, ippool_action_t action, * @param[in] key_len length of the key. * @param[in] wait_num If > 0 wait until this many slaves have replicated the data * from the last command. - * @param[in] wait_timeout How long to wait for slaves. + * @param[in] wait_timeout How long to wait for slaves to replicate the data. * @param[in] digest of script. * @param[in] script to upload. * @param[in] cmd EVALSHA command to execute. @@ -535,7 +535,7 @@ static fr_redis_rcode_t ippool_script(redisReply **out, request_t *request, fr_r redisAppendCommand(conn->handle, "EXEC"); pipelined = 4; if (wait_num) { - redisAppendCommand(conn->handle, "WAIT %i %i", wait_num, wait_timeout); + redisAppendCommand(conn->handle, "WAIT %i %i", wait_num, fr_time_delta_to_msec(wait_timeout)); pipelined++; } diff --git a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c index aa54b95709..3da432ad69 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_mysql/rlm_sql_mysql.c @@ -287,7 +287,7 @@ static sql_rcode_t sql_socket_init(rlm_sql_handle_t *handle, rlm_sql_config_t *c #if (MYSQL_VERSION_ID >= 50000) mysql_options(&(conn->db), MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout); - if (config->query_timeout) { + if (fr_time_delta_ispos(config->query_timeout)) { unsigned int read_timeout = fr_time_delta_to_sec(config->query_timeout); unsigned int write_timeout = fr_time_delta_to_sec(config->query_timeout); diff --git a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c index 7c6e8006ef..c90127faa6 100644 --- a/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c +++ b/src/modules/rlm_sql/drivers/rlm_sql_postgresql/rlm_sql_postgresql.c @@ -290,17 +290,18 @@ static CC_HINT(nonnull) sql_rcode_t sql_query(rlm_sql_handle_t *handle, rlm_sql_ while (PQisBusy(conn->db)) { int r; fd_set read_fd; - fr_time_delta_t elapsed = 0; + fr_time_delta_t elapsed = fr_time_delta_wrap(0); FD_ZERO(&read_fd); FD_SET(sockfd, &read_fd); - if (config->query_timeout) { + if (fr_time_delta_ispos(config->query_timeout)) { elapsed = fr_time_sub(fr_time(), start); - if (elapsed >= timeout) goto too_long; + if (fr_time_delta_gteq(elapsed, timeout)) goto too_long; } - r = select(sockfd + 1, &read_fd, NULL, NULL, config->query_timeout ? &fr_time_delta_to_timeval(timeout - elapsed) : NULL); + r = select(sockfd + 1, &read_fd, NULL, NULL, fr_time_delta_ispos(config->query_timeout) ? + &fr_time_delta_to_timeval(fr_time_delta_sub(timeout, elapsed)) : NULL); if (r == 0) { too_long: ERROR("Socket read timeout after %d seconds", (int) fr_time_delta_to_sec(config->query_timeout)); @@ -578,7 +579,7 @@ static int mod_instantiate(rlm_sql_config_t const *config, void *instance, CONF_ db_string = talloc_asprintf_append(db_string, " password='%s'", config->sql_password); } - if (config->query_timeout) { + if (fr_time_delta_ispos(config->query_timeout)) { db_string = talloc_asprintf_append(db_string, " connect_timeout=%d", (int) fr_time_delta_to_sec(config->query_timeout)); } @@ -610,7 +611,7 @@ static int mod_instantiate(rlm_sql_config_t const *config, void *instance, CONF_ db_string = talloc_asprintf_append(db_string, " password='%s'", config->sql_password); } - if ((config->query_timeout) && !strstr(db_string, "connect_timeout=")) { + if (fr_time_delta_ispos(config->query_timeout) && !strstr(db_string, "connect_timeout=")) { db_string = talloc_asprintf_append(db_string, " connect_timeout=%d", (int) fr_time_delta_to_sec(config->query_timeout)); } diff --git a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c index 3318e56b9f..175f5fa785 100644 --- a/src/modules/rlm_sqlcounter/rlm_sqlcounter.c +++ b/src/modules/rlm_sqlcounter/rlm_sqlcounter.c @@ -435,7 +435,7 @@ static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, mod /* * Check if check item > counter */ - if (limit->vp_uint64 <= (uint64_t)fr_time_delta_from_sec(counter)) { + if (limit->vp_uint64 <= counter) { fr_pair_t *vp; /* User is denied access, send back a reply message */ diff --git a/src/protocols/dhcpv6/decode.c b/src/protocols/dhcpv6/decode.c index ac9b311ddb..a564e96a41 100644 --- a/src/protocols/dhcpv6/decode.c +++ b/src/protocols/dhcpv6/decode.c @@ -229,7 +229,7 @@ static ssize_t decode_value(TALLOC_CTX *ctx, fr_dcursor_t *cursor, fr_dict_t con talloc_free(vp); goto raw; } - vp->vp_date += fr_time_delta_from_sec(DHCPV6_DATE_OFFSET); + vp->vp_date = fr_unix_time_add(vp->vp_date, fr_time_delta_from_sec(DHCPV6_DATE_OFFSET)); break; case FR_TYPE_STRUCT: