diff options
| author | erdgeist <> | 2008-01-17 10:46:25 +0000 |
|---|---|---|
| committer | erdgeist <> | 2008-01-17 10:46:25 +0000 |
| commit | 408c5f98ed073e43560be5319080a34104441e6a (patch) | |
| tree | ac48629c99a79a360b4deb6309b83cbc4e953223 | |
| parent | 7050e027d3b7d353dce6a8e100e54d71a46a8063 (diff) | |
Introducing live busy network detection.
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | opentracker.c | 2 | ||||
| -rw-r--r-- | ot_http.c | 2 | ||||
| -rw-r--r-- | ot_mutex.h | 1 | ||||
| -rw-r--r-- | ot_stats.c | 111 | ||||
| -rw-r--r-- | ot_stats.h | 2 | ||||
| -rw-r--r-- | ot_udp.c | 2 |
7 files changed, 117 insertions, 4 deletions
| @@ -25,6 +25,7 @@ BINDIR?=$(PREFIX)/bin | |||
| 25 | #FEATURES+=-DWANT_UTORRENT1600_WORKAROUND | 25 | #FEATURES+=-DWANT_UTORRENT1600_WORKAROUND |
| 26 | #FEATURES+=-DWANT_IP_FROM_QUERY_STRING | 26 | #FEATURES+=-DWANT_IP_FROM_QUERY_STRING |
| 27 | #FEATURES+=-DWANT_COMPRESSION_GZIP | 27 | #FEATURES+=-DWANT_COMPRESSION_GZIP |
| 28 | #FEATURES+=-DWANT_LOG_NETWORKS | ||
| 28 | #FEATURES+=-D_DEBUG_HTTPERROR | 29 | #FEATURES+=-D_DEBUG_HTTPERROR |
| 29 | 30 | ||
| 30 | OPTS_debug=-g -ggdb #-pg # -fprofile-arcs -ftest-coverage | 31 | 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 ) { | |||
| 167 | memset( h, 0, sizeof( struct http_data ) ); | 167 | memset( h, 0, sizeof( struct http_data ) ); |
| 168 | memmove( h->ip, ip, sizeof( ip ) ); | 168 | memmove( h->ip, ip, sizeof( ip ) ); |
| 169 | 169 | ||
| 170 | stats_issue_event( EVENT_ACCEPT, 1, 0); | 170 | stats_issue_event( EVENT_ACCEPT, 1, ntohl(*(uint32_t*)ip)); |
| 171 | 171 | ||
| 172 | /* That breaks taia encapsulation. But there is no way to take system | 172 | /* That breaks taia encapsulation. But there is no way to take system |
| 173 | time this often in FreeBSD and libowfat does not allow to set unix time */ | 173 | time this often in FreeBSD and libowfat does not allow to set unix time */ |
| @@ -259,6 +259,8 @@ static ssize_t http_handle_stats( const int64 client_socket, char *data, char *d | |||
| 259 | mode = TASK_STATS_TORADDREM; | 259 | mode = TASK_STATS_TORADDREM; |
| 260 | else if( !byte_diff(data,4,"vers")) | 260 | else if( !byte_diff(data,4,"vers")) |
| 261 | mode = TASK_STATS_VERSION; | 261 | mode = TASK_STATS_VERSION; |
| 262 | else if( !byte_diff(data,4,"busy")) | ||
| 263 | mode = TASK_STATS_BUSY_NETWORKS; | ||
| 262 | else | 264 | else |
| 263 | HTTPERROR_400_PARAM; | 265 | HTTPERROR_400_PARAM; |
| 264 | break; | 266 | break; |
| @@ -29,6 +29,7 @@ typedef enum { | |||
| 29 | TASK_STATS_STARTSTOP = 0x000a, | 29 | TASK_STATS_STARTSTOP = 0x000a, |
| 30 | TASK_STATS_TORADDREM = 0x000b, | 30 | TASK_STATS_TORADDREM = 0x000b, |
| 31 | TASK_STATS_VERSION = 0x000c, | 31 | TASK_STATS_VERSION = 0x000c, |
| 32 | TASK_STATS_BUSY_NETWORKS = 0x000d, | ||
| 32 | 33 | ||
| 33 | TASK_STATS_SLASH24S = 0x0100, | 34 | TASK_STATS_SLASH24S = 0x0100, |
| 34 | 35 | ||
| @@ -43,6 +43,110 @@ static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; | |||
| 43 | 43 | ||
| 44 | static time_t ot_start_time; | 44 | static time_t ot_start_time; |
| 45 | 45 | ||
| 46 | #ifdef WANT_LOG_NETWORKS | ||
| 47 | #define STATS_NETWORK_NODE_BITWIDTH 8 | ||
| 48 | #define STATS_NETWORK_NODE_MAXDEPTH 3 | ||
| 49 | |||
| 50 | #define STATS_NETWORK_NODE_BITMASK ((1<<STATS_NETWORK_NODE_BITWIDTH)-1) | ||
| 51 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) | ||
| 52 | |||
| 53 | typedef union stats_network_node stats_network_node; | ||
| 54 | union stats_network_node { | ||
| 55 | int counters[STATS_NETWORK_NODE_COUNT]; | ||
| 56 | stats_network_node *children[STATS_NETWORK_NODE_COUNT]; | ||
| 57 | }; | ||
| 58 | |||
| 59 | static stats_network_node *stats_network_counters_root = NULL; | ||
| 60 | |||
| 61 | static int stat_increase_network_count( stats_network_node **node, int depth, uint32_t ip ) { | ||
| 62 | int foo = ( ip >> ( 32 - STATS_NETWORK_NODE_BITWIDTH * ( ++depth ) ) ) & STATS_NETWORK_NODE_BITMASK; | ||
| 63 | |||
| 64 | if( !*node ) { | ||
| 65 | *node = malloc( sizeof( stats_network_node ) ); | ||
| 66 | if( !*node ) | ||
| 67 | return -1; | ||
| 68 | memset( *node, 0, sizeof( stats_network_node ) ); | ||
| 69 | } | ||
| 70 | |||
| 71 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) | ||
| 72 | return stat_increase_network_count( &(*node)->children[ foo ], depth, ip ); | ||
| 73 | |||
| 74 | (*node)->counters[ foo ]++; | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { | ||
| 79 | int i, rest = 0; | ||
| 80 | if( !*node ) return 0; | ||
| 81 | |||
| 82 | if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) | ||
| 83 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | ||
| 84 | rest += ((*node)->counters[i]>>=shift); | ||
| 85 | return rest; | ||
| 86 | } | ||
| 87 | |||
| 88 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | ||
| 89 | stats_network_node **childnode = &(*node)->children[i]; | ||
| 90 | int rest_val; | ||
| 91 | |||
| 92 | if( !*childnode ) continue; | ||
| 93 | |||
| 94 | rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); | ||
| 95 | |||
| 96 | if( rest_val ) continue; | ||
| 97 | |||
| 98 | free( (*node)->children[i] ); | ||
| 99 | (*node)->children[i] = NULL; | ||
| 100 | } | ||
| 101 | |||
| 102 | return rest; | ||
| 103 | } | ||
| 104 | |||
| 105 | static void stats_get_highscore_networks( stats_network_node *node, int depth, uint32_t node_value, int *scores, uint32_t *networks, int network_count ) { | ||
| 106 | int i; | ||
| 107 | |||
| 108 | if( !node ) return; | ||
| 109 | |||
| 110 | if( !depth++ ) { | ||
| 111 | memset( scores, 0, sizeof( *scores ) * network_count ); | ||
| 112 | memset( networks, 0, sizeof( *networks ) * network_count ); | ||
| 113 | } | ||
| 114 | |||
| 115 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { | ||
| 116 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | ||
| 117 | if( node->children[i] ) | ||
| 118 | stats_get_highscore_networks( node->children[i], depth, node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ), scores, networks, network_count ); | ||
| 119 | } else | ||
| 120 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | ||
| 121 | int j=1; | ||
| 122 | if( node->counters[i] <= scores[0] ) continue; | ||
| 123 | |||
| 124 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; | ||
| 125 | --j; | ||
| 126 | |||
| 127 | memmove( scores, scores + 1, j * sizeof( *scores ) ); | ||
| 128 | memmove( networks, networks + 1, j * sizeof( *networks ) ); | ||
| 129 | scores[ j ] = node->counters[ i ]; | ||
| 130 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | static size_t stats_return_busy_networks( char * reply ) { | ||
| 135 | uint32_t networks[16]; | ||
| 136 | int scores[16]; | ||
| 137 | int i; | ||
| 138 | char * r = reply; | ||
| 139 | |||
| 140 | stats_get_highscore_networks( stats_network_counters_root, 0, 0, scores, networks, 16 ); | ||
| 141 | |||
| 142 | for( i=15; i>=0; ++i) | ||
| 143 | r += sprintf( r, "%08i: %d.%d.%d.0/24\n", scores[i], (networks[i]>>24)&0xff, (networks[i]>>16)&0xff, (networks[i]>>8)&0xff ); | ||
| 144 | |||
| 145 | return r - reply; | ||
| 146 | } | ||
| 147 | |||
| 148 | #endif | ||
| 149 | |||
| 46 | /* Converter function from memory to human readable hex strings */ | 150 | /* Converter function from memory to human readable hex strings */ |
| 47 | static char*to_hex(char*d,uint8_t*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;} | 151 | static char*to_hex(char*d,uint8_t*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;} |
| 48 | 152 | ||
| @@ -377,15 +481,20 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) { | |||
| 377 | return stats_httperrors_txt( reply ); | 481 | return stats_httperrors_txt( reply ); |
| 378 | case TASK_STATS_VERSION: | 482 | case TASK_STATS_VERSION: |
| 379 | return stats_return_tracker_version( reply ); | 483 | return stats_return_tracker_version( reply ); |
| 484 | case TASK_STATS_BUSY_NETWORKS: | ||
| 485 | return stats_return_busy_networks( reply ); | ||
| 380 | default: | 486 | default: |
| 381 | return 0; | 487 | return 0; |
| 382 | } | 488 | } |
| 383 | } | 489 | } |
| 384 | 490 | ||
| 385 | void stats_issue_event( ot_status_event event, int is_tcp, size_t event_data ) { | 491 | void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ) { |
| 386 | switch( event ) { | 492 | switch( event ) { |
| 387 | case EVENT_ACCEPT: | 493 | case EVENT_ACCEPT: |
| 388 | if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; | 494 | if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; |
| 495 | #ifdef WANT_LOG_NETWORKS | ||
| 496 | stat_increase_network_count( &stats_network_counters_root, 0, event_data ); | ||
| 497 | #endif | ||
| 389 | break; | 498 | break; |
| 390 | case EVENT_ANNOUNCE: | 499 | case EVENT_ANNOUNCE: |
| 391 | if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; | 500 | if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; |
| @@ -34,7 +34,7 @@ enum { | |||
| 34 | CODE_HTTPERROR_COUNT | 34 | CODE_HTTPERROR_COUNT |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | void stats_issue_event( ot_status_event event, int is_tcp, size_t event_data ); | 37 | void stats_issue_event( ot_status_event event, int is_tcp, uint32_t event_data ); |
| 38 | size_t return_stats_for_tracker( char *reply, int mode, int format ); | 38 | size_t return_stats_for_tracker( char *reply, int mode, int format ); |
| 39 | size_t stats_return_tracker_version( char *reply ); | 39 | size_t stats_return_tracker_version( char *reply ); |
| 40 | void stats_init( ); | 40 | void stats_init( ); |
| @@ -54,7 +54,7 @@ void handle_udp4( int64 serversocket ) { | |||
| 54 | 54 | ||
| 55 | r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport); | 55 | r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport); |
| 56 | 56 | ||
| 57 | stats_issue_event( EVENT_ACCEPT, 0, 0 ); | 57 | stats_issue_event( EVENT_ACCEPT, 0, ntohl(*(uint32_t*)remoteip) ); |
| 58 | stats_issue_event( EVENT_READ, 0, r ); | 58 | stats_issue_event( EVENT_READ, 0, r ); |
| 59 | 59 | ||
| 60 | /* Minimum udp tracker packet size, also catches error */ | 60 | /* Minimum udp tracker packet size, also catches error */ |
