diff options
Diffstat (limited to 'ot_stats.c')
-rw-r--r-- | ot_stats.c | 63 |
1 files changed, 38 insertions, 25 deletions
@@ -57,11 +57,15 @@ static time_t ot_start_time; | |||
57 | 57 | ||
58 | #ifdef WANT_LOG_NETWORKS | 58 | #ifdef WANT_LOG_NETWORKS |
59 | #define STATS_NETWORK_NODE_BITWIDTH 8 | 59 | #define STATS_NETWORK_NODE_BITWIDTH 8 |
60 | #define STATS_NETWORK_NODE_MAXDEPTH 16 | ||
61 | |||
62 | #define STATS_NETWORK_NODE_BITMASK ((1<<STATS_NETWORK_NODE_BITWIDTH)-1) | ||
63 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) | 60 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) |
64 | 61 | ||
62 | #ifdef WANT_V6 | ||
63 | #define STATS_NETWORK_NODE_MAXDEPTH (48/8-1) | ||
64 | #else | ||
65 | #define STATS_NETWORK_NODE_MAXDEPTH (12+24/8-1) | ||
66 | #endif | ||
67 | |||
68 | |||
65 | typedef union stats_network_node stats_network_node; | 69 | typedef union stats_network_node stats_network_node; |
66 | union stats_network_node { | 70 | union stats_network_node { |
67 | int counters[STATS_NETWORK_NODE_COUNT]; | 71 | int counters[STATS_NETWORK_NODE_COUNT]; |
@@ -71,9 +75,9 @@ union stats_network_node { | |||
71 | static stats_network_node *stats_network_counters_root = NULL; | 75 | static stats_network_node *stats_network_counters_root = NULL; |
72 | 76 | ||
73 | static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) { | 77 | static int stat_increase_network_count( stats_network_node **node, int depth, uintptr_t ip ) { |
74 | ot_ip6 *_ip = (ot_ip6*)ip; | 78 | uint8_t *_ip = (uint8_t*)ip; |
75 | int foo = (*_ip)[depth]; | 79 | int foo = _ip[++depth]; |
76 | 80 | ||
77 | if( !*node ) { | 81 | if( !*node ) { |
78 | *node = malloc( sizeof( stats_network_node ) ); | 82 | *node = malloc( sizeof( stats_network_node ) ); |
79 | if( !*node ) | 83 | if( !*node ) |
@@ -91,31 +95,32 @@ static int stat_increase_network_count( stats_network_node **node, int depth, ui | |||
91 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { | 95 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { |
92 | int i, rest = 0; | 96 | int i, rest = 0; |
93 | if( !*node ) return 0; | 97 | if( !*node ) return 0; |
94 | 98 | ||
95 | if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) | 99 | if( ++depth == STATS_NETWORK_NODE_MAXDEPTH ) |
96 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 100 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
97 | rest += ((*node)->counters[i]>>=shift); | 101 | rest += ((*node)->counters[i]>>=shift); |
98 | return rest; | 102 | return rest; |
99 | } | 103 | } |
100 | 104 | ||
101 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 105 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
102 | stats_network_node **childnode = &(*node)->children[i]; | 106 | stats_network_node **childnode = &(*node)->children[i]; |
103 | int rest_val; | 107 | int rest_val; |
104 | 108 | ||
105 | if( !*childnode ) continue; | 109 | if( !*childnode ) continue; |
106 | 110 | ||
107 | rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); | 111 | rest += rest_val = stats_shift_down_network_count( childnode, depth, shift ); |
108 | 112 | ||
109 | if( rest_val ) continue; | 113 | if( rest_val ) continue; |
110 | 114 | ||
111 | free( (*node)->children[i] ); | 115 | free( (*node)->children[i] ); |
112 | (*node)->children[i] = NULL; | 116 | (*node)->children[i] = NULL; |
113 | } | 117 | } |
114 | 118 | ||
115 | return rest; | 119 | return rest; |
116 | } | 120 | } |
117 | 121 | ||
118 | static void stats_get_highscore_networks( stats_network_node *node, int depth, uint32_t node_value, int *scores, uint32_t *networks, int network_count ) { | 122 | static void stats_get_highscore_networks( stats_network_node *node, int depth, ot_ip6 node_value, int *scores, ot_ip6 *networks, int network_count ) { |
123 | uint8_t *_node_value = (uint8_t*)node_value; | ||
119 | int i; | 124 | int i; |
120 | 125 | ||
121 | if( !node ) return; | 126 | if( !node ) return; |
@@ -127,34 +132,41 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, u | |||
127 | 132 | ||
128 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { | 133 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) { |
129 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 134 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) |
130 | if( node->children[i] ) | 135 | if( node->children[i] ) { |
131 | stats_get_highscore_networks( node->children[i], depth, node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ), scores, networks, network_count ); | 136 | _node_value[depth] = i; |
137 | stats_get_highscore_networks( node->children[i], depth, node_value, scores, networks, network_count ); | ||
138 | } | ||
132 | } else | 139 | } else |
133 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 140 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { |
134 | int j=1; | 141 | int j=1; |
135 | if( node->counters[i] <= scores[0] ) continue; | 142 | if( node->counters[i] <= scores[0] ) continue; |
136 | 143 | ||
144 | _node_value[depth] = i; | ||
137 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; | 145 | while( (j<network_count) && (node->counters[i]>scores[j] ) ) ++j; |
138 | --j; | 146 | --j; |
139 | 147 | ||
140 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); | 148 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); |
141 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); | 149 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); |
142 | scores[ j ] = node->counters[ i ]; | 150 | scores[ j ] = node->counters[ i ]; |
143 | networks[ j ] = node_value | ( i << ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ); | 151 | memcpy( networks + j, _node_value, sizeof( *networks ) ); |
144 | } | 152 | } |
145 | } | 153 | } |
146 | 154 | ||
147 | static size_t stats_return_busy_networks( char * reply ) { | 155 | static size_t stats_return_busy_networks( char * reply ) { |
148 | uint32_t networks[16]; | 156 | ot_ip6 networks[256]; |
149 | int scores[16]; | 157 | ot_ip6 node_value; |
158 | int scores[256]; | ||
150 | int i; | 159 | int i; |
151 | char * r = reply; | 160 | char * r = reply; |
161 | |||
162 | stats_get_highscore_networks( stats_network_counters_root, 0, node_value, scores, networks, 256 ); | ||
152 | 163 | ||
153 | stats_get_highscore_networks( stats_network_counters_root, 0, 0, scores, networks, 16 ); | 164 | for( i=255; i>=0; --i) { |
154 | 165 | r += sprintf( r, "%08i: ", scores[i] ); | |
155 | for( i=15; i>=0; --i) | 166 | r += fmt_ip6c( r, networks[i] ); |
156 | r += sprintf( r, "%08i: %d.%d.%d.0/24\n", scores[i], (networks[i]>>24)&0xff, (networks[i]>>16)&0xff, (networks[i]>>8)&0xff ); | 167 | *r++ = '\n'; |
157 | 168 | } | |
169 | |||
158 | return r - reply; | 170 | return r - reply; |
159 | } | 171 | } |
160 | 172 | ||
@@ -442,6 +454,7 @@ static size_t stats_return_everything( char * reply ) { | |||
442 | 454 | ||
443 | iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); | 455 | iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); |
444 | 456 | ||
457 | r += sprintf( r, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" ); | ||
445 | r += sprintf( r, "<version>\n" ); r += stats_return_tracker_version( r ); r += sprintf( r, "</version>\n" ); | 458 | r += sprintf( r, "<version>\n" ); r += stats_return_tracker_version( r ); r += sprintf( r, "</version>\n" ); |
446 | r += sprintf( r, "<stats>\n" ); | 459 | r += sprintf( r, "<stats>\n" ); |
447 | r += sprintf( r, " <uptime>%llu</uptime>\n", (unsigned long long)(time( NULL ) - ot_start_time) ); | 460 | r += sprintf( r, " <uptime>%llu</uptime>\n", (unsigned long long)(time( NULL ) - ot_start_time) ); |