diff options
Diffstat (limited to 'src/ipcpd/local')
| -rw-r--r-- | src/ipcpd/local/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/ipcpd/local/main.c | 32 | ||||
| -rw-r--r-- | src/ipcpd/local/reg.c | 217 | ||||
| -rw-r--r-- | src/ipcpd/local/reg.h | 45 |
4 files changed, 279 insertions, 16 deletions
diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt index 91f300a3..af433d01 100644 --- a/src/ipcpd/local/CMakeLists.txt +++ b/src/ipcpd/local/CMakeLists.txt @@ -2,6 +2,7 @@ add_executable(${IPCP_LOCAL_TARGET} main.c + reg.c ${IPCP_SOURCES} ) diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index c0aeb51e..69eac8a6 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -42,7 +42,7 @@ #include "ipcp.h" #include "np1.h" -#include "shim-data.h" +#include "reg.h" #include <string.h> #include <stdlib.h> @@ -53,14 +53,14 @@ #define THIS_TYPE IPCP_LOCAL struct { - struct shim_data * shim_data; + struct reg * reg; - int in_out[SYS_MAX_FLOWS]; - fset_t * flows; - fqueue_t * fq; + int in_out[SYS_MAX_FLOWS]; + fset_t * flows; + fqueue_t * fq; - pthread_rwlock_t lock; - pthread_t packet_loop; + pthread_rwlock_t lock; + pthread_t packet_loop; } local_data; static int local_data_init(void) @@ -77,9 +77,9 @@ static int local_data_init(void) if (local_data.fq == NULL) goto fail_fqueue; - local_data.shim_data = shim_data_create(); - if (local_data.shim_data == NULL) - goto fail_shim_data; + local_data.reg = reg_create(); + if (local_data.reg == NULL) + goto fail_reg; if (pthread_rwlock_init(&local_data.lock, NULL) < 0) goto fail_rwlock_init; @@ -87,8 +87,8 @@ static int local_data_init(void) return 0; fail_rwlock_init: - shim_data_destroy(local_data.shim_data); - fail_shim_data: + reg_destroy(local_data.reg); + fail_reg: fqueue_destroy(local_data.fq); fail_fqueue: fset_destroy(local_data.flows); @@ -98,7 +98,7 @@ static int local_data_init(void) static void local_data_fini(void){ pthread_rwlock_destroy(&local_data.lock); - shim_data_destroy(local_data.shim_data); + reg_destroy(local_data.reg); fqueue_destroy(local_data.fq); fset_destroy(local_data.flows); } @@ -166,7 +166,7 @@ static int local_ipcp_bootstrap(struct ipcp_config * conf) static int local_ipcp_reg(const uint8_t * hash) { - if (shim_data_reg_add_entry(local_data.shim_data, hash)) { + if (reg_add(local_data.reg, hash) < 0) { log_err("Failed to add " HASH_FMT32 " to local registry.", HASH_VAL32(hash)); return -1; @@ -177,7 +177,7 @@ static int local_ipcp_reg(const uint8_t * hash) static int local_ipcp_unreg(const uint8_t * hash) { - shim_data_reg_del_entry(local_data.shim_data, hash); + reg_del(local_data.reg, hash); log_info("Unregistered " HASH_FMT32 ".", HASH_VAL32(hash)); @@ -188,7 +188,7 @@ static int local_ipcp_query(const uint8_t * hash) { int ret; - ret = (shim_data_reg_has(local_data.shim_data, hash) ? 0 : -1); + ret = (reg_has(local_data.reg, hash) ? 0 : -1); return ret; } diff --git a/src/ipcpd/local/reg.c b/src/ipcpd/local/reg.c new file mode 100644 index 00000000..36f19b16 --- /dev/null +++ b/src/ipcpd/local/reg.c @@ -0,0 +1,217 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * Names registered with the local IPCP + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#if defined(__linux__) || defined(__CYGWIN__) +#define _DEFAULT_SOURCE +#else +#define _POSIX_C_SOURCE 200112L +#endif + +#define OUROBOROS_PREFIX "local-reg" + +#include <ouroboros/hash.h> +#include <ouroboros/list.h> +#include <ouroboros/logs.h> + +#include "reg.h" +#include "ipcp.h" + +#include <assert.h> +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +struct reg_entry { + struct list_head list; + uint8_t * hash; +}; + +struct reg { + struct list_head names; + pthread_rwlock_t lock; +}; + +static struct reg_entry * reg_entry_create(uint8_t * hash) +{ + struct reg_entry * entry; + + entry = malloc(sizeof(*entry)); + if (entry == NULL) + return NULL; + + list_head_init(&entry->list); + + entry->hash = hash; + + return entry; +} + +static void reg_entry_destroy(struct reg_entry * entry) +{ + assert(entry); + + free(entry->hash); + free(entry); +} + +/* Call with the lock held. */ +static struct reg_entry * reg_find(struct reg * reg, + const uint8_t * hash) +{ + struct list_head * p; + + list_for_each(p, ®->names) { + struct reg_entry * e; + + e = list_entry(p, struct reg_entry, list); + if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) + return e; + } + + return NULL; +} + +struct reg * reg_create(void) +{ + struct reg * reg; + + reg = malloc(sizeof(*reg)); + if (reg == NULL) + goto fail_malloc; + + list_head_init(®->names); + + if (pthread_rwlock_init(®->lock, NULL) < 0) + goto fail_lock; + + return reg; + + fail_lock: + free(reg); + fail_malloc: + return NULL; +} + +void reg_destroy(struct reg * reg) +{ + if (reg == NULL) + return; + + pthread_rwlock_wrlock(®->lock); + + while (!list_is_empty(®->names)) { + struct reg_entry * e; + + e = list_first_entry(®->names, struct reg_entry, list); + + list_del(&e->list); + + reg_entry_destroy(e); + } + + pthread_rwlock_unlock(®->lock); + + pthread_rwlock_destroy(®->lock); + + free(reg); +} + +int reg_add(struct reg * reg, + const uint8_t * hash) +{ + struct reg_entry * entry; + uint8_t * dup; + + assert(reg); + assert(hash); + + pthread_rwlock_wrlock(®->lock); + + if (reg_find(reg, hash) != NULL) { + pthread_rwlock_unlock(®->lock); + log_dbg(HASH_FMT32 " was already registered.", + HASH_VAL32(hash)); + return 0; + } + + dup = ipcp_hash_dup(hash); + if (dup == NULL) + goto fail; + + entry = reg_entry_create(dup); + if (entry == NULL) { + free(dup); + goto fail; + } + + list_add(&entry->list, ®->names); + + pthread_rwlock_unlock(®->lock); + + return 0; + + fail: + pthread_rwlock_unlock(®->lock); + return -1; +} + +int reg_del(struct reg * reg, + const uint8_t * hash) +{ + struct reg_entry * e; + + if (reg == NULL) + return -1; + + pthread_rwlock_wrlock(®->lock); + + e = reg_find(reg, hash); + if (e == NULL) { + pthread_rwlock_unlock(®->lock); + return 0; /* nothing to do */ + } + + list_del(&e->list); + + pthread_rwlock_unlock(®->lock); + + reg_entry_destroy(e); + + return 0; +} + +bool reg_has(struct reg * reg, + const uint8_t * hash) +{ + bool ret; + + assert(reg); + assert(hash); + + pthread_rwlock_rdlock(®->lock); + + ret = reg_find(reg, hash) != NULL; + + pthread_rwlock_unlock(®->lock); + + return ret; +} diff --git a/src/ipcpd/local/reg.h b/src/ipcpd/local/reg.h new file mode 100644 index 00000000..2c6142bb --- /dev/null +++ b/src/ipcpd/local/reg.h @@ -0,0 +1,45 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * Names registered with the local IPCP + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_IPCPD_LOCAL_REG_H +#define OUROBOROS_IPCPD_LOCAL_REG_H + +#include <stdbool.h> +#include <stdint.h> + +/* The hashes of the names registered with this IPCP. */ +struct reg; + +struct reg * reg_create(void); + +void reg_destroy(struct reg * reg); + +int reg_add(struct reg * reg, + const uint8_t * hash); + +int reg_del(struct reg * reg, + const uint8_t * hash); + +bool reg_has(struct reg * reg, + const uint8_t * hash); + +#endif /* OUROBOROS_IPCPD_LOCAL_REG_H */ |
