Browse Source

Fix white spaces

Introduce loading tracker states with -l
Alter tracker state to a human readable form
dynamic-accesslists
erdgeist 16 years ago
parent
commit
c7ed890222
  1. 45
      opentracker.c
  2. 2
      ot_accesslist.c
  3. 6
      ot_fullscrape.c
  4. 11
      ot_http.c
  5. 60
      ot_stats.c
  6. 29
      trackerlogic.c
  7. 1
      trackerlogic.h

45
opentracker.c

@ -51,7 +51,7 @@ static void signal_handler( int s ) { @@ -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 ) { @@ -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 ) { @@ -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 ) { @@ -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 ) { @@ -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 ) { @@ -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 */

2
ot_accesslist.c

@ -120,7 +120,7 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { @@ -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" );

6
ot_fullscrape.c

@ -184,10 +184,8 @@ static void fullscrape_make( int *iovec_entries, struct iovec **iovector, ot_tas @@ -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;
}

11
ot_http.c

@ -288,7 +288,7 @@ static ssize_t http_handle_scrape( const int64 sock, struct ot_workstruct *ws, 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, @@ -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, @@ -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 ) { @@ -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;
}

60
ot_stats.c

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
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 @@ -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, @@ -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; i<STATS_NETWORK_NODE_COUNT; ++i )
if( node->children[i] ) {
@ -139,7 +139,7 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, o @@ -139,7 +139,7 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, o
_node_value[depth] = i;
while( (j<network_count) && (node->counters[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 ) { @@ -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 ) { @@ -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; bucket<OT_BUCKET_COUNT; ++bucket ) {
ot_vector *torrents_list = mutex_bucket_lock( bucket );
for( j=0; j<torrents_list->size; ++j ) {
@ -220,7 +220,7 @@ size_t stats_top10_txt( char * reply ) { @@ -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 ) { @@ -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 ) { @@ -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<<NUM_TOPBITS)
#define NUM_S24S (1<<NUM_LOWBITS)
#define MSK_S24S (NUM_S24S-1)
uint32_t *counts[ NUM_BUFS ];
uint32_t slash24s[amount*2]; /* first dword amount, second dword subnet */
size_t i, j, k, l;
char *r = reply;
byte_zero( counts, sizeof( counts ) );
byte_zero( slash24s, amount * 2 * sizeof(uint32_t) );
r += sprintf( r, "Stats for all /24s with more than %u announced torrents:\n\n", thresh );
#if 0
/* XXX: TOOD: Doesn't work yet with new peer storage model */
for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) {
@ -284,7 +284,7 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) @@ -284,7 +284,7 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh )
goto bailout_cleanup;
}
#endif
k = l = 0; /* Debug: count allocated bufs */
for( i=0; i < NUM_BUFS; ++i ) {
uint32_t *count = counts[i];
@ -308,20 +308,20 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) @@ -308,20 +308,20 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh )
}
free( count );
}
r += sprintf( r, "Allocated bufs: %zd, used s24s: %zd\n", k, l );
for( i=0; i < amount; ++i )
if( slash24s[ 2*i ] >= 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 ) { @@ -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 ) { @@ -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 ) { @@ -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; i<OT_PEER_TIMEOUT; ++i )
r+=sprintf(r,"%02i %llu\n", i, ot_renewed[i] );
return r - reply;
@ -526,12 +526,12 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) { @@ -526,12 +526,12 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) {
static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) {
char *r;
*iovec_entries = 0;
*iovector = NULL;
if( !( r = iovec_increase( iovec_entries, iovector, OT_STATS_TMPSIZE ) ) )
return;
switch( mode & TASK_TASK_MASK ) {
case TASK_STATS_TORRENTS: r += stats_torrents_mrtg( r ); break;
case TASK_STATS_PEERS: r += stats_peers_mrtg( r ); break;
@ -607,9 +607,9 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event @@ -607,9 +607,9 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
static void * stats_worker( void * args ) {
int iovec_entries;
struct iovec *iovector;
args = args;
while( 1 ) {
ot_tasktype tasktype = TASK_STATS;
ot_taskid taskid = mutex_workqueue_poptask( &tasktype );

29
trackerlogic.c

@ -41,6 +41,33 @@ void free_peerlist( ot_peerlist *peer_list ) { @@ -41,6 +41,33 @@ void free_peerlist( ot_peerlist *peer_list ) {
free( peer_list );
}
void add_torrent_from_saved_state( ot_hash hash, ot_time base, size_t down_count ) {
int exactmatch;
ot_torrent *torrent;
ot_vector *torrents_list = mutex_bucket_lock_by_hash( hash );
if( !accesslist_hashisvalid( hash ) )
return mutex_bucket_unlock_by_hash( hash, 0 );
torrent = vector_find_or_insert( torrents_list, (void*)hash, sizeof( ot_torrent ), OT_HASH_COMPARE_SIZE, &exactmatch );
if( !torrent || exactmatch )
return mutex_bucket_unlock_by_hash( hash, 0 );
/* Create a new torrent entry, then */
memcpy( torrent->hash, 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( ) { @@ -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<OT_BUCKET_COUNT; ++bucket ) {
ot_vector *torrents_list = mutex_bucket_lock( bucket );

1
trackerlogic.h

@ -147,6 +147,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO @@ -147,6 +147,7 @@ size_t add_peer_to_torrent_and_return_peers( ot_hash hash, ot_peer *peer, PROTO
size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO_FLAG proto );
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 );
void add_torrent_from_saved_state( ot_hash hash, ot_time base, size_t down_count );
/* torrent iterator */
void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data );

Loading…
Cancel
Save