summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2026-11-05 13:52:17 +0100
committerDirk Engling <erdgeist@erdgeist.org>2026-11-05 13:52:17 +0100
commit47293a4f116e04a88b0797bafad0c98b4393b744 (patch)
treeb71d19aa8637382a6d3b453614a6a52a2c1b3245 /src
parent9a3a01643fc78bf544a1e6f5ca5c7529e2026b25 (diff)
Clamp every elapsed time span at zero, using a set of helper functions
Diffstat (limited to 'src')
-rw-r--r--src/opentracker.c2
-rw-r--r--src/ot_accesslist.c2
-rw-r--r--src/ot_clean.c2
-rw-r--r--src/ot_http.c2
-rw-r--r--src/ot_livesync.c4
-rw-r--r--src/ot_stats.c23
-rw-r--r--src/ot_udp.c4
-rw-r--r--src/trackerlogic.h24
8 files changed, 40 insertions, 23 deletions
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) {
151 while ((sock = workqueue_popresult(&iovec_entries, &iovector, &is_partial)) != -1) 151 while ((sock = workqueue_popresult(&iovec_entries, &iovector, &is_partial)) != -1)
152 http_sendiovecdata(sock, &ws, iovec_entries, iovector, is_partial); 152 http_sendiovecdata(sock, &ws, iovec_entries, iovector, is_partial);
153 153
154 if (time_now_seconds() > next_timeout_check) { 154 if (time_is_past(next_timeout_check)) {
155 int cursor = 0; 155 int cursor = 0;
156 156
157 while ((sock = fdstate_next_expired(time_now_seconds(), &cursor)) != -1) 157 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) {
91 This will never delete head, because that might still be in use. */ 91 This will never delete head, because that might still be in use. */
92static void accesslist_clean(ot_accesslist *accesslist) { 92static void accesslist_clean(ot_accesslist *accesslist) {
93 while (accesslist && accesslist->next) { 93 while (accesslist && accesslist->next) {
94 if (accesslist->next->base + 5 < time_now_minutes()) 94 if (time_since_minutes(accesslist->next->base) > 5)
95 accesslist->next = accesslist_free(accesslist->next); 95 accesslist->next = accesslist_free(accesslist->next);
96 accesslist = accesslist->next; 96 accesslist = accesslist->next;
97 } 97 }
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
45 45
46int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { 46int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) {
47 ot_vector *peer_vector = &peer_list->peers; 47 ot_vector *peer_vector = &peer_list->peers;
48 time_t timedout = (time_t)(time_now_minutes() - peer_list->base); 48 ot_time timedout = time_since_minutes(peer_list->base);
49 size_t num_buckets = 1, removed_seeders = 0; 49 size_t num_buckets = 1, removed_seeders = 0;
50 50
51 /* No need to clean empty torrent */ 51 /* 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 *
414 pthread_mutex_unlock(&g_modest_fullscrape_mutex); 414 pthread_mutex_unlock(&g_modest_fullscrape_mutex);
415 HTTPERROR_500; 415 HTTPERROR_500;
416 } 416 }
417 if (exactmatch && (this_peer.last_fullscrape - new_peer->last_fullscrape) < OT_MODEST_PEER_TIMEOUT) { 417 if (exactmatch && time_since_seconds(new_peer->last_fullscrape) < OT_MODEST_PEER_TIMEOUT) {
418 pthread_mutex_unlock(&g_modest_fullscrape_mutex); 418 pthread_mutex_unlock(&g_modest_fullscrape_mutex);
419 HTTPERROR_402_NOTMODEST; 419 HTTPERROR_402_NOTMODEST;
420 } 420 }
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) {
178 178
179 /* livesync_issue_peersync sets g_next_packet_time */ 179 /* livesync_issue_peersync sets g_next_packet_time */
180 pthread_mutex_lock(&g_outbuf_mutex); 180 pthread_mutex_lock(&g_outbuf_mutex);
181 if (time_now_seconds() > g_v6_buf.next_packet_time && g_v6_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) 181 if (time_is_past(g_v6_buf.next_packet_time) && g_v6_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t))
182 livesync_issue_peersync(&g_v6_buf); 182 livesync_issue_peersync(&g_v6_buf);
183 else 183 else
184 pthread_mutex_unlock(&g_outbuf_mutex); 184 pthread_mutex_unlock(&g_outbuf_mutex);
185 185
186 pthread_mutex_lock(&g_outbuf_mutex); 186 pthread_mutex_lock(&g_outbuf_mutex);
187 if (time_now_seconds() > g_v4_buf.next_packet_time && g_v4_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t)) 187 if (time_is_past(g_v4_buf.next_packet_time) && g_v4_buf.fill > sizeof(g_tracker_id) + sizeof(uint32_t))
188 livesync_issue_peersync(&g_v4_buf); 188 livesync_issue_peersync(&g_v4_buf);
189 else 189 else
190 pthread_mutex_unlock(&g_outbuf_mutex); 190 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) {
373static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); } 373static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); }
374 374
375static void stats_connections_mrtg(char **reply, const char *reply_end) { 375static void stats_connections_mrtg(char **reply, const char *reply_end) {
376 ot_time t = time(NULL) - ot_start_time; 376 ot_time t = time_since_seconds(ot_start_time);
377 unsigned long long total[OT_COUNTER_COUNT]; 377 unsigned long long total[OT_COUNTER_COUNT];
378 378
379 counters_total(total); 379 counters_total(total);
@@ -386,7 +386,7 @@ static void stats_connections_mrtg(char **reply, const char *reply_end) {
386} 386}
387 387
388static void stats_udpconnections_mrtg(char **reply, const char *reply_end) { 388static void stats_udpconnections_mrtg(char **reply, const char *reply_end) {
389 ot_time t = time(NULL) - ot_start_time; 389 ot_time t = time_since_seconds(ot_start_time);
390 unsigned long long total[OT_COUNTER_COUNT]; 390 unsigned long long total[OT_COUNTER_COUNT];
391 391
392 counters_total(total); 392 counters_total(total);
@@ -398,7 +398,7 @@ static void stats_udpconnections_mrtg(char **reply, const char *reply_end) {
398} 398}
399 399
400static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) { 400static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) {
401 time_t t = time(NULL) - ot_start_time; 401 time_t t = time_since_seconds(ot_start_time);
402 unsigned long long total[OT_COUNTER_COUNT]; 402 unsigned long long total[OT_COUNTER_COUNT];
403 403
404 counters_total(total); 404 counters_total(total);
@@ -409,7 +409,7 @@ static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) {
409} 409}
410 410
411static void stats_scrape_mrtg(char **reply, const char *reply_end) { 411static void stats_scrape_mrtg(char **reply, const char *reply_end) {
412 time_t t = time(NULL) - ot_start_time; 412 time_t t = time_since_seconds(ot_start_time);
413 unsigned long long total[OT_COUNTER_COUNT]; 413 unsigned long long total[OT_COUNTER_COUNT];
414 414
415 counters_total(total); 415 counters_total(total);
@@ -420,7 +420,7 @@ static void stats_scrape_mrtg(char **reply, const char *reply_end) {
420} 420}
421 421
422static void stats_fullscrapes_mrtg(char **reply, const char *reply_end) { 422static void stats_fullscrapes_mrtg(char **reply, const char *reply_end) {
423 ot_time t = time(NULL) - ot_start_time; 423 ot_time t = time_since_seconds(ot_start_time);
424 unsigned long long total[OT_COUNTER_COUNT]; 424 unsigned long long total[OT_COUNTER_COUNT];
425 425
426 counters_total(total); 426 counters_total(total);
@@ -468,7 +468,7 @@ static void stats_return_renew_bucket(char **reply, const char *reply_end) {
468} 468}
469 469
470static void stats_return_sync_mrtg(char **reply, const char *reply_end) { 470static void stats_return_sync_mrtg(char **reply, const char *reply_end) {
471 ot_time t = time(NULL) - ot_start_time; 471 ot_time t = time_since_seconds(ot_start_time);
472 unsigned long long total[OT_COUNTER_COUNT]; 472 unsigned long long total[OT_COUNTER_COUNT];
473 473
474 counters_total(total); 474 counters_total(total);
@@ -479,7 +479,7 @@ static void stats_return_sync_mrtg(char **reply, const char *reply_end) {
479} 479}
480 480
481static void stats_return_completed_mrtg(char **reply, const char *reply_end) { 481static void stats_return_completed_mrtg(char **reply, const char *reply_end) {
482 ot_time t = time(NULL) - ot_start_time; 482 ot_time t = time_since_seconds(ot_start_time);
483 unsigned long long total[OT_COUNTER_COUNT]; 483 unsigned long long total[OT_COUNTER_COUNT];
484 484
485 counters_total(total); 485 counters_total(total);
@@ -510,7 +510,7 @@ static void stats_return_everything(char **reply, const char *reply_end) {
510 510
511 fmt_append(reply, reply_end, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 511 fmt_append(reply, reply_end, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
512 fmt_append(reply, reply_end, "<stats>\n"); 512 fmt_append(reply, reply_end, "<stats>\n");
513 fmt_append(reply, reply_end, " <uptime>%llu</uptime>\n", (unsigned long long)(time(NULL) - ot_start_time)); 513 fmt_append(reply, reply_end, " <uptime>%llu</uptime>\n", (unsigned long long)time_since_seconds(ot_start_time));
514 fmt_append(reply, reply_end, " <torrents>\n"); 514 fmt_append(reply, reply_end, " <torrents>\n");
515 fmt_append(reply, reply_end, " <count_mutex>%zd</count_mutex>\n", mutex_get_torrent_count()); 515 fmt_append(reply, reply_end, " <count_mutex>%zd</count_mutex>\n", mutex_get_torrent_count());
516 fmt_append(reply, reply_end, " <count_iterator>%llu</count_iterator>\n", stats.torrent_count); 516 fmt_append(reply, reply_end, " <count_iterator>%llu</count_iterator>\n", stats.torrent_count);
@@ -785,7 +785,7 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL
785 case EVENT_FULLSCRAPE_REQUEST: { 785 case EVENT_FULLSCRAPE_REQUEST: {
786 ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ 786 ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */
787 char _debug[512]; 787 char _debug[512];
788 int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(time_now_seconds() - ot_start_time) / 60); 788 int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)time_since_seconds(ot_start_time) / 60);
789 off += ip_format(_debug + off, *ip); 789 off += ip_format(_debug + off, *ip);
790 off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); 790 off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n");
791 (void)write(2, _debug, off); 791 (void)write(2, _debug, off);
@@ -794,7 +794,7 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL
794 case EVENT_FULLSCRAPE_REQUEST_GZIP: { 794 case EVENT_FULLSCRAPE_REQUEST_GZIP: {
795 ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ 795 ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */
796 char _debug[512]; 796 char _debug[512];
797 int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(time_now_seconds() - ot_start_time) / 60); 797 int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)time_since_seconds(ot_start_time) / 60);
798 off += ip_format(_debug + off, *ip); 798 off += ip_format(_debug + off, *ip);
799 off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); 799 off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n");
800 (void)write(2, _debug, off); 800 (void)write(2, _debug, off);
@@ -804,7 +804,8 @@ void stats_issue_event(struct ot_workstruct *ws, ot_status_event event, PROTO_FL
804 COUNT(OT_COUNTER_FAILED + event_data, 1); 804 COUNT(OT_COUNTER_FAILED + event_data, 1);
805 break; 805 break;
806 case EVENT_RENEW: 806 case EVENT_RENEW:
807 COUNT(OT_COUNTER_RENEWED + event_data, 1); 807 if (event_data < OT_PEER_TIMEOUT)
808 COUNT(OT_COUNTER_RENEWED + event_data, 1);
808 break; 809 break;
809 case EVENT_SYNC: 810 case EVENT_SYNC:
810 COUNT(OT_COUNTER_SYNCS, event_data); 811 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
39 int i; 39 int i;
40 uint32_t current_key_of_the_hour; 40 uint32_t current_key_of_the_hour;
41 41
42 if (time_now_minutes() - g_hour_of_the_key >= 60) { 42 if (time_since_minutes(g_hour_of_the_key) >= 60) {
43 uint32_t old_key_of_the_hour = g_key_of_the_hour[0]; 43 uint32_t old_key_of_the_hour = g_key_of_the_hour[0];
44 uint32_t new_key_of_the_hour = random_uint32(); 44 uint32_t new_key_of_the_hour = random_uint32();
45 /* If in the meantime another thread has performed 45 /* If in the meantime another thread has performed
46 key rotation, do not overwrite their results */ 46 key rotation, do not overwrite their results */
47 if (time_now_minutes() - g_hour_of_the_key >= 60) { 47 if (time_since_minutes(g_hour_of_the_key) >= 60) {
48 /* Upgrade en bloc */ 48 /* Upgrade en bloc */
49 g_hour_of_the_key = time_now_minutes(); 49 g_hour_of_the_key = time_now_minutes();
50 g_key_of_the_hour[0] = new_key_of_the_hour; 50 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 {
61#define OT_PEER_TIMEOUT 45 61#define OT_PEER_TIMEOUT 45
62 62
63/* We maintain a list of 1024 pointers to sorted list of ot_torrent structs 63/* We maintain a list of 1024 pointers to sorted list of ot_torrent structs
64 Sort key is, of course, its hash */ 64 Sort key is, of course, its hash.
65/* Set from the Makefile, 8 to 16. More buckets means shorter vectors and a 65 Can be tweked from the Makefile, sensible values are between 8 in 16. More
66 cheaper insert, which only pays for a tracker carrying millions of 66 buckets means shorter vectors and a cheaper insert, which only pays for a
67 torrents; see DESIGN. */ 67 tracker carrying millions of torrents. Consult the DESIGN document. */
68#ifndef OT_BUCKET_COUNT_BITS 68#ifndef OT_BUCKET_COUNT_BITS
69#define OT_BUCKET_COUNT_BITS 10 69#define OT_BUCKET_COUNT_BITS 10
70#endif 70#endif
@@ -95,6 +95,22 @@ static inline ot_time time_now_minutes(void) { return time_now_seconds() / 60; }
95/* For the deadlines the tracker sets on itself, which read better as the 95/* For the deadlines the tracker sets on itself, which read better as the
96 span they allow than as an addition to the current second */ 96 span they allow than as an addition to the current second */
97static inline ot_time time_future_seconds(int span) { return time_now_seconds() + span; } 97static inline ot_time time_future_seconds(int span) { return time_now_seconds() + span; }
98
99/* How long ago a stamp was taken. */
100_Static_assert((ot_time)-1 < 0, "ot_time has to be signed for time_since_* to clamp");
101
102static inline ot_time time_since_seconds(ot_time then) {
103 ot_time now = time_now_seconds();
104 return now > then ? now - then : 0;
105}
106
107static inline ot_time time_since_minutes(ot_time then) {
108 ot_time now = time_now_minutes();
109 return now > then ? now - then : 0;
110}
111
112/* Has a deadline the tracker set on itself gone by? */
113static inline int time_is_past(ot_time deadline) { return time_now_seconds() > deadline; }
98/* Cleared from the interrupt handler and read by every worker */ 114/* Cleared from the interrupt handler and read by every worker */
99extern _Atomic int g_opentracker_running; 115extern _Atomic int g_opentracker_running;
100 116