summaryrefslogtreecommitdiff
path: root/ot_accesslist.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_accesslist.c')
-rw-r--r--ot_accesslist.c316
1 files changed, 160 insertions, 156 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c
index 1badc25..c26e14a 100644
--- a/ot_accesslist.c
+++ b/ot_accesslist.c
@@ -5,35 +5,35 @@
5 5
6/* System */ 6/* System */
7#include <pthread.h> 7#include <pthread.h>
8#include <signal.h>
9#include <stdio.h>
8#include <stdlib.h> 10#include <stdlib.h>
9#include <string.h> 11#include <string.h>
10#include <stdio.h>
11#include <signal.h>
12#include <unistd.h> 12#include <unistd.h>
13#ifdef WANT_DYNAMIC_ACCESSLIST 13#ifdef WANT_DYNAMIC_ACCESSLIST
14#include <sys/types.h>
15#include <sys/stat.h>
16#include <errno.h> 14#include <errno.h>
15#include <sys/stat.h>
16#include <sys/types.h>
17#endif 17#endif
18 18
19/* Libowfat */ 19/* Libowfat */
20#include "byte.h" 20#include "byte.h"
21#include "scan.h" 21#include "fmt.h"
22#include "ip6.h" 22#include "ip6.h"
23#include "mmap.h" 23#include "mmap.h"
24#include "fmt.h" 24#include "scan.h"
25 25
26/* Opentracker */ 26/* Opentracker */
27#include "trackerlogic.h"
28#include "ot_accesslist.h" 27#include "ot_accesslist.h"
29#include "ot_vector.h" 28#include "ot_vector.h"
29#include "trackerlogic.h"
30 30
31/* GLOBAL VARIABLES */ 31/* GLOBAL VARIABLES */
32#ifdef WANT_ACCESSLIST 32#ifdef WANT_ACCESSLIST
33char *g_accesslist_filename = NULL; 33char *g_accesslist_filename = NULL;
34#ifdef WANT_DYNAMIC_ACCESSLIST 34#ifdef WANT_DYNAMIC_ACCESSLIST
35char *g_accesslist_pipe_add = NULL; 35char *g_accesslist_pipe_add = NULL;
36char *g_accesslist_pipe_delete = NULL; 36char *g_accesslist_pipe_delete = NULL;
37#endif 37#endif
38static pthread_mutex_t g_accesslist_mutex; 38static pthread_mutex_t g_accesslist_mutex;
39 39
@@ -55,20 +55,18 @@ struct ot_accesslist {
55 ot_time base; 55 ot_time base;
56 ot_accesslist *next; 56 ot_accesslist *next;
57}; 57};
58static ot_accesslist * _Atomic g_accesslist = NULL; 58static ot_accesslist *_Atomic g_accesslist = NULL;
59#ifdef WANT_DYNAMIC_ACCESSLIST 59#ifdef WANT_DYNAMIC_ACCESSLIST
60static ot_accesslist * _Atomic g_accesslist_add = NULL; 60static ot_accesslist *_Atomic g_accesslist_add = NULL;
61static ot_accesslist * _Atomic g_accesslist_delete = NULL; 61static ot_accesslist *_Atomic g_accesslist_delete = NULL;
62#endif 62#endif
63 63
64/* Helpers to work on access lists */ 64/* Helpers to work on access lists */
65static int vector_compare_hash(const void *hash1, const void *hash2 ) { 65static int vector_compare_hash(const void *hash1, const void *hash2) { return memcmp(hash1, hash2, OT_HASH_COMPARE_SIZE); }
66 return memcmp( hash1, hash2, OT_HASH_COMPARE_SIZE );
67}
68 66
69static ot_accesslist * accesslist_free(ot_accesslist *accesslist) { 67static ot_accesslist *accesslist_free(ot_accesslist *accesslist) {
70 while (accesslist) { 68 while (accesslist) {
71 ot_accesslist * this_accesslist = accesslist; 69 ot_accesslist *this_accesslist = accesslist;
72 accesslist = this_accesslist->next; 70 accesslist = this_accesslist->next;
73 free(this_accesslist->list); 71 free(this_accesslist->list);
74 free(this_accesslist); 72 free(this_accesslist);
@@ -76,8 +74,8 @@ static ot_accesslist * accesslist_free(ot_accesslist *accesslist) {
76 return NULL; 74 return NULL;
77} 75}
78 76
79static ot_accesslist * accesslist_make(ot_accesslist *next, size_t size) { 77static ot_accesslist *accesslist_make(ot_accesslist *next, size_t size) {
80 ot_accesslist * accesslist_new = malloc(sizeof(ot_accesslist)); 78 ot_accesslist *accesslist_new = malloc(sizeof(ot_accesslist));
81 if (accesslist_new) { 79 if (accesslist_new) {
82 accesslist_new->list = size ? malloc(sizeof(ot_hash) * size) : NULL; 80 accesslist_new->list = size ? malloc(sizeof(ot_hash) * size) : NULL;
83 accesslist_new->size = size; 81 accesslist_new->size = size;
@@ -102,76 +100,77 @@ static void accesslist_clean(ot_accesslist *accesslist) {
102} 100}
103 101
104/* Read initial access list */ 102/* Read initial access list */
105static void accesslist_readfile( void ) { 103static void accesslist_readfile(void) {
106 ot_accesslist * accesslist_new; 104 ot_accesslist *accesslist_new;
107 ot_hash *info_hash; 105 ot_hash *info_hash;
108 const char *map, *map_end, *read_offs; 106 const char *map, *map_end, *read_offs;
109 size_t maplen; 107 size_t maplen;
110 108
111 if( ( map = mmap_read( g_accesslist_filename, &maplen ) ) == NULL ) { 109 if ((map = mmap_read(g_accesslist_filename, &maplen)) == NULL) {
112 char *wd = getcwd( NULL, 0 ); 110 char *wd = getcwd(NULL, 0);
113 fprintf( stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).\nPWD: %s\n", g_accesslist_filename, wd ); 111 fprintf(stderr, "Warning: Can't open accesslist file: %s (but will try to create it later, if necessary and possible).\nPWD: %s\n", g_accesslist_filename, wd);
114 free( wd ); 112 free(wd);
115 return; 113 return;
116 } 114 }
117 115
118 /* You need at least 41 bytes to pass an info_hash, make enough room 116 /* You need at least 41 bytes to pass an info_hash, make enough room
119 for the maximum amount of them */ 117 for the maximum amount of them */
120 accesslist_new = accesslist_make(g_accesslist, maplen / 41); 118 accesslist_new = accesslist_make(g_accesslist, maplen / 41);
121 if( !accesslist_new ) { 119 if (!accesslist_new) {
122 fprintf( stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", ( maplen / 41 ) * 20 ); 120 fprintf(stderr, "Warning: Not enough memory to allocate %zd bytes for accesslist buffer. May succeed later.\n", (maplen / 41) * 20);
123 mmap_unmap( map, maplen); 121 mmap_unmap(map, maplen);
124 return; 122 return;
125 } 123 }
126 info_hash = accesslist_new->list; 124 info_hash = accesslist_new->list;
127 125
128 /* No use to scan if there's not enough room for another full info_hash */ 126 /* No use to scan if there's not enough room for another full info_hash */
129 map_end = map + maplen - 40; 127 map_end = map + maplen - 40;
130 read_offs = map; 128 read_offs = map;
131 129
132 /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" */ 130 /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" */
133 while( read_offs <= map_end ) { 131 while (read_offs <= map_end) {
134 int i; 132 int i;
135 for( i=0; i<(int)sizeof(ot_hash); ++i ) { 133 for (i = 0; i < (int)sizeof(ot_hash); ++i) {
136 int eger1 = scan_fromhex( (unsigned char)read_offs[ 2*i ] ); 134 int eger1 = scan_fromhex((unsigned char)read_offs[2 * i]);
137 int eger2 = scan_fromhex( (unsigned char)read_offs[ 1 + 2*i ] ); 135 int eger2 = scan_fromhex((unsigned char)read_offs[1 + 2 * i]);
138 if( eger1 < 0 || eger2 < 0 ) 136 if (eger1 < 0 || eger2 < 0)
139 break; 137 break;
140 (*info_hash)[i] = (uint8_t)(eger1 * 16 + eger2); 138 (*info_hash)[i] = (uint8_t)(eger1 * 16 + eger2);
141 } 139 }
142 140
143 if( i == sizeof(ot_hash) ) { 141 if (i == sizeof(ot_hash)) {
144 read_offs += 40; 142 read_offs += 40;
145 143
146 /* Append accesslist to accesslist vector */ 144 /* Append accesslist to accesslist vector */
147 if( read_offs == map_end || scan_fromhex( (unsigned char)*read_offs ) < 0 ) 145 if (read_offs == map_end || scan_fromhex((unsigned char)*read_offs) < 0)
148 ++info_hash; 146 ++info_hash;
149 } 147 }
150 148
151 /* Find start of next line */ 149 /* Find start of next line */
152 while( read_offs <= map_end && *(read_offs++) != '\n' ); 150 while (read_offs <= map_end && *(read_offs++) != '\n')
151 ;
153 } 152 }
154#ifdef _DEBUG 153#ifdef _DEBUG
155 fprintf( stderr, "Added %zd info_hashes to accesslist\n", (size_t)(info_hash - accesslist_new->list) ); 154 fprintf(stderr, "Added %zd info_hashes to accesslist\n", (size_t)(info_hash - accesslist_new->list));
156#endif 155#endif
157 156
158 mmap_unmap( map, maplen); 157 mmap_unmap(map, maplen);
159 158
160 qsort( accesslist_new->list, info_hash - accesslist_new->list, sizeof( *info_hash ), vector_compare_hash ); 159 qsort(accesslist_new->list, info_hash - accesslist_new->list, sizeof(*info_hash), vector_compare_hash);
161 accesslist_new->size = info_hash - accesslist_new->list; 160 accesslist_new->size = info_hash - accesslist_new->list;
162 161
163 /* Now exchange the accesslist vector in the least race condition prone way */ 162 /* Now exchange the accesslist vector in the least race condition prone way */
164 pthread_mutex_lock(&g_accesslist_mutex); 163 pthread_mutex_lock(&g_accesslist_mutex);
165 accesslist_new->next = g_accesslist; 164 accesslist_new->next = g_accesslist;
166 g_accesslist = accesslist_new; /* Only now set a new list */ 165 g_accesslist = accesslist_new; /* Only now set a new list */
167 166
168#ifdef WANT_DYNAMIC_ACCESSLIST 167#ifdef WANT_DYNAMIC_ACCESSLIST
169 /* If we have dynamic accesslists, reloading a new one will always void the add/delete lists. 168 /* If we have dynamic accesslists, reloading a new one will always void the add/delete lists.
170 Insert empty ones at the list head */ 169 Insert empty ones at the list head */
171 if (g_accesslist_add && (accesslist_new = accesslist_make(g_accesslist_add, 0)) != NULL) 170 if (g_accesslist_add && (accesslist_new = accesslist_make(g_accesslist_add, 0)) != NULL)
172 g_accesslist_add = accesslist_new; 171 g_accesslist_add = accesslist_new;
173 if (g_accesslist_delete && (accesslist_new = accesslist_make(g_accesslist_delete, 0)) != NULL) 172 if (g_accesslist_delete && (accesslist_new = accesslist_make(g_accesslist_delete, 0)) != NULL)
174 g_accesslist_delete = accesslist_new; 173 g_accesslist_delete = accesslist_new;
175#endif 174#endif
176 175
177 accesslist_clean(g_accesslist); 176 accesslist_clean(g_accesslist);
@@ -179,26 +178,26 @@ static void accesslist_readfile( void ) {
179 pthread_mutex_unlock(&g_accesslist_mutex); 178 pthread_mutex_unlock(&g_accesslist_mutex);
180} 179}
181 180
182int accesslist_hashisvalid( ot_hash hash ) { 181int accesslist_hashisvalid(ot_hash hash) {
183 /* Get working copy of current access list */ 182 /* Get working copy of current access list */
184 ot_accesslist * accesslist = g_accesslist; 183 ot_accesslist *accesslist = g_accesslist;
185#ifdef WANT_DYNAMIC_ACCESSLIST 184#ifdef WANT_DYNAMIC_ACCESSLIST
186 ot_accesslist * accesslist_add, * accesslist_delete; 185 ot_accesslist *accesslist_add, *accesslist_delete;
187#endif 186#endif
188 void * exactmatch = NULL; 187 void *exactmatch = NULL;
189 188
190 if (accesslist) 189 if (accesslist)
191 exactmatch = bsearch( hash, accesslist->list, accesslist->size, OT_HASH_COMPARE_SIZE, vector_compare_hash ); 190 exactmatch = bsearch(hash, accesslist->list, accesslist->size, OT_HASH_COMPARE_SIZE, vector_compare_hash);
192 191
193#ifdef WANT_DYNAMIC_ACCESSLIST 192#ifdef WANT_DYNAMIC_ACCESSLIST
194 /* If we had no match on the main list, scan the list of dynamically added hashes */ 193 /* If we had no match on the main list, scan the list of dynamically added hashes */
195 accesslist_add = g_accesslist_add; 194 accesslist_add = g_accesslist_add;
196 if ((exactmatch == NULL) && accesslist_add) 195 if ((exactmatch == NULL) && accesslist_add)
197 exactmatch = bsearch( hash, accesslist_add->list, accesslist_add->size, OT_HASH_COMPARE_SIZE, vector_compare_hash ); 196 exactmatch = bsearch(hash, accesslist_add->list, accesslist_add->size, OT_HASH_COMPARE_SIZE, vector_compare_hash);
198 197
199 /* If we found a matching hash on the main list, scan the list of dynamically deleted hashes */ 198 /* If we found a matching hash on the main list, scan the list of dynamically deleted hashes */
200 accesslist_delete = g_accesslist_delete; 199 accesslist_delete = g_accesslist_delete;
201 if ((exactmatch != NULL) && accesslist_delete && bsearch( hash, accesslist_add->list, accesslist_add->size, OT_HASH_COMPARE_SIZE, vector_compare_hash )) 200 if ((exactmatch != NULL) && accesslist_delete && bsearch(hash, accesslist_add->list, accesslist_add->size, OT_HASH_COMPARE_SIZE, vector_compare_hash))
202 exactmatch = NULL; 201 exactmatch = NULL;
203#endif 202#endif
204 203
@@ -209,31 +208,32 @@ int accesslist_hashisvalid( ot_hash hash ) {
209#endif 208#endif
210} 209}
211 210
212static void * accesslist_worker( void * args ) { 211static void *accesslist_worker(void *args) {
213 int sig; 212 int sig;
214 sigset_t signal_mask; 213 sigset_t signal_mask;
215 214
216 sigemptyset(&signal_mask); 215 sigemptyset(&signal_mask);
217 sigaddset(&signal_mask, SIGHUP); 216 sigaddset(&signal_mask, SIGHUP);
218 217
219 (void)args; 218 (void)args;
220 219
221 while( 1 ) { 220 while (1) {
222 if (!g_opentracker_running) 221 if (!g_opentracker_running)
223 return NULL; 222 return NULL;
224 223
225 /* Initial attempt to read accesslist */ 224 /* Initial attempt to read accesslist */
226 accesslist_readfile( ); 225 accesslist_readfile();
227 226
228 /* Wait for signals */ 227 /* Wait for signals */
229 while( sigwait (&signal_mask, &sig) != 0 && sig != SIGHUP ); 228 while (sigwait(&signal_mask, &sig) != 0 && sig != SIGHUP)
229 ;
230 } 230 }
231 return NULL; 231 return NULL;
232} 232}
233 233
234#ifdef WANT_DYNAMIC_ACCESSLIST 234#ifdef WANT_DYNAMIC_ACCESSLIST
235static pthread_t thread_adder_id, thread_deleter_id; 235static pthread_t thread_adder_id, thread_deleter_id;
236static void * accesslist_adddel_worker(char * fifoname, ot_accesslist * _Atomic * adding_to, ot_accesslist * _Atomic * removing_from) { 236static void *accesslist_adddel_worker(char *fifoname, ot_accesslist *_Atomic *adding_to, ot_accesslist *_Atomic *removing_from) {
237 struct stat st; 237 struct stat st;
238 238
239 if (!stat(fifoname, &st)) { 239 if (!stat(fifoname, &st)) {
@@ -250,9 +250,9 @@ static void * accesslist_adddel_worker(char * fifoname, ot_accesslist * _Atomic
250 } 250 }
251 251
252 while (g_opentracker_running) { 252 while (g_opentracker_running) {
253 FILE * fifo = fopen(fifoname, "r"); 253 FILE *fifo = fopen(fifoname, "r");
254 char *line = NULL; 254 char *line = NULL;
255 size_t linecap = 0; 255 size_t linecap = 0;
256 ssize_t linelen; 256 ssize_t linelen;
257 257
258 if (!fifo) { 258 if (!fifo) {
@@ -262,7 +262,7 @@ static void * accesslist_adddel_worker(char * fifoname, ot_accesslist * _Atomic
262 262
263 while ((linelen = getline(&line, &linecap, fifo)) > 0) { 263 while ((linelen = getline(&line, &linecap, fifo)) > 0) {
264 ot_hash info_hash; 264 ot_hash info_hash;
265 int i; 265 int i;
266 266
267 printf("Got line %*s", (int)linelen, line); 267 printf("Got line %*s", (int)linelen, line);
268 /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*" 268 /* We do ignore anything that is not of the form "^[:xdigit:]{40}[^:xdigit:].*"
@@ -270,15 +270,15 @@ static void * accesslist_adddel_worker(char * fifoname, ot_accesslist * _Atomic
270 if (linelen < 41) 270 if (linelen < 41)
271 continue; 271 continue;
272 272
273 for( i=0; i<(int)sizeof(ot_hash); ++i ) { 273 for (i = 0; i < (int)sizeof(ot_hash); ++i) {
274 int eger1 = scan_fromhex( (unsigned char)line[ 2*i ] ); 274 int eger1 = scan_fromhex((unsigned char)line[2 * i]);
275 int eger2 = scan_fromhex( (unsigned char)line[ 1 + 2*i ] ); 275 int eger2 = scan_fromhex((unsigned char)line[1 + 2 * i]);
276 if( eger1 < 0 || eger2 < 0 ) 276 if (eger1 < 0 || eger2 < 0)
277 break; 277 break;
278 ((uint8_t*)info_hash)[i] = (uint8_t)(eger1 * 16 + eger2); 278 ((uint8_t *)info_hash)[i] = (uint8_t)(eger1 * 16 + eger2);
279 } 279 }
280printf("parsed info_hash %20s\n", info_hash); 280 printf("parsed info_hash %20s\n", info_hash);
281 if( i != sizeof(ot_hash) ) 281 if (i != sizeof(ot_hash))
282 continue; 282 continue;
283 283
284 /* From now on we modify g_accesslist_add and g_accesslist_delete, so prevent the 284 /* From now on we modify g_accesslist_add and g_accesslist_delete, so prevent the
@@ -287,10 +287,10 @@ printf("parsed info_hash %20s\n", info_hash);
287 287
288 /* If the info hash is in the removing_from list, create a new head without that entry */ 288 /* If the info hash is in the removing_from list, create a new head without that entry */
289 if (*removing_from && (*removing_from)->list) { 289 if (*removing_from && (*removing_from)->list) {
290 ot_hash * exactmatch = bsearch( info_hash, (*removing_from)->list, (*removing_from)->size, OT_HASH_COMPARE_SIZE, vector_compare_hash ); 290 ot_hash *exactmatch = bsearch(info_hash, (*removing_from)->list, (*removing_from)->size, OT_HASH_COMPARE_SIZE, vector_compare_hash);
291 if (exactmatch) { 291 if (exactmatch) {
292 ptrdiff_t off = exactmatch - (*removing_from)->list; 292 ptrdiff_t off = exactmatch - (*removing_from)->list;
293 ot_accesslist * accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1); 293 ot_accesslist *accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1);
294 if (accesslist_new) { 294 if (accesslist_new) {
295 memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off); 295 memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off);
296 memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, (*removing_from)->size - off - 1); 296 memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, (*removing_from)->size - off - 1);
@@ -301,19 +301,19 @@ printf("parsed info_hash %20s\n", info_hash);
301 301
302 /* Simple case: there's no adding_to list yet, create one with one member */ 302 /* Simple case: there's no adding_to list yet, create one with one member */
303 if (!*adding_to) { 303 if (!*adding_to) {
304 ot_accesslist * accesslist_new = accesslist_make(NULL, 1); 304 ot_accesslist *accesslist_new = accesslist_make(NULL, 1);
305 if (accesslist_new) { 305 if (accesslist_new) {
306 memcpy(accesslist_new->list, info_hash, sizeof(ot_hash)); 306 memcpy(accesslist_new->list, info_hash, sizeof(ot_hash));
307 *adding_to = accesslist_new; 307 *adding_to = accesslist_new;
308 } 308 }
309 } else { 309 } else {
310 int exactmatch = 0; 310 int exactmatch = 0;
311 ot_hash * insert_point = binary_search( info_hash, (*adding_to)->list, (*adding_to)->size, OT_HASH_COMPARE_SIZE, sizeof(ot_hash), &exactmatch ); 311 ot_hash *insert_point = binary_search(info_hash, (*adding_to)->list, (*adding_to)->size, OT_HASH_COMPARE_SIZE, sizeof(ot_hash), &exactmatch);
312 312
313 /* Only if the info hash is not in the adding_to list, create a new head with that entry */ 313 /* Only if the info hash is not in the adding_to list, create a new head with that entry */
314 if (!exactmatch) { 314 if (!exactmatch) {
315 ot_accesslist * accesslist_new = accesslist_make(*adding_to, (*adding_to)->size + 1); 315 ot_accesslist *accesslist_new = accesslist_make(*adding_to, (*adding_to)->size + 1);
316 ptrdiff_t off = insert_point - (*adding_to)->list; 316 ptrdiff_t off = insert_point - (*adding_to)->list;
317 if (accesslist_new) { 317 if (accesslist_new) {
318 memcpy(accesslist_new->list, (*adding_to)->list, sizeof(ot_hash) * off); 318 memcpy(accesslist_new->list, (*adding_to)->list, sizeof(ot_hash) * off);
319 memcpy(accesslist_new->list + off, info_hash, sizeof(info_hash)); 319 memcpy(accesslist_new->list + off, info_hash, sizeof(info_hash));
@@ -331,29 +331,29 @@ printf("parsed info_hash %20s\n", info_hash);
331 return NULL; 331 return NULL;
332} 332}
333 333
334static void * accesslist_adder_worker( void * args ) { 334static void *accesslist_adder_worker(void *args) {
335 (void)args; 335 (void)args;
336 return accesslist_adddel_worker(g_accesslist_pipe_add, &g_accesslist_add, &g_accesslist_delete); 336 return accesslist_adddel_worker(g_accesslist_pipe_add, &g_accesslist_add, &g_accesslist_delete);
337} 337}
338static void * accesslist_deleter_worker( void * args ) { 338static void *accesslist_deleter_worker(void *args) {
339 (void)args; 339 (void)args;
340 return accesslist_adddel_worker(g_accesslist_pipe_delete, &g_accesslist_delete, &g_accesslist_add); 340 return accesslist_adddel_worker(g_accesslist_pipe_delete, &g_accesslist_delete, &g_accesslist_add);
341} 341}
342#endif 342#endif
343 343
344static pthread_t thread_id; 344static pthread_t thread_id;
345void accesslist_init( ) { 345void accesslist_init() {
346 pthread_mutex_init(&g_accesslist_mutex, NULL); 346 pthread_mutex_init(&g_accesslist_mutex, NULL);
347 pthread_create( &thread_id, NULL, accesslist_worker, NULL ); 347 pthread_create(&thread_id, NULL, accesslist_worker, NULL);
348#ifdef WANT_DYNAMIC_ACCESSLIST 348#ifdef WANT_DYNAMIC_ACCESSLIST
349 if (g_accesslist_pipe_add) 349 if (g_accesslist_pipe_add)
350 pthread_create( &thread_adder_id, NULL, accesslist_adder_worker, NULL ); 350 pthread_create(&thread_adder_id, NULL, accesslist_adder_worker, NULL);
351 if (g_accesslist_pipe_delete) 351 if (g_accesslist_pipe_delete)
352 pthread_create( &thread_deleter_id, NULL, accesslist_deleter_worker, NULL ); 352 pthread_create(&thread_deleter_id, NULL, accesslist_deleter_worker, NULL);
353#endif 353#endif
354} 354}
355 355
356void accesslist_deinit( void ) { 356void accesslist_deinit(void) {
357 /* Wake up sleeping worker */ 357 /* Wake up sleeping worker */
358 pthread_kill(thread_id, SIGHUP); 358 pthread_kill(thread_id, SIGHUP);
359 359
@@ -362,16 +362,16 @@ void accesslist_deinit( void ) {
362 g_accesslist = accesslist_free(g_accesslist); 362 g_accesslist = accesslist_free(g_accesslist);
363 363
364#ifdef WANT_DYNAMIC_ACCESSLIST 364#ifdef WANT_DYNAMIC_ACCESSLIST
365 g_accesslist_add = accesslist_free(g_accesslist_add); 365 g_accesslist_add = accesslist_free(g_accesslist_add);
366 g_accesslist_delete = accesslist_free(g_accesslist_delete); 366 g_accesslist_delete = accesslist_free(g_accesslist_delete);
367#endif 367#endif
368 368
369 pthread_mutex_unlock(&g_accesslist_mutex); 369 pthread_mutex_unlock(&g_accesslist_mutex);
370 pthread_cancel( thread_id ); 370 pthread_cancel(thread_id);
371 pthread_mutex_destroy(&g_accesslist_mutex); 371 pthread_mutex_destroy(&g_accesslist_mutex);
372} 372}
373 373
374void accesslist_cleanup( void ) { 374void accesslist_cleanup(void) {
375 pthread_mutex_lock(&g_accesslist_mutex); 375 pthread_mutex_lock(&g_accesslist_mutex);
376 376
377 accesslist_clean(g_accesslist); 377 accesslist_clean(g_accesslist);
@@ -384,35 +384,34 @@ void accesslist_cleanup( void ) {
384} 384}
385#endif 385#endif
386 386
387int address_in_net( const ot_ip6 address, const ot_net *net ) { 387int address_in_net(const ot_ip6 address, const ot_net *net) {
388 int bits = net->bits, checkbits = ( 0x7f00 >> ( bits & 7 )); 388 int bits = net->bits, checkbits = (0x7f00 >> (bits & 7));
389 int result = memcmp( address, &net->address, bits >> 3 ); 389 int result = memcmp(address, &net->address, bits >> 3);
390 if( !result && ( bits & 7 ) ) 390 if (!result && (bits & 7))
391 result = ( checkbits & address[bits>>3] ) - ( checkbits & net->address[bits>>3]); 391 result = (checkbits & address[bits >> 3]) - (checkbits & net->address[bits >> 3]);
392 return result == 0; 392 return result == 0;
393} 393}
394 394
395void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value, const size_t member_size ) { 395void *set_value_for_net(const ot_net *net, ot_vector *vector, const void *value, const size_t member_size) {
396 size_t i; 396 size_t i;
397 int exactmatch; 397 int exactmatch;
398 398
399 /* Caller must have a concept of ot_net in it's member */ 399 /* Caller must have a concept of ot_net in it's member */
400 if( member_size < sizeof(ot_net) ) 400 if (member_size < sizeof(ot_net))
401 return 0; 401 return 0;
402 402
403 /* Check each net in vector for overlap */ 403 /* Check each net in vector for overlap */
404 uint8_t *member = ((uint8_t*)vector->data); 404 uint8_t *member = ((uint8_t *)vector->data);
405 for( i=0; i<vector->size; ++i ) { 405 for (i = 0; i < vector->size; ++i) {
406 if( address_in_net( *(ot_ip6*)member, net ) || 406 if (address_in_net(*(ot_ip6 *)member, net) || address_in_net(net->address, (ot_net *)member))
407 address_in_net( net->address, (ot_net*)member ) )
408 return 0; 407 return 0;
409 member += member_size; 408 member += member_size;
410 } 409 }
411 410
412 member = vector_find_or_insert( vector, (void*)net, member_size, sizeof(ot_net), &exactmatch ); 411 member = vector_find_or_insert(vector, (void *)net, member_size, sizeof(ot_net), &exactmatch);
413 if( member ) { 412 if (member) {
414 memcpy( member, net, sizeof(ot_net)); 413 memcpy(member, net, sizeof(ot_net));
415 memcpy( member + sizeof(ot_net), value, member_size - sizeof(ot_net)); 414 memcpy(member + sizeof(ot_net), value, member_size - sizeof(ot_net));
416 } 415 }
417 416
418 return member; 417 return member;
@@ -420,43 +419,43 @@ void *set_value_for_net( const ot_net *net, ot_vector *vector, const void *value
420 419
421/* Takes a vector filled with { ot_net net, uint8_t[x] value }; 420/* Takes a vector filled with { ot_net net, uint8_t[x] value };
422 Returns value associated with the net, or NULL if not found */ 421 Returns value associated with the net, or NULL if not found */
423void *get_value_for_net( const ot_ip6 address, const ot_vector *vector, const size_t member_size ) { 422void *get_value_for_net(const ot_ip6 address, const ot_vector *vector, const size_t member_size) {
424 int exactmatch; 423 int exactmatch;
425 /* This binary search will return a pointer to the first non-containing network... */ 424 /* This binary search will return a pointer to the first non-containing network... */
426 ot_net *net = binary_search( address, vector->data, vector->size, member_size, sizeof(ot_ip6), &exactmatch ); 425 ot_net *net = binary_search(address, vector->data, vector->size, member_size, sizeof(ot_ip6), &exactmatch);
427 if( !net ) 426 if (!net)
428 return NULL; 427 return NULL;
429 /* ... so we'll need to move back one step unless we've exactly hit the first address in network */ 428 /* ... so we'll need to move back one step unless we've exactly hit the first address in network */
430 if( !exactmatch && ( (void*)net > vector->data ) ) 429 if (!exactmatch && ((void *)net > vector->data))
431 --net; 430 --net;
432 if( !address_in_net( address, net ) ) 431 if (!address_in_net(address, net))
433 return NULL; 432 return NULL;
434 return (void*)net; 433 return (void *)net;
435} 434}
436 435
437#ifdef WANT_FULLLOG_NETWORKS 436#ifdef WANT_FULLLOG_NETWORKS
438static ot_vector g_lognets_list; 437static ot_vector g_lognets_list;
439ot_log *g_logchain_first, *g_logchain_last; 438ot_log *g_logchain_first, *g_logchain_last;
440
441static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER; 439static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER;
442void loglist_add_network( const ot_net *net ) { 440
441void loglist_add_network(const ot_net *net) {
443 pthread_mutex_lock(&g_lognets_list_mutex); 442 pthread_mutex_lock(&g_lognets_list_mutex);
444 set_value_for_net( net, &g_lognets_list, NULL, sizeof(ot_net)); 443 set_value_for_net(net, &g_lognets_list, NULL, sizeof(ot_net));
445 pthread_mutex_unlock(&g_lognets_list_mutex); 444 pthread_mutex_unlock(&g_lognets_list_mutex);
446} 445}
447 446
448void loglist_reset( ) { 447void loglist_reset() {
449 pthread_mutex_lock(&g_lognets_list_mutex); 448 pthread_mutex_lock(&g_lognets_list_mutex);
450 free( g_lognets_list.data ); 449 free(g_lognets_list.data);
451 g_lognets_list.data = 0; 450 g_lognets_list.data = 0;
452 g_lognets_list.size = g_lognets_list.space = 0; 451 g_lognets_list.size = g_lognets_list.space = 0;
453 pthread_mutex_unlock(&g_lognets_list_mutex); 452 pthread_mutex_unlock(&g_lognets_list_mutex);
454} 453}
455 454
456int loglist_check_address( const ot_ip6 address ) { 455int loglist_check_address(const ot_ip6 address) {
457 int result; 456 int result;
458 pthread_mutex_lock(&g_lognets_list_mutex); 457 pthread_mutex_lock(&g_lognets_list_mutex);
459 result = ( NULL != get_value_for_net( address, &g_lognets_list, sizeof(ot_net)) ); 458 result = (NULL != get_value_for_net(address, &g_lognets_list, sizeof(ot_net)));
460 pthread_mutex_unlock(&g_lognets_list_mutex); 459 pthread_mutex_unlock(&g_lognets_list_mutex);
461 return result; 460 return result;
462} 461}
@@ -464,44 +463,44 @@ int loglist_check_address( const ot_ip6 address ) {
464 463
465#ifdef WANT_IP_FROM_PROXY 464#ifdef WANT_IP_FROM_PROXY
466typedef struct { 465typedef struct {
467 ot_net *proxy; 466 ot_net *proxy;
468 ot_vector networks; 467 ot_vector networks;
469} ot_proxymap; 468} ot_proxymap;
470 469
471static ot_vector g_proxies_list; 470static ot_vector g_proxies_list;
472static pthread_mutex_t g_proxies_list_mutex = PTHREAD_MUTEX_INITIALIZER; 471static pthread_mutex_t g_proxies_list_mutex = PTHREAD_MUTEX_INITIALIZER;
473 472
474int proxylist_add_network( const ot_net *proxy, const ot_net *net ) { 473int proxylist_add_network(const ot_net *proxy, const ot_net *net) {
475 ot_proxymap *map; 474 ot_proxymap *map;
476 int exactmatch, result = 1; 475 int exactmatch, result = 1;
477 pthread_mutex_lock(&g_proxies_list_mutex); 476 pthread_mutex_lock(&g_proxies_list_mutex);
478 477
479 /* If we have a direct hit, use and extend the vector there */ 478 /* If we have a direct hit, use and extend the vector there */
480 map = binary_search( proxy, g_proxies_list.data, g_proxies_list.size, sizeof(ot_proxymap), sizeof(ot_net), &exactmatch ); 479 map = binary_search(proxy, g_proxies_list.data, g_proxies_list.size, sizeof(ot_proxymap), sizeof(ot_net), &exactmatch);
481 480
482 if( !map || !exactmatch ) { 481 if (!map || !exactmatch) {
483 /* else see, if we've got overlapping networks 482 /* else see, if we've got overlapping networks
484 and get a new empty vector if not */ 483 and get a new empty vector if not */
485 ot_vector empty; 484 ot_vector empty;
486 memset( &empty, 0, sizeof( ot_vector ) ); 485 memset(&empty, 0, sizeof(ot_vector));
487 map = set_value_for_net( proxy, &g_proxies_list, &empty, sizeof(ot_proxymap)); 486 map = set_value_for_net(proxy, &g_proxies_list, &empty, sizeof(ot_proxymap));
488 } 487 }
489 488
490 if( map && set_value_for_net( net, &map->networks, NULL, sizeof(ot_net) ) ) 489 if (map && set_value_for_net(net, &map->networks, NULL, sizeof(ot_net)))
491 result = 1; 490 result = 1;
492 491
493 pthread_mutex_unlock(&g_proxies_list_mutex); 492 pthread_mutex_unlock(&g_proxies_list_mutex);
494 return result; 493 return result;
495} 494}
496 495
497int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) { 496int proxylist_check_proxy(const ot_ip6 proxy, const ot_ip6 address) {
498 int result = 0; 497 int result = 0;
499 ot_proxymap *map; 498 ot_proxymap *map;
500 499
501 pthread_mutex_lock(&g_proxies_list_mutex); 500 pthread_mutex_lock(&g_proxies_list_mutex);
502 501
503 if( ( map = get_value_for_net( proxy, &g_proxies_list, sizeof(ot_proxymap) ) ) ) 502 if ((map = get_value_for_net(proxy, &g_proxies_list, sizeof(ot_proxymap))))
504 if( !address || get_value_for_net( address, &map->networks, sizeof(ot_net) ) ) 503 if (!address || get_value_for_net(address, &map->networks, sizeof(ot_net)))
505 result = 1; 504 result = 1;
506 505
507 pthread_mutex_unlock(&g_proxies_list_mutex); 506 pthread_mutex_unlock(&g_proxies_list_mutex);
@@ -514,44 +513,49 @@ static ot_net g_admin_nets[OT_ADMINIP_MAX];
514static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX]; 513static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX];
515static unsigned int g_admin_nets_count = 0; 514static unsigned int g_admin_nets_count = 0;
516 515
517int accesslist_bless_net( ot_net *net, ot_permissions permissions ) { 516int accesslist_bless_net(ot_net *net, ot_permissions permissions) {
518 if( g_admin_nets_count >= OT_ADMINIP_MAX ) 517 if (g_admin_nets_count >= OT_ADMINIP_MAX)
519 return -1; 518 return -1;
520 519
521 memcpy(g_admin_nets + g_admin_nets_count, net, sizeof(ot_net)); 520 memcpy(g_admin_nets + g_admin_nets_count, net, sizeof(ot_net));
522 g_admin_nets_permissions[ g_admin_nets_count++ ] = permissions; 521 g_admin_nets_permissions[g_admin_nets_count++] = permissions;
523 522
524#ifdef _DEBUG 523#ifdef _DEBUG
525 { 524 {
526 char _debug[512]; 525 char _debug[512];
527 int off = snprintf( _debug, sizeof(_debug), "Blessing ip net " ); 526 int off = snprintf(_debug, sizeof(_debug), "Blessing ip net ");
528 off += fmt_ip6c(_debug+off, net->address ); 527 off += fmt_ip6c(_debug + off, net->address);
529 if( net->bits < 128) { 528 if (net->bits < 128) {
530 _debug[off++] = '/'; 529 _debug[off++] = '/';
531 if( ip6_isv4mapped(net->address) ) 530 if (ip6_isv4mapped(net->address))
532 off += fmt_long(_debug+off, net->bits-96); 531 off += fmt_long(_debug + off, net->bits - 96);
533 else 532 else
534 off += fmt_long(_debug+off, net->bits); 533 off += fmt_long(_debug + off, net->bits);
535 } 534 }
536 535
537 if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); 536 if (permissions & OT_PERMISSION_MAY_STAT)
538 if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); 537 off += snprintf(_debug + off, 512 - off, " may_fetch_stats");
539 if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); 538 if (permissions & OT_PERMISSION_MAY_LIVESYNC)
540 if( permissions & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" ); 539 off += snprintf(_debug + off, 512 - off, " may_sync_live");
541 if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing" ); 540 if (permissions & OT_PERMISSION_MAY_FULLSCRAPE)
541 off += snprintf(_debug + off, 512 - off, " may_fetch_fullscrapes");
542 if (permissions & OT_PERMISSION_MAY_PROXY)
543 off += snprintf(_debug + off, 512 - off, " may_proxy");
544 if (!permissions)
545 off += snprintf(_debug + off, sizeof(_debug) - off, " nothing");
542 _debug[off++] = '.'; 546 _debug[off++] = '.';
543 _debug[off++] = '\n'; 547 _debug[off++] = '\n';
544 (void)write( 2, _debug, off ); 548 (void)write(2, _debug, off);
545 } 549 }
546#endif 550#endif
547 551
548 return 0; 552 return 0;
549} 553}
550 554
551int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions ) { 555int accesslist_is_blessed(ot_ip6 ip, ot_permissions permissions) {
552 unsigned int i; 556 unsigned int i;
553 for( i=0; i<g_admin_nets_count; ++i ) 557 for (i = 0; i < g_admin_nets_count; ++i)
554 if( address_in_net(ip, g_admin_nets + i) && (g_admin_nets_permissions[ i ] & permissions )) 558 if (address_in_net(ip, g_admin_nets + i) && (g_admin_nets_permissions[i] & permissions))
555 return 1; 559 return 1;
556 return 0; 560 return 0;
557} 561}