]> git.ipfire.org Git - thirdparty/opentracker.git/commitdiff
Full scrapes are now being delivered in different modes, as triggered by stats&mode...
authorerdgeist <>
Sun, 18 Nov 2007 16:47:37 +0000 (16:47 +0000)
committererdgeist <>
Sun, 18 Nov 2007 16:47:37 +0000 (16:47 +0000)
opentracker.c
ot_fullscrape.c

index 06be4fa6e05bd5c2958dddbc92b667bbbfb09de7..59b561b50bca92e5766a3232dcad6c304a148036 100644 (file)
@@ -284,6 +284,7 @@ static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size
   ot_torrent *torrent;
   ot_hash    *hash = NULL;
   int         numwant, tmp, scanon, mode;
+  ot_tasktype format = TASK_FULLSCRAPE;
   unsigned short port = htons(6881);
   ssize_t     len;
   size_t      reply_size = 0, reply_off;
@@ -359,7 +360,7 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] );
     if( !byte_diff( data, 2, "sc" ) ) goto SCRAPE_WORKAROUND;
     if( byte_diff(data,5,"stats")) HTTPERROR_404;
     scanon = 1;
-    mode = STATS_PEERS;
+    mode = TASK_STATS_PEERS;
 
     while( scanon ) {
       switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) {
@@ -373,24 +374,52 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] );
         }
         if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 4 ) HTTPERROR_400_PARAM;
         if( !byte_diff(data,4,"peer"))
-          mode = STATS_PEERS;
+          mode = TASK_STATS_PEERS;
         else if( !byte_diff(data,4,"conn"))
-          mode = STATS_CONNS;
+          mode = TASK_STATS_CONNS;
         else if( !byte_diff(data,4,"top5"))
-          mode = STATS_TOP5;
+          mode = TASK_STATS_TOP5;
         else if( !byte_diff(data,4,"fscr"))
-          mode = STATS_FULLSCRAPE;
+          mode = TASK_STATS_FULLSCRAPE;
         else if( !byte_diff(data,4,"tcp4"))
-          mode = STATS_TCP;
+          mode = TASK_STATS_TCP;
         else if( !byte_diff(data,4,"udp4"))
-          mode = STATS_UDP;
+          mode = TASK_STATS_UDP;
         else if( !byte_diff(data,4,"s24s"))
-          mode = STATS_SLASH24S;
+          mode = TASK_STATS_SLASH24S;
+        else if( !byte_diff(data,4,"tpbs"))
+          mode = TASK_STATS_TPB;
         else
           HTTPERROR_400_PARAM;
+        break;
+      case 6:
+        if( byte_diff(data,6,"format")) {
+          scan_urlencoded_skipvalue( &c );
+          continue;
+        }
+        if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 3 ) HTTPERROR_400_PARAM;
+        if( !byte_diff(data,3,"bin"))
+          format = TASK_FULLSCRAPE_TPB_BINARY;
+        else if( !byte_diff(data,3,"ben"))
+          format = TASK_FULLSCRAPE;
+        else if( !byte_diff(data,3,"url"))
+          format = TASK_FULLSCRAPE_TPB_URLENCODED;
+        else if( !byte_diff(data,3,"txt"))
+          format = TASK_FULLSCRAPE_TPB_ASCII;
+        else
+          HTTPERROR_400_PARAM;
+        break;
       }
     }
 
+    if( mode == TASK_STATS_TPB ) {
+      /* Pass this task to the worker thread */
+      h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
+      fullscrape_deliver( s, format );
+      io_dontwantread( s );
+      return;
+    }
+
     // default format for now
     if( !( reply_size = return_stats_for_tracker( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, mode, 0 ) ) ) HTTPERROR_500;
     break;
@@ -410,7 +439,7 @@ write( 2, debug_request, l );
 #endif
       /* Pass this task to the worker thread */
       h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK;
-      fullscrape_deliver( s );
+      fullscrape_deliver( s, TASK_FULLSCRAPE );
       io_dontwantread( s );
       return;
     }
index 58e525f2a0f0c19b3da006cf53089da77712cc4a..25d6bd587ac3865cffebd8e86e81c5fd6475787a 100644 (file)
@@ -8,6 +8,7 @@
 #include <pthread.h>
 
 /* Libowfat */
