diff options
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | opentracker.c | 86 | ||||
-rw-r--r-- | ot_accesslist.c | 43 | ||||
-rw-r--r-- | ot_accesslist.h | 6 | ||||
-rw-r--r-- | ot_fullscrape.c | 8 | ||||
-rw-r--r-- | ot_http.c | 52 | ||||
-rw-r--r-- | ot_http.h | 2 | ||||
-rw-r--r-- | ot_livesync.c | 60 | ||||
-rw-r--r-- | ot_livesync.h | 2 | ||||
-rw-r--r-- | ot_mutex.c | 8 | ||||
-rw-r--r-- | ot_mutex.h | 4 | ||||
-rw-r--r-- | ot_stats.c | 34 | ||||
-rw-r--r-- | ot_stats.h | 2 | ||||
-rw-r--r-- | ot_udp.c | 28 | ||||
-rw-r--r-- | ot_udp.h | 2 | ||||
-rw-r--r-- | ot_vector.c | 24 | ||||
-rw-r--r-- | scan_urlencoded_query.c | 17 | ||||
-rw-r--r-- | scan_urlencoded_query.h | 15 | ||||
-rw-r--r-- | trackerlogic.c | 47 | ||||
-rw-r--r-- | trackerlogic.h | 55 |
20 files changed, 235 insertions, 265 deletions
@@ -19,6 +19,8 @@ LIBOWFAT_LIBRARY=$(PREFIX)/libowfat | |||
19 | 19 | ||
20 | BINDIR?=$(PREFIX)/bin | 20 | BINDIR?=$(PREFIX)/bin |
21 | 21 | ||
22 | #FEATURES+=-DWANT_V6 | ||
23 | |||
22 | #FEATURES+=-DWANT_ACCESSLIST_BLACK | 24 | #FEATURES+=-DWANT_ACCESSLIST_BLACK |
23 | #FEATURES+=-DWANT_ACCESSLIST_WHITE | 25 | #FEATURES+=-DWANT_ACCESSLIST_WHITE |
24 | 26 | ||
@@ -31,13 +33,12 @@ BINDIR?=$(PREFIX)/bin | |||
31 | FEATURES+=-DWANT_FULLSCRAPE | 33 | FEATURES+=-DWANT_FULLSCRAPE |
32 | 34 | ||
33 | #FEATURES+=-D_DEBUG_HTTPERROR | 35 | #FEATURES+=-D_DEBUG_HTTPERROR |
34 | #FEATURES+=-D_DEBUG_PEERID | ||
35 | 36 | ||
36 | OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage | 37 | OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage |
37 | OPTS_production=-Os | 38 | OPTS_production=-Os |
38 | 39 | ||
39 | CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra #-ansi -pedantic | 40 | CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra #-ansi -pedantic |
40 | LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lz | 41 | LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lpthread -lz |
41 | 42 | ||
42 | BINARY =opentracker | 43 | BINARY =opentracker |
43 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_mutex.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 | 44 | HEADERS=trackerlogic.h scan_urlencoded_query.h ot_mutex.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 |
diff --git a/opentracker.c b/opentracker.c index 8a4126c..46456dd 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "iob.h" | 22 | #include "iob.h" |
23 | #include "byte.h" | 23 | #include "byte.h" |
24 | #include "scan.h" | 24 | #include "scan.h" |
25 | #include "ip4.h" | 25 | #include "ip6.h" |
26 | 26 | ||
27 | /* Opentracker */ | 27 | /* Opentracker */ |
28 | #include "trackerlogic.h" | 28 | #include "trackerlogic.h" |
@@ -108,7 +108,7 @@ static ssize_t handle_read( const int64 clientsocket, struct ot_workstruct *ws ) | |||
108 | struct http_data* h = io_getcookie( clientsocket ); | 108 | struct http_data* h = io_getcookie( clientsocket ); |
109 | ssize_t l; | 109 | ssize_t l; |
110 | 110 | ||
111 | if( ( l = io_tryread( clientsocket, ws->inbuf, ws->inbuf_size ) ) <= 0 ) { | 111 | if( ( l = io_tryread( clientsocket, ws->inbuf, G_INBUF_SIZE ) ) <= 0 ) { |
112 | handle_dead( clientsocket ); | 112 | handle_dead( clientsocket ); |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
@@ -152,28 +152,28 @@ static void handle_write( const int64 clientsocket ) { | |||
152 | 152 | ||
153 | static void handle_accept( const int64 serversocket ) { | 153 | static void handle_accept( const int64 serversocket ) { |
154 | struct http_data *h; | 154 | struct http_data *h; |
155 | unsigned char ip[4]; | 155 | ot_ip6 ip; |
156 | uint16 port; | 156 | uint16 port; |
157 | tai6464 t; | 157 | tai6464 t; |
158 | int64 i; | 158 | int64 i; |
159 | 159 | ||
160 | while( ( i = socket_accept4( serversocket, (char*)ip, &port) ) != -1 ) { | 160 | while( ( i = socket_accept6( serversocket, ip, &port, NULL ) ) != -1 ) { |
161 | 161 | ||
162 | /* Put fd into a non-blocking mode */ | 162 | /* Put fd into a non-blocking mode */ |
163 | io_nonblock( i ); | 163 | io_nonblock( i ); |
164 | 164 | ||
165 | if( !io_fd( i ) || | 165 | if( !io_fd( i ) || |
166 | !( h = (struct http_data*)malloc( sizeof( struct http_data ) ) ) ) { | 166 | !( h = (struct http_data*)malloc( sizeof(struct http_data) ) ) ) { |
167 | io_close( i ); | 167 | io_close( i ); |
168 | continue; | 168 | continue; |
169 | } | 169 | } |
170 | io_setcookie( i, h ); | 170 | io_setcookie( i, h ); |
171 | io_wantread( i ); | 171 | io_wantread( i ); |
172 | 172 | ||
173 | memset( h, 0, sizeof( struct http_data ) ); | 173 | memset(h, 0, sizeof( struct http_data ) ); |
174 | WRITE32(h->ip,0,READ32(ip,0)); | 174 | memcpy(h->ip,ip,sizeof(ot_ip6)); |
175 | 175 | ||
176 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, ntohl(*(uint32_t*)ip)); | 176 | stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ip); |
177 | 177 | ||
178 | /* That breaks taia encapsulation. But there is no way to take system | 178 | /* That breaks taia encapsulation. But there is no way to take system |
179 | time this often in FreeBSD and libowfat does not allow to set unix time */ | 179 | time this often in FreeBSD and libowfat does not allow to set unix time */ |
@@ -193,20 +193,14 @@ static void server_mainloop( ) { | |||
193 | int iovec_entries; | 193 | int iovec_entries; |
194 | 194 | ||
195 | /* Initialize our "thread local storage" */ | 195 | /* Initialize our "thread local storage" */ |
196 | ws.inbuf = malloc( THREAD_INBUF_SIZE ); | 196 | ws.inbuf = malloc( G_INBUF_SIZE ); |
197 | ws.outbuf = malloc( THREAD_OUTBUF_SIZE ); | 197 | ws.outbuf = malloc( G_OUTBUF_SIZE ); |
198 | #ifdef _DEBUG_HTTPERROR | 198 | #ifdef _DEBUG_HTTPERROR |
199 | ws.debugbuf= malloc( THREAD_INBUF_SIZE ); | 199 | ws.debugbuf= malloc( G_INBUF_SIZE ); |
200 | #endif | 200 | #endif |
201 | if( !ws.inbuf || !ws.outbuf ) | 201 | if( !ws.inbuf || !ws.outbuf ) |
202 | panic( "Initializing worker failed" ); | 202 | panic( "Initializing worker failed" ); |
203 | 203 | ||
204 | ws.inbuf_size = THREAD_INBUF_SIZE; | ||
205 | ws.outbuf_size = THREAD_OUTBUF_SIZE; | ||
206 | #ifdef _DEBUG_HTTPERROR | ||
207 | ws.debugbuf_size= THREAD_INBUF_SIZE; | ||
208 | #endif | ||
209 | |||
210 | for( ; ; ) { | 204 | for( ; ; ) { |
211 | int64 i; | 205 | int64 i; |
212 | 206 | ||
@@ -217,7 +211,7 @@ static void server_mainloop( ) { | |||
217 | if( (intptr_t)cookie == FLAG_TCP ) | 211 | if( (intptr_t)cookie == FLAG_TCP ) |
218 | handle_accept( i ); | 212 | handle_accept( i ); |
219 | else if( (intptr_t)cookie == FLAG_UDP ) | 213 | else if( (intptr_t)cookie == FLAG_UDP ) |
220 | handle_udp4( i, &ws ); | 214 | handle_udp6( i, &ws ); |
221 | else | 215 | else |
222 | handle_read( i, &ws ); | 216 | handle_read( i, &ws ); |
223 | } | 217 | } |
@@ -241,17 +235,20 @@ static void server_mainloop( ) { | |||
241 | } | 235 | } |
242 | } | 236 | } |
243 | 237 | ||
244 | static int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) { | 238 | static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { |
245 | int64 s = proto == FLAG_TCP ? socket_tcp4( ) : socket_udp4( ); | 239 | int64 s = proto == FLAG_TCP ? socket_tcp6( ) : socket_udp6( ); |
246 | 240 | ||
247 | #ifdef _DEBUG | 241 | #ifdef _DEBUG |
248 | char *protos[] = {"TCP","UDP","UDP mcast"}; | 242 | char *protos[] = {"TCP","UDP","UDP mcast"}; |
249 | uint8_t *_ip = (uint8_t *)ip; | 243 | char _debug[512]; |
250 | fprintf( stderr, "Binding socket type %s to address %d.%d.%d.%d:%d...", protos[proto],_ip[0],_ip[1],_ip[2],_ip[3],port); | 244 | int off = snprintf( _debug, sizeof(_debug), "Binding socket type %s to address [", protos[proto] ); |
245 | off += fmt_ip6( _debug+off, ip); | ||
246 | off += snprintf( _debug + off, sizeof(_debug)-off, "]:%d...", port); | ||
247 | fputs( _debug, stderr ); | ||
251 | #endif | 248 | #endif |
252 | 249 | ||
253 | if( socket_bind4_reuse( s, ip, port ) == -1 ) | 250 | if( socket_bind6_reuse( s, ip, port, 0 ) == -1 ) |
254 | panic( "socket_bind4_reuse" ); | 251 | panic( "socket_bind6_reuse" ); |
255 | 252 | ||
256 | if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) ) | 253 | if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) ) |
257 | panic( "socket_listen" ); | 254 | panic( "socket_listen" ); |
@@ -279,16 +276,22 @@ char * set_config_option( char **option, char *value ) { | |||
279 | return *option = strdup( value ); | 276 | return *option = strdup( value ); |
280 | } | 277 | } |
281 | 278 | ||
282 | static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { | 279 | static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) { |
283 | const char *s = src; | 280 | const char *s = src; |
284 | int off; | 281 | int off, bracket = 0; |
285 | while( isspace(*s) ) ++s; | 282 | while( isspace(*s) ) ++s; |
286 | if( !(off = scan_ip4( s, ip ) ) ) | 283 | if( *s == '[' ) ++s, ++bracket; /* for v6 style notation */ |
284 | if( !(off = scan_ip6( s, ip ) ) ) | ||
287 | return 0; | 285 | return 0; |
288 | s += off; | 286 | s += off; |
289 | if( *s == 0 || isspace(*s)) return s-src; | 287 | if( *s == 0 || isspace(*s)) return s-src; |
290 | if( *(s++) != ':' ) | 288 | if( *s == ']' && bracket ) ++s; |
291 | return 0; | 289 | if( !ip6_isv4mapped(ip)){ |
290 | if( ( bracket && *(s) != ':' ) || ( *(s) != '.' ) ) return 0; | ||
291 | s++; | ||
292 | } else { | ||
293 | if( *(s++) != ':' ) return 0; | ||
294 | } | ||
292 | if( !(off = scan_ushort (s, port ) ) ) | 295 | if( !(off = scan_ushort (s, port ) ) ) |
293 | return 0; | 296 | return 0; |
294 | return off+s-src; | 297 | return off+s-src; |
@@ -296,7 +299,8 @@ static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { | |||
296 | 299 | ||
297 | int parse_configfile( char * config_filename ) { | 300 | int parse_configfile( char * config_filename ) { |
298 | FILE * accesslist_filehandle; | 301 | FILE * accesslist_filehandle; |
299 | char inbuf[512], tmpip[4]; | 302 | char inbuf[512]; |
303 | ot_ip6 tmpip; | ||
300 | int bound = 0; | 304 | int bound = 0; |
301 | 305 | ||
302 | accesslist_filehandle = fopen( config_filename, "r" ); | 306 | accesslist_filehandle = fopen( config_filename, "r" ); |
@@ -324,17 +328,17 @@ int parse_configfile( char * config_filename ) { | |||
324 | set_config_option( &g_serverdir, p+16 ); | 328 | set_config_option( &g_serverdir, p+16 ); |
325 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { | 329 | } else if(!byte_diff(p,14,"listen.tcp_udp" ) && isspace(p[14])) { |
326 | uint16_t tmpport = 6969; | 330 | uint16_t tmpport = 6969; |
327 | if( !scan_ip4_port( p+15, tmpip, &tmpport )) goto parse_error; | 331 | if( !scan_ip6_port( p+15, tmpip, &tmpport )) goto parse_error; |
328 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); ++bound; | 332 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); ++bound; |
329 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); ++bound; | 333 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); ++bound; |
330 | } else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) { | 334 | } else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) { |
331 | uint16_t tmpport = 6969; | 335 | uint16_t tmpport = 6969; |
332 | if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error; | 336 | if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error; |
333 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); | 337 | ot_try_bind( tmpip, tmpport, FLAG_TCP ); |
334 | ++bound; | 338 | ++bound; |
335 | } else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) { | 339 | } else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) { |
336 | uint16_t tmpport = 6969; | 340 | uint16_t tmpport = 6969; |
337 | if( !scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error; | 341 | if( !scan_ip6_port( p+11, tmpip, &tmpport )) goto parse_error; |
338 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); | 342 | ot_try_bind( tmpip, tmpport, FLAG_UDP ); |
339 | ++bound; | 343 | ++bound; |
340 | #ifdef WANT_ACCESSLIST_WHITE | 344 | #ifdef WANT_ACCESSLIST_WHITE |
@@ -346,18 +350,18 @@ int parse_configfile( char * config_filename ) { | |||
346 | #endif | 350 | #endif |
347 | #ifdef WANT_RESTRICT_STATS | 351 | #ifdef WANT_RESTRICT_STATS |
348 | } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { | 352 | } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { |
349 | if( !scan_ip4( p+13, tmpip )) goto parse_error; | 353 | if( !scan_ip6( p+13, tmpip )) goto parse_error; |
350 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); | 354 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); |
351 | #endif | 355 | #endif |
352 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { | 356 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { |
353 | set_config_option( &g_redirecturl, p+21 ); | 357 | set_config_option( &g_redirecturl, p+21 ); |
354 | #ifdef WANT_SYNC_LIVE | 358 | #ifdef WANT_SYNC_LIVE |
355 | } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { | 359 | } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { |
356 | if( !scan_ip4( p+25, tmpip )) goto parse_error; | 360 | if( !scan_ip6( p+25, tmpip )) goto parse_error; |
357 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); | 361 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); |
358 | } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { | 362 | } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { |
359 | uint16_t tmpport = LIVESYNC_PORT; | 363 | uint16_t tmpport = LIVESYNC_PORT; |
360 | if( !scan_ip4_port( p+24, tmpip, &tmpport )) goto parse_error; | 364 | if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error; |
361 | livesync_bind_mcast( tmpip, tmpport ); | 365 | livesync_bind_mcast( tmpip, tmpport ); |
362 | #endif | 366 | #endif |
363 | } else | 367 | } else |
@@ -411,10 +415,12 @@ int drop_privileges (const char * const serverdir) { | |||
411 | } | 415 | } |
412 | 416 | ||
413 | int main( int argc, char **argv ) { | 417 | int main( int argc, char **argv ) { |
414 | char serverip[4] = {0,0,0,0}, tmpip[4]; | 418 | ot_ip6 serverip, tmpip; |
415 | int bound = 0, scanon = 1; | 419 | int bound = 0, scanon = 1; |
416 | uint16_t tmpport; | 420 | uint16_t tmpport; |
417 | 421 | ||
422 | memset( serverip, 0, sizeof(ot_ip6) ); | ||
423 | |||
418 | while( scanon ) { | 424 | while( scanon ) { |
419 | switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v" | 425 | switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v" |
420 | #ifdef WANT_ACCESSLIST_BLACK | 426 | #ifdef WANT_ACCESSLIST_BLACK |
@@ -425,7 +431,7 @@ while( scanon ) { | |||
425 | "h" ) ) { | 431 | "h" ) ) { |
426 | case -1 : scanon = 0; break; | 432 | case -1 : scanon = 0; break; |
427 | case 'i': | 433 | case 'i': |
428 | if( !scan_ip4( optarg, serverip )) { usage( argv[0] ); exit( 1 ); } | 434 | if( !scan_ip6( optarg, serverip )) { usage( argv[0] ); exit( 1 ); } |
429 | break; | 435 | break; |
430 | #ifdef WANT_ACCESSLIST_BLACK | 436 | #ifdef WANT_ACCESSLIST_BLACK |
431 | case 'b': set_config_option( &g_accesslist_filename, optarg); break; | 437 | case 'b': set_config_option( &g_accesslist_filename, optarg); break; |
@@ -446,7 +452,7 @@ while( scanon ) { | |||
446 | case 'd': set_config_option( &g_serverdir, optarg ); break; | 452 | case 'd': set_config_option( &g_serverdir, optarg ); break; |
447 | case 'r': set_config_option( &g_redirecturl, optarg ); break; | 453 | case 'r': set_config_option( &g_redirecturl, optarg ); break; |
448 | case 'A': | 454 | case 'A': |
449 | if( !scan_ip4( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } | 455 | if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } |
450 | accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ | 456 | accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ |
451 | break; | 457 | break; |
452 | case 'f': bound += parse_configfile( optarg ); break; | 458 | case 'f': bound += parse_configfile( optarg ); break; |
diff --git a/ot_accesslist.c b/ot_accesslist.c index 0cb6fe7..304b3f1 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c | |||
@@ -8,10 +8,12 @@ | |||
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
10 | #include <signal.h> | 10 | #include <signal.h> |
11 | #include <unistd.h> | ||
11 | 12 | ||
12 | /* Libowfat */ | 13 | /* Libowfat */ |
13 | #include "byte.h" | 14 | #include "byte.h" |
14 | #include "scan.h" | 15 | #include "scan.h" |
16 | #include "ip6.h" | ||
15 | 17 | ||
16 | /* Opentracker */ | 18 | /* Opentracker */ |
17 | #include "trackerlogic.h" | 19 | #include "trackerlogic.h" |
@@ -32,14 +34,14 @@ void accesslist_deinit( void ) { | |||
32 | accesslist_reset( ); | 34 | accesslist_reset( ); |
33 | } | 35 | } |
34 | 36 | ||
35 | static int accesslist_addentry( ot_hash *infohash ) { | 37 | static int accesslist_addentry( ot_hash infohash ) { |
36 | int eger; | 38 | int eger; |
37 | void *insert = vector_find_or_insert( &accesslist, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &eger ); | 39 | void *insert = vector_find_or_insert( &accesslist, infohash, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &eger ); |
38 | 40 | ||
39 | if( !insert ) | 41 | if( !insert ) |
40 | return -1; | 42 | return -1; |
41 | 43 | ||
42 | memmove( insert, infohash, OT_HASH_COMPARE_SIZE ); | 44 | memcpy( insert, infohash, OT_HASH_COMPARE_SIZE ); |
43 | 45 | ||
44 | return 0; | 46 | return 0; |
45 | } | 47 | } |
@@ -64,7 +66,7 @@ static void accesslist_readfile( int foo ) { | |||
64 | /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" */ | 66 | /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" */ |
65 | while( fgets( inbuf, sizeof(inbuf), accesslist_filehandle ) ) { | 67 | while( fgets( inbuf, sizeof(inbuf), accesslist_filehandle ) ) { |
66 | int i; | 68 | int i; |
67 | for( i=0; i<20; ++i ) { | 69 | for( i=0; i<(int)sizeof(ot_hash); ++i ) { |
68 | int eger = 16 * scan_fromhex( inbuf[ 2*i ] ) + scan_fromhex( inbuf[ 1 + 2*i ] ); | 70 | int eger = 16 * scan_fromhex( inbuf[ 2*i ] ) + scan_fromhex( inbuf[ 1 + 2*i ] ); |
69 | if( eger < 0 ) | 71 | if( eger < 0 ) |
70 | continue; | 72 | continue; |
@@ -74,13 +76,13 @@ static void accesslist_readfile( int foo ) { | |||
74 | continue; | 76 | continue; |
75 | 77 | ||
76 | /* Append accesslist to accesslist vector */ | 78 | /* Append accesslist to accesslist vector */ |
77 | accesslist_addentry( &infohash ); | 79 | accesslist_addentry( infohash ); |
78 | } | 80 | } |
79 | 81 | ||
80 | fclose( accesslist_filehandle ); | 82 | fclose( accesslist_filehandle ); |
81 | } | 83 | } |
82 | 84 | ||
83 | int accesslist_hashisvalid( ot_hash *hash ) { | 85 | int accesslist_hashisvalid( ot_hash hash ) { |
84 | int exactmatch; | 86 | int exactmatch; |
85 | binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch ); | 87 | binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch ); |
86 | 88 | ||
@@ -102,30 +104,39 @@ void accesslist_init( ) { | |||
102 | } | 104 | } |
103 | #endif | 105 | #endif |
104 | 106 | ||
105 | static uint32_t g_adminip_addresses[OT_ADMINIP_MAX]; | 107 | static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; |
106 | static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; | 108 | static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; |
107 | static unsigned int g_adminip_count = 0; | 109 | static unsigned int g_adminip_count = 0; |
108 | 110 | ||
109 | int accesslist_blessip( char *ip, ot_permissions permissions ) { | 111 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { |
110 | if( g_adminip_count >= OT_ADMINIP_MAX ) | 112 | if( g_adminip_count >= OT_ADMINIP_MAX ) |
111 | return -1; | 113 | return -1; |
112 | WRITE32(g_adminip_addresses + g_adminip_count,0,READ32(ip,0)); | 114 | |
115 | memcpy(g_adminip_addresses + g_adminip_count,ip,sizeof(ot_ip6)); | ||
113 | g_adminip_permissions[ g_adminip_count++ ] = permissions; | 116 | g_adminip_permissions[ g_adminip_count++ ] = permissions; |
117 | |||
114 | #ifdef _DEBUG | 118 | #ifdef _DEBUG |
115 | uint8_t *_ip = (uint8_t*)ip; | 119 | { |
116 | fprintf( stderr, "Blessing ip address %d.%d.%d.%d with:", _ip[0], _ip[1], _ip[2], _ip[3]); | 120 | char _debug[512]; |
117 | if( permissions & OT_PERMISSION_MAY_STAT ) fputs( " may_fetch_stats", stderr ); | 121 | int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " ); |
118 | if( permissions & OT_PERMISSION_MAY_LIVESYNC ) fputs( " may_sync_live", stderr ); | 122 | off += fmt_ip6(_debug+off, ip ); |
119 | if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) fputs( " may_fetch_fullscrapes", stderr ); | 123 | |
120 | if( !permissions ) fputs(" nothing.\n", stderr); else fputs(".\n", stderr ); | 124 | if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); |
125 | if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); | ||
126 | if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); | ||
127 | if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" ); | ||
128 | _debug[off++] = '.'; | ||
129 | write( 2, _debug, off ); | ||
130 | } | ||
121 | #endif | 131 | #endif |
132 | |||
122 | return 0; | 133 | return 0; |
123 | } | 134 | } |
124 | 135 | ||
125 | int accesslist_isblessed( char *ip, ot_permissions permissions ) { | 136 | int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) { |
126 | unsigned int i; | 137 | unsigned int i; |
127 | for( i=0; i<g_adminip_count; ++i ) | 138 | for( i=0; i<g_adminip_count; ++i ) |
128 | if( !memcmp( g_adminip_addresses + i, ip, 4) && ( g_adminip_permissions[ i ] & permissions ) ) | 139 | if( !memcmp( g_adminip_addresses + i, ip, sizeof(ot_ip6)) && ( g_adminip_permissions[ i ] & permissions ) ) |
129 | return 1; | 140 | return 1; |
130 | return 0; | 141 | return 0; |
131 | } | 142 | } |
diff --git a/ot_accesslist.h b/ot_accesslist.h index 15a21f2..836a233 100644 --- a/ot_accesslist.h +++ b/ot_accesslist.h | |||
@@ -14,7 +14,7 @@ | |||
14 | #define WANT_ACCESSLIST | 14 | #define WANT_ACCESSLIST |
15 | void accesslist_init( ); | 15 | void accesslist_init( ); |
16 | void accesslist_deinit( ); | 16 | void accesslist_deinit( ); |
17 | int accesslist_hashisvalid( ot_hash *hash ); | 17 | int accesslist_hashisvalid( ot_hash hash ); |
18 | 18 | ||
19 | extern char *g_accesslist_filename; | 19 | extern char *g_accesslist_filename; |
20 | 20 | ||
@@ -30,7 +30,7 @@ typedef enum { | |||
30 | OT_PERMISSION_MAY_LIVESYNC = 0x4 | 30 | OT_PERMISSION_MAY_LIVESYNC = 0x4 |
31 | } ot_permissions; | 31 | } ot_permissions; |
32 | 32 | ||
33 | int accesslist_blessip( char * ip, ot_permissions permissions ); | 33 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); |
34 | int accesslist_isblessed( char * ip, ot_permissions permissions ); | 34 | int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ); |
35 | 35 | ||
36 | #endif | 36 | #endif |
diff --git a/ot_fullscrape.c b/ot_fullscrape.c index 3f60d40..17405b7 100644 --- a/ot_fullscrape.c +++ b/ot_fullscrape.c | |||
@@ -115,7 +115,7 @@ static int fullscrape_increase( int *iovec_entries, struct iovec **iovector, | |||
115 | } | 115 | } |
116 | 116 | ||
117 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { | 117 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { |
118 | int bucket,i; | 118 | int bucket; |
119 | char *r, *re; | 119 | char *r, *re; |
120 | #ifdef WANT_COMPRESSION_GZIP | 120 | #ifdef WANT_COMPRESSION_GZIP |
121 | char compress_buffer[OT_SCRAPE_MAXENTRYLEN]; | 121 | char compress_buffer[OT_SCRAPE_MAXENTRYLEN]; |
@@ -165,17 +165,17 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tas | |||
165 | 165 | ||
166 | /* push hash as bencoded string */ | 166 | /* push hash as bencoded string */ |
167 | *r++='2'; *r++='0'; *r++=':'; | 167 | *r++='2'; *r++='0'; *r++=':'; |
168 | for(i=0;i<20;i+=4) WRITE32(r,i,READ32(hash,i)); r+=20; | 168 | memcpy( r, hash, sizeof(ot_hash) ); r += sizeof(ot_hash); |
169 | /* push rest of the scrape string */ | 169 | /* push rest of the scrape string */ |
170 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count ); | 170 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count ); |
171 | 171 | ||
172 | break; | 172 | break; |
173 | case TASK_FULLSCRAPE_TPB_ASCII: | 173 | case TASK_FULLSCRAPE_TPB_ASCII: |
174 | to_hex( r, *hash ); r+=40; | 174 | to_hex( r, *hash ); r+= 2 * sizeof(ot_hash); |
175 | r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count ); | 175 | r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count ); |
176 | break; | 176 | break; |
177 | case TASK_FULLSCRAPE_TPB_BINARY: | 177 | case TASK_FULLSCRAPE_TPB_BINARY: |
178 | for(i=0;i<20;i+=4) WRITE32(r,i,READ32(hash,i)); r+=20; | 178 | memcpy( r, *hash, sizeof(ot_hash) ); r += sizeof(ot_hash); |
179 | *(uint32_t*)(r+0) = htonl( (uint32_t) peer_list->seed_count ); | 179 | *(uint32_t*)(r+0) = htonl( (uint32_t) peer_list->seed_count ); |
180 | *(uint32_t*)(r+4) = htonl( (uint32_t)( peer_list->peer_count-peer_list->seed_count) ); | 180 | *(uint32_t*)(r+4) = htonl( (uint32_t)( peer_list->peer_count-peer_list->seed_count) ); |
181 | r+=8; | 181 | r+=8; |
@@ -15,6 +15,7 @@ | |||
15 | #include "byte.h" | 15 | #include "byte.h" |
16 | #include "array.h" | 16 | #include "array.h" |
17 | #include "iob.h" | 17 | #include "iob.h" |
18 | #include "ip6.h" | ||
18 | 19 | ||
19 | /* Opentracker */ | 20 | /* Opentracker */ |
20 | #include "trackerlogic.h" | 21 | #include "trackerlogic.h" |
@@ -34,11 +35,6 @@ enum { | |||
34 | SUCCESS_HTTP_HEADER_LENGTH_CONTENT_ENCODING = 32, | 35 | SUCCESS_HTTP_HEADER_LENGTH_CONTENT_ENCODING = 32, |
35 | SUCCESS_HTTP_SIZE_OFF = 17 }; | 36 | SUCCESS_HTTP_SIZE_OFF = 17 }; |
36 | 37 | ||
37 | #ifdef _DEBUG_PEERID | ||
38 | size_t g_this_peerid_len = 0; | ||
39 | char *g_this_peerid_data = NULL; | ||
40 | #endif | ||
41 | |||
42 | static void http_senddata( const int64 client_socket, struct ot_workstruct *ws ) { | 38 | static void http_senddata( const int64 client_socket, struct ot_workstruct *ws ) { |
43 | struct http_data *h = io_getcookie( client_socket ); | 39 | struct http_data *h = io_getcookie( client_socket ); |
44 | ssize_t written_size; | 40 | ssize_t written_size; |
@@ -63,7 +59,7 @@ static void http_senddata( const int64 client_socket, struct ot_workstruct *ws ) | |||
63 | } | 59 | } |
64 | 60 | ||
65 | iob_reset( &h->data.batch ); | 61 | iob_reset( &h->data.batch ); |
66 | memmove( outbuf, ws->reply + written_size, ws->reply_size - written_size ); | 62 | memcpy( outbuf, ws->reply + written_size, ws->reply_size - written_size ); |
67 | iob_addbuf_free( &h->data.batch, outbuf, ws->reply_size - written_size ); | 63 | iob_addbuf_free( &h->data.batch, outbuf, ws->reply_size - written_size ); |
68 | h->flag |= STRUCT_HTTP_FLAG_IOB_USED; | 64 | h->flag |= STRUCT_HTTP_FLAG_IOB_USED; |
69 | 65 | ||
@@ -89,9 +85,9 @@ ssize_t http_issue_error( const int64 client_socket, struct ot_workstruct *ws, i | |||
89 | 85 | ||
90 | ws->reply = ws->outbuf; | 86 | ws->reply = ws->outbuf; |
91 | if( code == CODE_HTTPERROR_302 ) | 87 | if( code == CODE_HTTPERROR_302 ) |
92 | ws->reply_size = snprintf( ws->reply, ws->outbuf_size, "HTTP/1.0 302 Found\r\nContent-Length: 0\r\nLocation: %s\r\n\r\n", g_redirecturl ); | 88 | ws->reply_size = snprintf( ws->reply, G_OUTBUF_SIZE, "HTTP/1.0 302 Found\r\nContent-Length: 0\r\nLocation: %s\r\n\r\n", g_redirecturl ); |
93 | else | 89 | else |
94 | ws->reply_size = snprintf( ws->reply, ws->outbuf_size, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", title, strlen(title)+16-4,title+4); | 90 | ws->reply_size = snprintf( ws->reply, G_OUTBUF_SIZE, "HTTP/1.0 %s\r\nContent-Type: text/html\r\nConnection: close\r\nContent-Length: %zd\r\n\r\n<title>%s</title>\n", title, strlen(title)+16-4,title+4); |
95 | 91 | ||
96 | #ifdef _DEBUG_HTTPERROR | 92 | #ifdef _DEBUG_HTTPERROR |
97 | fprintf( stderr, "DEBUG: invalid request was: %s\n", ws->debugbuf ); | 93 | fprintf( stderr, "DEBUG: invalid request was: %s\n", ws->debugbuf ); |
@@ -245,13 +241,13 @@ static ssize_t http_handle_fullscrape( const int64 client_socket, struct ot_work | |||
245 | if( strstr( ws->request, "gzip" ) ) { | 241 | if( strstr( ws->request, "gzip" ) ) { |
246 | h->flag |= STRUCT_HTTP_FLAG_GZIP; | 242 | h->flag |= STRUCT_HTTP_FLAG_GZIP; |
247 | format = TASK_FLAG_GZIP; | 243 | format = TASK_FLAG_GZIP; |
248 | stats_issue_event( EVENT_FULLSCRAPE_REQUEST_GZIP, *(int*)h->ip, 0 ); | 244 | stats_issue_event( EVENT_FULLSCRAPE_REQUEST_GZIP, 0, (uintptr_t)h->ip ); |
249 | } else | 245 | } else |
250 | #endif | 246 | #endif |
251 | stats_issue_event( EVENT_FULLSCRAPE_REQUEST, *(int*)h->ip, 0 ); | 247 | stats_issue_event( EVENT_FULLSCRAPE_REQUEST, 0, (uintptr_t)h->ip ); |
252 | 248 | ||
253 | #ifdef _DEBUG_HTTPERROR | 249 | #ifdef _DEBUG_HTTPERROR |
254 | write( 2, ws->debugbuf, ws->debugbuf_size ); | 250 | write( 2, ws->debugbuf, G_DEBUGBUF_SIZE ); |
255 | #endif | 251 | #endif |
256 | 252 | ||
257 | /* Pass this task to the worker thread */ | 253 | /* Pass this task to the worker thread */ |
@@ -263,6 +259,7 @@ write( 2, ws->debugbuf, ws->debugbuf_size ); | |||
263 | return ws->reply_size = -2; | 259 | return ws->reply_size = -2; |
264 | } | 260 | } |
265 | #endif | 261 | #endif |
262 | |||
266 | static ssize_t http_handle_scrape( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { | 263 | static ssize_t http_handle_scrape( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { |
267 | static const ot_keywords keywords_scrape[] = { { "info_hash", 1 }, { NULL, -3 } }; | 264 | static const ot_keywords keywords_scrape[] = { { "info_hash", 1 }, { NULL, -3 } }; |
268 | 265 | ||
@@ -306,9 +303,6 @@ static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "even | |||
306 | #ifdef WANT_IP_FROM_QUERY_STRING | 303 | #ifdef WANT_IP_FROM_QUERY_STRING |
307 | { "ip", 7 }, | 304 | { "ip", 7 }, |
308 | #endif | 305 | #endif |
309 | #ifdef _DEBUG_PEERID | ||
310 | { "peer_id", 8 }, | ||
311 | #endif | ||
312 | { NULL, -3 } }; | 306 | { NULL, -3 } }; |
313 | static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } }; | 307 | static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } }; |
314 | static ssize_t http_handle_announce( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { | 308 | static ssize_t http_handle_announce( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { |
@@ -332,10 +326,6 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst | |||
332 | numwant = 50; | 326 | numwant = 50; |
333 | scanon = 1; | 327 | scanon = 1; |
334 | 328 | ||
335 | #ifdef _DEBUG_PEERID | ||
336 | ws->peer_id = NULL; | ||
337 | #endif | ||
338 | |||
339 | while( scanon ) { | 329 | while( scanon ) { |
340 | switch( scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM ) ) { | 330 | switch( scan_find_keywords(keywords_announce, &read_ptr, SCAN_SEARCHPATH_PARAM ) ) { |
341 | case -2: scanon = 0; break; /* TERMINATOR */ | 331 | case -2: scanon = 0; break; /* TERMINATOR */ |
@@ -383,17 +373,15 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst | |||
383 | break; | 373 | break; |
384 | #ifdef WANT_IP_FROM_QUERY_STRING | 374 | #ifdef WANT_IP_FROM_QUERY_STRING |
385 | case 7: /* matched "ip" */ | 375 | case 7: /* matched "ip" */ |
386 | len = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ); | 376 | { |
387 | if( ( len <= 0 ) || scan_fixed_ip( write_ptr, len, (unsigned char*)/*tmp*/ws->reply ) ) HTTPERROR_400_PARAM; | 377 | char *tmp_buf1 = ws->reply, *tmp_buf2 = ws->reply+16; |
388 | OT_SETIP( &peer, /*tmp*/ws->reply ); | 378 | len = scan_urlencoded_query( &read_ptr, tmp_buf2, SCAN_SEARCHPATH_VALUE ); |
379 | tmp_buf2[len] = 0; | ||
380 | if( ( len <= 0 ) || scan_ip6( tmp_buf2, tmp_buf1 ) ) HTTPERROR_400_PARAM; | ||
381 | OT_SETIP( &peer, tmp_buf1 ); | ||
382 | } | ||
389 | break; | 383 | break; |
390 | #endif | 384 | #endif |
391 | #ifdef _DEBUG_PEERID | ||
392 | case 8: /* matched "peer_id" */ | ||
393 | ws->peer_id_size = scan_urlencoded_query( &read_ptr, write_ptr = read_ptr, SCAN_SEARCHPATH_VALUE ); | ||
394 | ws->peer_id = ws->peer_id_size > 0 ? write_ptr : 0; | ||
395 | break; | ||
396 | #endif | ||
397 | } | 385 | } |
398 | } | 386 | } |
399 | 387 | ||
@@ -402,9 +390,9 @@ static ssize_t http_handle_announce( const int64 client_socket, struct ot_workst | |||
402 | return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" ); | 390 | return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" ); |
403 | 391 | ||
404 | if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED ) | 392 | if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED ) |
405 | ws->reply_size = remove_peer_from_torrent( hash, &peer, ws->reply, FLAG_TCP ); | 393 | ws->reply_size = remove_peer_from_torrent( *hash, &peer, ws->reply, FLAG_TCP ); |
406 | else | 394 | else |
407 | ws->reply_size = add_peer_to_torrent_and_return_peers(hash, &peer, FLAG_TCP, numwant, ws->reply ); | 395 | ws->reply_size = add_peer_to_torrent_and_return_peers( *hash, &peer, FLAG_TCP, numwant, ws->reply ); |
408 | 396 | ||
409 | if( !ws->reply_size ) HTTPERROR_500; | 397 | if( !ws->reply_size ) HTTPERROR_500; |
410 | 398 | ||
@@ -418,9 +406,9 @@ ssize_t http_handle_request( const int64 client_socket, struct ot_workstruct *ws | |||
418 | 406 | ||
419 | #ifdef _DEBUG_HTTPERROR | 407 | #ifdef _DEBUG_HTTPERROR |
420 | reply_off = ws->request_size; | 408 | reply_off = ws->request_size; |
421 | if( ws->request_size >= (ssize_t)ws->debugbuf_size ) | 409 | if( ws->request_size >= G_DEBUGBUF_SIZE ) |
422 | reply_off = ws->debugbuf_size - 1; | 410 | reply_off = G_DEBUGBUF_SIZE - 1; |
423 | memmove( ws->debugbuf, ws->request, reply_off ); | 411 | memcpy( ws->debugbuf, ws->request, reply_off ); |
424 | ws->debugbuf[ reply_off ] = 0; | 412 | ws->debugbuf[ reply_off ] = 0; |
425 | #endif | 413 | #endif |
426 | 414 | ||
@@ -19,7 +19,7 @@ struct http_data { | |||
19 | array request; | 19 | array request; |
20 | io_batch batch; | 20 | io_batch batch; |
21 | } data; | 21 | } data; |
22 | char ip[4]; | 22 | ot_ip6 ip; |
23 | STRUCT_HTTP_FLAG flag; | 23 | STRUCT_HTTP_FLAG flag; |
24 | }; | 24 | }; |
25 | 25 | ||
diff --git a/ot_livesync.c b/ot_livesync.c index a47edba..d577f7c 100644 --- a/ot_livesync.c +++ b/ot_livesync.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "socket.h" | 15 | #include "socket.h" |
16 | #include "ndelay.h" | 16 | #include "ndelay.h" |
17 | #include "byte.h" | 17 | #include "byte.h" |
18 | #include "ip6.h" | ||
18 | 19 | ||
19 | /* Opentracker */ | 20 | /* Opentracker */ |
20 | #include "trackerlogic.h" | 21 | #include "trackerlogic.h" |
@@ -88,14 +89,14 @@ void livesync_init( ) { | |||
88 | 89 | ||
89 | /* Prepare outgoing peers buffer */ | 90 | /* Prepare outgoing peers buffer */ |
90 | g_peerbuffer_pos = g_peerbuffer_start; | 91 | g_peerbuffer_pos = g_peerbuffer_start; |
91 | memmove( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); | 92 | memcpy( g_peerbuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); |
92 | uint32_pack_big( (char*)g_peerbuffer_pos + sizeof( g_tracker_id ), OT_SYNC_PEER); | 93 | uint32_pack_big( (char*)g_peerbuffer_pos + sizeof( g_tracker_id ), OT_SYNC_PEER); |
93 | g_peerbuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t); | 94 | g_peerbuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t); |
94 | 95 | ||
95 | #ifdef WANT_SYNC_SCRAPE | 96 | #ifdef WANT_SYNC_SCRAPE |
96 | /* Prepare outgoing scrape buffer */ | 97 | /* Prepare outgoing scrape buffer */ |
97 | g_scrapebuffer_pos = g_scrapebuffer_start; | 98 | g_scrapebuffer_pos = g_scrapebuffer_start; |
98 | memmove( g_scrapebuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); | 99 | memcpy( g_scrapebuffer_pos, &g_tracker_id, sizeof( g_tracker_id ) ); |
99 | uint32_pack_big( (char*)g_scrapebuffer_pos + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_TELL); | 100 | uint32_pack_big( (char*)g_scrapebuffer_pos + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_TELL); |
100 | g_scrapebuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t); | 101 | g_scrapebuffer_pos += sizeof( g_tracker_id ) + sizeof( uint32_t); |
101 | 102 | ||
@@ -116,8 +117,13 @@ void livesync_deinit() { | |||
116 | pthread_cancel( thread_id ); | 117 | pthread_cancel( thread_id ); |
117 | } | 118 | } |
118 | 119 | ||
119 | void livesync_bind_mcast( char *ip, uint16_t port) { | 120 | void livesync_bind_mcast( ot_ip6 ip, uint16_t port) { |
120 | char tmpip[4] = {0,0,0,0}; | 121 | char tmpip[4] = {0,0,0,0}; |
122 | char *v4ip; | ||
123 | |||
124 | if( !ip6_isv4mapped(ip)) | ||
125 | exerr("v6 mcast support not yet available."); | ||
126 | v4ip = ip+12; | ||
121 | 127 | ||
122 | if( g_socket_in != -1 ) | 128 | if( g_socket_in != -1 ) |
123 | exerr("Error: Livesync listen ip specified twice."); | 129 | exerr("Error: Livesync listen ip specified twice."); |
@@ -129,12 +135,12 @@ void livesync_bind_mcast( char *ip, uint16_t port) { | |||
129 | if( socket_bind4_reuse( g_socket_in, tmpip, port ) == -1 ) | 135 | if( socket_bind4_reuse( g_socket_in, tmpip, port ) == -1 ) |
130 | exerr("Error: Cant bind live sync incoming socket." ); | 136 | exerr("Error: Cant bind live sync incoming socket." ); |
131 | 137 | ||
132 | if( socket_mcjoin4( g_socket_in, groupip_1, ip ) ) | 138 | if( socket_mcjoin4( g_socket_in, groupip_1, v4ip ) ) |
133 | exerr("Error: Cant make live sync incoming socket join mcast group."); | 139 | exerr("Error: Cant make live sync incoming socket join mcast group."); |
134 | 140 | ||
135 | if( ( g_socket_out = socket_udp4()) < 0) | 141 | if( ( g_socket_out = socket_udp4()) < 0) |
136 | exerr("Error: Cant create live sync outgoing socket." ); | 142 | exerr("Error: Cant create live sync outgoing socket." ); |
137 | if( socket_bind4_reuse( g_socket_out, ip, port ) == -1 ) | 143 | if( socket_bind4_reuse( g_socket_out, v4ip, port ) == -1 ) |
138 | exerr("Error: Cant bind live sync outgoing socket." ); | 144 | exerr("Error: Cant bind live sync outgoing socket." ); |
139 | 145 | ||
140 | socket_mcttl4(g_socket_out, 1); | 146 | socket_mcttl4(g_socket_out, 1); |
@@ -160,9 +166,9 @@ static void livesync_handle_peersync( ssize_t datalen ) { | |||
160 | if( !g_opentracker_running ) return; | 166 | if( !g_opentracker_running ) return; |
161 | 167 | ||
162 | if( OT_PEERFLAG(peer) & PEER_FLAG_STOPPED ) | 168 | if( OT_PEERFLAG(peer) & PEER_FLAG_STOPPED ) |
163 | remove_peer_from_torrent(hash, peer, NULL, FLAG_MCA ); | 169 | remove_peer_from_torrent( *hash, peer, NULL, FLAG_MCA ); |
164 | else | 170 | else |
165 | add_peer_to_torrent( hash, peer, FLAG_MCA ); | 171 | add_peer_to_torrent( *hash, peer, FLAG_MCA ); |
166 | 172 | ||
167 | off += sizeof( ot_hash ) + sizeof( ot_peer ); | 173 | off += sizeof( ot_hash ) + sizeof( ot_peer ); |
168 | } | 174 | } |
@@ -175,7 +181,7 @@ void livesync_issue_beacon( ) { | |||
175 | size_t torrent_count = mutex_get_torrent_count(); | 181 | size_t torrent_count = mutex_get_torrent_count(); |
176 | uint8_t beacon[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof( uint64_t ) ]; | 182 | uint8_t beacon[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof( uint64_t ) ]; |
177 | 183 | ||
178 | memmove( beacon, &g_tracker_id, sizeof( g_tracker_id ) ); | 184 | memcpy( beacon, &g_tracker_id, sizeof( g_tracker_id ) ); |
179 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_BEACON); | 185 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_BEACON); |
180 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + sizeof(uint32_t), (uint32_t)((uint64_t)(torrent_count)>>32) ); | 186 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + sizeof(uint32_t), (uint32_t)((uint64_t)(torrent_count)>>32) ); |
181 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + 2 * sizeof(uint32_t), (uint32_t)torrent_count ); | 187 | uint32_pack_big( (char*)beacon + sizeof( g_tracker_id ) + 2 * sizeof(uint32_t), (uint32_t)torrent_count ); |
@@ -202,7 +208,7 @@ void livesync_handle_beacon( ssize_t datalen ) { | |||
202 | 208 | ||
203 | if( torrent_count_remote > g_inquire_remote_count ) { | 209 | if( torrent_count_remote > g_inquire_remote_count ) { |
204 | g_inquire_remote_count = torrent_count_remote; | 210 | g_inquire_remote_count = torrent_count_remote; |
205 | memmove( &g_inquire_remote_host, g_inbuffer, sizeof( g_tracker_id ) ); | 211 | memcpy( &g_inquire_remote_host, g_inbuffer, sizeof( g_tracker_id ) ); |
206 | } | 212 | } |
207 | } | 213 | } |
208 | } | 214 | } |
@@ -210,9 +216,9 @@ void livesync_handle_beacon( ssize_t datalen ) { | |||
210 | void livesync_issue_inquire( ) { | 216 | void livesync_issue_inquire( ) { |
211 | uint8_t inquire[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof(g_tracker_id)]; | 217 | uint8_t inquire[ sizeof(g_tracker_id) + sizeof(uint32_t) + sizeof(g_tracker_id)]; |
212 | 218 | ||
213 | memmove( inquire, &g_tracker_id, sizeof( g_tracker_id ) ); | 219 | memcpy( inquire, &g_tracker_id, sizeof( g_tracker_id ) ); |
214 | uint32_pack_big( (char*)inquire + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_INQUIRE); | 220 | uint32_pack_big( (char*)inquire + sizeof( g_tracker_id ), OT_SYNC_SCRAPE_INQUIRE); |
215 | memmove( inquire + sizeof(g_tracker_id) + sizeof(uint32_t), &g_inquire_remote_host, sizeof( g_tracker_id ) ); | 221 | memcpy( inquire + sizeof(g_tracker_id) + sizeof(uint32_t), &g_inquire_remote_host, sizeof( g_tracker_id ) ); |
216 | 222 | ||
217 | socket_send4(g_socket_out, (char*)inquire, sizeof(inquire), groupip_1, LIVESYNC_PORT); | 223 | socket_send4(g_socket_out, (char*)inquire, sizeof(inquire), groupip_1, LIVESYNC_PORT); |
218 | } | 224 | } |
@@ -239,7 +245,7 @@ void livesync_issue_tell( ) { | |||
239 | unsigned int j; | 245 | unsigned int j; |
240 | for( j=0; j<torrents_list->size; ++j ) { | 246 | for( j=0; j<torrents_list->size; ++j ) { |
241 | ot_torrent *torrent = (ot_torrent*)(torrents_list->data) + j; | 247 | ot_torrent *torrent = (ot_torrent*)(torrents_list->data) + j; |
242 | memmove(g_scrapebuffer_pos, torrent->hash, sizeof(ot_hash)); | 248 | memcpy(g_scrapebuffer_pos, torrent->hash, sizeof(ot_hash)); |
243 | g_scrapebuffer_pos += sizeof(ot_hash); | 249 | g_scrapebuffer_pos += sizeof(ot_hash); |
244 | uint32_pack_big( (char*)g_scrapebuffer_pos , (uint32_t)(g_now_minutes - torrent->peer_list->base )); | 250 | uint32_pack_big( (char*)g_scrapebuffer_pos , (uint32_t)(g_now_minutes - torrent->peer_list->base )); |
245 | uint32_pack_big( (char*)g_scrapebuffer_pos + 4, (uint32_t)((uint64_t)(torrent->peer_list->down_count)>>32) ); | 251 | uint32_pack_big( (char*)g_scrapebuffer_pos + 4, (uint32_t)((uint64_t)(torrent->peer_list->down_count)>>32) ); |
@@ -268,29 +274,29 @@ void livesync_handle_tell( ssize_t datalen ) { | |||
268 | /* Some instance is in progress of telling. Our inquiry was successful. | 274 | /* Some instance is in progress of telling. Our inquiry was successful. |
269 | Don't ask again until we see next beacon. */ | 275 | Don't ask again until we see next beacon. */ |
270 | g_next_inquire_time = 0; | 276 | g_next_inquire_time = 0; |
271 | 277 | ||
272 | /* Don't cause any new inquiries during another tracker's tell */ | 278 | /* Don't cause any new inquiries during another tracker's tell */ |
273 | if( g_next_beacon_time - g_now_seconds < LIVESYNC_BEACON_INTERVAL ) | 279 | if( g_next_beacon_time - g_now_seconds < LIVESYNC_BEACON_INTERVAL ) |
274 | g_next_beacon_time = g_now_seconds + LIVESYNC_BEACON_INTERVAL; | 280 | g_next_beacon_time = g_now_seconds + LIVESYNC_BEACON_INTERVAL; |
275 | 281 | ||
276 | while( off + sizeof(ot_hash) + 12 <= (size_t)datalen ) { | 282 | while( off + sizeof(ot_hash) + 12 <= (size_t)datalen ) { |
277 | ot_hash *hash = (ot_hash*)(g_inbuffer+off); | 283 | ot_hash *hash = (ot_hash*)(g_inbuffer+off); |
278 | ot_vector *torrents_list = mutex_bucket_lock_by_hash(hash); | 284 | ot_vector *torrents_list = mutex_bucket_lock_by_hash(*hash); |
279 | size_t down_count_remote; | 285 | size_t down_count_remote; |
280 | int exactmatch; | 286 | int exactmatch; |
281 | ot_torrent * torrent = vector_find_or_insert(torrents_list, hash, sizeof(ot_hash), OT_HASH_COMPARE_SIZE, &exactmatch); | 287 | ot_torrent * torrent = vector_find_or_insert(torrents_list, hash, sizeof(ot_hash), OT_HASH_COMPARE_SIZE, &exactmatch); |
282 | if( !torrent ) { | 288 | if( !torrent ) { |
283 | mutex_bucket_unlock_by_hash( hash, 0 ); | 289 | mutex_bucket_unlock_by_hash( *hash, 0 ); |
284 | continue; | 290 | continue; |
285 | } | 291 | } |
286 | 292 | ||
287 | if( !exactmatch ) { | 293 | if( !exactmatch ) { |
288 | /* Create a new torrent entry, then */ | 294 | /* Create a new torrent entry, then */ |
289 | int i; for(i=0;i<20;i+=4) WRITE32(&torrent->hash,i,READ32(hash,i)); | 295 | memcpy( &torrent->hash, hash, sizeof(ot_hash)); |
290 | 296 | ||
291 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { | 297 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { |
292 | vector_remove_torrent( torrents_list, torrent ); | 298 | vector_remove_torrent( torrents_list, torrent ); |
293 | mutex_bucket_unlock_by_hash( hash, 0 ); | 299 | mutex_bucket_unlock_by_hash( *hash, 0 ); |
294 | continue; | 300 | continue; |
295 | } | 301 | } |
296 | 302 | ||
@@ -298,8 +304,8 @@ void livesync_handle_tell( ssize_t datalen ) { | |||
298 | torrent->peer_list->base = g_now_minutes - uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash)); | 304 | torrent->peer_list->base = g_now_minutes - uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash)); |
299 | } | 305 | } |
300 | 306 | ||
301 | down_count_remote = (size_t)(((uint64_t)uint32_read_big((char*)g_inbuffer+off+sizeof( ot_hash ) + sizeof(uint32_t))) << 32); | 307 | down_count_remote = (size_t)(((uint64_t)uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash ) + sizeof(uint32_t))) << 32); |
302 | down_count_remote |= (size_t) uint32_read_big((char*)g_inbuffer+off+sizeof( ot_hash ) + 2 * sizeof(uint32_t)); | 308 | down_count_remote |= (size_t) uint32_read_big((char*)g_inbuffer+off+sizeof(ot_hash ) + 2 * sizeof(uint32_t)); |
303 | 309 | ||
304 | if( down_count_remote > torrent->peer_list->down_count ) | 310 | if( down_count_remote > torrent->peer_list->down_count ) |
305 | torrent->peer_list->down_count = down_count_remote; | 311 | torrent->peer_list->down_count = down_count_remote; |
@@ -319,7 +325,7 @@ void livesync_handle_tell( ssize_t datalen ) { | |||
319 | stuck when there's not enough traffic to fill udp packets fast | 325 | stuck when there's not enough traffic to fill udp packets fast |
320 | enough */ | 326 | enough */ |
321 | void livesync_ticker( ) { | 327 | void livesync_ticker( ) { |
322 | 328 | ||
323 | /* livesync_issue_peersync sets g_next_packet_time */ | 329 | /* livesync_issue_peersync sets g_next_packet_time */ |
324 | if( g_now_seconds > g_next_packet_time && | 330 | if( g_now_seconds > g_next_packet_time && |
325 | g_peerbuffer_pos > g_peerbuffer_start + sizeof( g_tracker_id ) ) | 331 | g_peerbuffer_pos > g_peerbuffer_start + sizeof( g_tracker_id ) ) |
@@ -350,21 +356,19 @@ void livesync_ticker( ) { | |||
350 | } | 356 | } |
351 | 357 | ||
352 | /* Inform live sync about whats going on. */ | 358 | /* Inform live sync about whats going on. */ |
353 | void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer ) { | 359 | void livesync_tell( ot_hash const info_hash, const ot_peer * const peer ) { |
354 | unsigned int i; | ||
355 | for(i=0;i<sizeof(ot_hash)/4;i+=4) WRITE32(g_peerbuffer_pos,i,READ32(info_hash,i)); | ||
356 | 360 | ||
357 | WRITE32(g_peerbuffer_pos,sizeof(ot_hash) ,READ32(peer,0)); | 361 | memcpy( g_peerbuffer_pos, info_hash, sizeof(ot_hash) ); |
358 | WRITE32(g_peerbuffer_pos,sizeof(ot_hash)+4,READ32(peer,4)); | 362 | memcpy( g_peerbuffer_pos+sizeof(ot_hash), peer, sizeof(ot_peer) ); |
359 | 363 | ||
360 | g_peerbuffer_pos += sizeof(ot_hash)+8; | 364 | g_peerbuffer_pos += sizeof(ot_hash)+sizeof(ot_peer); |
361 | 365 | ||
362 | if( g_peerbuffer_pos >= g_peerbuffer_highwater ) | 366 | if( g_peerbuffer_pos >= g_peerbuffer_highwater ) |
363 | livesync_issue_peersync(); | 367 | livesync_issue_peersync(); |
364 | } | 368 | } |
365 | 369 | ||
366 | static void * livesync_worker( void * args ) { | 370 | static void * livesync_worker( void * args ) { |
367 | uint8_t in_ip[4]; uint16_t in_port; | 371 | ot_ip6 in_ip; uint16_t in_port; |
368 | ssize_t datalen; | 372 | ssize_t datalen; |
369 | 373 | ||
370 | (void)args; | 374 | (void)args; |
@@ -375,7 +379,7 @@ static void * livesync_worker( void * args ) { | |||
375 | /* Expect at least tracker id and packet type */ | 379 | /* Expect at least tracker id and packet type */ |
376 | if( datalen <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) ) | 380 | if( datalen <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) ) |
377 | continue; | 381 | continue; |
378 | if( !accesslist_isblessed((char*)in_ip, OT_PERMISSION_MAY_LIVESYNC)) | 382 | if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC)) |
379 | continue; | 383 | continue; |
380 | if( !memcmp( g_inbuffer, &g_tracker_id, sizeof( g_tracker_id ) ) ) { | 384 | if( !memcmp( g_inbuffer, &g_tracker_id, sizeof( g_tracker_id ) ) ) { |
381 | /* TODO: log packet coming from ourselves */ | 385 | /* TODO: log packet coming from ourselves */ |
diff --git a/ot_livesync.h b/ot_livesync.h index ae9ab55..8e78afb 100644 --- a/ot_livesync.h +++ b/ot_livesync.h | |||
@@ -86,7 +86,7 @@ void livesync_deinit(); | |||
86 | void livesync_bind_mcast( char *ip, uint16_t port ); | 86 | void livesync_bind_mcast( char *ip, uint16_t port ); |
87 | 87 | ||
88 | /* Inform live sync about whats going on. */ | 88 | /* Inform live sync about whats going on. */ |
89 | void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer ); | 89 | void livesync_tell( ot_hash const info_hash, const ot_peer * const peer ); |
90 | 90 | ||
91 | /* Tickle the live sync module from time to time, so no events get | 91 | /* Tickle the live sync module from time to time, so no events get |
92 | stuck when there's not enough traffic to fill udp packets fast | 92 | stuck when there's not enough traffic to fill udp packets fast |
@@ -80,8 +80,8 @@ ot_vector *mutex_bucket_lock( int bucket ) { | |||
80 | return all_torrents + bucket; | 80 | return all_torrents + bucket; |
81 | } | 81 | } |
82 | 82 | ||
83 | ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash ) { | 83 | ot_vector *mutex_bucket_lock_by_hash( ot_hash hash ) { |
84 | int bucket = uint32_read_big( (char*)*hash ) >> OT_BUCKET_COUNT_SHIFT; | 84 | int bucket = uint32_read_big( (char*)hash ) >> OT_BUCKET_COUNT_SHIFT; |
85 | 85 | ||
86 | /* Can block */ | 86 | /* Can block */ |
87 | mutex_bucket_lock( bucket ); | 87 | mutex_bucket_lock( bucket ); |
@@ -96,8 +96,8 @@ void mutex_bucket_unlock( int bucket, int delta_torrentcount ) { | |||
96 | pthread_mutex_unlock( &bucket_mutex ); | 96 | pthread_mutex_unlock( &bucket_mutex ); |
97 | } | 97 | } |
98 | 98 | ||
99 | void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount ) { | 99 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ) { |
100 | mutex_bucket_unlock( uint32_read_big( (char*)*hash ) >> OT_BUCKET_COUNT_SHIFT, delta_torrentcount ); | 100 | mutex_bucket_unlock( uint32_read_big( (char*)hash ) >> OT_BUCKET_COUNT_SHIFT, delta_torrentcount ); |
101 | } | 101 | } |
102 | 102 | ||
103 | size_t mutex_get_torrent_count( ) { | 103 | size_t mutex_get_torrent_count( ) { |
@@ -12,10 +12,10 @@ void mutex_init( ); | |||
12 | void mutex_deinit( ); | 12 | void mutex_deinit( ); |
13 | 13 | ||
14 | ot_vector *mutex_bucket_lock( int bucket ); | 14 | ot_vector *mutex_bucket_lock( int bucket ); |
15 | ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash ); | 15 | ot_vector *mutex_bucket_lock_by_hash( ot_hash hash ); |
16 | 16 | ||
17 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ); | 17 | void mutex_bucket_unlock( int bucket, int delta_torrentcount ); |
18 | void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount ); | 18 | void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount ); |
19 | 19 | ||
20 | size_t mutex_get_torrent_count(); | 20 | size_t mutex_get_torrent_count(); |
21 | 21 | ||
@@ -12,10 +12,12 @@ | |||
12 | #include <stdio.h> | 12 | #include <stdio.h> |
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <pthread.h> | 14 | #include <pthread.h> |
15 | #include <unistd.h> | ||
15 | 16 | ||
16 | /* Libowfat */ | 17 | /* Libowfat */ |
17 | #include "byte.h" | 18 | #include "byte.h" |
18 | #include "io.h" | 19 | #include "io.h" |
20 | #include "ip6.h" | ||
19 | 21 | ||
20 | /* Opentracker */ | 22 | /* Opentracker */ |
21 | #include "trackerlogic.h" | 23 | #include "trackerlogic.h" |
@@ -132,8 +134,8 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, u | |||
132 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; | 134 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; |
133 | --j; | 135 | --j; |
134 | 136 | ||
135 | memmove( scores, scores + 1, j * sizeof( *scores ) ); | 137 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); |
136 | memmove( networks, networks + 1, j * sizeof( *networks ) ); | 138 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); |
137 | scores[ j ] = node->counters[ i ]; | 139 | scores[ j ] = node->counters[ i ]; |
138 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); | 140 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); |
139 | } | 141 | } |
@@ -176,13 +178,13 @@ size_t stats_top10_txt( char * reply ) { | |||
176 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; | 178 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; |
177 | int idx = 9; while( (idx >= 0) && ( peer_list->peer_count > top10c[idx].val ) ) --idx; | 179 | int idx = 9; while( (idx >= 0) && ( peer_list->peer_count > top10c[idx].val ) ) --idx; |
178 | if ( idx++ != 9 ) { | 180 | if ( idx++ != 9 ) { |
179 | memmove( top10c + idx + 1, top10c + idx, ( 9 - idx ) * sizeof( ot_record ) ); | 181 | memcpy( top10c + idx + 1, top10c + idx, ( 9 - idx ) * sizeof( ot_record ) ); |
180 | top10c[idx].val = peer_list->peer_count; | 182 | top10c[idx].val = peer_list->peer_count; |
181 | top10c[idx].torrent = (ot_torrent*)(torrents_list->data) + j; | 183 | top10c[idx].torrent = (ot_torrent*)(torrents_list->data) + j; |
182 | } | 184 | } |
183 | idx = 9; while( (idx >= 0) && ( peer_list->seed_count > top10s[idx].val ) ) --idx; | 185 | idx = 9; while( (idx >= 0) && ( peer_list->seed_count > top10s[idx].val ) ) --idx; |
184 | if ( idx++ != 9 ) { | 186 | if ( idx++ != 9 ) { |
185 | memmove( top10s + idx + 1, top10s + idx, ( 9 - idx ) * sizeof( ot_record ) ); | 187 | memcpy( top10s + idx + 1, top10s + idx, ( 9 - idx ) * sizeof( ot_record ) ); |
186 | top10s[idx].val = peer_list->seed_count; | 188 | top10s[idx].val = peer_list->seed_count; |
187 | top10s[idx].torrent = (ot_torrent*)(torrents_list->data) + j; | 189 | top10s[idx].torrent = (ot_torrent*)(torrents_list->data) + j; |
188 | } | 190 | } |
@@ -269,7 +271,7 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) | |||
269 | while( ( insert_pos >= 0 ) && ( count[j] > slash24s[ 2 * insert_pos ] ) ) | 271 | while( ( insert_pos >= 0 ) && ( count[j] > slash24s[ 2 * insert_pos ] ) ) |
270 | --insert_pos; | 272 | --insert_pos; |
271 | ++insert_pos; | 273 | ++insert_pos; |
272 | memmove( slash24s + 2 * ( insert_pos + 1 ), slash24s + 2 * ( insert_pos ), 2 * sizeof( uint32_t ) * ( amount - insert_pos - 1 ) ); | 274 | memcpy( slash24s + 2 * ( insert_pos + 1 ), slash24s + 2 * ( insert_pos ), 2 * sizeof( uint32_t ) * ( amount - insert_pos - 1 ) ); |
273 | slash24s[ 2 * insert_pos ] = count[j]; | 275 | slash24s[ 2 * insert_pos ] = count[j]; |
274 | slash24s[ 2 * insert_pos + 1 ] = ( i << NUM_TOPBITS ) + j; | 276 | slash24s[ 2 * insert_pos + 1 ] = ( i << NUM_TOPBITS ) + j; |
275 | if( slash24s[ 2 * amount - 2 ] > thresh ) | 277 | if( slash24s[ 2 * amount - 2 ] > thresh ) |
@@ -537,7 +539,7 @@ static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype | |||
537 | iovec_fixlast( iovec_entries, iovector, r ); | 539 | iovec_fixlast( iovec_entries, iovector, r ); |
538 | } | 540 | } |
539 | 541 | ||
540 | void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ) { | 542 | void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data ) { |
541 | switch( event ) { | 543 | switch( event ) { |
542 | case EVENT_ACCEPT: | 544 | case EVENT_ACCEPT: |
543 | if( proto == FLAG_TCP ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; | 545 | if( proto == FLAG_TCP ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; |
@@ -559,16 +561,24 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_ | |||
559 | break; | 561 | break; |
560 | case EVENT_FULLSCRAPE_REQUEST: | 562 | case EVENT_FULLSCRAPE_REQUEST: |
561 | { | 563 | { |
562 | uint8_t ip[4]; *(uint32_t*)ip = (uint32_t)proto; /* ugly hack to transfer ip to stats */ | 564 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ |
563 | LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now_seconds - ot_start_time)/60, ip[0], ip[1], ip[2], ip[3] ); | 565 | char _debug[512]; |
564 | ot_full_scrape_request_count++; | 566 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); |
567 | off += fmt_ip6( _debug+off, *ip ); | ||
568 | off += snprintf( _debug, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | ||
569 | write( 2, _debug, off ); | ||
570 | ot_full_scrape_request_count++; | ||
565 | } | 571 | } |
566 | break; | 572 | break; |
567 | case EVENT_FULLSCRAPE_REQUEST_GZIP: | 573 | case EVENT_FULLSCRAPE_REQUEST_GZIP: |
568 | { | 574 | { |
569 | uint8_t ip[4]; *(uint32_t*)ip = (uint32_t)proto; /* ugly hack to transfer ip to stats */ | 575 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ |
570 | LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE GZIP\n", (unsigned int)(g_now_seconds - ot_start_time)/60, ip[0], ip[1], ip[2], ip[3] ); | 576 | char _debug[512]; |
571 | ot_full_scrape_request_count++; | 577 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); |
578 | off += fmt_ip6(_debug+off, *ip ); | ||
579 | off += snprintf( _debug, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | ||
580 | write( 2, _debug, off ); | ||
581 | ot_full_scrape_request_count++; | ||
572 | } | 582 | } |
573 | break; | 583 | break; |
574 | case EVENT_FAILED: | 584 | case EVENT_FAILED: |
@@ -32,7 +32,7 @@ enum { | |||
32 | CODE_HTTPERROR_COUNT | 32 | CODE_HTTPERROR_COUNT |
33 | }; | 33 | }; |
34 | 34 | ||
35 | void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ); | 35 | void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data ); |
36 | void stats_deliver( int64 socket, int tasktype ); | 36 | void stats_deliver( int64 socket, int tasktype ); |
37 | size_t return_stats_for_tracker( char *reply, int mode, int format ); | 37 | size_t return_stats_for_tracker( char *reply, int mode, int format ); |
38 | size_t stats_return_tracker_version( char *reply ); | 38 | size_t stats_return_tracker_version( char *reply ); |
@@ -19,15 +19,15 @@ | |||
19 | 19 | ||
20 | static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; | 20 | static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; |
21 | 21 | ||
22 | static void udp_make_connectionid( uint32_t * connid, const char * remoteip ) { | 22 | static void udp_make_connectionid( uint32_t * connid, const ot_ip6 remoteip ) { |
23 | /* Touch unused variable */ | 23 | /* Touch unused variable */ |
24 | (void)remoteip; | 24 | (void)remoteip; |
25 | 25 | ||
26 | /* Use a static secret for now */ | 26 | /* Use a static secret for now */ |
27 | memmove( connid, g_static_connid, 8 ); | 27 | memcpy( connid, g_static_connid, 8 ); |
28 | } | 28 | } |
29 | 29 | ||
30 | static int udp_test_connectionid( const uint32_t * const connid, const char * remoteip ) { | 30 | static int udp_test_connectionid( const uint32_t * const connid, const ot_ip6 remoteip ) { |
31 | /* Touch unused variable */ | 31 | /* Touch unused variable */ |
32 | (void)remoteip; | 32 | (void)remoteip; |
33 | 33 | ||
@@ -36,19 +36,19 @@ static int udp_test_connectionid( const uint32_t * const connid, const char * re | |||
36 | } | 36 | } |
37 | 37 | ||
38 | /* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ | 38 | /* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ |
39 | void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) { | 39 | void handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { |
40 | ot_peer peer; | 40 | ot_peer peer; |
41 | ot_hash *hash = NULL; | 41 | ot_hash *hash = NULL; |
42 | char remoteip[4]; | 42 | ot_ip6 remoteip; |
43 | uint32_t *inpacket = (uint32_t*)ws->inbuf; | 43 | uint32_t *inpacket = (uint32_t*)ws->inbuf; |
44 | uint32_t *outpacket = (uint32_t*)ws->outbuf; | 44 | uint32_t *outpacket = (uint32_t*)ws->outbuf; |
45 | uint32_t numwant, left, event; | 45 | uint32_t numwant, left, event, scopeid; |
46 | uint16_t port, remoteport; | 46 | uint16_t port, remoteport; |
47 | size_t r, r_out; | 47 | size_t r, r_out; |
48 | 48 | ||
49 | r = socket_recv4( serversocket, ws->inbuf, ws->inbuf_size, remoteip, &remoteport); | 49 | r = socket_recv6( serversocket, ws->inbuf, G_INBUF_SIZE, remoteip, &remoteport, &scopeid ); |
50 | 50 | ||
51 | stats_issue_event( EVENT_ACCEPT, FLAG_UDP, ntohl(*(uint32_t*)remoteip) ); | 51 | stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip ); |
52 | stats_issue_event( EVENT_READ, FLAG_UDP, r ); | 52 | stats_issue_event( EVENT_READ, FLAG_UDP, r ); |
53 | 53 | ||
54 | /* Minimum udp tracker packet size, also catches error */ | 54 | /* Minimum udp tracker packet size, also catches error */ |
@@ -65,7 +65,7 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) { | |||
65 | outpacket[1] = inpacket[3]; | 65 | outpacket[1] = inpacket[3]; |
66 | udp_make_connectionid( outpacket + 2, remoteip ); | 66 | udp_make_connectionid( outpacket + 2, remoteip ); |
67 | 67 | ||
68 | socket_send4( serversocket, ws->outbuf, 16, remoteip, remoteport ); | 68 | socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 ); |
69 | stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 ); | 69 | stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 ); |
70 | break; | 70 | break; |
71 | case 1: /* This is an announce action */ | 71 | case 1: /* This is an announce action */ |
@@ -103,11 +103,11 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) { | |||
103 | outpacket[1] = inpacket[12/4]; | 103 | outpacket[1] = inpacket[12/4]; |
104 | 104 | ||
105 | if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED ) /* Peer is gone. */ | 105 | if( OT_PEERFLAG( &peer ) & PEER_FLAG_STOPPED ) /* Peer is gone. */ |
106 | r = remove_peer_from_torrent( hash, &peer, ws->outbuf, FLAG_UDP ); | 106 | r = remove_peer_from_torrent( *hash, &peer, ws->outbuf, FLAG_UDP ); |
107 | else | 107 | else |
108 | r = 8 + add_peer_to_torrent_and_return_peers( hash, &peer, FLAG_UDP, numwant, ((char*)outpacket) + 8 ); | 108 | r = 8 + add_peer_to_torrent_and_return_peers( *hash, &peer, FLAG_UDP, numwant, ((char*)outpacket) + 8 ); |
109 | 109 | ||
110 | socket_send4( serversocket, ws->outbuf, r, remoteip, remoteport ); | 110 | socket_send6( serversocket, ws->outbuf, r, remoteip, remoteport, 0 ); |
111 | stats_issue_event( EVENT_ANNOUNCE, FLAG_UDP, r ); | 111 | stats_issue_event( EVENT_ANNOUNCE, FLAG_UDP, r ); |
112 | break; | 112 | break; |
113 | 113 | ||
@@ -119,9 +119,9 @@ void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) { | |||
119 | outpacket[1] = inpacket[12/4]; | 119 | outpacket[1] = inpacket[12/4]; |
120 | 120 | ||
121 | for( r_out = 0; ( r_out * 20 < r - 16) && ( r_out <= 74 ); r_out++ ) | 121 | for( r_out = 0; ( r_out * 20 < r - 16) && ( r_out <= 74 ); r_out++ ) |
122 | return_udp_scrape_for_torrent( (ot_hash*)( ((char*)inpacket) + 16 + 20 * r_out ), ((char*)outpacket) + 8 + 12 * r_out ); | 122 | return_udp_scrape_for_torrent( *(ot_hash*)( ((char*)inpacket) + 16 + 20 * r_out ), ((char*)outpacket) + 8 + 12 * r_out ); |
123 | 123 | ||
124 | socket_send4( serversocket, ws->outbuf, 8 + 12 * r_out, remoteip, remoteport ); | 124 | socket_send6( serversocket, ws->outbuf, 8 + 12 * r_out, remoteip, remoteport, 0 ); |
125 | stats_issue_event( EVENT_SCRAPE, FLAG_UDP, r ); | 125 | stats_issue_event( EVENT_SCRAPE, FLAG_UDP, r ); |
126 | break; | 126 | break; |
127 | } | 127 | } |
@@ -6,6 +6,6 @@ | |||
6 | #ifndef __OT_UDP_H__ | 6 | #ifndef __OT_UDP_H__ |
7 | #define __OT_UDP_H__ | 7 | #define __OT_UDP_H__ |
8 | 8 | ||
9 | void handle_udp4( int64 serversocket, struct ot_workstruct *ws ); | 9 | void handle_udp6( int64 serversocket, struct ot_workstruct *ws ); |
10 | 10 | ||
11 | #endif | 11 | #endif |
diff --git a/ot_vector.c b/ot_vector.c index 29bdd49..f7481f1 100644 --- a/ot_vector.c +++ b/ot_vector.c | |||
@@ -17,9 +17,7 @@ | |||
17 | #include "uint16.h" | 17 | #include "uint16.h" |
18 | 18 | ||
19 | static int vector_compare_peer(const void *peer1, const void *peer2 ) { | 19 | static int vector_compare_peer(const void *peer1, const void *peer2 ) { |
20 | int32_t cmp = READ32(peer2,0) - READ32(peer1,0); | 20 | return memcmp( peer1, peer2, OT_PEER_COMPARE_SIZE ); |
21 | if (cmp == 0) cmp = READ16(peer2,4) - READ16(peer1,4); | ||
22 | return cmp; | ||
23 | } | 21 | } |
24 | 22 | ||
25 | /* This function gives us a binary search that returns a pointer, even if | 23 | /* This function gives us a binary search that returns a pointer, even if |
@@ -30,19 +28,14 @@ static int vector_compare_peer(const void *peer1, const void *peer2 ) { | |||
30 | */ | 28 | */ |
31 | void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size, | 29 | void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size, |
32 | size_t compare_size, int *exactmatch ) { | 30 | size_t compare_size, int *exactmatch ) { |
33 | size_t offs, mc = member_count; | 31 | size_t mc = member_count; |
34 | int8_t *lookat = ((int8_t*)base) + member_size * (mc >> 1); | 32 | int8_t *lookat = ((int8_t*)base) + member_size * (mc >> 1); |
35 | int32_t key_cache = READ32(key,0); | ||
36 | *exactmatch = 1; | 33 | *exactmatch = 1; |
37 | 34 | ||
38 | while( mc ) { | 35 | while( mc ) { |
39 | int32_t cmp = READ32(lookat,0) - key_cache; | 36 | int32_t cmp = memcmp( lookat, key, compare_size ); |
40 | if (cmp == 0) { | 37 | if( cmp == 0 ) |
41 | for( offs = 4; cmp == 0 && offs < compare_size; offs += 4 ) | 38 | return (void *)lookat; |
42 | cmp = READ32(lookat,offs) - READ32(key,offs); | ||
43 | if( cmp == 0 ) | ||
44 | return (void *)lookat; | ||
45 | } | ||
46 | 39 | ||
47 | if (cmp < 0) { | 40 | if (cmp < 0) { |
48 | base = (void*)(lookat + member_size); | 41 | base = (void*)(lookat + member_size); |
@@ -60,13 +53,10 @@ void *binary_search( const void * const key, const void * base, const size_t mem | |||
60 | ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, const size_t member_count, int *exactmatch ) { | 53 | ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, const size_t member_count, int *exactmatch ) { |
61 | size_t mc = member_count; | 54 | size_t mc = member_count; |
62 | const ot_peer *lookat = base + (mc >> 1); | 55 | const ot_peer *lookat = base + (mc >> 1); |
63 | int32_t low = READ32(peer,0); | ||
64 | int16_t high = READ16(peer,4); | ||
65 | *exactmatch = 1; | 56 | *exactmatch = 1; |
66 | 57 | ||
67 | while( mc ) { | 58 | while( mc ) { |
68 | int32_t cmp = READ32(lookat,0) - low; | 59 | int32_t cmp = memcmp(lookat,peer,OT_PEER_COMPARE_SIZE ); |
69 | if(cmp == 0) cmp = READ16(lookat,4) - high; | ||
70 | if(cmp == 0) return (ot_peer*)lookat; | 60 | if(cmp == 0) return (ot_peer*)lookat; |
71 | 61 | ||
72 | if (cmp < 0) { | 62 | if (cmp < 0) { |
@@ -84,7 +74,7 @@ ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, c | |||
84 | 74 | ||
85 | 75 | ||
86 | static uint8_t vector_hash_peer( ot_peer *peer, int bucket_count ) { | 76 | static uint8_t vector_hash_peer( ot_peer *peer, int bucket_count ) { |
87 | unsigned int hash = 5381, i = 6; | 77 | unsigned int hash = 5381, i = OT_PEER_COMPARE_SIZE; |
88 | uint8_t *p = (uint8_t*)peer; | 78 | uint8_t *p = (uint8_t*)peer; |
89 | while( i-- ) hash += (hash<<5) + *(p++); | 79 | while( i-- ) hash += (hash<<5) + *(p++); |
90 | return hash % bucket_count; | 80 | return hash % bucket_count; |
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index c3acefc..4a8ff63 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c | |||
@@ -140,21 +140,4 @@ ssize_t scan_fixed_int( char *data, size_t len, int *tmp ) { | |||
140 | return len; | 140 | return len; |
141 | } | 141 | } |
142 | 142 | ||
143 | ssize_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ) { | ||
144 | int u, i; | ||
145 | |||
146 | for( i=0; i<4; ++i ) { | ||
147 | ssize_t j = scan_fixed_int( data, len, &u ); | ||
148 | if( j == (ssize_t)len ) return len; | ||
149 | ip[i] = u; | ||
150 | data += len - j; | ||
151 | len = j; | ||
152 | if ( i<3 ) { | ||
153 | if( !len || *data != '.') return -1; | ||
154 | --len; ++data; | ||
155 | } | ||
156 | } | ||
157 | return len; | ||
158 | } | ||
159 | |||
160 | const char *g_version_scan_urlencoded_query_c = "$Source$: $Revision$\n"; | 143 | const char *g_version_scan_urlencoded_query_c = "$Source$: $Revision$\n"; |
diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index a0b77af..92e3f34 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h | |||
@@ -46,17 +46,10 @@ int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCH | |||
46 | void scan_urlencoded_skipvalue( char **string ); | 46 | void scan_urlencoded_skipvalue( char **string ); |
47 | 47 | ||
48 | /* data pointer to len chars of string | 48 | /* data pointer to len chars of string |
49 | len length of chars in data to parse | 49 | len length of chars in data to parse |
50 | number number to receive result | 50 | number number to receive result |
51 | returns number of bytes not parsed, mostly !=0 means fail | 51 | returns number of bytes not parsed, mostly !=0 means fail |
52 | */ | 52 | */ |
53 | ssize_t scan_fixed_int( char *data, size_t len, int *number ); | 53 | ssize_t scan_fixed_int( char *data, size_t len, int *number ); |
54 | 54 | ||
55 | /* data pointer to len chars of string | ||
56 | len length of chars in data to parse | ||
57 | ip buffer to receive result | ||
58 | returns number of bytes not parsed, mostly !=0 means fail | ||
59 | */ | ||
60 | ssize_t scan_fixed_ip( char *data, size_t len, unsigned char ip[4] ); | ||
61 | |||
62 | #endif | 55 | #endif |
diff --git a/trackerlogic.c b/trackerlogic.c index 38be9f7..5eff5c0 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
@@ -41,12 +41,7 @@ void free_peerlist( ot_peerlist *peer_list ) { | |||
41 | free( peer_list ); | 41 | free( peer_list ); |
42 | } | 42 | } |
43 | 43 | ||
44 | #ifdef _DEBUG_PEERID | 44 | size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) { |
45 | extern size_t g_this_peerid_len; | ||
46 | extern char *g_this_peerid_data; | ||
47 | #endif | ||
48 | |||
49 | size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) { | ||
50 | int exactmatch, delta_torrentcount = 0; | 45 | int exactmatch, delta_torrentcount = 0; |
51 | size_t reply_size; | 46 | size_t reply_size; |
52 | ot_torrent *torrent; | 47 | ot_torrent *torrent; |
@@ -66,7 +61,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO | |||
66 | 61 | ||
67 | if( !exactmatch ) { | 62 | if( !exactmatch ) { |
68 | /* Create a new torrent entry, then */ | 63 | /* Create a new torrent entry, then */ |
69 | int i; for(i=0;i<20;i+=4) WRITE32(&torrent->hash,i,READ32(hash,i)); | 64 | memcpy( torrent->hash, hash, sizeof(ot_hash) ); |
70 | 65 | ||
71 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { | 66 | if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { |
72 | vector_remove_torrent( torrents_list, torrent ); | 67 | vector_remove_torrent( torrents_list, torrent ); |
@@ -114,16 +109,6 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO | |||
114 | } else { | 109 | } else { |
115 | stats_issue_event( EVENT_RENEW, 0, OT_PEERTIME( peer_dest ) ); | 110 | stats_issue_event( EVENT_RENEW, 0, OT_PEERTIME( peer_dest ) ); |
116 | 111 | ||
117 | #ifdef _DEBUG_PEERID | ||
118 | if( OT_PEERTIME( peer_dest ) < 2 ) { | ||
119 | uint8_t *_ip = (uint8_t*)peer_dest; | ||
120 | int i; | ||
121 | for( i=0;i<20;++i)printf("%02X",(*hash)[i]); | ||
122 | if( g_this_peerid_data ) g_this_peerid_data[g_this_peerid_len] = 0; | ||
123 | printf( " %d.%d.%d.%d:%d\t%d %02X %s\n", _ip[0], _ip[1], _ip[2], _ip[3], OT_PEERTIME( peer_dest ), *(uint16_t*)( ((char*)peer_dest)+4 ), OT_PEERFLAG(peer_dest), g_this_peerid_data ? g_this_peerid_data : "-" ); | ||
124 | } | ||
125 | #endif | ||
126 | |||
127 | #ifdef WANT_SYNC_LIVE | 112 | #ifdef WANT_SYNC_LIVE |
128 | /* Won't live sync peers that come back too fast. Only exception: | 113 | /* Won't live sync peers that come back too fast. Only exception: |
129 | fresh "completed" reports */ | 114 | fresh "completed" reports */ |
@@ -144,7 +129,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO | |||
144 | OT_PEERFLAG( peer ) |= PEER_FLAG_COMPLETED; | 129 | OT_PEERFLAG( peer ) |= PEER_FLAG_COMPLETED; |
145 | } | 130 | } |
146 | 131 | ||
147 | *(uint64_t*)(peer_dest) = *(uint64_t*)(peer); | 132 | *peer_dest = *peer; |
148 | #ifdef WANT_SYNC | 133 | #ifdef WANT_SYNC |
149 | if( proto == FLAG_MCA ) { | 134 | if( proto == FLAG_MCA ) { |
150 | mutex_bucket_unlock_by_hash( hash, delta_torrentcount ); | 135 | mutex_bucket_unlock_by_hash( hash, delta_torrentcount ); |
@@ -153,7 +138,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO | |||
153 | #endif | 138 | #endif |
154 | 139 | ||
155 | reply_size = return_peers_for_torrent( torrent, amount, reply, proto ); | 140 | reply_size = return_peers_for_torrent( torrent, amount, reply, proto ); |
156 | mutex_bucket_unlock_by_hash( &torrent->hash, delta_torrentcount ); | 141 | mutex_bucket_unlock_by_hash( torrent->hash, delta_torrentcount ); |
157 | return reply_size; | 142 | return reply_size; |
158 | } | 143 | } |
159 | 144 | ||
@@ -171,9 +156,9 @@ static size_t return_peers_all( ot_peerlist *peer_list, char *reply ) { | |||
171 | ot_peer * peers = (ot_peer*)bucket_list[bucket].data; | 156 | ot_peer * peers = (ot_peer*)bucket_list[bucket].data; |
172 | size_t peer_count = bucket_list[bucket].size; | 157 | size_t peer_count = bucket_list[bucket].size; |
173 | while( peer_count-- ) { | 158 | while( peer_count-- ) { |
174 | WRITE32(r,0,READ32(peers,0)); | 159 | memcpy(r,peers,OT_PEER_COMPARE_SIZE); |
175 | WRITE16(r,4,READ16(peers++,4)); | 160 | peers+=sizeof(ot_peer); |
176 | r+=6; | 161 | r+=OT_PEER_COMPARE_SIZE; |
177 | } | 162 | } |
178 | } | 163 | } |
179 | 164 | ||
@@ -216,9 +201,8 @@ static size_t return_peers_selection( ot_peerlist *peer_list, size_t amount, cha | |||
216 | bucket_index = ( bucket_index + 1 ) % num_buckets; | 201 | bucket_index = ( bucket_index + 1 ) % num_buckets; |
217 | } | 202 | } |
218 | peer = ((ot_peer*)bucket_list[bucket_index].data) + bucket_offset; | 203 | peer = ((ot_peer*)bucket_list[bucket_index].data) + bucket_offset; |
219 | WRITE32(r,0,READ32(peer,0)); | 204 | memcpy(r,peer,OT_PEER_COMPARE_SIZE); |
220 | WRITE16(r,4,READ16(peer,4)); | 205 | r+=OT_PEER_COMPARE_SIZE; |
221 | r+=6; | ||
222 | } | 206 | } |
223 | return r - reply; | 207 | return r - reply; |
224 | } | 208 | } |
@@ -236,7 +220,7 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply | |||
236 | 220 | ||
237 | if( proto == FLAG_TCP ) { | 221 | if( proto == FLAG_TCP ) { |
238 | int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM; | 222 | int erval = OT_CLIENT_REQUEST_INTERVAL_RANDOM; |
239 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, erval, erval/2, 6*amount ); | 223 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie12:min intervali%ie5:peers" PEERS6 "%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, erval, erval/2, OT_PEER_COMPARE_SIZE*amount ); |
240 | } else { | 224 | } else { |
241 | *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); | 225 | *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); |
242 | *(uint32_t*)(r+4) = htonl( peer_list->peer_count ); | 226 | *(uint32_t*)(r+4) = htonl( peer_list->peer_count ); |
@@ -258,7 +242,7 @@ size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply | |||
258 | } | 242 | } |
259 | 243 | ||
260 | /* Fetches scrape info for a specific torrent */ | 244 | /* Fetches scrape info for a specific torrent */ |
261 | size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ) { | 245 | size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply ) { |
262 | int exactmatch, delta_torrentcount = 0; | 246 | int exactmatch, delta_torrentcount = 0; |
263 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 247 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); |
264 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 248 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
@@ -292,7 +276,7 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl | |||
292 | 276 | ||
293 | for( i=0; i<amount; ++i ) { | 277 | for( i=0; i<amount; ++i ) { |
294 | ot_hash *hash = hash_list + i; | 278 | ot_hash *hash = hash_list + i; |
295 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 279 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( *hash ); |
296 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); | 280 | ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); |
297 | 281 | ||
298 | if( exactmatch ) { | 282 | if( exactmatch ) { |
@@ -300,14 +284,13 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl | |||
300 | vector_remove_torrent( torrents_list, torrent ); | 284 | vector_remove_torrent( torrents_list, torrent ); |
301 | delta_torrentcount = -1; | 285 | delta_torrentcount = -1; |
302 | } else { | 286 | } else { |
303 | int j; | ||
304 | *r++='2';*r++='0';*r++=':'; | 287 | *r++='2';*r++='0';*r++=':'; |
305 | for(j=0;j<20;j+=4) WRITE32(r,j,READ32(hash,j)); r += 20; | 288 | memcpy( r, hash, sizeof(ot_hash) ); r+=sizeof(ot_hash); |
306 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", | 289 | r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", |
307 | torrent->peer_list->seed_count, torrent->peer_list->down_count, torrent->peer_list->peer_count-torrent->peer_list->seed_count ); | 290 | torrent->peer_list->seed_count, torrent->peer_list->down_count, torrent->peer_list->peer_count-torrent->peer_list->seed_count ); |
308 | } | 291 | } |
309 | } | 292 | } |
310 | mutex_bucket_unlock_by_hash( hash, delta_torrentcount ); | 293 | mutex_bucket_unlock_by_hash( *hash, delta_torrentcount ); |
311 | } | 294 | } |
312 | 295 | ||
313 | *r++ = 'e'; *r++ = 'e'; | 296 | *r++ = 'e'; *r++ = 'e'; |
@@ -315,7 +298,7 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl | |||
315 | } | 298 | } |
316 | 299 | ||
317 | static ot_peerlist dummy_list; | 300 | static ot_peerlist dummy_list; |
318 | size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) { | 301 | size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) { |
319 | int exactmatch; | 302 | int exactmatch; |
320 | size_t reply_size = 0; | 303 | size_t reply_size = 0; |
321 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); | 304 | ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); |
diff --git a/trackerlogic.h b/trackerlogic.h index eb2906b..da8f822 100644 --- a/trackerlogic.h +++ b/trackerlogic.h | |||
@@ -11,17 +11,16 @@ | |||
11 | #include <time.h> | 11 | #include <time.h> |
12 | #include <stdint.h> | 12 | #include <stdint.h> |
13 | 13 | ||
14 | /* Libowfat */ | ||
15 | #include <uint16.h> | ||
16 | #include <uint32.h> | ||
17 | |||
18 | #define READ16(addr,offs) ((int16_t)uint16_read((offs)+(uint8_t*)(addr))) | ||
19 | #define READ32(addr,offs) ((int32_t)uint32_read((offs)+(uint8_t*)(addr))) | ||
20 | #define WRITE16(addr,offs,val) uint16_pack((offs)+(uint8_t*)(addr),(val)) | ||
21 | #define WRITE32(addr,offs,val) uint32_pack((offs)+(uint8_t*)(addr),(val)) | ||
22 | |||
23 | typedef uint8_t ot_hash[20]; | 14 | typedef uint8_t ot_hash[20]; |
24 | typedef time_t ot_time; | 15 | typedef time_t ot_time; |
16 | typedef char ot_ip6[16]; | ||
17 | #ifdef WANT_V6 | ||
18 | #define OT_IP_SIZE 16 | ||
19 | #define PEERS6 "6" | ||
20 | #else | ||
21 | #define OT_IP_SIZE 4 | ||
22 | #define PEERS6 "" | ||
23 | #endif | ||
25 | 24 | ||
26 | /* Some tracker behaviour tunable */ | 25 | /* Some tracker behaviour tunable */ |
27 | #define OT_CLIENT_TIMEOUT 30 | 26 | #define OT_CLIENT_TIMEOUT 30 |
@@ -60,7 +59,7 @@ extern uint32_t g_tracker_id; | |||
60 | typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG; | 59 | typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG; |
61 | 60 | ||
62 | typedef struct { | 61 | typedef struct { |
63 | uint8_t data[8]; | 62 | uint8_t data[OT_IP_SIZE+2+2]; |
64 | } ot_peer; | 63 | } ot_peer; |
65 | static const uint8_t PEER_FLAG_SEEDING = 0x80; | 64 | static const uint8_t PEER_FLAG_SEEDING = 0x80; |
66 | static const uint8_t PEER_FLAG_COMPLETED = 0x40; | 65 | static const uint8_t PEER_FLAG_COMPLETED = 0x40; |
@@ -68,12 +67,17 @@ static const uint8_t PEER_FLAG_STOPPED = 0x20; | |||
68 | static const uint8_t PEER_FLAG_FROM_SYNC = 0x10; | 67 | static const uint8_t PEER_FLAG_FROM_SYNC = 0x10; |
69 | static const uint8_t PEER_FLAG_LEECHING = 0x00; | 68 | static const uint8_t PEER_FLAG_LEECHING = 0x00; |
70 | 69 | ||
71 | #define OT_SETIP(peer,ip) WRITE32((peer),0,READ32((ip),0)) | 70 | #ifdef WANT_V6 |
72 | #define OT_SETPORT(peer,port) WRITE16((peer),4,READ16((port),0)) | 71 | #define OT_SETIP(peer,ip) memcpy((peer),(ip),(OT_IP_SIZE)) |
73 | #define OT_PEERFLAG(peer) (((uint8_t*)(peer))[6]) | 72 | #else |
74 | #define OT_PEERTIME(peer) (((uint8_t*)(peer))[7]) | 73 | #define OT_SETIP(peer,ip) memcpy((peer),(((uint8_t*)ip)+12),(OT_IP_SIZE)) |
74 | #endif | ||
75 | #define OT_SETPORT(peer,port) memcpy(((uint8_t*)(peer))+(OT_IP_SIZE),(port),2) | ||
76 | #define OT_PEERFLAG(peer) (((uint8_t*)(peer))[(OT_IP_SIZE)+2]) | ||
77 | #define OT_PEERTIME(peer) (((uint8_t*)(peer))[(OT_IP_SIZE)+3]) | ||
75 | 78 | ||
76 | #define OT_HASH_COMPARE_SIZE (sizeof(ot_hash)) | 79 | #define OT_HASH_COMPARE_SIZE (sizeof(ot_hash)) |
80 | #define OT_PEER_COMPARE_SIZE ((OT_IP_SIZE)+2) | ||
77 | 81 | ||
78 | struct ot_peerlist; | 82 | struct ot_peerlist; |
79 | typedef struct ot_peerlist ot_peerlist; | 83 | typedef struct ot_peerlist ot_peerlist; |
@@ -98,16 +102,13 @@ struct ot_peerlist { | |||
98 | 102 | ||
99 | struct ot_workstruct { | 103 | struct ot_workstruct { |
100 | /* Thread specific, static */ | 104 | /* Thread specific, static */ |
101 | #define THREAD_INBUF_SIZE 8192 | ||
102 | char *inbuf; | 105 | char *inbuf; |
103 | size_t inbuf_size; | 106 | #define G_INBUF_SIZE 8192 |
104 | #define THREAD_OUTBUF_SIZE 8192 | ||
105 | char *outbuf; | 107 | char *outbuf; |
106 | size_t outbuf_size; | 108 | #define G_OUTBUF_SIZE 8192 |
107 | #ifdef _DEBUG_HTTPERROR | 109 | #ifdef _DEBUG_HTTPERROR |
108 | #define THREAD_DEBUGBUF_SIZE 8192 | ||
109 | char *debugbuf; | 110 | char *debugbuf; |
110 | size_t debugbuf_size; | 111 | #define G_DEBUGBUF_SIZE 8192 |
111 | #endif | 112 | #endif |
112 | 113 | ||
113 | /* HTTP specific, non static */ | 114 | /* HTTP specific, non static */ |
@@ -115,10 +116,6 @@ struct ot_workstruct { | |||
115 | ssize_t request_size; | 116 | ssize_t request_size; |
116 | char *reply; | 117 | char *reply; |
117 | ssize_t reply_size; | 118 | ssize_t reply_size; |
118 | #ifdef _DEBUG_PEERID | ||
119 | char *peer_id; | ||
120 | ssize_t peer_id_size; | ||
121 | #endif | ||
122 | }; | 119 | }; |
123 | 120 | ||
124 | /* | 121 | /* |
@@ -135,6 +132,10 @@ struct ot_workstruct { | |||
135 | #define WANT_SYNC_PARAM( param ) | 132 | #define WANT_SYNC_PARAM( param ) |
136 | #endif | 133 | #endif |
137 | 134 | ||
135 | #if defined WANT_V6 && defined WANT_LOG_NETWORKS | ||
136 | #undef WANT_LOG_NETWORKS | ||
137 | #endif | ||
138 | |||
138 | void trackerlogic_init( ); | 139 | void trackerlogic_init( ); |
139 | void trackerlogic_deinit( void ); | 140 | void trackerlogic_deinit( void ); |
140 | void exerr( char * message ); | 141 | void exerr( char * message ); |
@@ -142,10 +143,10 @@ void exerr( char * message ); | |||
142 | /* add_peer_to_torrent does only release the torrent bucket if from_sync is set, | 143 | /* add_peer_to_torrent does only release the torrent bucket if from_sync is set, |
143 | otherwise it is released in return_peers_for_torrent */ | 144 | otherwise it is released in return_peers_for_torrent */ |
144 | #define add_peer_to_torrent(hash,peer,proto) add_peer_to_torrent_and_return_peers(hash,peer,proto,0,NULL) | 145 | #define add_peer_to_torrent(hash,peer,proto) add_peer_to_torrent_and_return_peers(hash,peer,proto,0,NULL) |
145 | size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ); | 146 | size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ); |
146 | size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ); | 147 | size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto ); |
147 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); | 148 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); |
148 | size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); | 149 | size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply ); |
149 | 150 | ||
150 | /* Helper, before it moves to its own object */ | 151 | /* Helper, before it moves to its own object */ |
151 | void free_peerlist( ot_peerlist *peer_list ); | 152 | void free_peerlist( ot_peerlist *peer_list ); |