summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--opentracker.c26
-rw-r--r--ot_fdstate.c28
-rw-r--r--ot_fdstate.h5
-rw-r--r--ot_http.c24
-rw-r--r--ot_timeout.h39
-rw-r--r--proxy.c15
7 files changed, 69 insertions, 70 deletions
diff --git a/Makefile b/Makefile
index 3bf254a..87c20e2 100644
--- a/Makefile
+++ b/Makefile
@@ -70,7 +70,7 @@ LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread
70BINARY =opentracker 70BINARY =opentracker
71HEADERS=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 71HEADERS=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
72SOURCES=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 72SOURCES=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
73SOURCES_proxy=proxy.c ot_batch.c ot_vector.c ot_mutex.c ot_random.c ot_scan.c ot_ip.c ot_socket.c 73SOURCES_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
75OBJECTS = $(SOURCES:%.c=%.o) 75OBJECTS = $(SOURCES:%.c=%.o)
76OBJECTS_debug = $(SOURCES:%.c=%.debug.o) 76OBJECTS_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
120static void handle_dead(const int64_t sock) { 120static 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
134static void handle_read(const int64_t sock, struct ot_workstruct *ws) { 136static 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
178static void handle_write(const int64_t sock) { 180static 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
37static ot_fdslot *g_slots; 37static ot_fdslot *g_slots;
38static size_t g_slot_count; 38static 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. */
41static _Atomic size_t g_slot_highest;
39 42
40int fdstate_init(void) { 43int 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
64size_t fdstate_slots(void) { return g_slot_count; } 69size_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
167int 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
153void *fdstate_cookie(int fd) { 177void *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. */
46void fdstate_close(int fd); 46void 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. */
51int 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. */
49void *fdstate_cookie(int fd); 54void *fdstate_cookie(int fd);
50void fdstate_set_expiry(int fd, ot_time expiry); 55void fdstate_set_expiry(int fd, ot_time expiry);
diff --git a/ot_http.c b/ot_http.c
index 331a457..6bf343c 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -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;
39enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 }; 39enum { SUCCESS_HTTP_HEADER_LENGTH = 80, SUCCESS_HTTP_SIZE_OFF = 17 };
40 40
41static void http_senddata(const int64_t sock, struct ot_workstruct *ws) { 41static 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
136ssize_t http_sendiovecdata(const int64_t sock, struct ot_workstruct *ws, size_t iovec_entries, struct iovec *iovector, int is_partial) { 136ssize_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
336static ssize_t http_handle_fullscrape(const int64_t sock, struct ot_workstruct *ws) { 336static 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
24static inline void timeout_never(int64_t sock) {
25 tai6464 t;
26
27 memset(&t, 0, sizeof(t));
28 io_timeout(sock, t);
29}
30
31static 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
diff --git a/proxy.c b/proxy.c
index 63b4c4f..9486e75 100644
--- a/proxy.c
+++ b/proxy.c
@@ -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 */
393static void handle_write(int64_t peersocket) { 394static 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) {