diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-05 13:52:17 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2026-11-05 13:52:17 +0100 |
| commit | 47293a4f116e04a88b0797bafad0c98b4393b744 (patch) | |
| tree | b71d19aa8637382a6d3b453614a6a52a2c1b3245 /src | |
| parent | 9a3a01643fc78bf544a1e6f5ca5c7529e2026b25 (diff) | |
Clamp every elapsed time span at zero, using a set of helper functions
Diffstat (limited to 'src')
| -rw-r--r-- | src/opentracker.c | 2 | ||||
| -rw-r--r-- | src/ot_accesslist.c | 2 | ||||
| -rw-r--r-- | src/ot_clean.c | 2 | ||||
| -rw-r--r-- | src/ot_http.c | 2 | ||||
| -rw-r--r-- | src/ot_livesync.c | 4 | ||||
| -rw-r--r-- | src/ot_stats.c | 23 | ||||
| -rw-r--r-- | src/ot_udp.c | 4 | ||||
| -rw-r--r-- | src/trackerlogic.h | 24 |
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. */ |
| 92 | static void accesslist_clean(ot_accesslist *accesslist) { | 92 | static 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 | ||
| 46 | int clean_single_peer_list(ot_peerlist *peer_list, size_t peer_size) { | 46 | int 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) { | |||
| 373 | static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); } | 373 | static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); } |
| 374 | 374 | ||
| 375 | static void stats_connections_mrtg(char **reply, const char *reply_end) { | 375 | static 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 | ||
| 388 | static void stats_udpconnections_mrtg(char **reply, const char *reply_end) { | 388 | static 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 | ||
| 400 | static void stats_tcpconnections_mrtg(char **reply, const char *reply_end) { | 400 | static 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 | ||
| 411 | static void stats_scrape_mrtg(char **reply, const char *reply_end) { | 411 | static 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 | ||
| 422 | static void stats_fullscrapes_mrtg(char **reply, const char *reply_end) { | 422 | static 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 | ||
| 470 | static void stats_return_sync_mrtg(char **reply, const char *reply_end) { | 470 | static 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 | ||
| 481 | static void stats_return_completed_mrtg(char **reply, const char *reply_end) { | 481 | static 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 */ |
| 97 | static inline ot_time time_future_seconds(int span) { return time_now_seconds() + span; } | 97 | static 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 | |||
| 102 | static 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 | |||
| 107 | static 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? */ | ||
| 113 | static 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 */ |
| 99 | extern _Atomic int g_opentracker_running; | 115 | extern _Atomic int g_opentracker_running; |
| 100 | 116 | ||
