From 41019c79d802e9bc6c1d70e573b6f31f50765ad7 Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Fri, 19 Oct 2007 21:56:59 +0000 Subject: Introducing multiscrape --- opentracker.c | 27 ++++++++++++++++----------- trackerlogic.c | 31 +++++++++++++++++++------------ trackerlogic.h | 2 +- 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]; static char static_outbuf[8192]; static char static_tmpbuf[8192]; +#define OT_MAXMULTISCRAPE_COUNT 64 +static ot_hash multiscrape_buf[OT_MAXMULTISCRAPE_COUNT]; + static char *FLAG_TCP = "TCP"; static char *FLAG_UDP = "UDP"; static size_t ot_sockets_count = 0; @@ -217,7 +220,7 @@ static void httpresponse( const int64 s, char *data, size_t l ) { ot_peer peer; ot_torrent *torrent; ot_hash *hash = NULL; - int numwant, tmp, scanon, mode; + int numwant, tmp, scanon, mode, scrape_count; unsigned short port = htons(6881); time_t t; 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 case 6: /* scrape ? */ if( byte_diff( data, 6, "scrape") ) HTTPERROR_404; - /* We want the pure plain un-unescaped text */ - memmove( static_tmpbuf, static_inbuf, 8192 ); + /* We want the pure plain un-unescaped text */ + memmove( static_tmpbuf, static_inbuf, 8192 ); - /* This is to hack around stupid clients that just replace - "announce ?info_hash" with "scrape ?info_hash". - We do not want to bomb them with full scrapes */ - if( !byte_diff( c, 2, " ?" ) ) ++c; + /* This is to hack around stupid clients that just replace + "announce ?info_hash" with "scrape ?info_hash". + We do not want to bomb them with full scrapes */ + if( !byte_diff( c, 2, " ?" ) ) c+=2; SCRAPE_WORKAROUND: scanon = 1; + scrape_count = 0; while( scanon ) { switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { case -2: scanon = 0; break; /* TERMINATOR */ @@ -396,13 +400,14 @@ SCRAPE_WORKAROUND: } /* ignore this, when we have less than 20 bytes */ if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 20 ) HTTPERROR_400_PARAM; - hash = (ot_hash*)data; + if( scrape_count < OT_MAXMULTISCRAPE_COUNT ) + memmove( multiscrape_buf + scrape_count++, data, sizeof(ot_hash) ); break; } } /* Scanned whole query string, no hash means full scrape... you might want to limit that */ - if( !hash ) { + if( !scrape_count ) { LOG_TO_STDERR( "scrp: %d.%d.%d.%d - FULL SCRAPE\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); write( 2, static_tmpbuf, l ); write( 2, "\n\n\n", 1 ); @@ -412,7 +417,7 @@ write( 2, "\n\n\n", 1 ); } /* Enough for http header + whole scrape string */ - if( !( reply_size = return_tcp_scrape_for_torrent( hash, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; + if( !( reply_size = return_tcp_scrape_for_torrent( multiscrape_buf, scrape_count, SUCCESS_HTTP_HEADER_LENGTH + static_outbuf ) ) ) HTTPERROR_500; ot_overall_tcp_successfulannounces++; break; @@ -423,7 +428,7 @@ write( 2, "\n\n\n", 1 ); if( byte_diff( data, 8, "announce" ) ) HTTPERROR_404; /* This is to hack around stupid clients that send "announce ?info_hash" */ - if( !byte_diff( c, 2, " ?" ) ) ++c; + if( !byte_diff( c, 2, " ?" ) ) c+=2; ANNOUNCE_WORKAROUND: 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 ) { } /* Fetches scrape info for a specific torrent */ -size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ) { +size_t return_tcp_scrape_for_torrent( ot_hash *hash_list, int amount, char *reply ) { char *r = reply; - int exactmatch, i; - size_t peers = 0, seeds = 0; - ot_vector *torrents_list = &all_torrents[*hash[0]]; - ot_torrent *torrent = binary_search( hash, torrents_list->data, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); + int exactmatch, i, j; - if( !exactmatch ) return sprintf( r, "d5:filesdee" ); + r += sprintf( r, "d5:filesd" ); - for( i=0; ipeer_list->peers[i].size; - seeds += torrent->peer_list->seed_count[i]; - } + for( i=0; idata, torrents_list->size, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch ); + size_t peers = 0, seeds = 0; - memmove( r, "d5:filesd20:", 12 ); memmove( r+12, hash, 20 ); - r += sprintf( r+32, "d8:completei%zde10:downloadedi%zde10:incompletei%zdeeee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 32; + if( !exactmatch ) continue; + + for( j=0; jpeer_list->peers[j].size; + seeds += torrent->peer_list->seed_count[j]; + } + + memmove( r, "20:", 3 ); memmove( r+3, hash, 20 ); + r += sprintf( r+23, "d8:completei%zde10:downloadedi%zde10:incompletei%zdee", seeds, torrent->peer_list->downloaded, peers-seeds ) + 23; + } + *r++ = 'e'; *r++ = 'e'; return r - reply; } 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 size_t remove_peer_from_torrent( ot_hash *hash, ot_peer *peer, char *reply, int is_tcp ); size_t return_peers_for_torrent( ot_torrent *torrent, size_t amount, char *reply, int is_tcp ); size_t return_fullscrape_for_tracker( char **reply ); -size_t return_tcp_scrape_for_torrent( ot_hash *hash, char *reply ); +size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); size_t return_udp_scrape_for_torrent( ot_hash *hash, char *reply ); size_t return_stats_for_tracker( char *reply, int mode ); size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ); -- cgit v1.2.3