mirror of
git://erdgeist.org/opentracker
synced 2025-01-27 23:26:27 +00:00
Introducing live busy network detection.
This commit is contained in:
parent
7050e027d3
commit
408c5f98ed
1
Makefile
1
Makefile
@ -25,6 +25,7 @@ BINDIR?=$(PREFIX)/bin
|
|||||||
#FEATURES+=-DWANT_UTORRENT1600_WORKAROUND
|
#FEATURES+=-DWANT_UTORRENT1600_WORKAROUND
|
||||||
#FEATURES+=-DWANT_IP_FROM_QUERY_STRING
|
#FEATURES+=-DWANT_IP_FROM_QUERY_STRING
|
||||||
#FEATURES+=-DWANT_COMPRESSION_GZIP
|
#FEATURES+=-DWANT_COMPRESSION_GZIP
|
||||||
|
#FEATURES+=-DWANT_LOG_NETWORKS
|
||||||
#FEATURES+=-D_DEBUG_HTTPERROR
|
#FEATURES+=-D_DEBUG_HTTPERROR
|
||||||
|
|
||||||
OPTS_debug=-g -ggdb #-pg # -fprofile-arcs -ftest-coverage
|
OPTS_debug=-g -ggdb #-pg # -fprofile-arcs -ftest-coverage
|
||||||
|
@ -167,7 +167,7 @@ static void handle_accept( const int64 serversocket ) {
|
|||||||
memset( h, 0, sizeof( struct http_data ) );
|
memset( h, 0, sizeof( struct http_data ) );
|
||||||
memmove( h->ip, ip, sizeof( ip ) );
|
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
|
/* 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 */
|
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
|
|||||||
mode = TASK_STATS_TORADDREM;
|
mode = TASK_STATS_TORADDREM;
|
||||||
else if( !byte_diff(data,4,"vers"))
|
else if( !byte_diff(data,4,"vers"))
|
||||||
mode = TASK_STATS_VERSION;
|
mode = TASK_STATS_VERSION;
|
||||||
|
else if( !byte_diff(data,4,"busy"))
|
||||||
|
mode = TASK_STATS_BUSY_NETWORKS;
|
||||||
else
|
else
|
||||||
HTTPERROR_400_PARAM;
|
HTTPERROR_400_PARAM;
|
||||||
break;
|
break;
|
||||||
|
@ -29,6 +29,7 @@ typedef enum {
|
|||||||
TASK_STATS_STARTSTOP = 0x000a,
|
TASK_STATS_STARTSTOP = 0x000a,
|
||||||
TASK_STATS_TORADDREM = 0x000b,
|
TASK_STATS_TORADDREM = 0x000b,
|
||||||
TASK_STATS_VERSION = 0x000c,
|
TASK_STATS_VERSION = 0x000c,
|
||||||
|
TASK_STATS_BUSY_NETWORKS = 0x000d,
|
||||||
|
|
||||||
TASK_STATS_SLASH24S = 0x0100,
|
TASK_STATS_SLASH24S = 0x0100,
|
||||||
|
|
||||||
|
111
ot_stats.c
111
ot_stats.c
@ -43,6 +43,110 @@ static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT];
|
|||||||
|
|
||||||
static time_t ot_start_time;
|
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<<STATS_NETWORK_NODE_BITWIDTH)-1)
|
||||||
|
#define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH)
|
||||||
|
|
||||||
|
typedef union stats_network_node stats_network_node;
|
||||||
|
union stats_network_node {
|
||||||
|
int counters[STATS_NETWORK_NODE_COUNT];
|
||||||
|
stats_network_node *children[STATS_NETWORK_NODE_COUNT];
|
||||||
|
};
|
||||||
|
|
||||||
|
static stats_network_node *stats_network_counters_root = NULL;
|
||||||
|
|
||||||
|
static int stat_increase_network_count( stats_network_node **node, int depth, uint32_t ip ) {
|
||||||
|
int foo = ( ip >> ( 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; i<STATS_NETWORK_NODE_COUNT; ++i ) {
|
||||||
|
rest += ((*node)->counters[i]>>=shift);
|
||||||
|
return rest;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) {
|
||||||
|
stats_network_node **childnode = &(*node)->children[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; i<STATS_NETWORK_NODE_COUNT; ++i )
|
||||||
|
if( node->children[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; i<STATS_NETWORK_NODE_COUNT; ++i ) {
|
||||||
|
int j=1;
|
||||||
|
if( node->counters[i] <= scores[0] ) continue;
|
||||||
|
|
||||||
|
while( (j<network_count) && (node->counters[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 */
|
/* 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<e){*d++=m[*s>>4];*d++=m[*s++&15];}*d=0;return t;}
|
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;}
|
||||||
|
|
||||||
@ -377,15 +481,20 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) {
|
|||||||
return stats_httperrors_txt( reply );
|
return stats_httperrors_txt( reply );
|
||||||
case TASK_STATS_VERSION:
|
case TASK_STATS_VERSION:
|
||||||
return stats_return_tracker_version( reply );
|
return stats_return_tracker_version( reply );
|
||||||
|
case TASK_STATS_BUSY_NETWORKS:
|
||||||
|
return stats_return_busy_networks( reply );
|
||||||
default:
|
default:
|
||||||
return 0;
|
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 ) {
|
switch( event ) {
|
||||||
case EVENT_ACCEPT:
|
case EVENT_ACCEPT:
|
||||||
if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++;
|
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;
|
break;
|
||||||
case EVENT_ANNOUNCE:
|
case EVENT_ANNOUNCE:
|
||||||
if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++;
|
if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++;
|
||||||
|
@ -34,7 +34,7 @@ enum {
|
|||||||
CODE_HTTPERROR_COUNT
|
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 return_stats_for_tracker( char *reply, int mode, int format );
|
||||||
size_t stats_return_tracker_version( char *reply );
|
size_t stats_return_tracker_version( char *reply );
|
||||||
void stats_init( );
|
void stats_init( );
|
||||||
|
2
ot_udp.c
2
ot_udp.c
@ -54,7 +54,7 @@ void handle_udp4( int64 serversocket ) {
|
|||||||
|
|
||||||
r = socket_recv4( serversocket, static_inbuf, sizeof( static_inbuf ), remoteip, &remoteport);
|
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 );
|
stats_issue_event( EVENT_READ, 0, r );
|
||||||
|
|
||||||
/* Minimum udp tracker packet size, also catches error */
|
/* Minimum udp tracker packet size, also catches error */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user