]> git.ipfire.org Git - thirdparty/opentracker.git/commitdiff
Introducing multiscrape
authorerdgeist <>
Fri, 19 Oct 2007 21:56:59 +0000 (21:56 +0000)
committererdgeist <>
Fri, 19 Oct 2007 21:56:59 +0000 (21:56 +0000)
opentracker.c
trackerlogic.c
trackerlogic.h

index 81f5daa6388f21648412697d3cb71c3788373fec..75f43f007773f8f81de4a81d5708b55b6489d8cb 100644 (file)
@@ -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:
 
index 765a84537782f591c6e7a912a0348bfffbaf605a..00aec1f406e8e50c782eb01c72f179939234f306 100644 (file)
@@ -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; i<OT_POOLS_COUNT; ++i ) {
-    peers += torrent->peer_list->peers[i].size;
-    seeds += torrent->peer_list->seed_count[i];
-  }
+  for( i=0; i<amount; ++i ) {
+    ot_hash     *hash = hash_list + i;
+    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 );
+    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; j<OT_POOLS_COUNT; ++j ) {
+      peers += torrent->peer_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;
 }
 
index 81bd9133d7b53dd55586176412d8eca0f95f3f50..96b59f326276937e61164228080376f8e45ecc5c 100644 (file)
@@ -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 );