diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | opentracker.c | 26 | ||||
| -rw-r--r-- | ot_fdstate.c | 28 | ||||
| -rw-r--r-- | ot_fdstate.h | 5 | ||||
| -rw-r--r-- | ot_http.c | 24 | ||||
| -rw-r--r-- | ot_timeout.h | 39 | ||||
| -rw-r--r-- | proxy.c | 15 |
7 files changed, 69 insertions, 70 deletions
| @@ -70,7 +70,7 @@ LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread | |||
| 70 | BINARY =opentracker | 70 | BINARY =opentracker |
| 71 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_batch.h ot_buf.h ot_fdstate.h ot_hex.h ot_ip.h ot_config.h ot_scan.h ot_socket.h ot_mutex.h ot_random.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h ot_rijndael.h | 71 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_batch.h ot_buf.h ot_fdstate.h ot_hex.h ot_ip.h ot_config.h ot_scan.h ot_socket.h ot_mutex.h ot_random.h ot_stats.h ot_vector.h ot_clean.h ot_udp.h ot_iovec.h ot_fullscrape.h ot_accesslist.h ot_http.h ot_livesync.h ot_rijndael.h |
| 72 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c ot_batch.c ot_buf.c ot_fdstate.c ot_hex.c ot_ip.c ot_config.c ot_scan.c ot_socket.c ot_mutex.c ot_random.c ot_stats.c ot_vector.c ot_clean.c ot_udp.c ot_iovec.c ot_fullscrape.c ot_accesslist.c ot_http.c ot_livesync.c ot_rijndael.c | 72 | SOURCES=opentracker.c trackerlogic.c scan_urlencoded_query.c ot_batch.c ot_buf.c ot_fdstate.c ot_hex.c ot_ip.c ot_config.c ot_scan.c ot_socket.c ot_mutex.c ot_random.c ot_stats.c ot_vector.c ot_clean.c ot_udp.c ot_iovec.c ot_fullscrape.c ot_accesslist.c ot_http.c ot_livesync.c ot_rijndael.c |
| 73 | SOURCES_proxy=proxy.c ot_batch.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c ot_ip.c ot_socket.c | 73 | SOURCES_proxy=proxy.c ot_batch.c ot_fdstate.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c ot_ip.c ot_socket.c |
| 74 | 74 | ||
| 75 | OBJECTS = $(SOURCES:%.c=%.o) | 75 | OBJECTS = $(SOURCES:%.c=%.o) |
| 76 | OBJECTS_debug = $(SOURCES:%.c=%.debug.o) | 76 | OBJECTS_debug = $(SOURCES:%.c=%.debug.o) |
diff --git a/opentracker.c b/opentracker.c index 60bdceb..0f0b314 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -34,8 +34,8 @@ | |||
| 34 | #include "ot_mutex.h" | 34 | #include "ot_mutex.h" |
| 35 | #include "ot_random.h" | 35 | #include "ot_random.h" |
| 36 | #include "ot_scan.h" | 36 | #include "ot_scan.h" |
| 37 | #include "ot_fdstate.h" | ||
| 37 | #include "ot_socket.h" | 38 | #include "ot_socket.h" |
| 38 | #include "ot_timeout.h" | ||
| 39 | #include "ot_stats.h" | 39 | #include "ot_stats.h" |
| 40 | #include "ot_udp.h" | 40 | #include "ot_udp.h" |
| 41 | #include "trackerlogic.h" | 41 | #include "trackerlogic.h" |
| @@ -118,7 +118,7 @@ static ssize_t header_complete(char *request, ssize_t byte_count) { | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | static void handle_dead(const int64_t sock) { | 120 | static void handle_dead(const int64_t sock) { |
| 121 | struct http_data *cookie = io_getcookie(sock); | 121 | struct http_data *cookie = fdstate_cookie(sock); |
| 122 | if (cookie) { | 122 | if (cookie) { |
| 123 | if (cookie->batch) | 123 | if (cookie->batch) |
| 124 | batch_reset(cookie->batch); | 124 | batch_reset(cookie->batch); |
| @@ -128,11 +128,13 @@ static void handle_dead(const int64_t sock) { | |||
| 128 | mutex_workqueue_canceltask(sock); | 128 | mutex_workqueue_canceltask(sock); |
| 129 | free(cookie); | 129 | free(cookie); |
| 130 | } | 130 | } |
| 131 | /* The generation has to move before the kernel can reissue the number */ | ||
| 132 | fdstate_close(sock); | ||
| 131 | io_close(sock); | 133 | io_close(sock); |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | static void handle_read(const int64_t sock, struct ot_workstruct *ws) { | 136 | static void handle_read(const int64_t sock, struct ot_workstruct *ws) { |
| 135 | struct http_data *cookie = io_getcookie(sock); | 137 | struct http_data *cookie = fdstate_cookie(sock); |
| 136 | ssize_t byte_count = io_tryread(sock, ws->inbuf, G_INBUF_SIZE); | 138 | ssize_t byte_count = io_tryread(sock, ws->inbuf, G_INBUF_SIZE); |
| 137 | 139 | ||
| 138 | if (byte_count == 0 || byte_count == -3) { | 140 | if (byte_count == 0 || byte_count == -3) { |
| @@ -176,7 +178,7 @@ static void handle_read(const int64_t sock, struct ot_workstruct *ws) { | |||
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | static void handle_write(const int64_t sock) { | 180 | static void handle_write(const int64_t sock) { |
| 179 | struct http_data *cookie = io_getcookie(sock); | 181 | struct http_data *cookie = fdstate_cookie(sock); |
| 180 | int chunked = 0; | 182 | int chunked = 0; |
| 181 | 183 | ||
| 182 | if (cookie) { | 184 | if (cookie) { |
| @@ -218,12 +220,11 @@ static void handle_accept(const int64_t serversocket) { | |||
| 218 | memset(cookie, 0, sizeof(struct http_data)); | 220 | memset(cookie, 0, sizeof(struct http_data)); |
| 219 | memcpy(cookie->ip, ip, sizeof(ot_ip6)); | 221 | memcpy(cookie->ip, ip, sizeof(ot_ip6)); |
| 220 | 222 | ||
| 221 | io_setcookie(sock, cookie); | 223 | fdstate_open(sock, cookie, g_now_seconds + OT_CLIENT_TIMEOUT); |
| 222 | io_wantread(sock); | 224 | io_wantread(sock); |
| 223 | 225 | ||
| 224 | stats_issue_event(EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); | 226 | stats_issue_event(EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
| 225 | 227 | ||
| 226 | timeout_in(sock, OT_CLIENT_TIMEOUT); | ||
| 227 | } | 228 | } |
| 228 | io_eagain(serversocket); | 229 | io_eagain(serversocket); |
| 229 | } | 230 | } |
| @@ -255,7 +256,7 @@ static void *server_mainloop(void *args) { | |||
| 255 | io_wait(); | 256 | io_wait(); |
| 256 | 257 | ||
| 257 | while ((sock = io_canread()) != -1) { | 258 | while ((sock = io_canread()) != -1) { |
| 258 | const void *cookie = io_getcookie(sock); | 259 | const void *cookie = fdstate_cookie(sock); |
| 259 | if ((intptr_t)cookie == FLAG_TCP) | 260 | if ((intptr_t)cookie == FLAG_TCP) |
| 260 | handle_accept(sock); | 261 | handle_accept(sock); |
| 261 | else if ((intptr_t)cookie == FLAG_UDP) | 262 | else if ((intptr_t)cookie == FLAG_UDP) |
| @@ -273,7 +274,9 @@ static void *server_mainloop(void *args) { | |||
| 273 | handle_write(sock); | 274 | handle_write(sock); |
| 274 | 275 | ||
| 275 | if (g_now_seconds > next_timeout_check) { | 276 | if (g_now_seconds > next_timeout_check) { |
| 276 | while ((sock = io_timeouted()) != -1) | 277 | int cursor = 0; |
| 278 | |||
| 279 | while ((sock = fdstate_next_expired(g_now_seconds, &cursor)) != -1) | ||
| 277 | handle_dead(sock); | 280 | handle_dead(sock); |
| 278 | next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; | 281 | next_timeout_check = g_now_seconds + OT_CLIENT_TIMEOUT_CHECKINTERVAL; |
| 279 | } | 282 | } |
| @@ -319,7 +322,7 @@ static void listen_bind_one(ot_listen *entry) { | |||
| 319 | if (!io_fd(entry->sock)) | 322 | if (!io_fd(entry->sock)) |
| 320 | panic("io_fd"); | 323 | panic("io_fd"); |
| 321 | 324 | ||
| 322 | io_setcookie(entry->sock, (void *)entry->proto); | 325 | fdstate_open(entry->sock, (void *)entry->proto, 0); |
| 323 | io_wantread(entry->sock); | 326 | io_wantread(entry->sock); |
| 324 | 327 | ||
| 325 | #ifdef _DEBUG | 328 | #ifdef _DEBUG |
| @@ -448,6 +451,8 @@ int main(int argc, char **argv) { | |||
| 448 | pthread_t thread_id; /* time cacher */ | 451 | pthread_t thread_id; /* time cacher */ |
| 449 | 452 | ||
| 450 | random_init(); | 453 | random_init(); |
| 454 | if (fdstate_init() == -1) | ||
| 455 | panic("fdstate_init"); | ||
| 451 | config_parse(argc, argv); | 456 | config_parse(argc, argv); |
| 452 | 457 | ||
| 453 | listen_bind_all(); | 458 | listen_bind_all(); |
| @@ -473,7 +478,7 @@ int main(int argc, char **argv) { | |||
| 473 | panic("selfpipe io_fd failed: "); | 478 | panic("selfpipe io_fd failed: "); |
| 474 | if (!io_fd(g_self_pipe[1])) | 479 | if (!io_fd(g_self_pipe[1])) |
| 475 | panic("selfpipe io_fd failed: "); | 480 | panic("selfpipe io_fd failed: "); |
| 476 | io_setcookie(g_self_pipe[0], (void *)FLAG_SELFPIPE); | 481 | fdstate_open(g_self_pipe[0], (void *)FLAG_SELFPIPE, 0); |
| 477 | io_wantread(g_self_pipe[0]); | 482 | io_wantread(g_self_pipe[0]); |
| 478 | 483 | ||
| 479 | /* Init all sub systems. This call may fail with an exit() */ | 484 | /* Init all sub systems. This call may fail with an exit() */ |
| @@ -494,5 +499,6 @@ int main(int argc, char **argv) { | |||
| 494 | 499 | ||
| 495 | server_mainloop(0); | 500 | server_mainloop(0); |
| 496 | 501 | ||
| 502 | fdstate_deinit(); | ||
| 497 | return 0; | 503 | return 0; |
| 498 | } | 504 | } |
diff --git a/ot_fdstate.c b/ot_fdstate.c index 6ddbea3..7f73d3d 100644 --- a/ot_fdstate.c +++ b/ot_fdstate.c | |||
| @@ -34,8 +34,11 @@ typedef struct { | |||
| 34 | range descriptor is rejected */ | 34 | range descriptor is rejected */ |
| 35 | #define FD_SLOTS_MAX (1u << 20) | 35 | #define FD_SLOTS_MAX (1u << 20) |
| 36 | 36 | ||
| 37 | static ot_fdslot *g_slots; | 37 | static ot_fdslot *g_slots; |
| 38 | static size_t g_slot_count; | 38 | static size_t g_slot_count; |
| 39 | /* Descriptors are handed out lowest first, so a sweep only has to walk as | ||
| 40 | far as the highest one ever seen rather than the whole table. */ | ||
| 41 | static _Atomic size_t g_slot_highest; | ||
| 39 | 42 | ||
| 40 | int fdstate_init(void) { | 43 | int fdstate_init(void) { |
| 41 | struct rlimit limit; | 44 | struct rlimit limit; |
| @@ -51,6 +54,7 @@ int fdstate_init(void) { | |||
| 51 | } | 54 | } |
| 52 | 55 | ||
| 53 | g_slot_count = count; | 56 | g_slot_count = count; |
| 57 | atomic_store(&g_slot_highest, 0); | ||
| 54 | return 0; | 58 | return 0; |
| 55 | } | 59 | } |
| 56 | 60 | ||
| @@ -59,6 +63,7 @@ void fdstate_deinit(void) { | |||
| 59 | munmap(g_slots, g_slot_count * sizeof(ot_fdslot)); | 63 | munmap(g_slots, g_slot_count * sizeof(ot_fdslot)); |
| 60 | g_slots = NULL; | 64 | g_slots = NULL; |
| 61 | g_slot_count = 0; | 65 | g_slot_count = 0; |
| 66 | atomic_store(&g_slot_highest, 0); | ||
| 62 | } | 67 | } |
| 63 | 68 | ||
| 64 | size_t fdstate_slots(void) { return g_slot_count; } | 69 | size_t fdstate_slots(void) { return g_slot_count; } |
| @@ -76,6 +81,15 @@ uint32_t fdstate_open(int fd, void *cookie, ot_time expiry) { | |||
| 76 | if (!slot) | 81 | if (!slot) |
| 77 | return 0; | 82 | return 0; |
| 78 | 83 | ||
| 84 | { | ||
| 85 | size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed); | ||
| 86 | |||
| 87 | while ((size_t)fd > highest && | ||
| 88 | !atomic_compare_exchange_weak_explicit(&g_slot_highest, &highest, (size_t)fd, memory_order_relaxed, | ||
| 89 | memory_order_relaxed)) | ||
| 90 | ; | ||
| 91 | } | ||
| 92 | |||
| 79 | word = atomic_load_explicit(&slot->state, memory_order_relaxed); | 93 | word = atomic_load_explicit(&slot->state, memory_order_relaxed); |
| 80 | atomic_store_explicit(&slot->cookie, cookie, memory_order_relaxed); | 94 | atomic_store_explicit(&slot->cookie, cookie, memory_order_relaxed); |
| 81 | atomic_store_explicit(&slot->expiry, expiry, memory_order_relaxed); | 95 | atomic_store_explicit(&slot->expiry, expiry, memory_order_relaxed); |
| @@ -150,6 +164,16 @@ void fdstate_close(int fd) { | |||
| 150 | atomic_store_explicit(&slot->state, FD_WORD(FD_GEN(word) + 1, FD_FREE), memory_order_release); | 164 | atomic_store_explicit(&slot->state, FD_WORD(FD_GEN(word) + 1, FD_FREE), memory_order_release); |
| 151 | } | 165 | } |
| 152 | 166 | ||
| 167 | int fdstate_next_expired(ot_time now, int *cursor) { | ||
| 168 | size_t highest = atomic_load_explicit(&g_slot_highest, memory_order_relaxed); | ||
| 169 | |||
| 170 | for (; (size_t)*cursor <= highest; ++*cursor) | ||
| 171 | if (fdstate_claim_expired(*cursor, now)) | ||
| 172 | return (*cursor)++; | ||
| 173 | |||
| 174 | return -1; | ||
| 175 | } | ||
| 176 | |||
| 153 | void *fdstate_cookie(int fd) { | 177 | void *fdstate_cookie(int fd) { |
| 154 | ot_fdslot *slot = fdstate_slot(fd); | 178 | ot_fdslot *slot = fdstate_slot(fd); |
| 155 | 179 | ||
diff --git a/ot_fdstate.h b/ot_fdstate.h index 2693a3b..88f685d 100644 --- a/ot_fdstate.h +++ b/ot_fdstate.h | |||
| @@ -45,6 +45,11 @@ int fdstate_claim_expired(int fd, ot_time now); | |||
| 45 | quoting the old generation are still in flight. */ | 45 | quoting the old generation are still in flight. */ |
| 46 | void fdstate_close(int fd); | 46 | void fdstate_close(int fd); |
| 47 | 47 | ||
| 48 | /* Walks the table for descriptors that have expired, handing back one at a | ||
| 49 | time until it returns -1. The cursor belongs to the caller, so several | ||
| 50 | sweepers can run without sharing anything. */ | ||
| 51 | int fdstate_next_expired(ot_time now, int *cursor); | ||
| 52 | |||
| 48 | /* Both only valid while the caller holds the descriptor. */ | 53 | /* Both only valid while the caller holds the descriptor. */ |
| 49 | void *fdstate_cookie(int fd); | 54 | void *fdstate_cookie(int fd); |
| 50 | void fdstate_set_expiry(int fd, ot_time expiry); | 55 | void fdstate_set_expiry(int fd, ot_time expiry); |
| @@ -25,8 +25,8 @@ | |||
| 25 | #include "ot_ip.h" | 25 | #include "ot_ip.h" |
| 26 | #include "ot_mutex.h" | 26 | #include "ot_mutex.h" |
| 27 | #include "ot_scan.h" | 27 | #include "ot_scan.h" |
| 28 | #include "ot_fdstate.h" | ||
| 28 | #include "ot_stats.h" | 29 | #include "ot_stats.h" |
| 29 | #include "ot_timeout.h" | ||
| 30 | #include "scan_urlencoded_query.h" | 30 | #include "scan_urlencoded_query.h" |
| 31 | #include "trackerlogic.h" | 31 | #include "trackerlogic.h" |
| 32 | 32 | ||
| @@ -39,7 +39,7 @@ ssize_t g_stats_path_len; | |||
| 39 | enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; | 39 | enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; |
| 40 | 40 | ||
| 41 | static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | 41 | static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { |
| 42 | struct http_data *cookie = io_getcookie(sock); | 42 | struct http_data *cookie = fdstate_cookie(sock); |
| 43 | ssize_t written_size; | 43 | ssize_t written_size; |
| 44 | 44 | ||
| 45 | if (!cookie) { | 45 | if (!cookie) { |
| @@ -97,7 +97,7 @@ static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { | |||
| 97 | 97 | ||
| 98 | /* writeable short data sockets just have a tcp timeout */ | 98 | /* writeable short data sockets just have a tcp timeout */ |
| 99 | if (!ws->keep_alive) { | 99 | if (!ws->keep_alive) { |
| 100 | timeout_never(sock); | 100 | fdstate_set_expiry(sock, 0); |
| 101 | io_dontwantread(sock); | 101 | io_dontwantread(sock); |
| 102 | } | 102 | } |
| 103 | io_wantwrite(sock); | 103 | io_wantwrite(sock); |
| @@ -134,7 +134,7 @@ ssize_t http_issue_error(const int64_t sock, struct ot_workstruct *ws, int code) | |||
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) { | 136 | ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) { |
| 137 | struct http_data *cookie = io_getcookie(sock); | 137 | struct http_data *cookie = fdstate_cookie(sock); |
| 138 | char *header; | 138 | char *header; |
| 139 | const char *encoding = ""; | 139 | const char *encoding = ""; |
| 140 | size_t header_size, size = iovec_length(&iovec_entries, (const struct iovec **)&iovector); | 140 | size_t header_size, size = iovec_length(&iovec_entries, (const struct iovec **)&iovector); |
| @@ -207,7 +207,7 @@ ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t | |||
| 207 | cookie->flag &= ~STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER; | 207 | cookie->flag &= ~STRUCT_HTTP_FLAG_CHUNKED_IN_TRANSFER; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | timeout_in(sock, OT_CLIENT_TIMEOUT_SEND); | 210 | fdstate_set_expiry(sock, g_now_seconds + OT_CLIENT_TIMEOUT_SEND); |
| 211 | io_wantwrite(sock); | 211 | io_wantwrite(sock); |
| 212 | return 0; | 212 | return 0; |
| 213 | } | 213 | } |
| @@ -243,7 +243,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 243 | {"url", TASK_FULLSCRAPE_TPB_URLENCODED}, {"txt", TASK_FULLSCRAPE_TPB_ASCII}, | 243 | {"url", TASK_FULLSCRAPE_TPB_URLENCODED}, {"txt", TASK_FULLSCRAPE_TPB_ASCII}, |
| 244 | {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; | 244 | {"txtp", TASK_FULLSCRAPE_TPB_ASCII_PLUS}, {NULL, -3}}; |
| 245 | 245 | ||
| 246 | struct http_data *cookie = io_getcookie(sock); | 246 | struct http_data *cookie = fdstate_cookie(sock); |
| 247 | int mode = TASK_STATS_PEERS, scanon = 1, format = 0; | 247 | int mode = TASK_STATS_PEERS, scanon = 1, format = 0; |
| 248 | 248 | ||
| 249 | /* A socket without one is a dead socket, which is what http_sendiovecdata | 249 | /* A socket without one is a dead socket, which is what http_sendiovecdata |
| @@ -301,7 +301,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 301 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; | 301 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; |
| 302 | 302 | ||
| 303 | /* Clients waiting for us should not easily timeout */ | 303 | /* Clients waiting for us should not easily timeout */ |
| 304 | timeout_never(sock); | 304 | fdstate_set_expiry(sock, 0); |
| 305 | fullscrape_deliver(sock, format); | 305 | fullscrape_deliver(sock, format); |
| 306 | io_dontwantread(sock); | 306 | io_dontwantread(sock); |
| 307 | return ws->reply_size = -2; | 307 | return ws->reply_size = -2; |
| @@ -314,7 +314,7 @@ static ssize_t http_handle_stats(const int64_t sock, struct ot_workstruct *ws, c | |||
| 314 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; | 314 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 315 | 315 | ||
| 316 | /* Complex stats also include expensive memory debugging tools */ | 316 | /* Complex stats also include expensive memory debugging tools */ |
| 317 | timeout_never(sock); | 317 | fdstate_set_expiry(sock, 0); |
| 318 | stats_deliver(sock, mode); | 318 | stats_deliver(sock, mode); |
| 319 | return ws->reply_size = -2; | 319 | return ws->reply_size = -2; |
| 320 | } | 320 | } |
| @@ -334,7 +334,7 @@ typedef struct { | |||
| 334 | 334 | ||
| 335 | #ifdef WANT_FULLSCRAPE | 335 | #ifdef WANT_FULLSCRAPE |
| 336 | static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) { | 336 | static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) { |
| 337 | struct http_data *cookie = io_getcookie(sock); | 337 | struct http_data *cookie = fdstate_cookie(sock); |
| 338 | int format = 0; | 338 | int format = 0; |
| 339 | 339 | ||
| 340 | #ifdef WANT_MODEST_FULLSCRAPES | 340 | #ifdef WANT_MODEST_FULLSCRAPES |
| @@ -394,7 +394,7 @@ static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct * | |||
| 394 | /* Pass this task to the worker thread */ | 394 | /* Pass this task to the worker thread */ |
| 395 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; | 395 | cookie->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK | STRUCT_HTTP_FLAG_CHUNKED; |
| 396 | /* Clients waiting for us should not easily timeout */ | 396 | /* Clients waiting for us should not easily timeout */ |
| 397 | timeout_never(sock); | 397 | fdstate_set_expiry(sock, 0); |
| 398 | fullscrape_deliver(sock, format); | 398 | fullscrape_deliver(sock, format); |
| 399 | io_dontwantread(sock); | 399 | io_dontwantread(sock); |
| 400 | return ws->reply_size = -2; | 400 | return ws->reply_size = -2; |
| @@ -486,7 +486,7 @@ static ssize_t http_handle_announce(const int64_t sock, struct ot_workstruct | |||
| 486 | unsigned short port = 0; | 486 | unsigned short port = 0; |
| 487 | char *write_ptr; | 487 | char *write_ptr; |
| 488 | ssize_t len; | 488 | ssize_t len; |
| 489 | struct http_data *cookie = io_getcookie(sock); | 489 | struct http_data *cookie = fdstate_cookie(sock); |
| 490 | 490 | ||
| 491 | /* This is to hack around stupid clients that send "announce ?info_hash" */ | 491 | /* This is to hack around stupid clients that send "announce ?info_hash" */ |
| 492 | if (read_ptr[-1] != '?') { | 492 | if (read_ptr[-1] != '?') { |
| @@ -663,7 +663,7 @@ ssize_t http_handle_request(const int64_t sock, struct ot_workstruct *ws) { | |||
| 663 | char *read_ptr = ws->request, *write_ptr; | 663 | char *read_ptr = ws->request, *write_ptr; |
| 664 | 664 | ||
| 665 | #ifdef WANT_FULLLOG_NETWORKS | 665 | #ifdef WANT_FULLLOG_NETWORKS |
| 666 | struct http_data *cookie = io_getcookie(sock); | 666 | struct http_data *cookie = fdstate_cookie(sock); |
| 667 | if (loglist_check_address(cookie->ip)) { | 667 | if (loglist_check_address(cookie->ip)) { |
| 668 | ot_log *log = malloc(sizeof(ot_log)); | 668 | ot_log *log = malloc(sizeof(ot_log)); |
| 669 | if (log) { | 669 | if (log) { |
diff --git a/ot_timeout.h b/ot_timeout.h deleted file mode 100644 index 1027c2e..0000000 --- a/ot_timeout.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | ||
| 2 | It is considered beerware. Prost. Skol. Cheers or whatever. | ||
| 3 | |||
| 4 | $id$ */ | ||
| 5 | |||
| 6 | #ifndef OT_TIMEOUT_H__ | ||
| 7 | #define OT_TIMEOUT_H__ | ||
| 8 | |||
| 9 | #include <stdint.h> | ||
| 10 | #include <string.h> | ||
| 11 | |||
| 12 | /* Libowfat */ | ||
| 13 | #include "io.h" | ||
| 14 | |||
| 15 | #include "trackerlogic.h" | ||
| 16 | |||
| 17 | /* io_timeout wants an absolute TAI64 deadline and io_timeouted skips any | ||
| 18 | socket whose deadline is zero, so that is how a socket is told to wait | ||
| 19 | indefinitely. | ||
| 20 | |||
| 21 | The deadline is taken from the cached clock rather than from | ||
| 22 | gettimeofday, which is too expensive to call at this rate on FreeBSD. */ | ||
| 23 | |||
| 24 | static inline void timeout_never(int64_t sock) { | ||
| 25 | tai6464 t; | ||
| 26 | |||
| 27 | memset(&t, 0, sizeof(t)); | ||
| 28 | io_timeout(sock, t); | ||
| 29 | } | ||
| 30 | |||
| 31 | static inline void timeout_in(int64_t sock, unsigned int seconds) { | ||
| 32 | tai6464 t; | ||
| 33 | |||
| 34 | memset(&t, 0, sizeof(t)); | ||
| 35 | tai_unix(&t.sec, g_now_seconds + seconds); | ||
| 36 | io_timeout(sock, t); | ||
| 37 | } | ||
| 38 | |||
| 39 | #endif | ||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | /* Opentracker */ | 20 | /* Opentracker */ |
| 21 | #include "ot_batch.h" | 21 | #include "ot_batch.h" |
| 22 | #include "ot_fdstate.h" | ||
| 22 | #include "ot_ip.h" | 23 | #include "ot_ip.h" |
| 23 | #include "ot_mutex.h" | 24 | #include "ot_mutex.h" |
| 24 | #include "ot_random.h" | 25 | #include "ot_random.h" |
| @@ -267,7 +268,7 @@ static void handle_reconnects(void) { | |||
| 267 | continue; /* No socket for you */ | 268 | continue; /* No socket for you */ |
| 268 | io_fd(newfd); | 269 | io_fd(newfd); |
| 269 | io_wantwrite(newfd); /* So we will be informed when it is connected */ | 270 | io_wantwrite(newfd); /* So we will be informed when it is connected */ |
| 270 | io_setcookie(newfd, g_connections + i); | 271 | fdstate_open(newfd, g_connections + i, 0); |
| 271 | 272 | ||
| 272 | /* Prepare connection info block */ | 273 | /* Prepare connection info block */ |
| 273 | reset_info_block(g_connections + i); | 274 | reset_info_block(g_connections + i); |
| @@ -310,7 +311,7 @@ static void handle_accept(int64_t serversocket) { | |||
| 310 | g_connections[i].port = port; | 311 | g_connections[i].port = port; |
| 311 | g_connections[i].fd = newfd; | 312 | g_connections[i].fd = newfd; |
| 312 | 313 | ||
| 313 | io_setcookie(newfd, g_connections + i); | 314 | fdstate_open(newfd, g_connections + i, 0); |
| 314 | 315 | ||
| 315 | /* We expect the connecting side to begin with its tracker_id */ | 316 | /* We expect the connecting side to begin with its tracker_id */ |
| 316 | io_wantread(newfd); | 317 | io_wantread(newfd); |
| @@ -325,7 +326,7 @@ static void handle_read(int64_t peersocket) { | |||
| 325 | int i; | 326 | int i; |
| 326 | int64_t datalen; | 327 | int64_t datalen; |
| 327 | uint32_t tracker_id; | 328 | uint32_t tracker_id; |
| 328 | proxy_peer *peer = io_getcookie(peersocket); | 329 | proxy_peer *peer = fdstate_cookie(peersocket); |
| 329 | 330 | ||
| 330 | if (!peer) { | 331 | if (!peer) { |
| 331 | /* Can't happen ;) */ | 332 | /* Can't happen ;) */ |
| @@ -391,7 +392,7 @@ static void handle_read(int64_t peersocket) { | |||
| 391 | 392 | ||
| 392 | /* Can write new sync data to the stream */ | 393 | /* Can write new sync data to the stream */ |
| 393 | static void handle_write(int64_t peersocket) { | 394 | static void handle_write(int64_t peersocket) { |
| 394 | proxy_peer *peer = io_getcookie(peersocket); | 395 | proxy_peer *peer = fdstate_cookie(peersocket); |
| 395 | 396 | ||
| 396 | if (!peer) { | 397 | if (!peer) { |
| 397 | /* Can't happen ;) */ | 398 | /* Can't happen ;) */ |
| @@ -464,7 +465,7 @@ static void server_mainloop() { | |||
| 464 | 465 | ||
| 465 | /* Loop over readable sockets */ | 466 | /* Loop over readable sockets */ |
| 466 | while ((sock = io_canread()) != -1) { | 467 | while ((sock = io_canread()) != -1) { |
| 467 | const void *cookie = io_getcookie(sock); | 468 | const void *cookie = fdstate_cookie(sock); |
| 468 | if ((uintptr_t)cookie == FLAG_SERVERSOCKET) | 469 | if ((uintptr_t)cookie == FLAG_SERVERSOCKET) |
| 469 | handle_accept(sock); | 470 | handle_accept(sock); |
| 470 | else | 471 | else |
| @@ -493,7 +494,7 @@ static int64_t ot_try_bind(ot_ip6 ip, uint16_t port) { | |||
| 493 | if (!io_fd(sock)) | 494 | if (!io_fd(sock)) |
| 494 | panic("io_fd"); | 495 | panic("io_fd"); |
| 495 | 496 | ||
| 496 | io_setcookie(sock, (void *)FLAG_SERVERSOCKET); | 497 | fdstate_open(sock, (void *)FLAG_SERVERSOCKET, 0); |
| 497 | io_wantread(sock); | 498 | io_wantread(sock); |
| 498 | return sock; | 499 | return sock; |
| 499 | } | 500 | } |
| @@ -535,6 +536,8 @@ int main(int argc, char **argv) { | |||
| 535 | int scanon = 1, lbound = 0, sbound = 0; | 536 | int scanon = 1, lbound = 0, sbound = 0; |
| 536 | 537 | ||
| 537 | random_init(); | 538 | random_init(); |
| 539 | if (fdstate_init() == -1) | ||
| 540 | panic("fdstate_init"); | ||
| 538 | g_tracker_id = random_uint32(); | 541 | g_tracker_id = random_uint32(); |
| 539 | 542 | ||
| 540 | while (scanon) { | 543 | while (scanon) { |
