From 408c5f98ed073e43560be5319080a34104441e6a Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Thu, 17 Jan 2008 10:46:25 +0000 Subject: Introducing live busy network detection. --- Makefile | 1 + opentracker.c | 2 +- ot_http.c | 2 ++ ot_mutex.h | 1 + ot_stats.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- ot_stats.h | 2 +- ot_udp.c | 2 +- 7 files changed, 117 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 3d4f97b..cf42a68 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,7 @@ BINDIR?=$(PREFIX)/bin #FEATURES+=-DWANT_UTORRENT1600_WORKAROUND #FEATURES+=-DWANT_IP_FROM_QUERY_STRING #FEATURES+=-DWANT_COMPRESSION_GZIP +#FEATURES+=-DWANT_LOG_NETWORKS #FEATURES+=-D_DEBUG_HTTPERROR OPTS_debug=-g -ggdb #-pg # -fprofile-arcs -ftest-coverage diff --git a/opentracker.c b/opentracker.c index a3aa827..21b3d87 100644 --- a/opentracker.c +++ b/opentracker.c @@ -167,7 +167,7 @@ static void handle_accept( const int64 serversocket ) { memset( h, 0, sizeof( struct http_data ) ); memmove( h->ip, ip, sizeof( ip ) ); - stats_issue_event( EVENT_ACCEPT, 1, 0); + stats_issue_event( EVENT_ACCEPT, 1, ntohl(*(uint32_t*)ip)); /* That breaks taia encapsulation. But there is no way to take system time this often in FreeBSD and libowfat does not allow to set unix time */ diff --git a/ot_http.c b/ot_http.c index 7b0e7ae..682195b 100644 --- a/ot_http.c +++ b/ot_http.c @@ -259,6 +259,8 @@ static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d mode = TASK_STATS_TORADDREM; else if( !byte_diff(data,4,"vers")) mode = TASK_STATS_VERSION; + else if( !byte_diff(data,4,"busy")) + mode = TASK_STATS_BUSY_NETWORKS; else HTTPERROR_400_PARAM; break; diff --git a/ot_mutex.h b/ot_mutex.h index dcb50eb..17cb5b4 100644 --- a/ot_mutex.h +++ b/ot_mutex.h @@ -29,6 +29,7 @@ typedef enum { TASK_STATS_STARTSTOP = 0x000a, TASK_STATS_TORADDREM = 0x000b, TASK_STATS_VERSION = 0x000c, + TASK_STATS_BUSY_NETWORKS = 0x000d, TASK_STATS_SLASH24S = 0x0100, diff --git a/ot_stats.c b/ot_stats.c index 6113275..81ff487 100644 --- a/ot_stats.c +++ b/ot_stats.c @@ -43,6 +43,110 @@ static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; static time_t ot_start_time; +#ifdef WANT_LOG_NETWORKS +#define STATS_NETWORK_NODE_BITWIDTH 8 +#define STATS_NETWORK_NODE_MAXDEPTH 3 + +#define STATS_NETWORK_NODE_BITMASK ((1<> ( 32 - STATS_NETWORK_NODE_BITWIDTH * ( ++depth ) ) ) & STATS_NETWORK_NODE_BITMASK; + + if( !*node ) { + *node = malloc( sizeof( stats_network_node ) ); + if( !*node ) + return -1; + memset( *node, 0, sizeof( stats_network_node ) ); + } + + if( depth < STATS_NETWORK_NODE_MAXDEPTH ) + return stat_increase_network_count( &(*node)->children[ foo ], depth, ip ); + + (*node)->counters[ foo ]++; + return 0; +} + +static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { + int i, rest = 0; + if( !*node ) return 0; + + if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) + for( i=0; icounters[i]>>=shift); + return rest; + } + + for( i=0; ichildren[i]; + int rest_val; + + if( !*childnode ) continue; + + rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); + + if( rest_val ) continue; + + free( (*node)->children[i] ); + (*node)->children[i] = NULL; + } + + return rest; +} + +static void stats_get_highscore_networks( stats_network_node *node, int depth, uint32_t node_value, int *scores, uint32_t *networks, int network_count ) { + int i; + + if( !node ) return; + + if( !depth++ ) { + memset( scores, 0, sizeof( *scores ) * network_count ); + memset( networks, 0, sizeof( *networks ) * network_count ); + } + + if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { + for( i=0; ichildren[i] ) + stats_get_highscore_networks( node->children[i], depth, node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ), scores, networks, network_count ); + } else + for( i=0; icounters[i] <= scores[0] ) continue; + + while( (jcounters[i]>scores[j] ) ) ++j; + --j; + + memmove( scores, scores + 1, j * sizeof( *scores ) ); + memmove( networks, networks + 1, j * sizeof( *networks ) ); + scores[ j ] = node->counters[ i ]; + networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); + } +} + +static size_t stats_return_busy_networks( char * reply ) { + uint32_t networks[16]; + int scores[16]; + int i; + char * r = reply; + + stats_get_highscore_networks( stats_network_counters_root, 0, 0, scores, networks, 16 ); + + for( i=15; i>=0; ++i) + r += sprintf( r, "%08i: %d.%d.%d.0/24\n", scores[i], (networks[i]>>24)&0xff, (networks[i]>>16)&0xff, (networks[i]>>8)&0xff ); + + return r - reply; +} + +#endif + /* Converter function from memory to human readable hex strings */ static char*to_hex(char*d,uint8_t*s){char*m="0123456789ABCDEF";char *t=d;char*e=d+40;while(d>4];*d++=m[*s++&15];}*d=0;return t;} @@ -377,15 +481,20 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) { return stats_httperrors_txt( reply ); case TASK_STATS_VERSION: return stats_return_tracker_version( reply ); + case TASK_STATS_BUSY_NETWORKS: + return stats_return_busy_networks( reply ); default: return 0; } } -void stats_issue_event( ot_status_event event, int is_tcp, size_t event_data ) { +void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ) { switch( event ) { case EVENT_ACCEPT: if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; +#ifdef WANT_LOG_NETWORKS + stat_increase_network_count( &stats_network_counters_root, 0, event_data ); +#endif break; case EVENT_ANNOUNCE: if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; diff --git a/ot_stats.h b/ot_stats.h index c07a950..8cc7a5b 100644 --- a/ot_stats.h +++ b/ot_stats.h @@ -34,7 +34,7 @@ enum { CODE_HTTPERROR_COUNT }; -void stats_issue_event( ot_status_event event, int is_tcp, size_t event_data ); +void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ); size_t return_stats_for_tracker( char *reply, int mode, int format ); size_t stats_return_tracker_version( char *reply ); void stats_init( ); diff --git a/ot_udp.c b/ot_udp.c index e1af2fe..3cafd35 100644 --- a/ot_udp.c +++ b/ot_udp.c @@ -54,7 +54,7 @@ void handle_udp4( int64 serversocket ) { r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport); - stats_issue_event( EVENT_ACCEPT, 0, 0 ); + stats_issue_event( EVENT_ACCEPT, 0, ntohl(*(uint32_t*)remoteip) ); stats_issue_event( EVENT_READ, 0, r ); /* Minimum udp tracker packet size, also catches error */ -- cgit v1.2.3