From 47293a4f116e04a88b0797bafad0c98b4393b744 Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Thu, 5 Nov 2026 13:52:17 +0100 Subject: Clamp every elapsed time span at zero, using a set of helper functions --- src/opentracker.c | 2 +- src/ot_accesslist.c | 2 +- src/ot_clean.c | 2 +- src/ot_http.c | 2 +- src/ot_livesync.c | 4 ++-- src/ot_stats.c | 23 ++++++++++++----------- src/ot_udp.c | 4 ++-- src/trackerlogic.h | 24 ++++++++++++++++++++---- 8 files changed, 40 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/opentracker.c b/src/opentracker.c index 60a6d8c..8de3fc1 100644 --- a/src/opentracker.c +++ b/src/opentracker.c @@ -151,7 +151,7 @@ static void *server_mainloop(void *args) { while ((sock = workqueue_popresult(&iovec_entries, &iovector, &is_partial)) != -1) http_sendiovecdata(sock, &ws, iovec_entries, iovector, is_partial); - if (time_now_seconds() > next_timeout_check) { + if (time_is_past(next_timeout_check)) { int cursor = 0; while ((sock = fdstate_next_expired(time_now_seconds(), &cursor)) != -1) diff --git a/src/ot_accesslist.c b/src/ot_accesslist.c index 86f9a7d..ea5bdba 100644 --- a/src/ot_accesslist.c +++ b/src/ot_accesslist.c @@ -91,7 +91,7 @@ static ot_accesslist *accesslist_make(ot_accesslist *next, size_t size) { This will never delete head, because that might still be in use. */ static void accesslist_clean(ot_accesslist *accesslist) { while (accesslist && accesslist->next) { - if (accesslist->next->base + 5 < time_now_minutes()) + if (time_since_minutes(accesslist->next->base) > 5) accesslist->next = accesslist_free(accesslist->next); accesslist = accesslist->next; } diff --git a/src/ot_clean.c b/src/ot_clean.c index f181e83..2ebfd42 100644 --- a/src/ot_clean.c +++ b/src/ot_clean.c @@ -45,7 +45,7 @@ static ssize_t clean_single_bucket(ot_peer *peers, size_t peer_count, size_t pee int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { ot_vector *peer_vector = &peer_list->peers; - time_t timedout = (time_t)(time_now_minutes() - peer_list->base); + ot_time timedout = time_since_minutes(peer_list->base); size_t num_buckets = 1, removed_seeders = 0; /* No need to clean empty torrent */ diff --git a/src/ot_http.c b/src/ot_http.c index 96b8f4e..533a876 100644 --- a/src/ot_http.c +++ b/src/ot_http.c @@ -414,7 +414,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * pthread_mutex_unlock(&g_modest_fullscrape_mutex); HTTPERROR_500; } - if (exactmatch && (this_peer.last_fullscrape - new_peer->last_fullscrape) < OT_MODEST_PEER_TIMEOUT) { + if (exactmatch && time_since_seconds(new_peer->last_fullscrape) < OT_MODEST_PEER_TIMEOUT) { pthread_mutex_unlock(&g_modest_fullscrape_mutex); HTTPERROR_402_NOTMODEST; } diff --git a/src/ot_livesync.c b/src/ot_livesync.c index 85577f7..7d7208e 100644 --- a/src/ot_livesync.c +++ b/src/ot_livesync.c @@ -178,13 +178,13 @@ void livesync_ticker(void) { /* livesync_issue_peersync sets g_next_packet_time */ pthread_mutex_lock(&g_outbuf_mutex); - if (time_now_seconds() > g_v6_buf.next_packet_time && g_v6_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) + if (time_is_past(g_v6_buf.next_packet_time) && g_v6_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) livesync_issue_peersync(&g_v6_buf); else pthread_mutex_unlock(&g_outbuf_mutex); pthread_mutex_lock(&g_outbuf_mutex); - if (time_now_seconds() > g_v4_buf.next_packet_time && g_v4_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) + if (time_is_past(g_v4_buf.next_packet_time) && g_v4_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) livesync_issue_peersync(&g_v4_buf); else pthread_mutex_unlock(&g_outbuf_mutex); diff --git a/src/ot_stats.c b/src/ot_stats.c index 2d6335b..7b5b1b9 100644 --- a/src/ot_stats.c +++ b/src/ot_stats.c @@ -373,7 +373,7 @@ void stats_top_txt(char **reply, const char *reply_end, size_t amount) { static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); } static void stats_connections_mrtg(char **reply, const char *reply_end) { - ot_time t = time(NULL) - ot_start_time; + ot_time t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -386,7 +386,7 @@ static void stats_connections_mrtg(char **reply, const char *reply_end) { } static void stats_udpconnections_mrtg(char **reply, const char *reply_end) { - ot_time t = time(NULL) - ot_start_time; + ot_time t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -398,7 +398,7 @@ static void stats_udpconnections_mrtg(char **reply, const char *reply_end) { } static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) { - time_t t = time(NULL) - ot_start_time; + time_t t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -409,7 +409,7 @@ static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) { } static void stats_scrape_mrtg(char **reply, const char *reply_end) { - time_t t = time(NULL) - ot_start_time; + time_t t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -420,7 +420,7 @@ static void stats_scrape_mrtg(char **reply, const char *reply_end) { } static void stats_fullscrapes_mrtg(char **reply, const char *reply_end) { - ot_time t = time(NULL) - ot_start_time; + ot_time t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -468,7 +468,7 @@ static void stats_return_renew_bucket(char **reply, const char *reply_end) { } static void stats_return_sync_mrtg(char **reply, const char *reply_end) { - ot_time t = time(NULL) - ot_start_time; + ot_time t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -479,7 +479,7 @@ static void stats_return_sync_mrtg(char **reply, const char *reply_end) { } static void stats_return_completed_mrtg(char **reply, const char *reply_end) { - ot_time t = time(NULL) - ot_start_time; + ot_time t = time_since_seconds(ot_start_time); unsigned long long total[OT_COUNTER_COUNT]; counters_total(total); @@ -510,7 +510,7 @@ static void stats_return_everything(char **reply, const char *reply_end) { fmt_append(reply, reply_end, "\n"); fmt_append(reply, reply_end, "\n"); - fmt_append(reply, reply_end, " %llu\n", (unsigned long long)(time(NULL) - ot_start_time)); + fmt_append(reply, reply_end, " %llu\n", (unsigned long long)time_since_seconds(ot_start_time)); fmt_append(reply, reply_end, " \n"); fmt_append(reply, reply_end, " %zd\n", mutex_get_torrent_count()); fmt_append(reply, reply_end, " %llu\n", stats.torrent_count); @@ -785,7 +785,7 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL case EVENT_FULLSCRAPE_REQUEST: { ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ char _debug[512]; - int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(time_now_seconds() - ot_start_time) / 60); + int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)time_since_seconds(ot_start_time) / 60); off += ip_format(_debug + off, *ip); off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); (void)write(2, _debug, off); @@ -794,7 +794,7 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL case EVENT_FULLSCRAPE_REQUEST_GZIP: { ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ char _debug[512]; - int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(time_now_seconds() - ot_start_time) / 60); + int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)time_since_seconds(ot_start_time) / 60); off += ip_format(_debug + off, *ip); off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); (void)write(2, _debug, off); @@ -804,7 +804,8 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL COUNT(OT_COUNTER_FAILED + event_data, 1); break; case EVENT_RENEW: - COUNT(OT_COUNTER_RENEWED + event_data, 1); + if (event_data < OT_PEER_TIMEOUT) + COUNT(OT_COUNTER_RENEWED + event_data, 1); break; case EVENT_SYNC: COUNT(OT_COUNTER_SYNCS, event_data); diff --git a/src/ot_udp.c b/src/ot_udp.c index 644b71d..e67ca1f 100644 --- a/src/ot_udp.c +++ b/src/ot_udp.c @@ -39,12 +39,12 @@ static void udp_make_connectionid(uint32_t connid[2], const ot_ip6 remoteip, int int i; uint32_t current_key_of_the_hour; - if (time_now_minutes() - g_hour_of_the_key >= 60) { + if (time_since_minutes(g_hour_of_the_key) >= 60) { uint32_t old_key_of_the_hour = g_key_of_the_hour[0]; uint32_t new_key_of_the_hour = random_uint32(); /* If in the meantime another thread has performed key rotation, do not overwrite their results */ - if (time_now_minutes() - g_hour_of_the_key >= 60) { + if (time_since_minutes(g_hour_of_the_key) >= 60) { /* Upgrade en bloc */ g_hour_of_the_key = time_now_minutes(); g_key_of_the_hour[0] = new_key_of_the_hour; diff --git a/src/trackerlogic.h b/src/trackerlogic.h index 692b6af..c8d859c 100644 --- a/src/trackerlogic.h +++ b/src/trackerlogic.h @@ -61,10 +61,10 @@ typedef struct { #define OT_PEER_TIMEOUT 45 /* We maintain a list of 1024 pointers to sorted list of ot_torrent structs - Sort key is, of course, its hash */ -/* Set from the Makefile, 8 to 16. More buckets means shorter vectors and a - cheaper insert, which only pays for a tracker carrying millions of - torrents; see DESIGN. */ + Sort key is, of course, its hash. + Can be tweked from the Makefile, sensible values are between 8 in 16. More + buckets means shorter vectors and a cheaper insert, which only pays for a + tracker carrying millions of torrents. Consult the DESIGN document. */ #ifndef OT_BUCKET_COUNT_BITS #define OT_BUCKET_COUNT_BITS 10 #endif @@ -95,6 +95,22 @@ static inline ot_time time_now_minutes(void) { return time_now_seconds() / 60; } /* For the deadlines the tracker sets on itself, which read better as the span they allow than as an addition to the current second */ static inline ot_time time_future_seconds(int span) { return time_now_seconds() + span; } + +/* How long ago a stamp was taken. */ +_Static_assert((ot_time)-1 < 0, "ot_time has to be signed for time_since_* to clamp"); + +static inline ot_time time_since_seconds(ot_time then) { + ot_time now = time_now_seconds(); + return now > then ? now - then : 0; +} + +static inline ot_time time_since_minutes(ot_time then) { + ot_time now = time_now_minutes(); + return now > then ? now - then : 0; +} + +/* Has a deadline the tracker set on itself gone by? */ +static inline int time_is_past(ot_time deadline) { return time_now_seconds() > deadline; } /* Cleared from the interrupt handler and read by every worker */ extern _Atomic int g_opentracker_running; -- cgit v1.3