summaryrefslogtreecommitdiff
path: root/ot_accesslist.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_accesslist.c')
-rw-r--r--ot_accesslist.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/ot_accesslist.c b/ot_accesslist.c
index e8e0476..86f9a7d 100644
--- a/ot_accesslist.c
+++ b/ot_accesslist.c
@@ -1,7 +1,5 @@
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
4 $id$ */
5 3
6/* System */ 4/* System */
7#include <pthread.h> 5#include <pthread.h>
@@ -273,7 +271,8 @@ static void *accesslist_worker(void *args) {
273} 271}
274 272
275#ifdef WANT_DYNAMIC_ACCESSLIST 273#ifdef WANT_DYNAMIC_ACCESSLIST
276static pthread_t thread_adder_id, thread_deleter_id; 274static pthread_t thread_adder_id, thread_deleter_id;
275static _Atomic int adder_left, deleter_left;
277static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_Atomic *adding_to, ot_accesslist *_Atomic *removing_from) { 276static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_Atomic *adding_to, ot_accesslist *_Atomic *removing_from) {
278 struct stat st; 277 struct stat st;
279 278
@@ -297,6 +296,9 @@ static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_
297 ssize_t linelen; 296 ssize_t linelen;
298 297
299 if (!fifo) { 298 if (!fifo) {
299 /* Woken on purpose: the loop condition above decides what happens next */
300 if (errno == EINTR)
301 continue;
300 fprintf(stderr, "Error when reading dynamic accesslists: Couldn't open FIFO at %s, error: %s\n", fifoname, strerror(errno)); 302 fprintf(stderr, "Error when reading dynamic accesslists: Couldn't open FIFO at %s, error: %s\n", fifoname, strerror(errno));
301 return NULL; 303 return NULL;
302 } 304 }
@@ -324,8 +326,14 @@ static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_
324 ptrdiff_t off = exactmatch - (*removing_from)->list; 326 ptrdiff_t off = exactmatch - (*removing_from)->list;
325 ot_accesslist *accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1); 327 ot_accesslist *accesslist_new = accesslist_make(*removing_from, (*removing_from)->size - 1);
326 if (accesslist_new) { 328 if (accesslist_new) {
327 memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off); 329 size_t after = (*removing_from)->size - off - 1;
328 memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, sizeof(ot_hash) * ((*removing_from)->size - off - 1)); 330
331 /* Removing the only entry leaves a list with no room at all, and
332 memcpy may not be handed that even for nothing */
333 if (off)
334 memcpy(accesslist_new->list, (*removing_from)->list, sizeof(ot_hash) * off);
335 if (after)
336 memcpy(accesslist_new->list + off, (*removing_from)->list + off + 1, sizeof(ot_hash) * after);
329 (*removing_from)->base = time_now_minutes(); 337 (*removing_from)->base = time_now_minutes();
330 *removing_from = accesslist_new; 338 *removing_from = accesslist_new;
331 } 339 }
@@ -360,6 +368,7 @@ static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_
360 pthread_mutex_unlock(&g_accesslist_mutex); 368 pthread_mutex_unlock(&g_accesslist_mutex);
361 } 369 }
362 370
371 free(line);
363 fclose(fifo); 372 fclose(fifo);
364 } 373 }
365 return NULL; 374 return NULL;
@@ -367,11 +376,30 @@ static void *accesslist_adddel_worker(const char *fifoname, ot_accesslist *_
367 376
368static void *accesslist_adder_worker(void *args) { 377static void *accesslist_adder_worker(void *args) {
369 (void)args; 378 (void)args;
370 return accesslist_adddel_worker(g_accesslist_pipe_add, &g_accesslist_add, &g_accesslist_delete); 379 accesslist_adddel_worker(g_accesslist_pipe_add, &g_accesslist_add, &g_accesslist_delete);
380 atomic_store(&adder_left, 1);
381 return NULL;
371} 382}
372static void *accesslist_deleter_worker(void *args) { 383static void *accesslist_deleter_worker(void *args) {
373 (void)args; 384 (void)args;
374 return accesslist_adddel_worker(g_accesslist_pipe_delete, &g_accesslist_delete, &g_accesslist_add); 385 accesslist_adddel_worker(g_accesslist_pipe_delete, &g_accesslist_delete, &g_accesslist_add);
386 atomic_store(&deleter_left, 1);
387 return NULL;
388}
389
390/* These sit in a blocking open or read on a FIFO, so they are woken the way
391 the other workers are, and the signal is repeated because it only
392 interrupts a call already under way. The pipe name is what says whether
393 the thread was ever started. */
394static void accesslist_stop_fifo_worker(pthread_t thread, _Atomic int *left, const char *pipe_name) {
395 if (!pipe_name)
396 return;
397
398 while (!atomic_load(left)) {
399 pthread_kill(thread, OT_SIGNAL_WAKE);
400 usleep(1000);
401 }
402 pthread_join(thread, NULL);
375} 403}
376#endif 404#endif
377 405
@@ -392,6 +420,12 @@ void accesslist_deinit(void) {
392 pthread_kill(thread_id, SIGHUP); 420 pthread_kill(thread_id, SIGHUP);
393 pthread_join(thread_id, NULL); 421 pthread_join(thread_id, NULL);
394 422
423#ifdef WANT_DYNAMIC_ACCESSLIST
424 /* Before the lists they are reading are freed below */
425 accesslist_stop_fifo_worker(thread_adder_id, &adder_left, g_accesslist_pipe_add);
426 accesslist_stop_fifo_worker(thread_deleter_id, &deleter_left, g_accesslist_pipe_delete);
427#endif
428
395 pthread_mutex_lock(&g_accesslist_mutex); 429 pthread_mutex_lock(&g_accesslist_mutex);
396 430
397 g_accesslist = accesslist_free(g_accesslist); 431 g_accesslist = accesslist_free(g_accesslist);
@@ -467,34 +501,6 @@ void *accesslist_get_value_for_net(const ot_ip6 address, const ot_vector *vector
467 return (void *)net; 501 return (void *)net;
468} 502}
469 503
470#ifdef WANT_FULLLOG_NETWORKS
471static ot_vector g_lognets_list;
472ot_log *g_logchain_first, *g_logchain_last;
473static pthread_mutex_t g_lognets_list_mutex = PTHREAD_MUTEX_INITIALIZER;
474
475void loglist_add_network(const ot_net *net) {
476 pthread_mutex_lock(&g_lognets_list_mutex);
477 accesslist_set_value_for_net(net, &g_lognets_list, NULL, sizeof(ot_net));
478 pthread_mutex_unlock(&g_lognets_list_mutex);
479}
480
481void loglist_reset(void) {
482 pthread_mutex_lock(&g_lognets_list_mutex);
483 free(g_lognets_list.data);
484 g_lognets_list.data = 0;
485 g_lognets_list.size = g_lognets_list.space = 0;
486 pthread_mutex_unlock(&g_lognets_list_mutex);
487}
488
489int loglist_check_address(const ot_ip6 address) {
490 int result;
491 pthread_mutex_lock(&g_lognets_list_mutex);
492 result = (NULL != accesslist_get_value_for_net(address, &g_lognets_list, sizeof(ot_net)));
493 pthread_mutex_unlock(&g_lognets_list_mutex);
494 return result;
495}
496#endif
497
498#ifdef WANT_IP_FROM_PROXY 504#ifdef WANT_IP_FROM_PROXY
499typedef struct { 505typedef struct {
500 ot_net *proxy; 506 ot_net *proxy;