diff options
| author | erdgeist <> | 2007-11-18 16:47:37 +0000 |
|---|---|---|
| committer | erdgeist <> | 2007-11-18 16:47:37 +0000 |
| commit | 8d5f2217852e709eb6125441b2d1055fe40ddfc8 (patch) | |
| tree | b8ef51961718457d6c6043e3efa0d36089e8e874 | |
| parent | dab9055590a29351308492e4edbc425a739e5fdc (diff) | |
Full scrapes are now being delivered in different modes, as triggered by stats&mode=tpbs
| -rw-r--r-- | opentracker.c | 47 | ||||
| -rw-r--r-- | ot_fullscrape.c | 51 |
2 files changed, 76 insertions, 22 deletions
diff --git a/opentracker.c b/opentracker.c index 06be4fa..59b561b 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -284,6 +284,7 @@ static void httpresponse( const int64 s, char *data _DEBUG_HTTPERROR_PARAM( size | |||
| 284 | ot_torrent *torrent; | 284 | ot_torrent *torrent; |
| 285 | ot_hash *hash = NULL; | 285 | ot_hash *hash = NULL; |
| 286 | int numwant, tmp, scanon, mode; | 286 | int numwant, tmp, scanon, mode; |
| 287 | ot_tasktype format = TASK_FULLSCRAPE; | ||
| 287 | unsigned short port = htons(6881); | 288 | unsigned short port = htons(6881); |
| 288 | ssize_t len; | 289 | ssize_t len; |
| 289 | size_t reply_size = 0, reply_off; | 290 | 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] ); | |||
| 359 | if( !byte_diff( data, 2, "sc" ) ) goto SCRAPE_WORKAROUND; | 360 | if( !byte_diff( data, 2, "sc" ) ) goto SCRAPE_WORKAROUND; |
| 360 | if( byte_diff(data,5,"stats")) HTTPERROR_404; | 361 | if( byte_diff(data,5,"stats")) HTTPERROR_404; |
| 361 | scanon = 1; | 362 | scanon = 1; |
| 362 | mode = STATS_PEERS; | 363 | mode = TASK_STATS_PEERS; |
| 363 | 364 | ||
| 364 | while( scanon ) { | 365 | while( scanon ) { |
| 365 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | 366 | 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] ); | |||
| 373 | } | 374 | } |
| 374 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 4 ) HTTPERROR_400_PARAM; | 375 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 4 ) HTTPERROR_400_PARAM; |
| 375 | if( !byte_diff(data,4,"peer")) | 376 | if( !byte_diff(data,4,"peer")) |
| 376 | mode = STATS_PEERS; | 377 | mode = TASK_STATS_PEERS; |
| 377 | else if( !byte_diff(data,4,"conn")) | 378 | else if( !byte_diff(data,4,"conn")) |
| 378 | mode = STATS_CONNS; | 379 | mode = TASK_STATS_CONNS; |
| 379 | else if( !byte_diff(data,4,"top5")) | 380 | else if( !byte_diff(data,4,"top5")) |
| 380 | mode = STATS_TOP5; | 381 | mode = TASK_STATS_TOP5; |
| 381 | else if( !byte_diff(data,4,"fscr")) | 382 | else if( !byte_diff(data,4,"fscr")) |
| 382 | mode = STATS_FULLSCRAPE; | 383 | mode = TASK_STATS_FULLSCRAPE; |
| 383 | else if( !byte_diff(data,4,"tcp4")) | 384 | else if( !byte_diff(data,4,"tcp4")) |
| 384 | mode = STATS_TCP; | 385 | mode = TASK_STATS_TCP; |
| 385 | else if( !byte_diff(data,4,"udp4")) | 386 | else if( !byte_diff(data,4,"udp4")) |
| 386 | mode = STATS_UDP; | 387 | mode = TASK_STATS_UDP; |
| 387 | else if( !byte_diff(data,4,"s24s")) | 388 | else if( !byte_diff(data,4,"s24s")) |
| 388 | mode = STATS_SLASH24S; | 389 | mode = TASK_STATS_SLASH24S; |
| 390 | else if( !byte_diff(data,4,"tpbs")) | ||
| 391 | mode = TASK_STATS_TPB; | ||
| 389 | else | 392 | else |
| 390 | HTTPERROR_400_PARAM; | 393 | HTTPERROR_400_PARAM; |
| 394 | break; | ||
| 395 | case 6: | ||
| 396 | if( byte_diff(data,6,"format")) { | ||
| 397 | scan_urlencoded_skipvalue( &c ); | ||
| 398 | continue; | ||
| 399 | } | ||
| 400 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 3 ) HTTPERROR_400_PARAM; | ||
| 401 | if( !byte_diff(data,3,"bin")) | ||
| 402 | format = TASK_FULLSCRAPE_TPB_BINARY; | ||
| 403 | else if( !byte_diff(data,3,"ben")) | ||
| 404 | format = TASK_FULLSCRAPE; | ||
| 405 | else if( !byte_diff(data,3,"url")) | ||
| 406 | format = TASK_FULLSCRAPE_TPB_URLENCODED; | ||
| 407 | else if( !byte_diff(data,3,"txt")) | ||
| 408 | format = TASK_FULLSCRAPE_TPB_ASCII; | ||
| 409 | else | ||
| 410 | HTTPERROR_400_PARAM; | ||
| 411 | break; | ||
| 391 | } | 412 | } |
| 392 | } | 413 | } |
| 393 | 414 | ||
| 415 | if( mode == TASK_STATS_TPB ) { | ||
| 416 | /* Pass this task to the worker thread */ | ||
| 417 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; | ||
| 418 | fullscrape_deliver( s, format ); | ||
| 419 | io_dontwantread( s ); | ||
| 420 | return; | ||
| 421 | } | ||
| 422 | |||
| 394 | // default format for now | 423 | // default format for now |
| 395 | if( !( reply_size = return_stats_for_tracker( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, mode, 0 ) ) ) HTTPERROR_500; | 424 | if( !( reply_size = return_stats_for_tracker( static_outbuf + SUCCESS_HTTP_HEADER_LENGTH, mode, 0 ) ) ) HTTPERROR_500; |
| 396 | break; | 425 | break; |
| @@ -410,7 +439,7 @@ write( 2, debug_request, l ); | |||
| 410 | #endif | 439 | #endif |
| 411 | /* Pass this task to the worker thread */ | 440 | /* Pass this task to the worker thread */ |
| 412 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; | 441 | h->flag |= STRUCT_HTTP_FLAG_WAITINGFORTASK; |
| 413 | fullscrape_deliver( s ); | 442 | fullscrape_deliver( s, TASK_FULLSCRAPE ); |
| 414 | io_dontwantread( s ); | 443 | io_dontwantread( s ); |
| 415 | return; | 444 | return; |
| 416 | } | 445 | } |
diff --git a/ot_fullscrape.c b/ot_fullscrape.c index 58e525f..25d6bd5 100644 --- a/ot_fullscrape.c +++ b/ot_fullscrape.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #include <pthread.h> | 8 | #include <pthread.h> |
| 9 | 9 | ||
| 10 | /* Libowfat */ | 10 | /* Libowfat */ |
| 11 | #include "textcode.h" | ||
| 11 | 12 | ||
| 12 | /* Opentracker */ | 13 | /* Opentracker */ |
| 13 | #include "trackerlogic.h" | 14 | #include "trackerlogic.h" |
| @@ -25,7 +26,11 @@ | |||
| 25 | #define OT_FULLSCRAPE_MAXENTRYLEN 100 | 26 | #define OT_FULLSCRAPE_MAXENTRYLEN 100 |
| 26 | 27 | ||
| 27 | /* Forward declaration */ | 28 | /* Forward declaration */ |
| 28 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector ); | 29 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ); |
| 30 | |||
| 31 | /* Converter function from memory to human readable hex strings | ||
| 32 | XXX - Duplicated from ot_stats. Needs fix. */ | ||
| 33 | 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;} | ||
| 29 | 34 | ||
| 30 | /* This is the entry point into this worker thread | 35 | /* This is the entry point into this worker thread |
| 31 | It grabs tasks from mutex_tasklist and delivers results back | 36 | It grabs tasks from mutex_tasklist and delivers results back |
| @@ -37,8 +42,9 @@ static void * fullscrape_worker( void * args) { | |||
| 37 | args = args; | 42 | args = args; |
| 38 | 43 | ||
| 39 | while( 1 ) { | 44 | while( 1 ) { |
| 40 | ot_taskid taskid = mutex_workqueue_poptask( OT_TASKTYPE_FULLSCRAPE ); | 45 | ot_tasktype tasktype = TASK_FULLSCRAPE; |
| 41 | fullscrape_make( &iovec_entries, &iovector ); | 46 | ot_taskid taskid = mutex_workqueue_poptask( &tasktype ); |
| 47 | fullscrape_make( &iovec_entries, &iovector, tasktype ); | ||
| 42 | if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) ) | 48 | if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) ) |
| 43 | iovec_free( &iovec_entries, &iovector ); | 49 | iovec_free( &iovec_entries, &iovector ); |
| 44 | } | 50 | } |
| @@ -50,11 +56,11 @@ void fullscrape_init( ) { | |||
| 50 | pthread_create( &thread_id, NULL, fullscrape_worker, NULL ); | 56 | pthread_create( &thread_id, NULL, fullscrape_worker, NULL ); |
| 51 | } | 57 | } |
| 52 | 58 | ||
| 53 | void fullscrape_deliver( int64 socket ) { | 59 | void fullscrape_deliver( int64 socket, ot_tasktype tasktype ) { |
| 54 | mutex_workqueue_pushtask( socket, OT_TASKTYPE_FULLSCRAPE ); | 60 | mutex_workqueue_pushtask( socket, tasktype ); |
| 55 | } | 61 | } |
| 56 | 62 | ||
| 57 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) { | 63 | static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { |
| 58 | int bucket; | 64 | int bucket; |
| 59 | char *r, *re; | 65 | char *r, *re; |
| 60 | 66 | ||
| @@ -68,8 +74,11 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) { | |||
| 68 | This works as a low watermark */ | 74 | This works as a low watermark */ |
| 69 | re = r + OT_SCRAPE_CHUNK_SIZE; | 75 | re = r + OT_SCRAPE_CHUNK_SIZE; |
| 70 | 76 | ||
| 71 | /* Start reply dictionary */ | 77 | /* Reply dictionary only needed for bencoded fullscrape */ |
| 72 | memmove( r, "d5:filesd", 9 ); r += 9; | 78 | if( mode == TASK_FULLSCRAPE ) { |
| 79 | memmove( r, "d5:filesd", 9 ); | ||
| 80 | r += 9; | ||
| 81 | } | ||
| 73 | 82 | ||
| 74 | /* For each bucket... */ | 83 | /* For each bucket... */ |
| 75 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 84 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { |
| @@ -83,15 +92,29 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) { | |||
| 83 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[tor_offset] ).peer_list; | 92 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[tor_offset] ).peer_list; |
| 84 | ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[tor_offset] ).hash; | 93 | ot_hash *hash =&( ((ot_torrent*)(torrents_list->data))[tor_offset] ).hash; |
| 85 | 94 | ||
| 86 | /* If torrent has peers or download count, its interesting */ | 95 | switch( mode ) { |
| 87 | if( peer_list->peer_count || peer_list->down_count ) { | 96 | case TASK_FULLSCRAPE: |
| 88 | 97 | default: | |
| 89 | /* push hash as bencoded string */ | 98 | /* push hash as bencoded string */ |
| 90 | *r++='2'; *r++='0'; *r++=':'; | 99 | *r++='2'; *r++='0'; *r++=':'; |
| 91 | memmove( r, hash, 20 ); r+=20; | 100 | memmove( r, hash, 20 ); r+=20; |
| 92 | 101 | ||
| 93 | /* push rest of the scrape string */ | 102 | /* push rest of the scrape string */ |
| 94 | 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 ); | 103 | 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 ); |
| 104 | break; | ||
| 105 | case TASK_FULLSCRAPE_TPB_ASCII: | ||
| 106 | to_hex( r, *hash ); r+=40; | ||
| 107 | r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count ); | ||
| 108 | break; | ||
| 109 | case TASK_FULLSCRAPE_TPB_BINARY: | ||
| 110 | memmove( r, hash, 20 ); r+=20; | ||
| 111 | *(ot_dword*)r++ = htonl( (uint32_t)peer_list->seed_count ); | ||
| 112 | *(ot_dword*)r++ = htonl( (uint32_t)( peer_list->peer_count-peer_list->seed_count) ); | ||
| 113 | break; | ||
| 114 | case TASK_FULLSCRAPE_TPB_URLENCODED: | ||
| 115 | r += fmt_urlencoded( r, (char *)*hash, 20 ); | ||
| 116 | r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count ); | ||
| 117 | break; | ||
| 95 | } | 118 | } |
| 96 | 119 | ||
| 97 | /* If we reached our low watermark in buffer... */ | 120 | /* If we reached our low watermark in buffer... */ |
| @@ -120,8 +143,10 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector ) { | |||
| 120 | mutex_bucket_unlock( bucket ); | 143 | mutex_bucket_unlock( bucket ); |
| 121 | } | 144 | } |
| 122 | 145 | ||
| 123 | /* Close bencoded scrape dictionary */ | 146 | /* Close bencoded scrape dictionary if necessary */ |
| 124 | *r++='e'; *r++='e'; | 147 | if( mode == TASK_FULLSCRAPE ) { |
| 148 | *r++='e'; *r++='e'; | ||
| 149 | } | ||
| 125 | 150 | ||
| 126 | /* Release unused memory in current output buffer */ | 151 | /* Release unused memory in current output buffer */ |
| 127 | iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) ); | 152 | iovec_fixlast( iovec_entries, iovector, OT_SCRAPE_CHUNK_SIZE - ( re - r ) ); |
