summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c179
-rw-r--r--opentracker.xcodeproj/project.pbxproj6
-rw-r--r--ot_accesslist.c18
-rw-r--r--ot_accesslist.h16
-rw-r--r--ot_clean.c4
-rw-r--r--ot_fullscrape.c3
-rw-r--r--ot_fullscrape.h9
-rw-r--r--ot_http.c35
-rw-r--r--ot_stats.c20
-rw-r--r--ot_stats.h2
-rw-r--r--ot_sync.c4
-rw-r--r--ot_sync.h7
-rw-r--r--ot_udp.c14
-rw-r--r--scan_urlencoded_query.c4
-rw-r--r--tests/testsuite2.sh14
-rw-r--r--trackerlogic.c70
-rw-r--r--trackerlogic.h25
17 files changed, 304 insertions, 126 deletions
diff --git a/opentracker.c b/opentracker.c
index fda914a..b7431d4 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -8,12 +8,14 @@
8#include <string.h> 8#include <string.h>
9#include <sys/types.h> 9#include <sys/types.h>
10#include <sys/socket.h> 10#include <sys/socket.h>
11#include <arpa/inet.h>
11#include <unistd.h> 12#include <unistd.h>
12#include <stdlib.h> 13#include <stdlib.h>
13#include <errno.h> 14#include <errno.h>
14#include <signal.h> 15#include <signal.h>
15#include <stdio.h> 16#include <stdio.h>
16#include <pwd.h> 17#include <pwd.h>
18#include <ctype.h>
17#include <arpa/inet.h> 19#include <arpa/inet.h>
18 20
19/* Libowfat */ 21/* Libowfat */
@@ -21,6 +23,7 @@
21#include "io.h" 23#include "io.h"
22#include "iob.h" 24#include "iob.h"
23#include "array.h" 25#include "array.h"
26#include "byte.h"
24#include "fmt.h" 27#include "fmt.h"
25#include "scan.h" 28#include "scan.h"
26#include "ip4.h" 29#include "ip4.h"
@@ -34,17 +37,18 @@
34#include "ot_clean.h" 37#include "ot_clean.h"
35#include "ot_accesslist.h" 38#include "ot_accesslist.h"
36#include "ot_stats.h" 39#include "ot_stats.h"
40#include "ot_livesync.h"
37 41
38/* Globals */ 42/* Globals */
39time_t g_now; 43time_t g_now;
40char * g_redirecturl = NULL; 44char * g_redirecturl = NULL;
45uint32_t g_tracker_id;
46
47static char * g_serverdir = NULL;
41 48
42/* To always have space for error messages ;) */ 49/* To always have space for error messages ;) */
43static char static_inbuf[8192]; 50static char static_inbuf[8192];
44 51
45static char *FLAG_TCP = "T";
46static char *FLAG_UDP = "U";
47
48static void panic( const char *routine ) { 52static void panic( const char *routine ) {
49 fprintf( stderr, "%s: %s\n", routine, strerror(errno) ); 53 fprintf( stderr, "%s: %s\n", routine, strerror(errno) );
50 exit( 111 ); 54 exit( 111 );
@@ -63,10 +67,10 @@ static void signal_handler( int s ) {
63} 67}
64 68
65static void usage( char *name ) { 69static void usage( char *name ) {
66 fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-A ip]" 70 fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-A ip] [-f config] [-s livesyncport]"
67#ifdef WANT_BLACKLISTING 71#ifdef WANT_ACCESSLIST_BLACK
68 " [-b blacklistfile]" 72 " [-b blacklistfile]"
69#elif defined ( WANT_CLOSED_TRACKER ) 73#elif defined ( WANT_ACCESSLIST_WHITE )
70 " [-w whitelistfile]" 74 " [-w whitelistfile]"
71#endif 75#endif
72 "\n", name ); 76 "\n", name );
@@ -82,9 +86,9 @@ static void help( char *name ) {
82 HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); 86 HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)");
83 HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); 87 HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")");
84 HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); 88 HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)");
85#ifdef WANT_BLACKLISTING 89#ifdef WANT_ACCESSLIST_BLACK
86 HELPLINE("-b file","specify blacklist file."); 90 HELPLINE("-b file","specify blacklist file.");
87#elif defined( WANT_CLOSED_TRACKER ) 91#elif defined( WANT_ACCESSLIST_WHITE )
88 HELPLINE("-w file","specify whitelist file."); 92 HELPLINE("-w file","specify whitelist file.");
89#endif 93#endif
90 94
@@ -168,7 +172,7 @@ static void handle_accept( const int64 serversocket ) {
168 memset( h, 0, sizeof( struct http_data ) ); 172 memset( h, 0, sizeof( struct http_data ) );
169 memmove( h->ip, ip, sizeof( ip ) ); 173 memmove( h->ip, ip, sizeof( ip ) );
170 174
171 stats_issue_event( EVENT_ACCEPT, 1, ntohl(*(uint32_t*)ip)); 175 stats_issue_event( EVENT_ACCEPT, FLAG_TCP, ntohl(*(uint32_t*)ip));
172 176
173 /* That breaks taia encapsulation. But there is no way to take system 177 /* That breaks taia encapsulation. But there is no way to take system
174 time this often in FreeBSD and libowfat does not allow to set unix time */ 178 time this often in FreeBSD and libowfat does not allow to set unix time */
@@ -194,10 +198,12 @@ static void server_mainloop( ) {
194 198
195 while( ( i = io_canread( ) ) != -1 ) { 199 while( ( i = io_canread( ) ) != -1 ) {
196 const void *cookie = io_getcookie( i ); 200 const void *cookie = io_getcookie( i );
197 if( cookie == FLAG_TCP ) 201 if( (int)cookie == FLAG_TCP )
198 handle_accept( i ); 202 handle_accept( i );
199 else if( cookie == FLAG_UDP ) 203 else if( (int)cookie == FLAG_UDP )
200 handle_udp4( i ); 204 handle_udp4( i );
205 else if( (int)cookie == FLAG_MCA )
206 handle_livesync(i);
201 else 207 else
202 handle_read( i ); 208 handle_read( i );
203 } 209 }
@@ -214,6 +220,8 @@ static void server_mainloop( ) {
214 next_timeout_check = g_now + OT_CLIENT_TIMEOUT_CHECKINTERVAL; 220 next_timeout_check = g_now + OT_CLIENT_TIMEOUT_CHECKINTERVAL;
215 } 221 }
216 222
223 livesync_ticker();
224
217 /* See if we need to move our pools */ 225 /* See if we need to move our pools */
218 if( NOW != ot_last_clean_time ) { 226 if( NOW != ot_last_clean_time ) {
219 ot_last_clean_time = NOW; 227 ot_last_clean_time = NOW;
@@ -225,55 +233,148 @@ static void server_mainloop( ) {
225 } 233 }
226} 234}
227 235
228static void ot_try_bind( char ip[4], uint16 port, int is_tcp ) { 236int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto ) {
229 int64 s = is_tcp ? socket_tcp4( ) : socket_udp4(); 237 int64 s = proto == FLAG_TCP ? socket_tcp4( ) : socket_udp4();
230 238
231 if( socket_bind4_reuse( s, ip, port ) == -1 ) 239 if( socket_bind4_reuse( s, ip, port ) == -1 )
232 panic( "socket_bind4_reuse" ); 240 panic( "socket_bind4_reuse" );
233 241
234 if( is_tcp && ( socket_listen( s, SOMAXCONN) == -1 ) ) 242 if( ( proto == FLAG_TCP ) && ( socket_listen( s, SOMAXCONN) == -1 ) )
235 panic( "socket_listen" ); 243 panic( "socket_listen" );
236 244
237 if( !io_fd( s ) ) 245 if( !io_fd( s ) )
238 panic( "io_fd" ); 246 panic( "io_fd" );
239 247
240 io_setcookie( s, is_tcp ? FLAG_TCP : FLAG_UDP ); 248 io_setcookie( s, (void*)proto );
241 249
242 io_wantread( s ); 250 io_wantread( s );
251
252 return s;
253}
254
255char * set_config_option( char **option, char *value ) {
256 while( isspace(*value) ) ++value;
257 if( *option ) free( *option );
258 return *option = strdup( value );
259}
260
261/* WARNING! Does not behave like scan_ip4 regarding return values */
262static int scan_ip4_port( const char *src, char *ip, uint16 *port ) {
263 int off;
264 while( isspace(*src) ) ++src;
265 if( !(off = scan_ip4( src, ip ) ) )
266 return -1;
267 src += off;
268 if( *src == 0 ) return 0;
269 if( *src != ':' )
270 return -1;
271 *port = atol(src+1);
272 return 0;
273}
274
275int parse_configfile( char * config_filename ) {
276 FILE * accesslist_filehandle;
277 char inbuf[512], tmpip[4];
278 int bound = 0;
279
280 accesslist_filehandle = fopen( config_filename, "r" );
281
282 if( accesslist_filehandle == NULL ) {
283 fprintf( stderr, "Warning: Can't open config file: %s.", config_filename );
284 return 0;
285 }
286
287 while( fgets( inbuf, sizeof(inbuf), accesslist_filehandle ) ) {
288 char *newl;
289 char *p = inbuf;
290
291 /* Skip white spaces */
292 while(isspace(*p)) ++p;
293
294 /* Ignore comments and empty lines */
295 if((*p=='#')||(*p=='\n')||(*p==0)) continue;
296
297 /* chomp */
298 if(( newl = strchr(p, '\n' ))) *newl = 0;
299
300 /* Scan for commands */
301 if(!byte_diff(p,15,"tracker.rootdir" ) && isspace(p[15])) {
302 set_config_option( &g_serverdir, p+16 );
303 } else if(!byte_diff(p,10,"listen.tcp" ) && isspace(p[10])) {
304 uint16_t tmpport = 6969;
305 if( scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error;
306 ot_try_bind( tmpip, tmpport, FLAG_TCP );
307 ++bound;
308 } else if(!byte_diff(p, 10, "listen.udp" ) && isspace(p[10])) {
309 uint16_t tmpport = 6969;
310 if( scan_ip4_port( p+11, tmpip, &tmpport )) goto parse_error;
311 ot_try_bind( tmpip, tmpport, FLAG_UDP );
312 ++bound;
313#ifdef WANT_ACCESSLIST_BLACK
314 } else if(!byte_diff(p, 16, "access.whitelist" ) && isspace(p[16])) {
315 set_config_option( &g_accesslist_filename, p+17 );
316#elif defined( WANT_ACCESSLIST_WHITE )
317 } else if(!byte_diff(p, 16, "access.blacklist" ) && isspace(p[16])) {
318 set_config_option( &g_accesslist_filename, p+17 );
319#endif
320 } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) {
321 set_config_option( &g_redirecturl, p+21 );
322#ifdef WANT_SYNC_BATCH
323 } else if(!byte_diff(p, 26, "batchsync.cluster.admin_ip" ) && isspace(p[26])) {
324 if(!scan_ip4( p+27, tmpip )) goto parse_error;
325 accesslist_blessip( tmpip, OT_PERMISSION_MAY_SYNC );
326#endif
327#ifdef WANT_SYNC_LIVE
328 } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) {
329 if( !scan_ip4( p+25, tmpip )) goto parse_error;
330 accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC );
331 } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) {
332 uint16_t tmpport = LIVESYNC_PORT;
333 if( scan_ip4_port( p+24, tmpip, &tmpport )) goto parse_error;
334 livesync_bind_mcast( tmpip, tmpport );
335#endif
336 } else
337 fprintf( stderr, "Unhandled line in config file: %s\n", inbuf );
338 continue;
339 parse_error:
340 fprintf( stderr, "Parse error in config file: %s\n", inbuf);
341 }
342 fclose( accesslist_filehandle );
343 return bound;
243} 344}
244 345
245int main( int argc, char **argv ) { 346int main( int argc, char **argv ) {
246 struct passwd *pws = NULL; 347 struct passwd *pws = NULL;
247 char serverip[4] = {0,0,0,0}, tmpip[4]; 348 char serverip[4] = {0,0,0,0}, tmpip[4];
248 char *serverdir = ".";
249 int bound = 0, scanon = 1; 349 int bound = 0, scanon = 1;
250#ifdef WANT_ACCESS_CONTROL 350
251 char *accesslist_filename = NULL; 351while( scanon ) {
252#endif 352 switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v"
253 353#ifdef WANT_ACCESSLIST_BLACK
254 while( scanon ) {
255 switch( getopt( argc, argv, ":i:p:A:P:d:r:v"
256#ifdef WANT_BLACKLISTING
257"b:" 354"b:"
258#elif defined( WANT_CLOSED_TRACKER ) 355#elif defined( WANT_ACCESSLIST_WHITE )
259"w:" 356"w:"
260#endif 357#endif
261 "h" ) ) { 358 "h" ) ) {
262 case -1 : scanon = 0; break; 359 case -1 : scanon = 0; break;
263 case 'i': scan_ip4( optarg, serverip ); break; 360 case 'i': scan_ip4( optarg, serverip ); break;
264#ifdef WANT_BLACKLISTING 361#ifdef WANT_ACCESSLIST_BLACK
265 case 'b': accesslist_filename = optarg; break; 362 case 'b': set_config_option( &g_accesslist_filename, optarg); break;
266#elif defined( WANT_CLOSED_TRACKER ) 363#elif defined( WANT_ACCESSLIST_WHITE )
267 case 'w': accesslist_filename = optarg; break; 364 case 'w': set_config_option( &g_accesslist_filename, optarg); break;
268#endif 365#endif
269 case 'p': ot_try_bind( serverip, (uint16)atol( optarg ), 1 ); bound++; break; 366 case 'p': ot_try_bind( serverip, (uint16)atol( optarg ), FLAG_TCP ); bound++; break;
270 case 'P': ot_try_bind( serverip, (uint16)atol( optarg ), 0 ); bound++; break; 367 case 'P': ot_try_bind( serverip, (uint16)atol( optarg ), FLAG_UDP ); bound++; break;
271 case 'd': serverdir = optarg; break; 368#ifdef WANT_SYNC_LIVE
272 case 'r': g_redirecturl = optarg; break; 369 case 's': livesync_bind_mcast( serverip, (uint16)atol( optarg )); break;
370#endif
371 case 'd': set_config_option( &g_serverdir, optarg ); break;
372 case 'r': set_config_option( &g_redirecturl, optarg ); break;
273 case 'A': 373 case 'A':
274 scan_ip4( optarg, tmpip ); 374 scan_ip4( optarg, tmpip );
275 accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ 375 accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */
276 break; 376 break;
377 case 'f': bound += parse_configfile( optarg ); break;
277 case 'h': help( argv[0] ); exit( 0 ); 378 case 'h': help( argv[0] ); exit( 0 );
278 case 'v': write( 2, static_inbuf, stats_return_tracker_version( static_inbuf )); exit( 0 ); 379 case 'v': write( 2, static_inbuf, stats_return_tracker_version( static_inbuf )); exit( 0 );
279 default: 380 default:
@@ -283,8 +384,8 @@ int main( int argc, char **argv ) {
283 384
284 /* Bind to our default tcp/udp ports */ 385 /* Bind to our default tcp/udp ports */
285 if( !bound) { 386 if( !bound) {
286 ot_try_bind( serverip, 6969, 1 ); 387 ot_try_bind( serverip, 6969, FLAG_TCP );
287 ot_try_bind( serverip, 6969, 0 ); 388 ot_try_bind( serverip, 6969, FLAG_UDP );
288 } 389 }
289 390
290 /* Drop permissions */ 391 /* Drop permissions */
@@ -298,15 +399,13 @@ int main( int argc, char **argv ) {
298 } 399 }
299 endpwent(); 400 endpwent();
300 401
301 accesslist_init( accesslist_filename );
302
303 signal( SIGPIPE, SIG_IGN ); 402 signal( SIGPIPE, SIG_IGN );
304 signal( SIGINT, signal_handler ); 403 signal( SIGINT, signal_handler );
305 signal( SIGALRM, signal_handler ); 404 signal( SIGALRM, signal_handler );
306 405
307 g_now = time( NULL ); 406 g_now = time( NULL );
308 407
309 if( trackerlogic_init( serverdir ) == -1 ) 408 if( trackerlogic_init( g_serverdir ? g_serverdir : "." ) == -1 )
310 panic( "Logic not started" ); 409 panic( "Logic not started" );
311 410
312 alarm(5); 411 alarm(5);
diff --git a/opentracker.xcodeproj/project.pbxproj b/opentracker.xcodeproj/project.pbxproj
index 7068fa5..895f63f 100644
--- a/opentracker.xcodeproj/project.pbxproj
+++ b/opentracker.xcodeproj/project.pbxproj
@@ -21,6 +21,7 @@
21 65542EE80CE0CA6B00469330 /* ot_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 65542EE70CE0CA6B00469330 /* ot_udp.c */; }; 21 65542EE80CE0CA6B00469330 /* ot_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = 65542EE70CE0CA6B00469330 /* ot_udp.c */; };
22 65542F920CE17CA900469330 /* ot_fullscrape.c in Sources */ = {isa = PBXBuildFile; fileRef = 65542F910CE17CA900469330 /* ot_fullscrape.c */; }; 22 65542F920CE17CA900469330 /* ot_fullscrape.c in Sources */ = {isa = PBXBuildFile; fileRef = 65542F910CE17CA900469330 /* ot_fullscrape.c */; };
23 65B8DF3C0D0310D20017149E /* ot_http.c in Sources */ = {isa = PBXBuildFile; fileRef = 65B8DF3B0D0310D20017149E /* ot_http.c */; }; 23 65B8DF3C0D0310D20017149E /* ot_http.c in Sources */ = {isa = PBXBuildFile; fileRef = 65B8DF3B0D0310D20017149E /* ot_http.c */; };
24 65FA33990E7EF09200F7D5A5 /* ot_livesync.c in Sources */ = {isa = PBXBuildFile; fileRef = 65FA33980E7EF09200F7D5A5 /* ot_livesync.c */; };
24 8DD76FB00486AB0100D96B5E /* opentracker.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6A0FF2C0290799A04C91782 /* opentracker.1 */; }; 25 8DD76FB00486AB0100D96B5E /* opentracker.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6A0FF2C0290799A04C91782 /* opentracker.1 */; };
25/* End PBXBuildFile section */ 26/* End PBXBuildFile section */
26 27
@@ -66,6 +67,8 @@
66 65542F910CE17CA900469330 /* ot_fullscrape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ot_fullscrape.c; sourceTree = "<group>"; }; 67 65542F910CE17CA900469330 /* ot_fullscrape.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ot_fullscrape.c; sourceTree = "<group>"; };
67 65B8DF3A0D0310D20017149E /* ot_http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ot_http.h; sourceTree = "<group>"; }; 68 65B8DF3A0D0310D20017149E /* ot_http.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ot_http.h; sourceTree = "<group>"; };
68 65B8DF3B0D0310D20017149E /* ot_http.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ot_http.c; sourceTree = "<group>"; }; 69 65B8DF3B0D0310D20017149E /* ot_http.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ot_http.c; sourceTree = "<group>"; };
70 65FA33970E7EF09200F7D5A5 /* ot_livesync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ot_livesync.h; sourceTree = "<group>"; };
71 65FA33980E7EF09200F7D5A5 /* ot_livesync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ot_livesync.c; sourceTree = "<group>"; };
69 C6A0FF2C0290799A04C91782 /* opentracker.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = opentracker.1; sourceTree = "<group>"; }; 72 C6A0FF2C0290799A04C91782 /* opentracker.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = opentracker.1; sourceTree = "<group>"; };
70/* End PBXFileReference section */ 73/* End PBXFileReference section */
71 74
@@ -107,6 +110,7 @@
107 65542E740CE08B9100469330 /* ot_clean.c */, 110 65542E740CE08B9100469330 /* ot_clean.c */,
108 65542F910CE17CA900469330 /* ot_fullscrape.c */, 111 65542F910CE17CA900469330 /* ot_fullscrape.c */,
109 65B8DF3B0D0310D20017149E /* ot_http.c */, 112 65B8DF3B0D0310D20017149E /* ot_http.c */,
113 65FA33980E7EF09200F7D5A5 /* ot_livesync.c */,
110 653A56B40CE28EC5000CF140 /* ot_iovec.c */, 114 653A56B40CE28EC5000CF140 /* ot_iovec.c */,
111 65542D8F0CE07CED00469330 /* ot_mutex.c */, 115 65542D8F0CE07CED00469330 /* ot_mutex.c */,
112 65542D910CE07CED00469330 /* ot_stats.c */, 116 65542D910CE07CED00469330 /* ot_stats.c */,
@@ -132,6 +136,7 @@
132 65542D810CE0786F00469330 /* Headers */ = { 136 65542D810CE0786F00469330 /* Headers */ = {
133 isa = PBXGroup; 137 isa = PBXGroup;
134 children = ( 138 children = (
139 65FA33970E7EF09200F7D5A5 /* ot_livesync.h */,
135 653A320A0CE7F475007F0D03 /* ot_accesslist.h */, 140 653A320A0CE7F475007F0D03 /* ot_accesslist.h */,
136 65542E730CE08B9100469330 /* ot_clean.h */, 141 65542E730CE08B9100469330 /* ot_clean.h */,
137 65542F900CE17CA900469330 /* ot_fullscrape.h */, 142 65542F900CE17CA900469330 /* ot_fullscrape.h */,
@@ -248,6 +253,7 @@
248 653A56B50CE28EC5000CF140 /* ot_iovec.c in Sources */, 253 653A56B50CE28EC5000CF140 /* ot_iovec.c in Sources */,
249 653A320C0CE7F475007F0D03 /* ot_accesslist.c in Sources */, 254 653A320C0CE7F475007F0D03 /* ot_accesslist.c in Sources */,
250 65B8DF3C0D0310D20017149E /* ot_http.c in Sources */, 255 65B8DF3C0D0310D20017149E /* ot_http.c in Sources */,
256 65FA33990E7EF09200F7D5A5 /* ot_livesync.c in Sources */,
251 ); 257 );
252 runOnlyForDeploymentPostprocessing = 0; 258 runOnlyForDeploymentPostprocessing = 0;
253 }; 259 };
diff --git a/ot_accesslist.c b/ot_accesslist.c
index df3d64c..cebb064 100644
--- a/ot_accesslist.c
+++ b/ot_accesslist.c
@@ -18,8 +18,8 @@
18#include "ot_accesslist.h" 18#include "ot_accesslist.h"
19 19
20/* GLOBAL VARIABLES */ 20/* GLOBAL VARIABLES */
21#ifdef WANT_ACCESS_CONTROL 21#ifdef WANT_ACCESSLIST
22static char *accesslist_filename = NULL; 22char *g_accesslist_filename = NULL;
23static ot_vector accesslist; 23static ot_vector accesslist;
24 24
25static void accesslist_reset( void ) { 25static void accesslist_reset( void ) {
@@ -46,13 +46,13 @@ static void accesslist_readfile( int foo ) {
46 char inbuf[512]; 46 char inbuf[512];
47 foo = foo; 47 foo = foo;
48 48
49 accesslist_filehandle = fopen( accesslist_filename, "r" ); 49 accesslist_filehandle = fopen( g_accesslist_filename, "r" );
50 50
51 /* Free accesslist vector in trackerlogic.c*/ 51 /* Free accesslist vector in trackerlogic.c*/
52 accesslist_reset(); 52 accesslist_reset();
53 53
54 if( accesslist_filehandle == NULL ) { 54 if( accesslist_filehandle == NULL ) {
55 fprintf( stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).", accesslist_filename ); 55 fprintf( stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).", g_accesslist_filename );
56 return; 56 return;
57 } 57 }
58 58
@@ -79,21 +79,20 @@ int accesslist_hashisvalid( ot_hash *hash ) {
79 int exactmatch; 79 int exactmatch;
80 binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch ); 80 binary_search( hash, accesslist.data, accesslist.size, OT_HASH_COMPARE_SIZE, OT_HASH_COMPARE_SIZE, &exactmatch );
81 81
82#ifdef WANT_BLACKLISTING 82#ifdef WANT_ACCESSLIST_BLACK
83 exactmatch = !exactmatch; 83 exactmatch = !exactmatch;
84#endif 84#endif
85 85
86 return exactmatch; 86 return exactmatch;
87} 87}
88 88
89void accesslist_init( char *accesslist_filename_in ) { 89void accesslist_init( ) {
90 byte_zero( &accesslist, sizeof( accesslist ) ); 90 byte_zero( &accesslist, sizeof( accesslist ) );
91 91
92 /* Passing "0" since read_blacklist_file also is SIGHUP handler */ 92 /* Passing "0" since read_blacklist_file also is SIGHUP handler */
93 if( accesslist_filename_in ) { 93 if( g_accesslist_filename ) {
94 accesslist_filename = accesslist_filename_in;
95 accesslist_readfile( 0 ); 94 accesslist_readfile( 0 );
96 signal( SIGHUP, accesslist_readfile ); 95 signal( SIGHUP, accesslist_readfile );
97 } 96 }
98} 97}
99 98
@@ -108,6 +107,7 @@ int accesslist_blessip( char *ip, ot_permissions permissions ) {
108 return -1; 107 return -1;
109 memmove( g_adminip_addresses + g_adminip_count, ip, 4 ); 108 memmove( g_adminip_addresses + g_adminip_count, ip, 4 );
110 g_adminip_permissions[ g_adminip_count++ ] = permissions; 109 g_adminip_permissions[ g_adminip_count++ ] = permissions;
110// fprintf( stderr, "Blessing ip address %d.%d.%d.%d with %02x\n", (uint8_t)ip[0], (uint8_t)ip[1], (uint8_t)ip[2], (uint8_t)ip[3], permissions );
111 return 0; 111 return 0;
112} 112}
113 113
diff --git a/ot_accesslist.h b/ot_accesslist.h
index 6adefd9..2783b3c 100644
--- a/ot_accesslist.h
+++ b/ot_accesslist.h
@@ -6,14 +6,17 @@
6#ifndef __OT_ACCESSLIST_H__ 6#ifndef __OT_ACCESSLIST_H__
7#define __OT_ACCESSLIST_H__ 7#define __OT_ACCESSLIST_H__
8 8
9#if defined ( WANT_BLACKLISTING ) && defined (WANT_CLOSED_TRACKER ) 9#if defined ( WANT_ACCESSLIST_BLACK ) && defined (WANT_ACCESSLIST_WHITE )
10 #error WANT_BLACKLISTING and WANT_CLOSED_TRACKER are exclusive. 10 #error WANT_ACCESSLIST_BLACK and WANT_ACCESSLIST_WHITE are exclusive.
11#endif 11#endif
12 12
13#if defined ( WANT_BLACKLISTING ) || defined (WANT_CLOSED_TRACKER ) 13#if defined ( WANT_ACCESSLIST_BLACK ) || defined (WANT_ACCESSLIST_WHITE )
14#define WANT_ACCESS_CONTROL 14#define WANT_ACCESSLIST
15void accesslist_init( char *accesslist_filename ); 15void accesslist_init( );
16int accesslist_hashisvalid( ot_hash *hash ); 16int accesslist_hashisvalid( ot_hash *hash );
17
18extern char *g_accesslist_filename;
19
17#else 20#else
18#define accesslist_init( accesslist_filename ) 21#define accesslist_init( accesslist_filename )
19#define accesslist_hashisvalid( hash ) 1 22#define accesslist_hashisvalid( hash ) 1
@@ -22,7 +25,8 @@ int accesslist_hashisvalid( ot_hash *hash );
22typedef enum { 25typedef enum {
23 OT_PERMISSION_MAY_FULLSCRAPE, 26 OT_PERMISSION_MAY_FULLSCRAPE,
24 OT_PERMISSION_MAY_SYNC, 27 OT_PERMISSION_MAY_SYNC,
25 OT_PERMISSION_MAY_STAT 28 OT_PERMISSION_MAY_STAT,
29 OT_PERMISSION_MAY_LIVESYNC
26} ot_permissions; 30} ot_permissions;
27 31
28int accesslist_blessip( char * ip, ot_permissions permissions ); 32int accesslist_blessip( char * ip, ot_permissions permissions );
diff --git a/ot_clean.c b/ot_clean.c
index a45a3dc..f8bb637 100644
--- a/ot_clean.c
+++ b/ot_clean.c
@@ -25,7 +25,7 @@ int clean_single_torrent( ot_torrent *torrent ) {
25 size_t peers_count = 0, seeds_count; 25 size_t peers_count = 0, seeds_count;
26 time_t timedout = (int)( NOW - peer_list->base ); 26 time_t timedout = (int)( NOW - peer_list->base );
27 int i; 27 int i;
28#ifdef WANT_TRACKER_SYNC 28#ifdef WANT_SYNC_BATCH
29 char *new_peers; 29 char *new_peers;
30#endif 30#endif
31 31
@@ -55,7 +55,7 @@ int clean_single_torrent( ot_torrent *torrent ) {
55 memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) ); 55 memmove( peer_list->seed_counts + timedout, peer_list->seed_counts, sizeof( size_t ) * ( OT_POOLS_COUNT - timedout ) );
56 byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout ); 56 byte_zero( peer_list->seed_counts, sizeof( size_t ) * timedout );
57 57
58#ifdef WANT_TRACKER_SYNC 58#ifdef WANT_SYNC_BATCH
59 /* Save the block modified within last OT_POOLS_TIMEOUT */ 59 /* Save the block modified within last OT_POOLS_TIMEOUT */
60 if( peer_list->peers[1].size && 60 if( peer_list->peers[1].size &&
61 ( new_peers = realloc( peer_list->changeset.data, sizeof( ot_peer ) * peer_list->peers[1].size ) ) ) 61 ( new_peers = realloc( peer_list->changeset.data, sizeof( ot_peer ) * peer_list->peers[1].size ) ) )
diff --git a/ot_fullscrape.c b/ot_fullscrape.c
index 0aa7fb9..8175722 100644
--- a/ot_fullscrape.c
+++ b/ot_fullscrape.c
@@ -3,6 +3,8 @@
3 3
4 $id$ */ 4 $id$ */
5 5
6#ifdef WANT_FULLSCRAPE
7
6/* System */ 8/* System */
7#include <sys/param.h> 9#include <sys/param.h>
8#include <sys/uio.h> 10#include <sys/uio.h>
@@ -226,5 +228,6 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tas
226 /* Release unused memory in current output buffer */ 228 /* Release unused memory in current output buffer */
227 iovec_fixlast( iovec_entries, iovector, r ); 229 iovec_fixlast( iovec_entries, iovector, r );
228} 230}
231#endif
229 232
230const char *g_version_fullscrape_c = "$Source$: $Revision$\n"; 233const char *g_version_fullscrape_c = "$Source$: $Revision$\n";
diff --git a/ot_fullscrape.h b/ot_fullscrape.h
index ccd39f4..4025be1 100644
--- a/ot_fullscrape.h
+++ b/ot_fullscrape.h
@@ -6,8 +6,17 @@
6#ifndef __OT_FULLSCRAPE_H__ 6#ifndef __OT_FULLSCRAPE_H__
7#define __OT_FULLSCRAPE_H__ 7#define __OT_FULLSCRAPE_H__
8 8
9#ifdef WANT_FULLSCRAPE
10
9void fullscrape_init( ); 11void fullscrape_init( );
10void fullscrape_deinit( ); 12void fullscrape_deinit( );
11void fullscrape_deliver( int64 socket, ot_tasktype tasktype ); 13void fullscrape_deliver( int64 socket, ot_tasktype tasktype );
12 14
15#else
16
17#define fullscrape_init()
18#define fullscrape_deinit()
19
20#endif
21
13#endif 22#endif
diff --git a/ot_http.c b/ot_http.c
index 682195b..462b8dd 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -28,10 +28,6 @@
28#include "ot_accesslist.h" 28#include "ot_accesslist.h"
29#include "ot_sync.h" 29#include "ot_sync.h"
30 30
31#ifndef WANT_TRACKER_SYNC
32#define add_peer_to_torrent(A,B,C) add_peer_to_torrent(A,B)
33#endif
34
35#define OT_MAXMULTISCRAPE_COUNT 64 31#define OT_MAXMULTISCRAPE_COUNT 64
36static ot_hash multiscrape_buf[OT_MAXMULTISCRAPE_COUNT]; 32static ot_hash multiscrape_buf[OT_MAXMULTISCRAPE_COUNT];
37extern char *g_redirecturl; 33extern char *g_redirecturl;
@@ -103,7 +99,7 @@ ssize_t http_issue_error( const int64 client_socket, int code ) {
103#ifdef _DEBUG_HTTPERROR 99#ifdef _DEBUG_HTTPERROR
104 fprintf( stderr, "DEBUG: invalid request was: %s\n", debug_request ); 100 fprintf( stderr, "DEBUG: invalid request was: %s\n", debug_request );
105#endif 101#endif
106 stats_issue_event( EVENT_FAILED, 1, code ); 102 stats_issue_event( EVENT_FAILED, FLAG_TCP, code );
107 http_senddata( client_socket, static_outbuf, reply_size); 103 http_senddata( client_socket, static_outbuf, reply_size);
108 return -2; 104 return -2;
109} 105}
@@ -169,7 +165,7 @@ ssize_t http_sendiovecdata( const int64 client_socket, int iovec_entries, struct
169 return 0; 165 return 0;
170} 166}
171 167
172#ifdef WANT_TRACKER_SYNC 168#ifdef WANT_SYNC_BATCH
173static ssize_t http_handle_sync( const int64 client_socket, char *data ) { 169static ssize_t http_handle_sync( const int64 client_socket, char *data ) {
174 struct http_data* h = io_getcookie( client_socket ); 170 struct http_data* h = io_getcookie( client_socket );
175 size_t len; 171 size_t len;
@@ -193,7 +189,7 @@ static ssize_t http_handle_sync( const int64 client_socket, char *data ) {
193 if( ( len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) < 10 ) HTTPERROR_400_PARAM; 189 if( ( len = scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) < 10 ) HTTPERROR_400_PARAM;
194 if( add_changeset_to_tracker( (uint8_t*)data, len ) ) HTTPERROR_400_PARAM; 190 if( add_changeset_to_tracker( (uint8_t*)data, len ) ) HTTPERROR_400_PARAM;
195 if( mode == SYNC_OUT ) { 191 if( mode == SYNC_OUT ) {
196 stats_issue_event( EVENT_SYNC_IN, 1, 0 ); 192 stats_issue_event( EVENT_SYNC_IN, FLAG_TCP, 0 );
197 mode = SYNC_IN; 193 mode = SYNC_IN;
198 } 194 }
199 break; 195 break;
@@ -203,7 +199,7 @@ static ssize_t http_handle_sync( const int64 client_socket, char *data ) {
203 if( mode == SYNC_OUT ) { 199 if( mode == SYNC_OUT ) {
204 /* Pass this task to the worker thread */ 200 /* Pass this task to the worker thread */
205 h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; 201 h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
206 stats_issue_event( EVENT_SYNC_OUT_REQUEST, 1, 0 ); 202 stats_issue_event( EVENT_SYNC_OUT_REQUEST, FLAG_TCP, 0 );
207 sync_deliver( client_socket ); 203 sync_deliver( client_socket );
208 io_dontwantread( client_socket ); 204 io_dontwantread( client_socket );
209 return -2; 205 return -2;
@@ -216,7 +212,6 @@ static ssize_t http_handle_sync( const int64 client_socket, char *data ) {
216#endif 212#endif
217 213
218static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d, size_t l ) { 214static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d, size_t l ) {
219 struct http_data* h = io_getcookie( client_socket );
220 char *c = data; 215 char *c = data;
221 int mode = TASK_STATS_PEERS, scanon = 1, format = 0; 216 int mode = TASK_STATS_PEERS, scanon = 1, format = 0;
222 217
@@ -284,7 +279,11 @@ static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d
284 } 279 }
285 } 280 }
286 281
282 /* Touch variable */
283 d=d;
284#ifdef WANT_FULLSCRAPE
287 if( mode == TASK_STATS_TPB ) { 285 if( mode == TASK_STATS_TPB ) {
286 struct http_data* h = io_getcookie( client_socket );
288 tai6464 t; 287 tai6464 t;
289#ifdef WANT_COMPRESSION_GZIP 288#ifdef WANT_COMPRESSION_GZIP
290 d[l-1] = 0; 289 d[l-1] = 0;
@@ -292,9 +291,6 @@ static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d
292 h->flag |= STRUCT_HTTP_FLAG_GZIP; 291 h->flag |= STRUCT_HTTP_FLAG_GZIP;
293 format |= TASK_FLAG_GZIP; 292 format |= TASK_FLAG_GZIP;
294 } 293 }
295#else
296 /* Touch variable */
297 d=d;
298#endif 294#endif
299 /* Pass this task to the worker thread */ 295 /* Pass this task to the worker thread */
300 h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; 296 h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
@@ -305,12 +301,14 @@ static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d
305 io_dontwantread( client_socket ); 301 io_dontwantread( client_socket );
306 return -2; 302 return -2;
307 } 303 }
304#endif
308 305
309 /* default format for now */ 306 /* default format for now */
310 if( !( l = return_stats_for_tracker( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, mode, 0 ) ) ) HTTPERROR_500; 307 if( !( l = return_stats_for_tracker( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, mode, 0 ) ) ) HTTPERROR_500;
311 return l; 308 return l;
312} 309}
313 310
311#ifdef WANT_FULLSCRAPE
314static ssize_t http_handle_fullscrape( const int64 client_socket, char *d, size_t l ) { 312static ssize_t http_handle_fullscrape( const int64 client_socket, char *d, size_t l ) {
315 struct http_data* h = io_getcookie( client_socket ); 313 struct http_data* h = io_getcookie( client_socket );
316 int format = 0; 314 int format = 0;
@@ -341,6 +339,7 @@ write( 2, debug_request, l );
341 io_dontwantread( client_socket ); 339 io_dontwantread( client_socket );
342 return -2; 340 return -2;
343} 341}
342#endif
344 343
345static ssize_t http_handle_scrape( const int64 client_socket, char *data ) { 344static ssize_t http_handle_scrape( const int64 client_socket, char *data ) {
346 int scanon = 1, numwant = 0; 345 int scanon = 1, numwant = 0;
@@ -387,7 +386,7 @@ UTORRENT1600_WORKAROUND:
387 386
388 /* Enough for http header + whole scrape string */ 387 /* Enough for http header + whole scrape string */
389 if( !( l = return_tcp_scrape_for_torrent( multiscrape_buf, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; 388 if( !( l = return_tcp_scrape_for_torrent( multiscrape_buf, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500;
390 stats_issue_event( EVENT_SCRAPE, 1, l ); 389 stats_issue_event( EVENT_SCRAPE, FLAG_TCP, l );
391 return l; 390 return l;
392} 391}
393 392
@@ -486,12 +485,12 @@ static ssize_t http_handle_announce( const int64 client_socket, char *data ) {
486 return sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d14:failure reason81:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" ); 485 return sprintf( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, "d14:failure reason81:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" );
487 486
488 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) 487 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED )
489 len = remove_peer_from_torrent( hash, &peer, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ); 488 len = remove_peer_from_torrent( hash, &peer, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, FLAG_TCP );
490 else { 489 else {
491 torrent = add_peer_to_torrent( hash, &peer, 0 ); 490 torrent = add_peer_to_torrent( hash, &peer WANT_SYNC_PARAM( 0 ) );
492 if( !torrent || !( len = return_peers_for_torrent( hash, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500; 491 if( !torrent || !( len = return_peers_for_torrent( hash, numwant, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf, 1 ) ) ) HTTPERROR_500;
493 } 492 }
494 stats_issue_event( EVENT_ANNOUNCE, 1, len); 493 stats_issue_event( EVENT_ANNOUNCE, FLAG_TCP, len);
495 return len; 494 return len;
496} 495}
497 496
@@ -529,14 +528,16 @@ ssize_t http_handle_request( const int64 client_socket, char *data, size_t recv_
529 /* This is the hardcore match for announce*/ 528 /* This is the hardcore match for announce*/
530 if( ( *data == 'a' ) || ( *data == '?' ) ) 529 if( ( *data == 'a' ) || ( *data == '?' ) )
531 reply_size = http_handle_announce( client_socket, c ); 530 reply_size = http_handle_announce( client_socket, c );
531#ifdef WANT_FULLSCRAPE
532 else if( !byte_diff( data, 12, "scrape HTTP/" ) ) 532 else if( !byte_diff( data, 12, "scrape HTTP/" ) )
533 reply_size = http_handle_fullscrape( client_socket, recv_header, recv_length ); 533 reply_size = http_handle_fullscrape( client_socket, recv_header, recv_length );
534#endif
534 /* This is the hardcore match for scrape */ 535 /* This is the hardcore match for scrape */
535 else if( !byte_diff( data, 2, "sc" ) ) 536 else if( !byte_diff( data, 2, "sc" ) )
536 reply_size = http_handle_scrape( client_socket, c ); 537 reply_size = http_handle_scrape( client_socket, c );
537 /* All the rest is matched the standard way */ 538 /* All the rest is matched the standard way */
538 else switch( len ) { 539 else switch( len ) {
539#ifdef WANT_TRACKER_SYNC 540#ifdef WANT_SYNC_BATCH
540 case 4: /* sync ? */ 541 case 4: /* sync ? */
541 if( byte_diff( data, 4, "sync") ) HTTPERROR_404; 542 if( byte_diff( data, 4, "sync") ) HTTPERROR_404;
542 reply_size = http_handle_sync( client_socket, c ); 543 reply_size = http_handle_sync( client_socket, c );
diff --git a/ot_stats.c b/ot_stats.c
index 1177616..cc7dc30 100644
--- a/ot_stats.c
+++ b/ot_stats.c
@@ -443,13 +443,13 @@ static size_t stats_httperrors_txt ( char * reply ) {
443extern const char 443extern const char
444*g_version_opentracker_c, *g_version_accesslist_c, *g_version_clean_c, *g_version_fullscrape_c, *g_version_http_c, 444*g_version_opentracker_c, *g_version_accesslist_c, *g_version_clean_c, *g_version_fullscrape_c, *g_version_http_c,
445*g_version_iovec_c, *g_version_mutex_c, *g_version_stats_c, *g_version_sync_c, *g_version_udp_c, *g_version_vector_c, 445*g_version_iovec_c, *g_version_mutex_c, *g_version_stats_c, *g_version_sync_c, *g_version_udp_c, *g_version_vector_c,
446*g_version_scan_urlencoded_query_c, *g_version_trackerlogic_c; 446*g_version_scan_urlencoded_query_c, *g_version_trackerlogic_c, *g_version_livesync_c;
447 447
448size_t stats_return_tracker_version( char *reply ) { 448size_t stats_return_tracker_version( char *reply ) {
449 return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s", 449 return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
450 g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c, 450 g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c,
451 g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_sync_c, g_version_udp_c, g_version_vector_c, 451 g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_sync_c, g_version_udp_c, g_version_vector_c,
452 g_version_scan_urlencoded_query_c, g_version_trackerlogic_c ); 452 g_version_scan_urlencoded_query_c, g_version_trackerlogic_c, g_version_livesync_c );
453} 453}
454 454
455size_t return_stats_for_tracker( char *reply, int mode, int format ) { 455size_t return_stats_for_tracker( char *reply, int mode, int format ) {
@@ -490,36 +490,36 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) {
490 } 490 }
491} 491}
492 492
493void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ) { 493void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data ) {
494 switch( event ) { 494 switch( event ) {
495 case EVENT_ACCEPT: 495 case EVENT_ACCEPT:
496 if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; 496 if( proto == FLAG_TCP ) ot_overall_tcp_connections++; else ot_overall_udp_connections++;
497#ifdef WANT_LOG_NETWORKS 497#ifdef WANT_LOG_NETWORKS
498 stat_increase_network_count( &stats_network_counters_root, 0, event_data ); 498 stat_increase_network_count( &stats_network_counters_root, 0, event_data );
499#endif 499#endif
500 break; 500 break;
501 case EVENT_ANNOUNCE: 501 case EVENT_ANNOUNCE:
502 if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; 502 if( proto == FLAG_TCP ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++;
503 break; 503 break;
504 case EVENT_CONNECT: 504 case EVENT_CONNECT:
505 if( is_tcp ) ot_overall_tcp_connects++; else ot_overall_udp_connects++; 505 if( proto == FLAG_TCP ) ot_overall_tcp_connects++; else ot_overall_udp_connects++;
506 break; 506 break;
507 case EVENT_SCRAPE: 507 case EVENT_SCRAPE:
508 if( is_tcp ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++; 508 if( proto == FLAG_TCP ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++;
509 case EVENT_FULLSCRAPE: 509 case EVENT_FULLSCRAPE:
510 ot_full_scrape_count++; 510 ot_full_scrape_count++;
511 ot_full_scrape_size += event_data; 511 ot_full_scrape_size += event_data;
512 break; 512 break;
513 case EVENT_FULLSCRAPE_REQUEST: 513 case EVENT_FULLSCRAPE_REQUEST:
514 { 514 {
515 unsigned char ip[4]; *(int*)ip = is_tcp; /* ugly hack to transfer ip to stats */ 515 unsigned char ip[4]; *(int*)ip = (int)proto; /* ugly hack to transfer ip to stats */
516 LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now - ot_start_time), ip[0], ip[1], ip[2], ip[3] ); 516 LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE\n", (unsigned int)(g_now - ot_start_time), ip[0], ip[1], ip[2], ip[3] );
517 ot_full_scrape_request_count++; 517 ot_full_scrape_request_count++;
518 } 518 }
519 break; 519 break;
520 case EVENT_FULLSCRAPE_REQUEST_GZIP: 520 case EVENT_FULLSCRAPE_REQUEST_GZIP:
521 { 521 {
522 unsigned char ip[4]; *(int*)ip = is_tcp; /* ugly hack to transfer ip to stats */ 522 unsigned char ip[4]; *(int*)ip = (int)proto; /* ugly hack to transfer ip to stats */
523 LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE GZIP\n", (unsigned int)(g_now - ot_start_time), ip[0], ip[1], ip[2], ip[3] ); 523 LOG_TO_STDERR( "[%08d] scrp: %d.%d.%d.%d - FULL SCRAPE GZIP\n", (unsigned int)(g_now - ot_start_time), ip[0], ip[1], ip[2], ip[3] );
524 ot_full_scrape_request_count++; 524 ot_full_scrape_request_count++;
525 } 525 }
diff --git a/ot_stats.h b/ot_stats.h
index 8cc7a5b..72c5b93 100644
--- a/ot_stats.h
+++ b/ot_stats.h
@@ -34,7 +34,7 @@ enum {
34 CODE_HTTPERROR_COUNT 34 CODE_HTTPERROR_COUNT
35}; 35};
36 36
37void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ); 37void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uint32_t event_data );
38size_t return_stats_for_tracker( char *reply, int mode, int format ); 38size_t return_stats_for_tracker( char *reply, int mode, int format );
39size_t stats_return_tracker_version( char *reply ); 39size_t stats_return_tracker_version( char *reply );
40void stats_init( ); 40void stats_init( );
diff --git a/ot_sync.c b/ot_sync.c
index 5f772fb..4beb60d 100644
--- a/ot_sync.c
+++ b/ot_sync.c
@@ -23,7 +23,7 @@
23#include "ot_stats.h" 23#include "ot_stats.h"
24#include "ot_iovec.h" 24#include "ot_iovec.h"
25 25
26#ifdef WANT_TRACKER_SYNC 26#ifdef WANT_SYNC_BATCH
27 27
28#define OT_SYNC_CHUNK_SIZE (512*1024) 28#define OT_SYNC_CHUNK_SIZE (512*1024)
29 29
@@ -141,7 +141,7 @@ static void * sync_worker( void * args) {
141 ot_tasktype tasktype = TASK_SYNC_OUT; 141 ot_tasktype tasktype = TASK_SYNC_OUT;
142 ot_taskid taskid = mutex_workqueue_poptask( &tasktype ); 142 ot_taskid taskid = mutex_workqueue_poptask( &tasktype );
143 sync_make( &iovec_entries, &iovector ); 143 sync_make( &iovec_entries, &iovector );
144 stats_issue_event( EVENT_SYNC_OUT, 1, iovec_length( &iovec_entries, &iovector) ); 144 stats_issue_event( EVENT_SYNC_OUT, FLAG_TCP, iovec_length( &iovec_entries, &iovector) );
145 if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) ) 145 if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) )
146 iovec_free( &iovec_entries, &iovector ); 146 iovec_free( &iovec_entries, &iovector );
147 } 147 }
diff --git a/ot_sync.h b/ot_sync.h
index 210d9d7..ae54e67 100644
--- a/ot_sync.h
+++ b/ot_sync.h
@@ -6,7 +6,7 @@
6#ifndef __OT_SYNC_H__ 6#ifndef __OT_SYNC_H__
7#define __OT_SYNC_H__ 7#define __OT_SYNC_H__
8 8
9#ifdef WANT_TRACKER_SYNC 9#ifdef WANT_SYNC_BATCH
10enum { SYNC_IN, SYNC_OUT }; 10enum { SYNC_IN, SYNC_OUT };
11 11
12void sync_init( ); 12void sync_init( );
@@ -14,6 +14,11 @@ void sync_deinit( );
14void sync_deliver( int64 socket ); 14void sync_deliver( int64 socket );
15 15
16int add_changeset_to_tracker( uint8_t *data, size_t len ); 16int add_changeset_to_tracker( uint8_t *data, size_t len );
17#else
18
19#define sync_init()
20#define sync_deinit()
21
17#endif 22#endif
18 23
19#endif 24#endif
diff --git a/ot_udp.c b/ot_udp.c
index 0a6458e..64f9c50 100644
--- a/ot_udp.c
+++ b/ot_udp.c
@@ -52,8 +52,8 @@ void handle_udp4( int64 serversocket ) {
52 52
53 r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport); 53 r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport);
54 54
55 stats_issue_event( EVENT_ACCEPT, 0, ntohl(*(uint32_t*)remoteip) ); 55 stats_issue_event( EVENT_ACCEPT, FLAG_UDP, ntohl(*(uint32_t*)remoteip) );
56 stats_issue_event( EVENT_READ, 0, r ); 56 stats_issue_event( EVENT_READ, FLAG_UDP, r );
57 57
58 /* Minimum udp tracker packet size, also catches error */ 58 /* Minimum udp tracker packet size, also catches error */
59 if( r < 16 ) 59 if( r < 16 )
@@ -72,7 +72,7 @@ void handle_udp4( int64 serversocket ) {
72 udp_make_connectionid( outpacket + 2, remoteip ); 72 udp_make_connectionid( outpacket + 2, remoteip );
73 73
74 socket_send4( serversocket, static_outbuf, 16, remoteip, remoteport ); 74 socket_send4( serversocket, static_outbuf, 16, remoteip, remoteport );
75 stats_issue_event( EVENT_CONNECT, 0, 16 ); 75 stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 );
76 break; 76 break;
77 case 1: /* This is an announce action */ 77 case 1: /* This is an announce action */
78 /* Minimum udp announce packet size */ 78 /* Minimum udp announce packet size */
@@ -109,9 +109,9 @@ void handle_udp4( int64 serversocket ) {
109 outpacket[1] = inpacket[12/4]; 109 outpacket[1] = inpacket[12/4];
110 110
111 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) /* Peer is gone. */ 111 if( OT_FLAG( &peer ) & PEER_FLAG_STOPPED ) /* Peer is gone. */
112 r = remove_peer_from_torrent( hash, &peer, static_outbuf, 0 ); 112 r = remove_peer_from_torrent( hash, &peer, static_outbuf, FLAG_UDP );
113 else { 113 else {
114 torrent = add_peer_to_torrent( hash, &peer WANT_TRACKER_SYNC_PARAM( 0 ) ); 114 torrent = add_peer_to_torrent( hash, &peer WANT_SYNC_PARAM( 0 ) );
115 if( !torrent ) 115 if( !torrent )
116 return; /* XXX maybe send error */ 116 return; /* XXX maybe send error */
117 117
@@ -119,7 +119,7 @@ void handle_udp4( int64 serversocket ) {
119 } 119 }
120 120
121 socket_send4( serversocket, static_outbuf, r, remoteip, remoteport ); 121 socket_send4( serversocket, static_outbuf, r, remoteip, remoteport );
122 stats_issue_event( EVENT_ANNOUNCE, 0, r ); 122 stats_issue_event( EVENT_ANNOUNCE, FLAG_UDP, r );
123 break; 123 break;
124 124
125 case 2: /* This is a scrape action */ 125 case 2: /* This is a scrape action */
@@ -133,7 +133,7 @@ void handle_udp4( int64 serversocket ) {
133 return_udp_scrape_for_torrent( (ot_hash*)( static_inbuf + 16 + 20 * r_out ), static_outbuf + 8 + 12 * r_out ); 133 return_udp_scrape_for_torrent( (ot_hash*)( static_inbuf + 16 + 20 * r_out ), static_outbuf + 8 + 12 * r_out );
134 134
135 socket_send4( serversocket, static_outbuf, 8 + 12 * r_out, remoteip, remoteport ); 135 socket_send4( serversocket, static_outbuf, 8 + 12 * r_out, remoteip, remoteport );
136 stats_issue_event( EVENT_SCRAPE, 0, r ); 136 stats_issue_event( EVENT_SCRAPE, FLAG_UDP, r );
137 break; 137 break;
138 } 138 }
139} 139}
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c
index 85f0d82..e84fbfd 100644
--- a/scan_urlencoded_query.c
+++ b/scan_urlencoded_query.c
@@ -64,13 +64,13 @@ void scan_urlencoded_skipvalue( char **string ) {
64ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags) { 64ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags) {
65 const unsigned char* s=*(const unsigned char**) string; 65 const unsigned char* s=*(const unsigned char**) string;
66 unsigned char *d = (unsigned char*)deststring; 66 unsigned char *d = (unsigned char*)deststring;
67 unsigned char b, c, f; 67 unsigned char b, c;
68 68
69 /* This is the main decoding loop. 69 /* This is the main decoding loop.
70 'flag' determines, which characters are non-terminating in current context 70 'flag' determines, which characters are non-terminating in current context
71 (ie. stop at '=' and '&' if scanning for a 'param'; stop at '?' if scanning for the path ) 71 (ie. stop at '=' and '&' if scanning for a 'param'; stop at '?' if scanning for the path )
72 */ 72 */
73 while( ( f = is_unreserved[ c = *s++ ] ) & flags ) { 73 while( is_unreserved[ c = *s++ ] & flags ) {
74 74
75 /* When encountering an url escaped character, try to decode */ 75 /* When encountering an url escaped character, try to decode */
76 if( c=='%') { 76 if( c=='%') {
diff --git a/tests/testsuite2.sh b/tests/testsuite2.sh
new file mode 100644
index 0000000..5189187
--- /dev/null
+++ b/tests/testsuite2.sh
@@ -0,0 +1,14 @@
1#!/bin/sh
2
3while true; do
4 request_string="GET /announce?info_hash=012345678901234567\
5%$(printf %02X $(( $RANDOM & 0xff )) )\
6%$(printf %02X $(( $RANDOM & 0xff )) )\
7&ip=$(( $RANDOM & 0xff )).17.13.15&port=$(( $RANDOM & 0xff )) HTTP/1.0\n"
8
9 echo $request_string
10 echo
11 echo $request_string | nc 10.0.1.3 6969 >/dev/null
12 echo
13
14done
diff --git a/trackerlogic.c b/trackerlogic.c
index 37bb878..bff3a3c 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -14,6 +14,7 @@
14#include <unistd.h> 14#include <unistd.h>
15#include <time.h> 15#include <time.h>
16#include <math.h> 16#include <math.h>
17#include <errno.h>
17 18
18/* Libowfat */ 19/* Libowfat */
19#include "scan.h" 20#include "scan.h"
@@ -28,19 +29,20 @@
28#include "ot_accesslist.h" 29#include "ot_accesslist.h"
29#include "ot_fullscrape.h" 30#include "ot_fullscrape.h"
30#include "ot_sync.h" 31#include "ot_sync.h"
32#include "ot_livesync.h"
31 33
32void free_peerlist( ot_peerlist *peer_list ) { 34void free_peerlist( ot_peerlist *peer_list ) {
33 size_t i; 35 size_t i;
34 for( i=0; i<OT_POOLS_COUNT; ++i ) 36 for( i=0; i<OT_POOLS_COUNT; ++i )
35 if( peer_list->peers[i].data ) 37 if( peer_list->peers[i].data )
36 free( peer_list->peers[i].data ); 38 free( peer_list->peers[i].data );
37#ifdef WANT_TRACKER_SYNC 39#ifdef WANT_SYNC_BATCH
38 free( peer_list->changeset.data ); 40 free( peer_list->changeset.data );
39#endif 41#endif
40 free( peer_list ); 42 free( peer_list );
41} 43}
42 44
43ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC_PARAM( int from_changeset ) ) { 45ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_SYNC_PARAM( int from_changeset ) ) {
44 int exactmatch; 46 int exactmatch;
45 ot_torrent *torrent; 47 ot_torrent *torrent;
46 ot_peer *peer_dest; 48 ot_peer *peer_dest;
@@ -58,6 +60,11 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC
58 return NULL; 60 return NULL;
59 } 61 }
60 62
63#ifdef WANT_SYNC_LIVE
64 if( !from_changeset )
65 livesync_tell( hash, peer, PEER_FLAG_LEECHING );
66#endif
67
61 if( !exactmatch ) { 68 if( !exactmatch ) {
62 /* Create a new torrent entry, then */ 69 /* Create a new torrent entry, then */
63 memmove( &torrent->hash, hash, sizeof( ot_hash ) ); 70 memmove( &torrent->hash, hash, sizeof( ot_hash ) );
@@ -79,7 +86,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC
79 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED ) 86 if( ( OT_FLAG( peer ) & ( PEER_FLAG_COMPLETED | PEER_FLAG_SEEDING ) ) == PEER_FLAG_COMPLETED )
80 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED; 87 OT_FLAG( peer ) ^= PEER_FLAG_COMPLETED;
81 88
82#ifdef WANT_TRACKER_SYNC 89#ifdef WANT_SYNC
83 if( from_changeset ) { 90 if( from_changeset ) {
84 /* Check, whether peer already is in current pool, do nothing if so */ 91 /* Check, whether peer already is in current pool, do nothing if so */
85 peer_pool = &torrent->peer_list->peers[0]; 92 peer_pool = &torrent->peer_list->peers[0];
@@ -148,7 +155,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC
148 * RANDOM may return huge values 155 * RANDOM may return huge values
149 * does not yet check not to return self 156 * does not yet check not to return self
150*/ 157*/
151size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int is_tcp ) { 158size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, PROTO_FLAG proto ) {
152 char *r = reply; 159 char *r = reply;
153 int exactmatch; 160 int exactmatch;
154 ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); 161 ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
@@ -164,7 +171,7 @@ size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int
164 if( peer_list->peer_count < amount ) 171 if( peer_list->peer_count < amount )
165 amount = peer_list->peer_count; 172 amount = peer_list->peer_count;
166 173
167 if( is_tcp ) 174 if( proto == FLAG_TCP )
168 r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount ); 175 r += sprintf( r, "d8:completei%zde10:downloadedi%zde10:incompletei%zde8:intervali%ie5:peers%zd:", peer_list->seed_count, peer_list->down_count, peer_list->peer_count-peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM, 6*amount );
169 else { 176 else {
170 *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 177 *(uint32_t*)(r+0) = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
@@ -204,7 +211,7 @@ size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int
204 r += 6; 211 r += 6;
205 } 212 }
206 } 213 }
207 if( is_tcp ) 214 if( proto == FLAG_TCP )
208 *r++ = 'e'; 215 *r++ = 'e';
209 216
210 mutex_bucket_unlock_by_hash( hash ); 217 mutex_bucket_unlock_by_hash( hash );
@@ -263,23 +270,33 @@ size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *repl
263 return r - reply; 270 return r - reply;
264} 271}
265 272
266size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ) { 273size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto ) {
267 int exactmatch; 274 int exactmatch;
268 size_t index; 275 size_t index;
269 ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash ); 276 ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
270 ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); 277 ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
271 ot_peerlist *peer_list; 278 ot_peerlist *peer_list;
272 279
280#ifdef WANT_SYNC_LIVE
281 if( proto != FLAG_MCA )
282 livesync_tell( hash, peer, PEER_FLAG_STOPPED );
283#endif
284
273 if( !exactmatch ) { 285 if( !exactmatch ) {
274 mutex_bucket_unlock_by_hash( hash ); 286 mutex_bucket_unlock_by_hash( hash );
275 287
276 if( is_tcp ) 288 if( proto == FLAG_TCP )
277 return sprintf( reply, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 289 return sprintf( reply, "d8:completei0e10:incompletei0e8:intervali%ie5:peers0:e", OT_CLIENT_REQUEST_INTERVAL_RANDOM );
278 290
279 /* Create fake packet to satisfy parser on the other end */ 291 /* Create fake packet to satisfy parser on the other end */
280 ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 292 if( proto == FLAG_UDP ) {
281 ((uint32_t*)reply)[3] = ((uint32_t*)reply)[4] = 0; 293 ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
282 return (size_t)20; 294 ((uint32_t*)reply)[3] = ((uint32_t*)reply)[4] = 0;
295 return (size_t)20;
296 }
297
298 if( proto == FLAG_MCA )
299 return 0;
283 } 300 }
284 301
285 peer_list = torrent->peer_list; 302 peer_list = torrent->peer_list;
@@ -296,37 +313,46 @@ size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int
296 313
297exit_loop: 314exit_loop:
298 315
299 if( is_tcp ) { 316 if( proto == FLAG_TCP ) {
300 size_t reply_size = sprintf( reply, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 317 size_t reply_size = sprintf( reply, "d8:completei%zde10:incompletei%zde8:intervali%ie5:peers0:e", peer_list->seed_count, peer_list->peer_count - peer_list->seed_count, OT_CLIENT_REQUEST_INTERVAL_RANDOM );
301 mutex_bucket_unlock_by_hash( hash ); 318 mutex_bucket_unlock_by_hash( hash );
302 return reply_size; 319 return reply_size;
303 } 320 }
304 321
305 /* else { Handle UDP reply */ 322 /* Handle UDP reply */
306 ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM ); 323 if( proto == FLAG_TCP ) {
307 ((uint32_t*)reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count ); 324 ((uint32_t*)reply)[2] = htonl( OT_CLIENT_REQUEST_INTERVAL_RANDOM );
308 ((uint32_t*)reply)[4] = htonl( peer_list->seed_count); 325 ((uint32_t*)reply)[3] = htonl( peer_list->peer_count - peer_list->seed_count );
326 ((uint32_t*)reply)[4] = htonl( peer_list->seed_count);
327 }
309 328
310 mutex_bucket_unlock_by_hash( hash ); 329 mutex_bucket_unlock_by_hash( hash );
311 return (size_t)20; 330 return (size_t)20;
312} 331}
313 332
333void exerr( char * message ) {
334 fprintf( stderr, "%s\n", message );
335 exit( 111 );
336}
337
314int trackerlogic_init( const char * const serverdir ) { 338int trackerlogic_init( const char * const serverdir ) {
315 if( serverdir && chdir( serverdir ) ) { 339 if( serverdir && chdir( serverdir ) ) {
316 fprintf( stderr, "Could not chdir() to %s\n", serverdir ); 340 fprintf( stderr, "Could not chdir() to %s, because %s\n", serverdir, strerror(errno) );
317 return -1; 341 return -1;
318 } 342 }
319 343
320 srandom( time(NULL) ); 344 srandom( time(NULL) );
321 345 g_tracker_id = random();
346
322 /* Initialise background worker threads */ 347 /* Initialise background worker threads */
323 mutex_init( ); 348 mutex_init( );
324 clean_init( ); 349 clean_init( );
325 fullscrape_init( ); 350 fullscrape_init( );
326#ifdef WANT_TRACKER_SYNC 351 accesslist_init( );
352 livesync_init( );
327 sync_init( ); 353 sync_init( );
328#endif
329 stats_init( ); 354 stats_init( );
355
330 return 0; 356 return 0;
331} 357}
332 358
@@ -349,9 +375,9 @@ void trackerlogic_deinit( void ) {
349 375
350 /* Deinitialise background worker threads */ 376 /* Deinitialise background worker threads */
351 stats_deinit( ); 377 stats_deinit( );
352#ifdef WANT_TRACKER_SYNC
353 sync_deinit( ); 378 sync_deinit( );
354#endif 379 livesync_init( );
380 accesslist_init( );
355 fullscrape_deinit( ); 381 fullscrape_deinit( );
356 clean_deinit( ); 382 clean_deinit( );
357 mutex_deinit( ); 383 mutex_deinit( );
diff --git a/trackerlogic.h b/trackerlogic.h
index 3525421..986c17a 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -43,6 +43,11 @@ typedef time_t ot_time;
43/* From opentracker.c */ 43/* From opentracker.c */
44extern time_t g_now; 44extern time_t g_now;
45#define NOW (g_now/OT_POOLS_TIMEOUT) 45#define NOW (g_now/OT_POOLS_TIMEOUT)
46extern uint32_t g_tracker_id;
47typedef enum { FLAG_TCP, FLAG_UDP, FLAG_MCA } PROTO_FLAG;
48
49/* Try to bind to ip:port pair. May call exit() on failure */
50int64_t ot_try_bind( char ip[4], uint16_t port, PROTO_FLAG proto );
46 51
47typedef struct { 52typedef struct {
48 uint8_t data[8]; 53 uint8_t data[8];
@@ -50,6 +55,7 @@ typedef struct {
50static const uint8_t PEER_FLAG_SEEDING = 0x80; 55static const uint8_t PEER_FLAG_SEEDING = 0x80;
51static const uint8_t PEER_FLAG_COMPLETED = 0x40; 56static const uint8_t PEER_FLAG_COMPLETED = 0x40;
52static const uint8_t PEER_FLAG_STOPPED = 0x20; 57static const uint8_t PEER_FLAG_STOPPED = 0x20;
58static const uint8_t PEER_FLAG_LEECHING = 0x00;
53 59
54#define OT_SETIP( peer, ip ) memmove((peer),(ip),4); 60#define OT_SETIP( peer, ip ) memmove((peer),(ip),4);
55#define OT_SETPORT( peer, port ) memmove(((uint8_t*)peer)+4,(port),2); 61#define OT_SETPORT( peer, port ) memmove(((uint8_t*)peer)+4,(port),2);
@@ -74,7 +80,7 @@ struct ot_peerlist {
74 size_t down_count; 80 size_t down_count;
75 size_t seed_counts[ OT_POOLS_COUNT ]; 81 size_t seed_counts[ OT_POOLS_COUNT ];
76 ot_vector peers[ OT_POOLS_COUNT ]; 82 ot_vector peers[ OT_POOLS_COUNT ];
77#ifdef WANT_TRACKER_SYNC 83#ifdef WANT_SYNC_BATCH
78 ot_vector changeset; 84 ot_vector changeset;
79#endif 85#endif
80}; 86};
@@ -83,18 +89,23 @@ struct ot_peerlist {
83 Exported functions 89 Exported functions
84*/ 90*/
85 91
86#ifdef WANT_TRACKER_SYNC 92#if defined( WANT_SYNC_BATCH ) || defined( WANT_SYNC_LIVE )
87#define WANT_TRACKER_SYNC_PARAM( param ) , param 93#define WANT_SYNC
94#endif
95
96#ifdef WANT_SYNC
97#define WANT_SYNC_PARAM( param ) , param
88#else 98#else
89#define WANT_TRACKER_SYNC_PARAM( param ) 99#define WANT_SYNC_PARAM( param )
90#endif 100#endif
91 101
92int trackerlogic_init( const char * const serverdir ); 102int trackerlogic_init( const char * const serverdir );
93void trackerlogic_deinit( void ); 103void trackerlogic_deinit( void );
104void exerr( char * message );
94 105
95ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_TRACKER_SYNC_PARAM( int from_changeset ) ); 106ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer WANT_SYNC_PARAM( int from_changeset ) );
96size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ); 107size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, PROTO_FLAG proto );
97size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, int is_tcp ); 108size_t return_peers_for_torrent( ot_hash *hash, size_t amount, char *reply, PROTO_FLAG proto );
98size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); 109size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
99size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); 110size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply );
100 111