+#include "textcode.h"
 
 /* Opentracker */
 #include "trackerlogic.h"
 #define OT_FULLSCRAPE_MAXENTRYLEN 100
 
 /* Forward declaration */
-static void fullscrape_make( int *iovec_entries, struct iovec **iovector );
+static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode );
+
+/* Converter function from memory to human readable hex strings
+   XXX - Duplicated from ot_stats. Needs fix. */
+static char*to_hex(char*d,ot_byte*s){char*m="0123456789ABCDEF";char *t=d;char*e=d+40;while(d<e){*d++=m[*s>>4];*d++=m[*s++&15];}*d=0;return t;}
 
 /* This is the entry point into this worker thread
    It grabs tasks from mutex_tasklist and delivers results back
@@ -37,8 +42,9 @@ static void * fullscrape_worker( void * args) {
   args = args;
 
   while( 1 ) {
-    ot_taskid taskid = mutex_workqueue_poptask( OT_TASKTYPE_FULLSCRAPE );
-    fullscrape_make( &iovec_entries, &iovector );
+    ot_tasktype tasktype = TASK_FULLSCRAPE;
+    ot_taskid   taskid   = mutex_workqueue_poptask( &tasktype );
+    fullscrape_make( &iovec_entries, &iovector, tasktype );
     if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) )
       iovec_free( &iovec_entries, &iovector );
   }
@@ -50,11 +56,11 @@ void fullscrape_init( ) {
   pthread_create( &thread_id, NULL, fullscrape_worker, NULL );
 }
 
-void fullscrape_deliver( int64 socket ) {
-  mutex_workqueue_pushtask( socket, OT_TASKTYPE_FULLSCRAPE );
+void fullscrape_deliver( int64 socket, ot_tasktype tasktype ) {
+  mutex_workqueue_pushtask( socket, tasktype );
 }
 
-static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) {
+static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) {
   int    bucket;
   char  *r, *re;
 
@@ -68,8 +74,11 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) {
      This works as a low watermark */
   re = r + OT_SCRAPE_CHUNK_SIZE;
 
-  /* Start reply dictionary */
-  memmove( r, "d5:filesd", 9 ); r += 9;
+  /* Reply dictionary only needed for bencoded fullscrape */
+  if( mode == TASK_FULLSCRAPE ) {
+    memmove( r, "d5:filesd", 9 );
+    r += 9;
+  }
 
   /* For each bucket... */
   for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) {
@@ -83,15 +92,29 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) {
       ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[tor_offset] ).peer_list;
       ot_hash     *hash      =&( ((ot_torrent*)(torrents_list->data))[tor_offset] ).hash;
 
-      /* If torrent has peers or download count, its interesting */
-      if( peer_list->peer_count || peer_list->down_count ) {
-
+      switch( mode ) {
+      case TASK_FULLSCRAPE:
+      default:
         /* push hash as bencoded string */
         *r++='2'; *r++='0'; *r++=':';
         memmove( r, hash, 20 ); r+=20;
 
         /* push rest of the scrape string */
         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 );
+        break;
+      case TASK_FULLSCRAPE_TPB_ASCII:
+        to_hex( r, *hash ); r+=40;
+        r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count );
+        break;
+      case TASK_FULLSCRAPE_TPB_BINARY:
+        memmove( r, hash, 20 ); r+=20;
+        *(ot_dword*)r++ = htonl( (uint32_t)peer_list->seed_count );
+        *(ot_dword*)r++ = htonl( (uint32_t)( peer_list->peer_count-peer_list->seed_count) );
+        break;
+      case TASK_FULLSCRAPE_TPB_URLENCODED:
+        r += fmt_urlencoded( r, (char *)*hash, 20 );
+        r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count );
+        break;        
       }
 
       /* If we reached our low watermark in buffer... */
@@ -120,8 +143,10 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) {
     mutex_bucket_unlock( bucket );
   }
 
-  /* Close bencoded scrape dictionary */
-  *r++='e'; *r++='e';
+  /* Close bencoded scrape dictionary if necessary */
+  if( mode == TASK_FULLSCRAPE ) {
+    *r++='e'; *r++='e';
+  }
 
   /* Release unused memory in current output buffer */
   iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) );