summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opentracker.c27
-rw-r--r--trackerlogic.c31
-rw-r--r--trackerlogic.h2
3 files changed, 36 insertions, 24 deletions
diff --git a/opentracker.c b/opentracker.c
index 81f5daa..75f43f0 100644
--- a/opentracker.c
+++ b/opentracker.c
@@ -61,6 +61,9 @@ static char static_inbuf[8192];
61static char static_outbuf[8192]; 61static char static_outbuf[8192];
62static char static_tmpbuf[8192]; 62static char static_tmpbuf[8192];
63 63
64#define OT_MAXMULTISCRAPE_COUNT 64
65static ot_hash multiscrape_buf[OT_MAXMULTISCRAPE_COUNT];
66
64static char *FLAG_TCP = "TCP"; 67static char *FLAG_TCP = "TCP";
65static char *FLAG_UDP = "UDP"; 68static char *FLAG_UDP = "UDP";
66static size_t ot_sockets_count = 0; 69static size_t ot_sockets_count = 0;
@@ -217,7 +220,7 @@ static void httpresponse( const int64 s, char *data, size_t l ) {
217 ot_peer peer; 220 ot_peer peer;
218 ot_torrent *torrent; 221 ot_torrent *torrent;
219 ot_hash *hash = NULL; 222 ot_hash *hash = NULL;
220 int numwant, tmp, scanon, mode; 223 int numwant, tmp, scanon, mode, scrape_count;
221 unsigned short port = htons(6881); 224 unsigned short port = htons(6881);
222 time_t t; 225 time_t t;
223 ssize_t len; 226 ssize_t len;
@@ -373,17 +376,18 @@ LOG_TO_STDERR( "stats: %d.%d.%d.%d - mode: s24s old\n", h->ip[0], h->ip[1], h->i
373 case 6: /* scrape ? */ 376 case 6: /* scrape ? */
374 if( byte_diff( data, 6, "scrape") ) HTTPERROR_404; 377 if( byte_diff( data, 6, "scrape") ) HTTPERROR_404;
375 378
376 /* We want the pure plain un-unescaped text */ 379 /* We want the pure plain un-unescaped text */
377 memmove( static_tmpbuf, static_inbuf, 8192 ); 380 memmove( static_tmpbuf, static_inbuf, 8192 );
378 381
379 /* This is to hack around stupid clients that just replace 382 /* This is to hack around stupid clients that just replace
380 "announce ?info_hash" with "scrape ?info_hash". 383 "announce ?info_hash" with "scrape ?info_hash".
381 We do not want to bomb them with full scrapes */ 384 We do not want to bomb them with full scrapes */
382 if( !byte_diff( c, 2, " ?" ) ) ++c; 385 if( !byte_diff( c, 2, " ?" ) ) c+=2;
383 386
384SCRAPE_WORKAROUND: 387SCRAPE_WORKAROUND:
385 388
386 scanon = 1; 389 scanon = 1;
390 scrape_count = 0;
387 while( scanon ) { 391 while( scanon ) {
388 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { 392 switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
389 case -2: scanon = 0; break; /* TERMINATOR */ 393 case -2: scanon = 0; break; /* TERMINATOR */
@@ -396,13 +400,14 @@ SCRAPE_WORKAROUND:
396 } 400 }
397 /* ignore this, when we have less than 20 bytes */ 401 /* ignore this, when we have less than 20 bytes */
398 if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM; 402 if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM;
399 hash = (ot_hash*)data; 403 if( scrape_count < OT_MAXMULTISCRAPE_COUNT )
404 memmove( multiscrape_buf + scrape_count++, data, sizeof(ot_hash) );
400 break; 405 break;
401 } 406 }
402 } 407 }
403 408
404 /* Scanned whole query string, no hash means full scrape... you might want to limit that */ 409 /* Scanned whole query string, no hash means full scrape... you might want to limit that */
405 if( !hash ) { 410 if( !scrape_count ) {
406LOG_TO_STDERR( "scrp: %d.%d.%d.%d - FULL SCRAPE\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); 411LOG_TO_STDERR( "scrp: %d.%d.%d.%d - FULL SCRAPE\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] );
407write( 2, static_tmpbuf, l ); 412write( 2, static_tmpbuf, l );
408write( 2, "\n\n\n", 1 ); 413write( 2, "\n\n\n", 1 );
@@ -412,7 +417,7 @@ write( 2, "\n\n\n", 1 );
412 } 417 }
413 418
414 /* Enough for http header + whole scrape string */ 419 /* Enough for http header + whole scrape string */
415 if( !( reply_size = return_tcp_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; 420 if( !( reply_size = return_tcp_scrape_for_torrent( multiscrape_buf, scrape_count, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500;
416 421
417 ot_overall_tcp_successfulannounces++; 422 ot_overall_tcp_successfulannounces++;
418 break; 423 break;
@@ -423,7 +428,7 @@ write( 2, "\n\n\n", 1 );
423 if( byte_diff( data, 8, "announce" ) ) HTTPERROR_404; 428 if( byte_diff( data, 8, "announce" ) ) HTTPERROR_404;
424 429
425 /* This is to hack around stupid clients that send "announce ?info_hash" */ 430 /* This is to hack around stupid clients that send "announce ?info_hash" */
426 if( !byte_diff( c, 2, " ?" ) ) ++c; 431 if( !byte_diff( c, 2, " ?" ) ) c+=2;
427 432
428ANNOUNCE_WORKAROUND: 433ANNOUNCE_WORKAROUND:
429 434
diff --git a/trackerlogic.c b/trackerlogic.c
index 765a845..00aec1f 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -411,23 +411,30 @@ size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ) {
411} 411}
412 412
413/* Fetches scrape info for a specific torrent */ 413/* Fetches scrape info for a specific torrent */
414size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ) { 414size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *reply ) {
415 char *r = reply; 415 char *r = reply;
416 int exactmatch, i; 416 int exactmatch, i, j;
417 size_t peers = 0, seeds = 0;
418 ot_vector *torrents_list = &all_torrents[*hash[0]];
419 ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
420 417
421 if( !exactmatch ) return sprintf( r, "d5:filesdee" ); 418 r += sprintf( r, "d5:filesd" );
422 419
423 for( i=0; i<OT_POOLS_COUNT; ++i ) { 420 for( i=0; i<amount; ++i ) {
424 peers += torrent->peer_list->peers[i].size; 421 ot_hash *hash = hash_list + i;
425 seeds += torrent->peer_list->seed_count[i]; 422 ot_vector *torrents_list = &all_torrents[*hash[0]];
426 } 423 ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
424 size_t peers = 0, seeds = 0;
427 425
428 memmove( r, "d5:filesd20:", 12 ); memmove( r+12, hash, 20 ); 426 if( !exactmatch ) continue;
429 r += sprintf( r+32, "d8:completei%zde10:downloadedi%zde10:incompletei%zdeeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32; 427
428 for( j=0; j<OT_POOLS_COUNT; ++j ) {
429 peers += torrent->peer_list->peers[j].size;
430 seeds += torrent->peer_list->seed_count[j];
431 }
432
433 memmove( r, "20:", 3 ); memmove( r+3, hash, 20 );
434 r += sprintf( r+23, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 23;
435 }
430 436
437 *r++ = 'e'; *r++ = 'e';
431 return r - reply; 438 return r - reply;
432} 439}
433 440
diff --git a/trackerlogic.h b/trackerlogic.h
index 81bd913..96b59f3 100644
--- a/trackerlogic.h
+++ b/trackerlogic.h
@@ -94,7 +94,7 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer, int from_changese
94size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ); 94size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp );
95size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ); 95size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp );
96size_t return_fullscrape_for_tracker( char **reply ); 96size_t return_fullscrape_for_tracker( char **reply );
97size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ); 97size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply );
98size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); 98size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply );
99size_t return_stats_for_tracker( char *reply, int mode ); 99size_t return_stats_for_tracker( char *reply, int mode );
100size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ); 100size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh );