diff options
-rw-r--r-- | opentracker.c | 11 | ||||
-rw-r--r-- | ot_accesslist.c | 1 | ||||
-rw-r--r-- | ot_accesslist.h | 3 | ||||
-rw-r--r-- | ot_http.c | 43 | ||||
-rw-r--r-- | ot_mutex.c | 5 | ||||
-rw-r--r-- | ot_stats.c | 341 | ||||
-rw-r--r-- | ot_stats.h | 3 | ||||
-rw-r--r-- | trackerlogic.c | 19 | ||||
-rw-r--r-- | trackerlogic.h | 3 |
9 files changed, 252 insertions, 177 deletions
diff --git a/opentracker.c b/opentracker.c index b839efc..c67e331 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -135,12 +135,10 @@ static ssize_t handle_read( const int64 sock, struct ot_workstruct *ws ) { | |||
135 | 135 | ||
136 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); | 136 | array_catb( &cookie->data.request, ws->inbuf, byte_count ); |
137 | 137 | ||
138 | if( array_failed( &cookie->data.request ) ) | 138 | if( array_failed( &cookie->data.request ) || |
139 | array_bytes( &cookie->data.request ) > 8192 ) | ||
139 | return http_issue_error( sock, ws, CODE_HTTPERROR_500 ); | 140 | return http_issue_error( sock, ws, CODE_HTTPERROR_500 ); |
140 | 141 | ||
141 | if( array_bytes( &cookie->data.request ) > 8192 ) | ||
142 | return http_issue_error( sock, ws, CODE_HTTPERROR_500 ); | ||
143 | |||
144 | if( !memchr( array_start( &cookie->data.request ), '\n', array_bytes( &cookie->data.request ) ) ) | 142 | if( !memchr( array_start( &cookie->data.request ), '\n', array_bytes( &cookie->data.request ) ) ) |
145 | return 0; | 143 | return 0; |
146 | 144 | ||
@@ -370,6 +368,11 @@ int parse_configfile( char * config_filename ) { | |||
370 | if( !scan_ip6( p+13, tmpip )) goto parse_error; | 368 | if( !scan_ip6( p+13, tmpip )) goto parse_error; |
371 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); | 369 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); |
372 | #endif | 370 | #endif |
371 | #ifdef WANT_IP_FROM_PROXY | ||
372 | } else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) { | ||
373 | if( !scan_ip6( p+13, tmpip )) goto parse_error; | ||
374 | accesslist_blessip( tmpip, OT_PERMISSION_MAY_PROXY ); | ||
375 | #endif | ||
373 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { | 376 | } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { |
374 | set_config_option( &g_redirecturl, p+21 ); | 377 | set_config_option( &g_redirecturl, p+21 ); |
375 | #ifdef WANT_SYNC_LIVE | 378 | #ifdef WANT_SYNC_LIVE |
diff --git a/ot_accesslist.c b/ot_accesslist.c index 304b3f1..631ab88 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c | |||
@@ -124,6 +124,7 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { | |||
124 | if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); | 124 | if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); |
125 | if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); | 125 | if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); |
126 | if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); | 126 | if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); |
127 | if( permissions & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" ); | ||
127 | if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" ); | 128 | if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" ); |
128 | _debug[off++] = '.'; | 129 | _debug[off++] = '.'; |
129 | write( 2, _debug, off ); | 130 | write( 2, _debug, off ); |
diff --git a/ot_accesslist.h b/ot_accesslist.h index 836a233..5954a4a 100644 --- a/ot_accesslist.h +++ b/ot_accesslist.h | |||
@@ -27,7 +27,8 @@ extern char *g_accesslist_filename; | |||
27 | typedef enum { | 27 | typedef enum { |
28 | OT_PERMISSION_MAY_FULLSCRAPE = 0x1, | 28 | OT_PERMISSION_MAY_FULLSCRAPE = 0x1, |
29 | OT_PERMISSION_MAY_STAT = 0x2, | 29 | OT_PERMISSION_MAY_STAT = 0x2, |
30 | OT_PERMISSION_MAY_LIVESYNC = 0x4 | 30 | OT_PERMISSION_MAY_LIVESYNC = 0x4, |
31 | OT_PERMISSION_MAY_PROXY = 0x8 | ||
31 | } ot_permissions; | 32 | } ot_permissions; |
32 | 33 | ||
33 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); | 34 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); |
@@ -306,13 +306,14 @@ static ot_keywords keywords_announce[] = { { "port", 1 }, { "left", 2 }, { "even | |||
306 | { NULL, -3 } }; | 306 | { NULL, -3 } }; |
307 | static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } }; | 307 | static ot_keywords keywords_announce_event[] = { { "completed", 1 }, { "stopped", 2 }, { NULL, -3 } }; |
308 | static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, char *read_ptr ) { | 308 | static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, char *read_ptr ) { |
309 | int numwant, tmp, scanon; | 309 | int numwant, tmp, scanon; |
310 | ot_peer peer; | 310 | ot_peer peer; |
311 | ot_hash *hash = NULL; | 311 | ot_hash *hash = NULL; |
312 | unsigned short port = htons(6881); | 312 | unsigned short port = htons(6881); |
313 | char *write_ptr; | 313 | char *write_ptr; |
314 | ssize_t len; | 314 | ssize_t len; |
315 | 315 | struct http_data *cookie = io_getcookie( sock ); | |
316 | |||
316 | /* This is to hack around stupid clients that send "announce ?info_hash" */ | 317 | /* This is to hack around stupid clients that send "announce ?info_hash" */ |
317 | if( read_ptr[-1] != '?' ) { | 318 | if( read_ptr[-1] != '?' ) { |
318 | while( ( *read_ptr != '?' ) && ( *read_ptr != '\n' ) ) ++read_ptr; | 319 | while( ( *read_ptr != '?' ) && ( *read_ptr != '\n' ) ) ++read_ptr; |
@@ -320,7 +321,33 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, | |||
320 | ++read_ptr; | 321 | ++read_ptr; |
321 | } | 322 | } |
322 | 323 | ||
323 | OT_SETIP( &peer, ((struct http_data*)io_getcookie( sock ) )->ip ); | 324 | #ifdef WANT_IP_FROM_PROXY |
325 | if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) { | ||
326 | ot_ip6 proxied_ip; | ||
327 | char *fwd, *fwd_new = ws->request; | ||
328 | |||
329 | /* Zero terminate for string routines. Normally we'd only overwrite bollocks */ | ||
330 | ws->request[ws->request_size-1] = 0; | ||
331 | |||
332 | /* Find last occurence of the forwarded header */ | ||
333 | do { | ||
334 | fwd = fwd_new; | ||
335 | fwd_new = strcasestr( fwd_new, "\nX-Forwarded-For:" ); | ||
336 | } while( fwd_new ); | ||
337 | |||
338 | /* Skip spaces between : and the ip address */ | ||
339 | if( fwd ) { | ||
340 | fwd += 18; /* sizeof( "\nX-Forwarded-For:" ) */ | ||
341 | while( *fwd == ' ' ) ++fwd; | ||
342 | } | ||
343 | |||
344 | if( fwd && scan_ip6( fwd, proxied_ip ) ) | ||
345 | OT_SETIP( &peer, proxied_ip ); | ||
346 | else | ||
347 | OT_SETIP( &peer, cookie->ip ); | ||
348 | } | ||
349 | #endif | ||
350 | OT_SETIP( &peer, cookie->ip ); | ||
324 | OT_SETPORT( &peer, &port ); | 351 | OT_SETPORT( &peer, &port ); |
325 | OT_PEERFLAG( &peer ) = 0; | 352 | OT_PEERFLAG( &peer ) = 0; |
326 | numwant = 50; | 353 | numwant = 50; |
@@ -18,6 +18,7 @@ | |||
18 | /* Opentracker */ | 18 | /* Opentracker */ |
19 | #include "trackerlogic.h" | 19 | #include "trackerlogic.h" |
20 | #include "ot_mutex.h" | 20 | #include "ot_mutex.h" |
21 | #include "ot_stats.h" | ||
21 | 22 | ||
22 | /* #define MTX_DBG( STRING ) fprintf( stderr, STRING ) */ | 23 | /* #define MTX_DBG( STRING ) fprintf( stderr, STRING ) */ |
23 | #define MTX_DBG( STRING ) | 24 | #define MTX_DBG( STRING ) |
@@ -47,8 +48,10 @@ static int bucket_check( int bucket ) { | |||
47 | 48 | ||
48 | /* See, if bucket is already locked */ | 49 | /* See, if bucket is already locked */ |
49 | for( i=0; i<bucket_locklist_count; ++i ) | 50 | for( i=0; i<bucket_locklist_count; ++i ) |
50 | if( bucket_locklist[ i ] == bucket ) | 51 | if( bucket_locklist[ i ] == bucket ) { |
52 | stats_issue_event( EVENT_BUCKET_LOCKED, 0, 0 ); | ||
51 | return -1; | 53 | return -1; |
54 | } | ||
52 | 55 | ||
53 | return 0; | 56 | return 0; |
54 | } | 57 | } |
@@ -1,7 +1,7 @@ | |||
1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> | 1 | /* This software was written by Dirk Engling <erdgeist@erdgeist.org> |
2 | It is considered beerware. Prost. Skol. Cheers or whatever. | 2 | It is considered beerware. Prost. Skol. Cheers or whatever. |
3 | 3 | ||
4 | $id$ */ | 4 | $id$ */ |
5 | 5 | ||
6 | /* System */ | 6 | /* System */ |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
@@ -50,12 +50,13 @@ static unsigned long long ot_full_scrape_size = 0; | |||
50 | static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; | 50 | static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; |
51 | static unsigned long long ot_renewed[OT_PEER_TIMEOUT]; | 51 | static unsigned long long ot_renewed[OT_PEER_TIMEOUT]; |
52 | static unsigned long long ot_overall_sync_count; | 52 | static unsigned long long ot_overall_sync_count; |
53 | static unsigned long long ot_overall_stall_count; | ||
53 | 54 | ||
54 | static time_t ot_start_time; | 55 | static time_t ot_start_time; |
55 | 56 | ||
56 | #ifdef WANT_LOG_NETWORKS | 57 | #ifdef WANT_LOG_NETWORKS |
57 | #define STATS_NETWORK_NODE_BITWIDTH 8 | 58 | #define STATS_NETWORK_NODE_BITWIDTH 8 |
58 | #define STATS_NETWORK_NODE_MAXDEPTH 3 | 59 | #define STATS_NETWORK_NODE_MAXDEPTH 16 |
59 | 60 | ||
60 | #define STATS_NETWORK_NODE_BITMASK ((1<<STATS_NETWORK_NODE_BITWIDTH)-1) | 61 | #define STATS_NETWORK_NODE_BITMASK ((1<<STATS_NETWORK_NODE_BITWIDTH)-1) |
61 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) | 62 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) |
@@ -68,19 +69,20 @@ union stats_network_node { | |||
68 | 69 | ||
69 | static stats_network_node *stats_network_counters_root = NULL; | 70 | static stats_network_node *stats_network_counters_root = NULL; |
70 | 71 | ||
71 | static int stat_increase_network_count( stats_network_node **node, int depth, uint32_t ip ) { | 72 | static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) { |
72 | int foo = ( ip >> ( 32 - STATS_NETWORK_NODE_BITWIDTH * ( ++depth ) ) ) & STATS_NETWORK_NODE_BITMASK; | 73 | ot_ip6 *_ip = (ot_ip6*)ip; |
73 | 74 | int foo = (*_ip)[depth]; | |
75 | |||
74 | if( !*node ) { | 76 | if( !*node ) { |
75 | *node = malloc( sizeof( stats_network_node ) ); | 77 | *node = malloc( sizeof( stats_network_node ) ); |
76 | if( !*node ) | 78 | if( !*node ) |
77 | return -1; | 79 | return -1; |
78 | memset( *node, 0, sizeof( stats_network_node ) ); | 80 | memset( *node, 0, sizeof( stats_network_node ) ); |
79 | } | 81 | } |
80 | 82 | ||
81 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) | 83 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) |
82 | return stat_increase_network_count( &(*node)->children[ foo ], depth, ip ); | 84 | return stat_increase_network_count( &(*node)->children[ foo ], depth, ip ); |
83 | 85 | ||
84 | (*node)->counters[ foo ]++; | 86 | (*node)->counters[ foo ]++; |
85 | return 0; | 87 | return 0; |
86 | } | 88 | } |
@@ -88,40 +90,40 @@ static int stat_increase_network_count( stats_network_node **node, int depth, ui | |||
88 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { | 90 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { |
89 | int i, rest = 0; | 91 | int i, rest = 0; |
90 | if( !*node ) return 0; | 92 | if( !*node ) return 0; |
91 | 93 | ||
92 | if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) | 94 | if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) |
93 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 95 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
94 | rest += ((*node)->counters[i]>>=shift); | 96 | rest += ((*node)->counters[i]>>=shift); |
95 | return rest; | 97 | return rest; |
96 | } | 98 | } |
97 | 99 | ||
98 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 100 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
99 | stats_network_node **childnode = &(*node)->children[i]; | 101 | stats_network_node **childnode = &(*node)->children[i]; |
100 | int rest_val; | 102 | int rest_val; |
101 | 103 | ||
102 | if( !*childnode ) continue; | 104 | if( !*childnode ) continue; |
103 | 105 | ||
104 | rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); | 106 | rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); |
105 | 107 | ||
106 | if( rest_val ) continue; | 108 | if( rest_val ) continue; |
107 | 109 | ||
108 | free( (*node)->children[i] ); | 110 | free( (*node)->children[i] ); |
109 | (*node)->children[i] = NULL; | 111 | (*node)->children[i] = NULL; |
110 | } | 112 | } |
111 | 113 | ||
112 | return rest; | 114 | return rest; |
113 | } | 115 | } |
114 | 116 | ||
115 | static void stats_get_highscore_networks( stats_network_node *node, int depth, uint32_t node_value, int *scores, uint32_t *networks, int network_count ) { | 117 | static void stats_get_highscore_networks( stats_network_node *node, int depth, uint32_t node_value, int *scores, uint32_t *networks, int network_count ) { |
116 | int i; | 118 | int i; |
117 | 119 | ||
118 | if( !node ) return; | 120 | if( !node ) return; |
119 | 121 | ||
120 | if( !depth++ ) { | 122 | if( !depth++ ) { |
121 | memset( scores, 0, sizeof( *scores ) * network_count ); | 123 | memset( scores, 0, sizeof( *scores ) * network_count ); |
122 | memset( networks, 0, sizeof( *networks ) * network_count ); | 124 | memset( networks, 0, sizeof( *networks ) * network_count ); |
123 | } | 125 | } |
124 | 126 | ||
125 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { | 127 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { |
126 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 128 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) |
127 | if( node->children[i] ) | 129 | if( node->children[i] ) |
@@ -130,15 +132,15 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, u | |||
130 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 132 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
131 | int j=1; | 133 | int j=1; |
132 | if( node->counters[i] <= scores[0] ) continue; | 134 | if( node->counters[i] <= scores[0] ) continue; |
133 | 135 | ||
134 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; | 136 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; |
135 | --j; | 137 | --j; |
136 | 138 | ||
137 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); | 139 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); |
138 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); | 140 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); |
139 | scores[ j ] = node->counters[ i ]; | 141 | scores[ j ] = node->counters[ i ]; |
140 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); | 142 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); |
141 | } | 143 | } |
142 | } | 144 | } |
143 | 145 | ||
144 | static size_t stats_return_busy_networks( char * reply ) { | 146 | static size_t stats_return_busy_networks( char * reply ) { |
@@ -146,17 +148,31 @@ static size_t stats_return_busy_networks( char * reply ) { | |||
146 | int scores[16]; | 148 | int scores[16]; |
147 | int i; | 149 | int i; |
148 | char * r = reply; | 150 | char * r = reply; |
149 | 151 | ||
150 | stats_get_highscore_networks( stats_network_counters_root, 0, 0, scores, networks, 16 ); | 152 | stats_get_highscore_networks( stats_network_counters_root, 0, 0, scores, networks, 16 ); |
151 | 153 | ||
152 | for( i=15; i>=0; --i) | 154 | for( i=15; i>=0; --i) |
153 | r += sprintf( r, "%08i: %d.%d.%d.0/24\n", scores[i], (networks[i]>>24)&0xff, (networks[i]>>16)&0xff, (networks[i]>>8)&0xff ); | 155 | r += sprintf( r, "%08i: %d.%d.%d.0/24\n", scores[i], (networks[i]>>24)&0xff, (networks[i]>>16)&0xff, (networks[i]>>8)&0xff ); |
154 | 156 | ||
155 | return r - reply; | 157 | return r - reply; |
156 | } | 158 | } |
157 | 159 | ||
158 | #endif | 160 | #endif |
159 | 161 | ||
162 | typedef struct { | ||
163 | unsigned long long torrent_count; | ||
164 | unsigned long long peer_count; | ||
165 | unsigned long long seed_count; | ||
166 | } torrent_stats; | ||
167 | |||
168 | static int torrent_statter( ot_torrent *torrent, uintptr_t data ) { | ||
169 | torrent_stats *stats = (torrent_stats*)data; | ||
170 | stats->torrent_count++; | ||
171 | stats->peer_count += torrent->peer_list->peer_count; | ||
172 | stats->seed_count += torrent->peer_list->seed_count; | ||
173 | return 0; | ||
174 | } | ||
175 | |||
160 | /* Converter function from memory to human readable hex strings */ | 176 | /* Converter function from memory to human readable hex strings */ |
161 | 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;} | 177 | 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;} |
162 | 178 | ||
@@ -168,10 +184,10 @@ size_t stats_top10_txt( char * reply ) { | |||
168 | ot_record top10s[10], top10c[10]; | 184 | ot_record top10s[10], top10c[10]; |
169 | char *r = reply, hex_out[42]; | 185 | char *r = reply, hex_out[42]; |
170 | int idx, bucket; | 186 | int idx, bucket; |
171 | 187 | ||
172 | byte_zero( top10s, sizeof( top10s ) ); | 188 | byte_zero( top10s, sizeof( top10s ) ); |
173 | byte_zero( top10c, sizeof( top10c ) ); | 189 | byte_zero( top10c, sizeof( top10c ) ); |
174 | 190 | ||
175 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 191 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { |
176 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 192 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); |
177 | for( j=0; j<torrents_list->size; ++j ) { | 193 | for( j=0; j<torrents_list->size; ++j ) { |
@@ -193,7 +209,7 @@ size_t stats_top10_txt( char * reply ) { | |||
193 | if( !g_opentracker_running ) | 209 | if( !g_opentracker_running ) |
194 | return 0; | 210 | return 0; |
195 | } | 211 | } |
196 | 212 | ||
197 | r += sprintf( r, "Top 10 torrents by peers:\n" ); | 213 | r += sprintf( r, "Top 10 torrents by peers:\n" ); |
198 | for( idx=0; idx<10; ++idx ) | 214 | for( idx=0; idx<10; ++idx ) |
199 | if( top10c[idx].torrent ) | 215 | if( top10c[idx].torrent ) |
@@ -202,31 +218,31 @@ size_t stats_top10_txt( char * reply ) { | |||
202 | for( idx=0; idx<10; ++idx ) | 218 | for( idx=0; idx<10; ++idx ) |
203 | if( top10s[idx].torrent ) | 219 | if( top10s[idx].torrent ) |
204 | r += sprintf( r, "\t%zd\t%s\n", top10s[idx].val, to_hex( hex_out, top10s[idx].torrent->hash) ); | 220 | r += sprintf( r, "\t%zd\t%s\n", top10s[idx].val, to_hex( hex_out, top10s[idx].torrent->hash) ); |
205 | 221 | ||
206 | return r - reply; | 222 | return r - reply; |
207 | } | 223 | } |
208 | 224 | ||
209 | /* This function collects 4096 /24s in 4096 possible | 225 | /* This function collects 4096 /24s in 4096 possible |
210 | malloc blocks | 226 | malloc blocks |
211 | */ | 227 | */ |
212 | static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) { | 228 | static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) { |
213 | 229 | ||
214 | #define NUM_TOPBITS 12 | 230 | #define NUM_TOPBITS 12 |
215 | #define NUM_LOWBITS (24-NUM_TOPBITS) | 231 | #define NUM_LOWBITS (24-NUM_TOPBITS) |
216 | #define NUM_BUFS (1<<NUM_TOPBITS) | 232 | #define NUM_BUFS (1<<NUM_TOPBITS) |
217 | #define NUM_S24S (1<<NUM_LOWBITS) | 233 | #define NUM_S24S (1<<NUM_LOWBITS) |
218 | #define MSK_S24S (NUM_S24S-1) | 234 | #define MSK_S24S (NUM_S24S-1) |
219 | 235 | ||
220 | uint32_t *counts[ NUM_BUFS ]; | 236 | uint32_t *counts[ NUM_BUFS ]; |
221 | uint32_t slash24s[amount*2]; /* first dword amount, second dword subnet */ | 237 | uint32_t slash24s[amount*2]; /* first dword amount, second dword subnet */ |
222 | size_t i, j, k, l; | 238 | size_t i, j, k, l; |
223 | char *r = reply; | 239 | char *r = reply; |
224 | 240 | ||
225 | byte_zero( counts, sizeof( counts ) ); | 241 | byte_zero( counts, sizeof( counts ) ); |
226 | byte_zero( slash24s, amount * 2 * sizeof(uint32_t) ); | 242 | byte_zero( slash24s, amount * 2 * sizeof(uint32_t) ); |
227 | 243 | ||
228 | r += sprintf( r, "Stats for all /24s with more than %u announced torrents:\n\n", thresh ); | 244 | r += sprintf( r, "Stats for all /24s with more than %u announced torrents:\n\n", thresh ); |
229 | 245 | ||
230 | #if 0 | 246 | #if 0 |
231 | /* XXX: TOOD: Doesn't work yet with new peer storage model */ | 247 | /* XXX: TOOD: Doesn't work yet with new peer storage model */ |
232 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 248 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { |
@@ -257,7 +273,7 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) | |||
257 | goto bailout_cleanup; | 273 | goto bailout_cleanup; |
258 | } | 274 | } |
259 | #endif | 275 | #endif |
260 | 276 | ||
261 | k = l = 0; /* Debug: count allocated bufs */ | 277 | k = l = 0; /* Debug: count allocated bufs */ |
262 | for( i=0; i < NUM_BUFS; ++i ) { | 278 | for( i=0; i < NUM_BUFS; ++i ) { |
263 | uint32_t *count = counts[i]; | 279 | uint32_t *count = counts[i]; |
@@ -281,28 +297,28 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh ) | |||
281 | } | 297 | } |
282 | free( count ); | 298 | free( count ); |
283 | } | 299 | } |
284 | 300 | ||
285 | r += sprintf( r, "Allocated bufs: %zd, used s24s: %zd\n", k, l ); | 301 | r += sprintf( r, "Allocated bufs: %zd, used s24s: %zd\n", k, l ); |
286 | 302 | ||
287 | for( i=0; i < amount; ++i ) | 303 | for( i=0; i < amount; ++i ) |
288 | if( slash24s[ 2*i ] >= thresh ) { | 304 | if( slash24s[ 2*i ] >= thresh ) { |
289 | uint32_t ip = slash24s[ 2*i +1 ]; | 305 | uint32_t ip = slash24s[ 2*i +1 ]; |
290 | r += sprintf( r, "% 10ld %d.%d.%d.0/24\n", (long)slash24s[ 2*i ], (int)(ip >> 16), (int)(255 & ( ip >> 8 )), (int)(ip & 255) ); | 306 | r += sprintf( r, "% 10ld %d.%d.%d.0/24\n", (long)slash24s[ 2*i ], (int)(ip >> 16), (int)(255 & ( ip >> 8 )), (int)(ip & 255) ); |
291 | } | 307 | } |
292 | 308 | ||
293 | return r - reply; | 309 | return r - reply; |
294 | 310 | ||
295 | for( i=0; i < NUM_BUFS; ++i ) | 311 | for( i=0; i < NUM_BUFS; ++i ) |
296 | free( counts[i] ); | 312 | free( counts[i] ); |
297 | 313 | ||
298 | return 0; | 314 | return 0; |
299 | } | 315 | } |
300 | 316 | ||
301 | /* | 317 | /* |
302 | struct { | 318 | struct { |
303 | size_t size | 319 | size_t size |
304 | size_t space | 320 | size_t space |
305 | size_t count | 321 | size_t count |
306 | } | 322 | } |
307 | */ | 323 | */ |
308 | 324 | ||
@@ -313,105 +329,95 @@ static unsigned long events_per_time( unsigned long long events, time_t t ) { | |||
313 | static size_t stats_connections_mrtg( char * reply ) { | 329 | static size_t stats_connections_mrtg( char * reply ) { |
314 | ot_time t = time( NULL ) - ot_start_time; | 330 | ot_time t = time( NULL ) - ot_start_time; |
315 | return sprintf( reply, | 331 | return sprintf( reply, |
316 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", | 332 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", |
317 | ot_overall_tcp_connections+ot_overall_udp_connections, | 333 | ot_overall_tcp_connections+ot_overall_udp_connections, |
318 | ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, | 334 | ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, |
319 | (int)t, | 335 | (int)t, |
320 | (int)(t / 3600), | 336 | (int)(t / 3600), |
321 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), | 337 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), |
322 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | 338 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) |
323 | ); | 339 | ); |
324 | } | 340 | } |
325 | 341 | ||
326 | static size_t stats_udpconnections_mrtg( char * reply ) { | 342 | static size_t stats_udpconnections_mrtg( char * reply ) { |
327 | ot_time t = time( NULL ) - ot_start_time; | 343 | ot_time t = time( NULL ) - ot_start_time; |
328 | return sprintf( reply, | 344 | return sprintf( reply, |
329 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", | 345 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", |
330 | ot_overall_udp_connections, | 346 | ot_overall_udp_connections, |
331 | ot_overall_udp_successfulannounces+ot_overall_udp_connects, | 347 | ot_overall_udp_successfulannounces+ot_overall_udp_connects, |
332 | (int)t, | 348 | (int)t, |
333 | (int)(t / 3600), | 349 | (int)(t / 3600), |
334 | events_per_time( ot_overall_udp_connections, t ), | 350 | events_per_time( ot_overall_udp_connections, t ), |
335 | events_per_time( ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | 351 | events_per_time( ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) |
336 | ); | 352 | ); |
337 | } | 353 | } |
338 | 354 | ||
339 | static size_t stats_tcpconnections_mrtg( char * reply ) { | 355 | static size_t stats_tcpconnections_mrtg( char * reply ) { |
340 | time_t t = time( NULL ) - ot_start_time; | 356 | time_t t = time( NULL ) - ot_start_time; |
341 | return sprintf( reply, | 357 | return sprintf( reply, |
342 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", | 358 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", |
343 | ot_overall_tcp_connections, | 359 | ot_overall_tcp_connections, |
344 | ot_overall_tcp_successfulannounces, | 360 | ot_overall_tcp_successfulannounces, |
345 | (int)t, | 361 | (int)t, |
346 | (int)(t / 3600), | 362 | (int)(t / 3600), |
347 | events_per_time( ot_overall_tcp_connections, t ), | 363 | events_per_time( ot_overall_tcp_connections, t ), |
348 | events_per_time( ot_overall_tcp_successfulannounces, t ) | 364 | events_per_time( ot_overall_tcp_successfulannounces, t ) |
349 | ); | 365 | ); |
350 | } | 366 | } |
351 | 367 | ||
352 | static size_t stats_scrape_mrtg( char * reply ) { | 368 | static size_t stats_scrape_mrtg( char * reply ) { |
353 | time_t t = time( NULL ) - ot_start_time; | 369 | time_t t = time( NULL ) - ot_start_time; |
354 | return sprintf( reply, | 370 | return sprintf( reply, |
355 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)", | 371 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)", |
356 | ot_overall_tcp_successfulscrapes, | 372 | ot_overall_tcp_successfulscrapes, |
357 | ot_overall_udp_successfulscrapes, | 373 | ot_overall_udp_successfulscrapes, |
358 | (int)t, | 374 | (int)t, |
359 | (int)(t / 3600), | 375 | (int)(t / 3600), |
360 | events_per_time( (ot_overall_tcp_successfulscrapes+ot_overall_udp_successfulscrapes), t ) | 376 | events_per_time( (ot_overall_tcp_successfulscrapes+ot_overall_udp_successfulscrapes), t ) |
361 | ); | 377 | ); |
362 | } | 378 | } |
363 | 379 | ||
364 | static size_t stats_fullscrapes_mrtg( char * reply ) { | 380 | static size_t stats_fullscrapes_mrtg( char * reply ) { |
365 | ot_time t = time( NULL ) - ot_start_time; | 381 | ot_time t = time( NULL ) - ot_start_time; |
366 | return sprintf( reply, | 382 | return sprintf( reply, |
367 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.", | 383 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.", |
368 | ot_full_scrape_count * 1000, | 384 | ot_full_scrape_count * 1000, |
369 | ot_full_scrape_size, | 385 | ot_full_scrape_size, |
370 | (int)t, | 386 | (int)t, |
371 | (int)(t / 3600), | 387 | (int)(t / 3600), |
372 | events_per_time( ot_full_scrape_count, t ), | 388 | events_per_time( ot_full_scrape_count, t ), |
373 | events_per_time( ot_full_scrape_size, t ) | 389 | events_per_time( ot_full_scrape_size, t ) |
374 | ); | 390 | ); |
375 | } | 391 | } |
376 | 392 | ||
377 | static size_t stats_peers_mrtg( char * reply ) { | 393 | static size_t stats_peers_mrtg( char * reply ) { |
378 | size_t torrent_count = 0, peer_count = 0, seed_count = 0, j; | 394 | torrent_stats stats = {0,0,0}; |
379 | int bucket; | 395 | |
380 | 396 | iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); | |
381 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 397 | |
382 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 398 | return sprintf( reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker", |
383 | torrent_count += torrents_list->size; | 399 | stats.peer_count, |
384 | for( j=0; j<torrents_list->size; ++j ) { | 400 | stats.seed_count, |
385 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; | 401 | stats.torrent_count |
386 | peer_count += peer_list->peer_count; seed_count += peer_list->seed_count; | 402 | ); |
387 | } | ||
388 | mutex_bucket_unlock( bucket, 0 ); | ||
389 | if( !g_opentracker_running ) | ||
390 | return 0; | ||
391 | } | ||
392 | return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", | ||
393 | peer_count, | ||
394 | seed_count, | ||
395 | torrent_count | ||
396 | ); | ||
397 | } | 403 | } |
398 | 404 | ||
399 | static size_t stats_startstop_mrtg( char * reply ) | 405 | static size_t stats_startstop_mrtg( char * reply ) |
400 | { | 406 | { |
401 | size_t torrent_count = mutex_get_torrent_count(); | 407 | size_t torrent_count = mutex_get_torrent_count(); |
402 | 408 | ||
403 | return sprintf( reply, "%zd\n%zd\nopentracker handling %zd torrents\nopentracker", | 409 | return sprintf( reply, "%zd\n%zd\nopentracker handling %zd torrents\nopentracker", |
404 | (size_t)0, | 410 | (size_t)0, |
405 | (size_t)0, | 411 | (size_t)0, |
406 | torrent_count | 412 | torrent_count |
407 | ); | 413 | ); |
408 | } | 414 | } |
409 | 415 | ||
410 | static size_t stats_toraddrem_mrtg( char * reply ) | 416 | static size_t stats_toraddrem_mrtg( char * reply ) |
411 | { | 417 | { |
412 | size_t peer_count = 0, j; | 418 | size_t peer_count = 0, j; |
413 | int bucket; | 419 | int bucket; |
414 | 420 | ||
415 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) | 421 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) |
416 | { | 422 | { |
417 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 423 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); |
@@ -424,53 +430,63 @@ static size_t stats_toraddrem_mrtg( char * reply ) | |||
424 | if( !g_opentracker_running ) | 430 | if( !g_opentracker_running ) |
425 | return 0; | 431 | return 0; |
426 | } | 432 | } |
427 | 433 | ||
428 | return sprintf( reply, "%zd\n%zd\nopentracker handling %zd peers\nopentracker", | 434 | return sprintf( reply, "%zd\n%zd\nopentracker handling %zd peers\nopentracker", |
429 | (size_t)0, | 435 | (size_t)0, |
430 | (size_t)0, | 436 | (size_t)0, |
431 | peer_count | 437 | peer_count |
432 | ); | 438 | ); |
433 | } | 439 | } |
434 | 440 | ||
435 | static size_t stats_torrents_mrtg( char * reply ) | 441 | static size_t stats_torrents_mrtg( char * reply ) |
436 | { | 442 | { |
437 | size_t torrent_count = mutex_get_torrent_count(); | 443 | size_t torrent_count = mutex_get_torrent_count(); |
438 | 444 | ||
439 | return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", | 445 | return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", |
440 | torrent_count, | 446 | torrent_count, |
441 | (size_t)0, | 447 | (size_t)0, |
442 | torrent_count | 448 | torrent_count |
443 | ); | 449 | ); |
444 | } | 450 | } |
445 | 451 | ||
446 | static size_t stats_httperrors_txt ( char * reply ) { | 452 | static size_t stats_httperrors_txt ( char * reply ) { |
447 | return sprintf( reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n", | 453 | return sprintf( reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n", |
448 | ot_failed_request_counts[0], ot_failed_request_counts[1], ot_failed_request_counts[2], | 454 | ot_failed_request_counts[0], ot_failed_request_counts[1], ot_failed_request_counts[2], |
449 | ot_failed_request_counts[3], ot_failed_request_counts[4], ot_failed_request_counts[5], | 455 | ot_failed_request_counts[3], ot_failed_request_counts[4], ot_failed_request_counts[5], |
450 | ot_failed_request_counts[6] ); | 456 | ot_failed_request_counts[6] ); |
451 | } | 457 | } |
452 | 458 | ||
453 | static size_t stats_return_renew_bucket( char * reply ) { | 459 | static size_t stats_return_renew_bucket( char * reply ) { |
454 | char *r = reply; | 460 | char *r = reply; |
455 | int i; | 461 | int i; |
456 | 462 | ||
457 | for( i=0; i<OT_PEER_TIMEOUT; ++i ) | 463 | for( i=0; i<OT_PEER_TIMEOUT; ++i ) |
458 | r+=sprintf(r,"%02i %llu\n", i, ot_renewed[i] ); | 464 | r+=sprintf(r,"%02i %llu\n", i, ot_renewed[i] ); |
459 | return r - reply; | 465 | return r - reply; |
460 | } | 466 | } |
461 | 467 | ||
462 | static size_t stats_return_sync_mrtg( char * reply ) | 468 | static size_t stats_return_sync_mrtg( char * reply ) { |
463 | { | ||
464 | ot_time t = time( NULL ) - ot_start_time; | 469 | ot_time t = time( NULL ) - ot_start_time; |
465 | return sprintf( reply, | 470 | return sprintf( reply, |
466 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", | 471 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", |
467 | ot_overall_sync_count, | 472 | ot_overall_sync_count, |
468 | 0LL, | 473 | 0LL, |
469 | (int)t, | 474 | (int)t, |
470 | (int)(t / 3600), | 475 | (int)(t / 3600), |
471 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), | 476 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), |
472 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | 477 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) |
473 | ); | 478 | ); |
479 | } | ||
480 | |||
481 | static size_t stats_return_everything( char * reply ) { | ||
482 | char * r = reply; | ||
483 | r += sprintf( r, "<stats>\n" ); | ||
484 | r += sprintf( r, " <uptime>%llu</uptime>\n", (unsigned long long)(time( NULL ) - ot_start_time) ); | ||
485 | r += sprintf( r, " <torrents>%zd</torrents>\n", mutex_get_torrent_count() ); | ||
486 | /* r += sprintf( r, " <peers>%llu</peers>\n", ); */ | ||
487 | |||
488 | r += sprintf( reply, "</stats>" ); | ||
489 | return r - reply; | ||
474 | } | 490 | } |
475 | 491 | ||
476 | extern const char | 492 | extern const char |
@@ -480,9 +496,9 @@ extern const char | |||
480 | 496 | ||
481 | size_t stats_return_tracker_version( char *reply ) { | 497 | size_t stats_return_tracker_version( char *reply ) { |
482 | return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s", | 498 | return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s", |
483 | g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c, | 499 | g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c, |
484 | g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_udp_c, g_version_vector_c, | 500 | g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_udp_c, g_version_vector_c, |
485 | g_version_scan_urlencoded_query_c, g_version_trackerlogic_c, g_version_livesync_c ); | 501 | g_version_scan_urlencoded_query_c, g_version_trackerlogic_c, g_version_livesync_c ); |
486 | } | 502 | } |
487 | 503 | ||
488 | size_t return_stats_for_tracker( char *reply, int mode, int format ) { | 504 | size_t return_stats_for_tracker( char *reply, int mode, int format ) { |
@@ -509,7 +525,7 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) { | |||
509 | case TASK_STATS_RENEW: | 525 | case TASK_STATS_RENEW: |
510 | return stats_return_renew_bucket( reply ); | 526 | return stats_return_renew_bucket( reply ); |
511 | case TASK_STATS_SYNCS: | 527 | case TASK_STATS_SYNCS: |
512 | return stats_return_sync_mrtg( reply ); | 528 | return stats_return_sync_mrtg( reply ); |
513 | #ifdef WANT_LOG_NETWORKS | 529 | #ifdef WANT_LOG_NETWORKS |
514 | case TASK_STATS_BUSY_NETWORKS: | 530 | case TASK_STATS_BUSY_NETWORKS: |
515 | return stats_return_busy_networks( reply ); | 531 | return stats_return_busy_networks( reply ); |
@@ -521,12 +537,12 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) { | |||
521 | 537 | ||
522 | static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { | 538 | static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { |
523 | char *r; | 539 | char *r; |
524 | 540 | ||
525 | *iovec_entries = 0; | 541 | *iovec_entries = 0; |
526 | *iovector = NULL; | 542 | *iovector = NULL; |
527 | if( !( r = iovec_increase( iovec_entries, iovector, OT_STATS_TMPSIZE ) ) ) | 543 | if( !( r = iovec_increase( iovec_entries, iovector, OT_STATS_TMPSIZE ) ) ) |
528 | return; | 544 | return; |
529 | 545 | ||
530 | switch( mode & TASK_TASK_MASK ) { | 546 | switch( mode & TASK_TASK_MASK ) { |
531 | case TASK_STATS_TORRENTS: r += stats_torrents_mrtg( r ); break; | 547 | case TASK_STATS_TORRENTS: r += stats_torrents_mrtg( r ); break; |
532 | case TASK_STATS_PEERS: r += stats_peers_mrtg( r ); break; | 548 | case TASK_STATS_PEERS: r += stats_peers_mrtg( r ); break; |
@@ -560,26 +576,26 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event | |||
560 | ot_full_scrape_size += event_data; | 576 | ot_full_scrape_size += event_data; |
561 | break; | 577 | break; |
562 | case EVENT_FULLSCRAPE_REQUEST: | 578 | case EVENT_FULLSCRAPE_REQUEST: |
563 | { | 579 | { |
564 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ | 580 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ |
565 | char _debug[512]; | 581 | char _debug[512]; |
566 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); | 582 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); |
567 | off += fmt_ip6( _debug+off, *ip ); | 583 | off += fmt_ip6( _debug+off, *ip ); |
568 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | 584 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); |
569 | write( 2, _debug, off ); | 585 | write( 2, _debug, off ); |
570 | ot_full_scrape_request_count++; | 586 | ot_full_scrape_request_count++; |
571 | } | 587 | } |
572 | break; | 588 | break; |
573 | case EVENT_FULLSCRAPE_REQUEST_GZIP: | 589 | case EVENT_FULLSCRAPE_REQUEST_GZIP: |
574 | { | 590 | { |
575 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ | 591 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ |
576 | char _debug[512]; | 592 | char _debug[512]; |
577 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); | 593 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); |
578 | off += fmt_ip6(_debug+off, *ip ); | 594 | off += fmt_ip6(_debug+off, *ip ); |
579 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | 595 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); |
580 | write( 2, _debug, off ); | 596 | write( 2, _debug, off ); |
581 | ot_full_scrape_request_count++; | 597 | ot_full_scrape_request_count++; |
582 | } | 598 | } |
583 | break; | 599 | break; |
584 | case EVENT_FAILED: | 600 | case EVENT_FAILED: |
585 | ot_failed_request_counts[event_data]++; | 601 | ot_failed_request_counts[event_data]++; |
@@ -590,6 +606,9 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event | |||
590 | case EVENT_SYNC: | 606 | case EVENT_SYNC: |
591 | ot_overall_sync_count+=event_data; | 607 | ot_overall_sync_count+=event_data; |
592 | break; | 608 | break; |
609 | case EVENT_BUCKET_LOCKED: | ||
610 | ot_overall_stall_count++; | ||
611 | break; | ||
593 | default: | 612 | default: |
594 | break; | 613 | break; |
595 | } | 614 | } |
@@ -598,9 +617,9 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event | |||
598 | static void * stats_worker( void * args ) { | 617 | static void * stats_worker( void * args ) { |
599 | int iovec_entries; | 618 | int iovec_entries; |
600 | struct iovec *iovector; | 619 | struct iovec *iovector; |
601 | 620 | ||
602 | args = args; | 621 | args = args; |
603 | 622 | ||
604 | while( 1 ) { | 623 | while( 1 ) { |
605 | ot_tasktype tasktype = TASK_STATS; | 624 | ot_tasktype tasktype = TASK_STATS; |
606 | ot_taskid taskid = mutex_workqueue_poptask( &tasktype ); | 625 | ot_taskid taskid = mutex_workqueue_poptask( &tasktype ); |
@@ -17,7 +17,8 @@ typedef enum { | |||
17 | EVENT_FULLSCRAPE_REQUEST, | 17 | EVENT_FULLSCRAPE_REQUEST, |
18 | EVENT_FULLSCRAPE_REQUEST_GZIP, | 18 | EVENT_FULLSCRAPE_REQUEST_GZIP, |
19 | EVENT_FULLSCRAPE, /* TCP only */ | 19 | EVENT_FULLSCRAPE, /* TCP only */ |
20 | EVENT_FAILED | 20 | EVENT_FAILED, |
21 | EVENT_BUCKET_LOCKED | ||
21 | } ot_status_event; | 22 | } ot_status_event; |
22 | 23 | ||
23 | enum { | 24 | enum { |
diff --git a/trackerlogic.c b/trackerlogic.c index 249a2a0..8ebaa46 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
@@ -337,6 +337,23 @@ size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROTO | |||
337 | return reply_size; | 337 | return reply_size; |
338 | } | 338 | } |
339 | 339 | ||
340 | void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data ) { | ||
341 | int bucket; | ||
342 | size_t j; | ||
343 | |||
344 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | ||
345 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | ||
346 | ot_torrent *torrents = (ot_torrent*)(torrents_list->data); | ||
347 | |||
348 | for( j=0; j<torrents_list->size; ++j ) | ||
349 | if( for_each( torrents + j, data ) ) | ||
350 | break; | ||
351 | |||
352 | mutex_bucket_unlock( bucket, 0 ); | ||
353 | if( !g_opentracker_running ) return; | ||
354 | } | ||
355 | } | ||
356 | |||
340 | void exerr( char * message ) { | 357 | void exerr( char * message ) { |
341 | fprintf( stderr, "%s\n", message ); | 358 | fprintf( stderr, "%s\n", message ); |
342 | exit( 111 ); | 359 | exit( 111 ); |
@@ -358,7 +375,7 @@ void trackerlogic_init( ) { | |||
358 | void trackerlogic_deinit( void ) { | 375 | void trackerlogic_deinit( void ) { |
359 | int bucket, delta_torrentcount = 0; | 376 | int bucket, delta_torrentcount = 0; |
360 | size_t j; | 377 | size_t j; |
361 | 378 | ||
362 | /* Free all torrents... */ | 379 | /* Free all torrents... */ |
363 | for(bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 380 | for(bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { |
364 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 381 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); |
diff --git a/trackerlogic.h b/trackerlogic.h index 69deddd..ce3feb1 100644 --- a/trackerlogic.h +++ b/trackerlogic.h | |||
@@ -148,6 +148,9 @@ size_t remove_peer_from_torrent( ot_hash hash, ot_peer *peer, char *reply, PROT | |||
148 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); | 148 | size_t return_tcp_scrape_for_torrent( ot_hash *hash, int amount, char *reply ); |
149 | size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply ); | 149 | size_t return_udp_scrape_for_torrent( ot_hash hash, char *reply ); |
150 | 150 | ||
151 | /* torrent iterator */ | ||
152 | void iterate_all_torrents( int (*for_each)( ot_torrent* torrent, uintptr_t data ), uintptr_t data ); | ||
153 | |||
151 | /* Helper, before it moves to its own object */ | 154 | /* Helper, before it moves to its own object */ |
152 | void free_peerlist( ot_peerlist *peer_list ); | 155 | void free_peerlist( ot_peerlist *peer_list ); |
153 | 156 | ||