summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2009-01-13 22:41:17 +0000
committererdgeist <>2009-01-13 22:41:17 +0000
commit131211b4daf83b7c594337f4e7c71e4711094d71 (patch)
tree63dc942c426103c01d61aa15959a81df91f2d4e1
parent779d6c235ff8fe5284fd10dc82a9b99e7fa38d06 (diff)
V6
-rw-r--r--Makefile5
-rw-r--r--opentracker.c86
-rw-r--r--ot_accesslist.c43
-rw-r--r--ot_accesslist.h6
-rw-r--r--ot_fullscrape.c8
-rw-r--r--ot_http.c52
-rw-r--r--ot_http.h2
-rw-r--r--ot_livesync.c60
-rw-r--r--ot_livesync.h2
-rw-r--r--ot_mutex.c8
-rw-r--r--ot_mutex.h4
-rw-r--r--ot_stats.c34
-rw-r--r--ot_stats.h2
-rw-r--r--ot_udp.c28
-rw-r--r--ot_udp.h2
-rw-r--r--ot_vector.c24
-rw-r--r--scan_urlencoded_query.c17
-rw-r--r--scan_urlencoded_query.h15
-rw-r--r--trackerlogic.c47
-rw-r--r--trackerlogic.h55
20 files changed, 235 insertions, 265 deletions
diff --git a/Makefile b/Makefile
index ca4e71b..41b0d68 100644
--- a/Makefile
+++ b/Makefile
@@ -19,6 +19,8 @@ LIBOWFAT_LIBRARY=$(PREFIX)/libowfat
19 19
20BINDIR?=$(PREFIX)/bin 20BINDIR?=$(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
31FEATURES+=-DWANT_FULLSCRAPE 33FEATURES+=-DWANT_FULLSCRAPE
32 34
33#FEATURES+=-D_DEBUG_HTTPERROR 35#FEATURES+=-D_DEBUG_HTTPERROR
34#FEATURES+=-D_DEBUG_PEERID
35 36
36OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage 37OPTS_debug=-D_DEBUG -g -ggdb # -pg -fprofile-arcs -ftest-coverage
37OPTS_production=-Os 38OPTS_production=-Os
38 39
39CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra #-ansi -pedantic 40CFLAGS+=-I$(LIBOWFAT_HEADERS) -Wall -pipe -Wextra #-ansi -pedantic
40LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lz 41LDFLAGS+=-L$(LIBOWFAT_LIBRARY) -lowfat -pthread -lpthread -lz
41 42
42BINARY =opentracker 43BINARY =opentracker
43HEADERS=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 44HEADERS=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
153static void handle_accept( const int64 serversocket ) { 153static 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
244static int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) { 238static 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
282static int scan_ip4_port( const char *src, char *ip, uint16 *port ) { 279static 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
297int parse_configfile( char * config_filename ) { 300int 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
413int main( int argc, char **argv ) { 417int 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
418while( scanon ) { 424while( 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
35static int accesslist_addentry( ot_hash *infohash ) { 37static 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
83int accesslist_hashisvalid( ot_hash *hash ) { 85int 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
105static uint32_t g_adminip_addresses[OT_ADMINIP_MAX]; 107static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX];
106static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; 108static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX];
107static unsigned int g_adminip_count = 0; 109static unsigned int g_adminip_count = 0;
108 110
109int accesslist_blessip( char *ip, ot_permissions permissions ) { 111int 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
125int accesslist_isblessed( char *ip, ot_permissions permissions ) { 136int 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
15void accesslist_init( ); 15void accesslist_init( );
16void accesslist_deinit( ); 16void accesslist_deinit( );
17int accesslist_hashisvalid( ot_hash *hash ); 17int accesslist_hashisvalid( ot_hash hash );
18 18
19extern char *g_accesslist_filename; 19extern 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
33int accesslist_blessip( char * ip, ot_permissions permissions ); 33int accesslist_blessip( ot_ip6 ip, ot_permissions permissions );
34int accesslist_isblessed( char * ip, ot_permissions permissions ); 34int 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
117static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { 117static 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;
diff --git a/ot_http.c b/ot_http.c
index 8c85689..08ecc13 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -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
38size_t g_this_peerid_len = 0;
39char *g_this_peerid_data = NULL;
40#endif
41
42static void http_senddata( const int64 client_socket, struct ot_workstruct *ws ) { 38static 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
254write( 2, ws->debugbuf, ws->debugbuf_size ); 250write( 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
266static ssize_t http_handle_scrape( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { 263static 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 } };
313static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } }; 307static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } };
314static ssize_t http_handle_announce( const int64 client_socket, struct ot_workstruct *ws, char *read_ptr ) { 308static 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
diff --git a/ot_http.h b/ot_http.h
index 18e8156..ced8160 100644
--- a/ot_http.h
+++ b/ot_http.h
@@ -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
119void livesync_bind_mcast( char *ip, uint16_t port) { 120void 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 ) {
210void livesync_issue_inquire( ) { 216void 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 */
321void livesync_ticker( ) { 327void 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. */
353void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer ) { 359void 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
366static void * livesync_worker( void * args ) { 370static 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();
86void livesync_bind_mcast( char *ip, uint16_t port ); 86void 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. */
89void livesync_tell( ot_hash * const info_hash, const ot_peer * const peer ); 89void 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
diff --git a/ot_mutex.c b/ot_mutex.c
index 6edfaef..36de5ff 100644
--- a/ot_mutex.c
+++ b/ot_mutex.c
@@ -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
83ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash ) { 83ot_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
99void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount ) { 99void 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
103size_t mutex_get_torrent_count( ) { 103size_t mutex_get_torrent_count( ) {
diff --git a/ot_mutex.h b/ot_mutex.h
index ba5684d..16b25a0 100644
--- a/ot_mutex.h
+++ b/ot_mutex.h
@@ -12,10 +12,10 @@ void mutex_init( );
12void mutex_deinit( ); 12void mutex_deinit( );
13 13
14ot_vector *mutex_bucket_lock( int bucket ); 14ot_vector *mutex_bucket_lock( int bucket );
15ot_vector *mutex_bucket_lock_by_hash( ot_hash *hash ); 15ot_vector *mutex_bucket_lock_by_hash( ot_hash hash );
16 16
17void mutex_bucket_unlock( int bucket, int delta_torrentcount ); 17void mutex_bucket_unlock( int bucket, int delta_torrentcount );
18void mutex_bucket_unlock_by_hash( ot_hash *hash, int delta_torrentcount ); 18void mutex_bucket_unlock_by_hash( ot_hash hash, int delta_torrentcount );
19 19
20size_t mutex_get_torrent_count(); 20size_t mutex_get_torrent_count();
21 21
diff --git a/ot_stats.c b/ot_stats.c
index 31d53e8..30a599c 100644
--- a/ot_stats.c
+++ b/ot_stats.c
@@ -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
540void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ) { 542void 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:
diff --git a/ot_stats.h b/ot_stats.h
index 287382f..7cb0c06 100644
--- a/ot_stats.h
+++ b/ot_stats.h
@@ -32,7 +32,7 @@ enum {
32 CODE_HTTPERROR_COUNT 32 CODE_HTTPERROR_COUNT
33}; 33};
34 34
35void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ); 35void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data );
36void stats_deliver( int64 socket, int tasktype ); 36void stats_deliver( int64 socket, int tasktype );
37size_t return_stats_for_tracker( char *reply, int mode, int format ); 37size_t return_stats_for_tracker( char *reply, int mode, int format );
38size_t stats_return_tracker_version( char *reply ); 38size_t stats_return_tracker_version( char *reply );
diff --git a/ot_udp.c b/ot_udp.c
index 81c4d63..2ea76dd 100644
--- a/ot_udp.c
+++ b/ot_udp.c
@@ -19,15 +19,15 @@
19 19
20static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; 20static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff };
21 21
22static void udp_make_connectionid( uint32_t * connid, const char * remoteip ) { 22static 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
30static int udp_test_connectionid( const uint32_t * const connid, const char * remoteip ) { 30static 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 */
39void handle_udp4( int64 serversocket, struct ot_workstruct *ws ) { 39void 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 }
diff --git a/ot_udp.h b/ot_udp.h
index c146392..39356cb 100644
--- a/ot_udp.h
+++ b/ot_udp.h
@@ -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
9void handle_udp4( int64 serversocket, struct ot_workstruct *ws ); 9void 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
19static int vector_compare_peer(const void *peer1, const void *peer2 ) { 19static 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*/
31void *binary_search( const void * const key, const void * base, const size_t member_count, const size_t member_size, 29void *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
60ot_peer *binary_search_peer( const ot_peer * const peer, const ot_peer * base, const size_t member_count, int *exactmatch ) { 53ot_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
86static uint8_t vector_hash_peer( ot_peer *peer, int bucket_count ) { 76static 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
143ssize_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
160const char *g_version_scan_urlencoded_query_c = "$Source$: $Revision$\n"; 143const 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
46void scan_urlencoded_skipvalue( char **string ); 46void 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 */
53ssize_t scan_fixed_int( char *data, size_t len, int *number ); 53ssize_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*/
60ssize_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 44size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) {
45extern size_t g_this_peerid_len;
46extern char *g_this_peerid_data;
47#endif
48
49size_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 */
261size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ) { 245size_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
317static ot_peerlist dummy_list; 300static ot_peerlist dummy_list;
318size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) { 301size_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
23typedef uint8_t ot_hash[20]; 14typedef uint8_t ot_hash[20];
24typedef time_t ot_time; 15typedef time_t ot_time;
16typedef 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;
60typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG; 59typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG;
61 60
62typedef struct { 61typedef struct {
63 uint8_t data[8]; 62 uint8_t data[OT_IP_SIZE+2+2];
64} ot_peer; 63} ot_peer;
65static const uint8_t PEER_FLAG_SEEDING = 0x80; 64static const uint8_t PEER_FLAG_SEEDING = 0x80;
66static const uint8_t PEER_FLAG_COMPLETED = 0x40; 65static const uint8_t PEER_FLAG_COMPLETED = 0x40;
@@ -68,12 +67,17 @@ static const uint8_t PEER_FLAG_STOPPED = 0x20;
68static const uint8_t PEER_FLAG_FROM_SYNC = 0x10; 67static const uint8_t PEER_FLAG_FROM_SYNC = 0x10;
69static const uint8_t PEER_FLAG_LEECHING = 0x00; 68static 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
78struct ot_peerlist; 82struct ot_peerlist;
79typedef struct ot_peerlist ot_peerlist; 83typedef struct ot_peerlist ot_peerlist;
@@ -98,16 +102,13 @@ struct ot_peerlist {
98 102
99struct ot_workstruct { 103struct 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
138void trackerlogic_init( ); 139void trackerlogic_init( );
139void trackerlogic_deinit( void ); 140void trackerlogic_deinit( void );
140void exerr( char * message ); 141void 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)
145size_t add_peer_to_torrent_and_return_peers( ot_hash *hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ); 146size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply );
146size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ); 147size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto );
147size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); 148size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
148size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); 149size_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 */
151void free_peerlist( ot_peerlist *peer_list ); 152void free_peerlist( ot_peerlist *peer_list );