From c7ed890222939ff9d9a3b575eb83f216ccfebe9e Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 17 Mar 2009 23:57:20 +0000 Subject: Fix white spaces Introduce loading tracker states with -l Alter tracker state to a human readable form --- opentracker.c | 45 +++++++++++++++++++++++++++++++++++++++---- ot_accesslist.c | 2 +- ot_fullscrape.c | 6 ++---- ot_http.c | 11 +++++++---- ot_stats.c | 60 ++++++++++++++++++++++++++++----------------------------- trackerlogic.c | 29 +++++++++++++++++++++++++++- trackerlogic.h | 1 + 7 files changed, 110 insertions(+), 44 deletions(-) diff --git a/opentracker.c b/opentracker.c index c67e331..a82518d 100644 --- a/opentracker.c +++ b/opentracker.c @@ -51,7 +51,7 @@ static void signal_handler( int s ) { if( s == SIGINT ) { /* Any new interrupt signal quits the application */ signal( SIGINT, SIG_DFL); - + /* Tell all other threads to not acquire any new lock on a bucket but cancel their operations and return */ g_opentracker_running = 0; @@ -250,7 +250,7 @@ static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { #else if( ip6_isv4mapped(ip) ) { exerr( "V6 Tracker is V6 only!" ); - } + } #endif #ifdef _DEBUG @@ -261,7 +261,7 @@ static int64_t ot_try_bind( ot_ip6 ip, uint16_t port, PROTO_FLAG proto ) { snprintf( _debug + off, sizeof(_debug)-off, "]:%d...", port); fputs( _debug, stderr ); #endif - + if( socket_bind6_reuse( sock, ip, port, 0 ) == -1 ) panic( "socket_bind6_reuse" ); @@ -394,6 +394,42 @@ int parse_configfile( char * config_filename ) { return bound; } +void load_state(const char * const state_filename ) { + FILE * state_filehandle; + char inbuf[512]; + ot_hash infohash; + unsigned long long base, downcount; + int consumed; + + state_filehandle = fopen( state_filename, "r" ); + + if( state_filehandle == NULL ) { + fprintf( stderr, "Warning: Can't open config file: %s.", state_filename ); + return; + } + + /* We do ignore anything that is not of the form "^[:xdigit:]:\d+:\d+" */ + while( fgets( inbuf, sizeof(inbuf), state_filehandle ) ) { + int i; + for( i=0; i<(int)sizeof(ot_hash); ++i ) { + int eger = 16 * scan_fromhex( inbuf[ 2*i ] ) + scan_fromhex( inbuf[ 1 + 2*i ] ); + if( eger < 0 ) + continue; + infohash[i] = eger; + } + + if( i != (int)sizeof(ot_hash) ) continue; + i *= 2; + + if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &base ) ) ) continue; + i += consumed; + if( inbuf[ i++ ] != ':' || !( consumed = scan_ulonglong( inbuf+i, &downcount ) ) ) continue; + add_torrent_from_saved_state( infohash, base, downcount ); + } + + fclose( state_filehandle ); +} + int drop_privileges (const char * const serverdir) { struct passwd *pws = NULL; @@ -448,7 +484,7 @@ int main( int argc, char **argv ) { #endif while( scanon ) { - switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:v" + switch( getopt( argc, argv, ":i:p:A:P:d:r:s:f:l:v" #ifdef WANT_ACCESSLIST_BLACK "b:" #elif defined( WANT_ACCESSLIST_WHITE ) @@ -477,6 +513,7 @@ while( scanon ) { #endif case 'd': set_config_option( &g_serverdir, optarg ); break; case 'r': set_config_option( &g_redirecturl, optarg ); break; + case 'l': load_state( optarg ); break; case 'A': if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ diff --git a/ot_accesslist.c b/ot_accesslist.c index 631ab88..b69035e 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c @@ -120,7 +120,7 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { char _debug[512]; int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " ); off += fmt_ip6(_debug+off, ip ); - + if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); diff --git a/ot_fullscrape.c b/ot_fullscrape.c index d284bd4..46ce8f8 100644 --- a/ot_fullscrape.c +++ b/ot_fullscrape.c @@ -184,10 +184,8 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tas r += sprintf( r, ":%zd:%zd\n", peer_list->seed_count, peer_list->peer_count-peer_list->seed_count ); break; case TASK_FULLSCRAPE_TRACKERSTATE: - memcpy( r, *hash, sizeof(ot_hash) ); r += sizeof(ot_hash); - uint64_pack_big( r, (uint64_t)peer_list->down_count ); - uint64_pack_big( r + 8, (uint64_t)peer_list->base ); - r += 16; + to_hex( r, *hash ); r+= 2 * sizeof(ot_hash); + r += sprintf( r, ":%zd:%zd\n", peer_list->base, peer_list->down_count ); break; } diff --git a/ot_http.c b/ot_http.c index aee9d3c..bf60104 100644 --- a/ot_http.c +++ b/ot_http.c @@ -288,7 +288,7 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, c /* No info_hash found? Inform user */ if( !numwant ) HTTPERROR_400_PARAM; - + /* Limit number of hashes to process */ if( numwant > OT_MAXMULTISCRAPE_COUNT ) numwant = OT_MAXMULTISCRAPE_COUNT; @@ -312,7 +312,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, unsigned short port = htons(6881); char *write_ptr; ssize_t len; - struct http_data *cookie = io_getcookie( sock ); + struct http_data *cookie = io_getcookie( sock ); /* This is to hack around stupid clients that send "announce ?info_hash" */ if( read_ptr[-1] != '?' ) { @@ -412,6 +412,9 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, } } + /* XXX DEBUG */ + stats_issue_event( EVENT_ACCEPT, FLAG_TCP, (uintptr_t)ws->reply ); + /* Scanned whole query string */ if( !hash ) return ws->reply_size = sprintf( ws->reply, "d14:failure reason80:Your client forgot to send your torrent's info_hash. Please upgrade your client.e" ); @@ -488,14 +491,14 @@ ssize_t http_handle_request( const int64 sock, struct ot_workstruct *ws ) { */ reply_off = SUCCESS_HTTP_SIZE_OFF - snprintf( ws->outbuf, 0, "%zd", ws->reply_size ); ws->reply = ws->outbuf + reply_off; - + /* 2. Now we sprintf our header so that sprintf writes its terminating '\0' exactly one byte before content starts. Complete packet size is increased by size of header plus one byte '\n', we will copy over '\0' in next step */ ws->reply_size += 1 + sprintf( ws->reply, "HTTP/1.0 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %zd\r\n\r", ws->reply_size ); /* 3. Finally we join both blocks neatly */ ws->outbuf[ SUCCESS_HTTP_HEADER_LENGTH - 1 ] = '\n'; - + http_senddata( sock, ws ); return ws->reply_size; } diff --git a/ot_stats.c b/ot_stats.c index e1bce7c..6116c41 100644 --- a/ot_stats.c +++ b/ot_stats.c @@ -1,6 +1,6 @@ /* This software was written by Dirk Engling It is considered beerware. Prost. Skol. Cheers or whatever. - + $id$ */ /* System */ @@ -84,10 +84,10 @@ static int stat_increase_network_count( stats_network_node **node, int depth, ui return -1; memset( *node, 0, sizeof( stats_network_node ) ); } - + if( depth < STATS_NETWORK_NODE_MAXDEPTH ) return stat_increase_network_count( &(*node)->children[ foo ], depth+1, ip ); - + (*node)->counters[ foo ]++; return 0; } @@ -122,9 +122,9 @@ static int stats_shift_down_network_count( stats_network_node **node, int depth, static void stats_get_highscore_networks( stats_network_node *node, int depth, ot_ip6 node_value, int *scores, ot_ip6 *networks, int network_count ) { uint8_t *_node_value = (uint8_t*)node_value; int i; - + if( !node ) return; - + if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { for( i=0; ichildren[i] ) { @@ -139,7 +139,7 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, o _node_value[depth] = i; while( (jcounters[i]>scores[j] ) ) ++j; --j; - + memcpy( scores, scores + 1, j * sizeof( *scores ) ); memcpy( networks, networks + 1, j * sizeof( *networks ) ); scores[ j ] = node->counters[ i ]; @@ -158,7 +158,7 @@ static size_t stats_return_busy_networks( char * reply ) { memset( networks, 0, sizeof( *networks ) * 256 ); stats_get_highscore_networks( stats_network_counters_root, 0, node_value, scores, networks, 256 ); - + for( i=255; i>=0; --i) { r += sprintf( r, "%08i: ", scores[i] ); r += fmt_ip6c( r, networks[i] ); @@ -195,10 +195,10 @@ size_t stats_top10_txt( char * reply ) { ot_record top10s[10], top10c[10]; char *r = reply, hex_out[42]; int idx, bucket; - + byte_zero( top10s, sizeof( top10s ) ); byte_zero( top10c, sizeof( top10c ) ); - + for( bucket=0; bucketsize; ++j ) { @@ -220,7 +220,7 @@ size_t stats_top10_txt( char * reply ) { if( !g_opentracker_running ) return 0; } - + r += sprintf( r, "Top 10 torrents by peers:\n" ); for( idx=0; idx<10; ++idx ) if( top10c[idx].torrent ) @@ -229,7 +229,7 @@ size_t stats_top10_txt( char * reply ) { for( idx=0; idx<10; ++idx ) if( top10s[idx].torrent ) r += sprintf( r, "\t%zd\t%s\n", top10s[idx].val, to_hex( hex_out, top10s[idx].torrent->hash) ); - + return r - reply; } @@ -237,23 +237,23 @@ size_t stats_top10_txt( char * reply ) { malloc blocks */ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) { - + #define NUM_TOPBITS 12 #define NUM_LOWBITS (24-NUM_TOPBITS) #define NUM_BUFS (1<= thresh ) { uint32_t ip = slash24s[ 2*i +1 ]; r += sprintf( r, "% 10ld %d.%d.%d.0/24\n", (long)slash24s[ 2*i ], (int)(ip >> 16), (int)(255 & ( ip >> 8 )), (int)(ip & 255) ); } - + return r - reply; - + for( i=0; i < NUM_BUFS; ++i ) free( counts[i] ); - + return 0; } @@ -395,9 +395,9 @@ static size_t stats_fullscrapes_mrtg( char * reply ) { static size_t stats_peers_mrtg( char * reply ) { torrent_stats stats = {0,0,0}; - + iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); - + return sprintf( reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker", stats.peer_count, stats.seed_count, @@ -408,7 +408,7 @@ static size_t stats_peers_mrtg( char * reply ) { static size_t stats_torrents_mrtg( char * reply ) { size_t torrent_count = mutex_get_torrent_count(); - + return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", torrent_count, (size_t)0, @@ -426,7 +426,7 @@ static size_t stats_httperrors_txt ( char * reply ) { static size_t stats_return_renew_bucket( char * reply ) { char *r = reply; int i; - + for( i=0; ihash, hash, sizeof(ot_hash) ); + + if( !( torrent->peer_list = malloc( sizeof (ot_peerlist) ) ) ) { + vector_remove_torrent( torrents_list, torrent ); + return mutex_bucket_unlock_by_hash( hash, 0 ); + } + + byte_zero( torrent->peer_list, sizeof( ot_peerlist ) ); + torrent->peer_list->base = base; + torrent->peer_list->down_count = down_count; + + return mutex_bucket_unlock_by_hash( hash, 1 ); +} + size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO_FLAG proto, size_t amount, char * reply ) { int exactmatch, delta_torrentcount = 0; size_t reply_size; @@ -375,7 +402,7 @@ void trackerlogic_init( ) { void trackerlogic_deinit( void ) { int bucket, delta_torrentcount = 0; size_t j; - + /* Free all torrents... */ for(bucket=0; bucket