summaryrefslogtreecommitdiff
path: root/src/ipcpd/shim-data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/shim-data.c')
-rw-r--r--src/ipcpd/shim-data.c582
1 files changed, 0 insertions, 582 deletions
diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c
deleted file mode 100644
index 90a676da..00000000
--- a/src/ipcpd/shim-data.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2026
- *
- * IPC process utilities
- *
- * 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
-
-#include "config.h"
-
-#define OUROBOROS_PREFIX "shim-data"
-
-#include <ouroboros/errno.h>
-#include <ouroboros/hash.h>
-#include <ouroboros/list.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/time.h>
-
-#include "shim-data.h"
-#include "ipcp.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct reg_entry {
- struct list_head list;
- uint8_t * hash;
-};
-
-struct dir_entry {
- struct list_head list;
- uint8_t * hash;
- struct addr addr;
-};
-
-static void destroy_dir_query(struct dir_query * query)
-{
- assert(query);
-
- pthread_mutex_lock(&query->lock);
-
- switch (query->state) {
- case QUERY_INIT:
- query->state = QUERY_DONE;
- break;
- case QUERY_PENDING:
- query->state = QUERY_DESTROY;
- pthread_cond_broadcast(&query->cond);
- break;
- case QUERY_RESPONSE:
- case QUERY_DONE:
- break;
- case QUERY_DESTROY:
- pthread_mutex_unlock(&query->lock);
- return;
- default:
- assert(false);
- return;
- }
-
- while (query->state != QUERY_DONE)
- pthread_cond_wait(&query->cond, &query->lock);
-
- pthread_mutex_unlock(&query->lock);
-
- pthread_cond_destroy(&query->cond);
- pthread_mutex_destroy(&query->lock);
-
- free(query->hash);
- free(query);
-}
-
-static struct reg_entry * reg_entry_create(uint8_t * hash)
-{
- struct reg_entry * entry = malloc(sizeof(*entry));
- if (entry == NULL)
- return NULL;
-
- assert(hash);
-
- entry->hash = hash;
-
- return entry;
-}
-
-static void reg_entry_destroy(struct reg_entry * entry)
-{
- assert(entry);
-
- free(entry->hash);
- free(entry);
-}
-
-static struct dir_entry * dir_entry_create(uint8_t * hash,
- struct addr addr)
-{
- struct dir_entry * entry = malloc(sizeof(*entry));
- if (entry == NULL)
- return NULL;
-
- assert(hash);
-
- entry->addr = addr;
- entry->hash = hash;
-
- return entry;
-}
-
-static void dir_entry_destroy(struct dir_entry * entry)
-{
- assert(entry);
-
- free(entry->hash);
- free(entry);
-}
-
-struct shim_data * shim_data_create(void)
-{
- struct shim_data * sd;
-
- sd = malloc(sizeof(*sd));
- if (sd == NULL)
- return NULL;
-
- /* init the lists */
- list_head_init(&sd->registry);
- list_head_init(&sd->directory);
- list_head_init(&sd->dir_queries);
-
- /* init the locks */
- if (pthread_rwlock_init(&sd->reg_lock, NULL) < 0)
- goto fail_reg_lock_init;
-
- if (pthread_rwlock_init(&sd->dir_lock, NULL) < 0)
- goto fail_dir_lock_init;
-
- if (pthread_mutex_init(&sd->dir_queries_lock, NULL) < 0)
- goto fail_mutex_init;
-
- return sd;
-
- fail_mutex_init:
- pthread_rwlock_destroy(&sd->dir_lock);
- fail_dir_lock_init:
- pthread_rwlock_destroy(&sd->reg_lock);
- fail_reg_lock_init:
- return NULL;
-}
-
-static void clear_registry(struct shim_data * data)
-{
- struct list_head * h;
- struct list_head * t;
-
- assert(data);
-
- list_for_each_safe(h, t, &data->registry) {
- struct reg_entry * e = list_entry(h, struct reg_entry, list);
- list_del(&e->list);
- reg_entry_destroy(e);
- }
-}
-
-static void clear_directory(struct shim_data * data)
-{
- struct list_head * h;
- struct list_head * t;
-
- assert(data);
-
- list_for_each_safe(h, t, &data->directory) {
- struct dir_entry * e = list_entry(h, struct dir_entry, list);
- list_del(&e->list);
- dir_entry_destroy(e);
- }
-}
-
-static void clear_dir_queries(struct shim_data * data)
-{
- struct list_head * h;
- struct list_head * t;
-
- assert(data);
-
- list_for_each_safe(h, t, &data->dir_queries) {
- struct dir_query * e = list_entry(h, struct dir_query, next);
- list_del(&e->next);
- destroy_dir_query(e);
- }
-}
-
-void shim_data_destroy(struct shim_data * data)
-{
- if (data == NULL)
- return;
-
- /* clear the lists */
- pthread_rwlock_wrlock(&data->reg_lock);
- clear_registry(data);
- pthread_rwlock_unlock(&data->reg_lock);
-
- pthread_rwlock_wrlock(&data->dir_lock);
- clear_directory(data);
- pthread_rwlock_unlock(&data->dir_lock);
-
- pthread_mutex_lock(&data->dir_queries_lock);
- clear_dir_queries(data);
- pthread_mutex_unlock(&data->dir_queries_lock);
-
- pthread_rwlock_destroy(&data->dir_lock);
- pthread_rwlock_destroy(&data->reg_lock);
- pthread_mutex_destroy(&data->dir_queries_lock);
-
- free(data);
-}
-
-static struct reg_entry * find_reg_entry_by_hash(struct shim_data * data,
- const uint8_t * hash)
-{
- struct list_head * h;
-
- assert(data);
- assert(hash);
-
- list_for_each(h, &data->registry) {
- struct reg_entry * e = list_entry(h, struct reg_entry, list);
- if (!memcmp(e->hash, hash, ipcp_dir_hash_len()))
- return e;
- }
-
- return NULL;
-}
-
-static struct dir_entry * find_dir_entry(struct shim_data * data,
- const uint8_t * hash,
- struct addr addr)
-{
- struct list_head * h;
- list_for_each(h, &data->directory) {
- struct dir_entry * e = list_entry(h, struct dir_entry, list);
- if (memcmp(&e->addr, &addr, sizeof(addr)) != 0)
- continue;
-
- if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0)
- return e;
- }
-
- return NULL;
-}
-
-static struct dir_entry * find_dir_entry_any(struct shim_data * data,
- const uint8_t * hash)
-{
- struct list_head * h;
- list_for_each(h, &data->directory) {
- struct dir_entry * e = list_entry(h, struct dir_entry, list);
- if (!memcmp(e->hash, hash, ipcp_dir_hash_len()))
- return e;
- }
-
- return NULL;
-}
-
-int shim_data_reg_add_entry(struct shim_data * data,
- const uint8_t * hash)
-{
- struct reg_entry * entry;
- uint8_t * hash_dup;
-
- assert(data);
- assert(hash);
-
- pthread_rwlock_wrlock(&data->reg_lock);
-
- if (find_reg_entry_by_hash(data, hash)) {
- pthread_rwlock_unlock(&data->reg_lock);
- log_dbg(HASH_FMT32 " was already in the directory.",
- HASH_VAL32(hash));
- return 0;
- }
-
- hash_dup = ipcp_hash_dup(hash);
- if (hash_dup == NULL) {
- pthread_rwlock_unlock(&data->reg_lock);
- return -1;
- }
-
- entry = reg_entry_create(hash_dup);
- if (entry == NULL) {
- pthread_rwlock_unlock(&data->reg_lock);
- return -1;
- }
-
- list_add(&entry->list, &data->registry);
-
- pthread_rwlock_unlock(&data->reg_lock);
-
- return 0;
-}
-
-int shim_data_reg_del_entry(struct shim_data * data,
- const uint8_t * hash)
-{
- struct reg_entry * e;
- if (data == NULL)
- return -1;
-
- pthread_rwlock_wrlock(&data->reg_lock);
-
- e = find_reg_entry_by_hash(data, hash);
- if (e == NULL) {
- pthread_rwlock_unlock(&data->reg_lock);
- return 0; /* nothing to do */
- }
-
- list_del(&e->list);
-
- pthread_rwlock_unlock(&data->reg_lock);
-
- reg_entry_destroy(e);
-
- return 0;
-}
-
-bool shim_data_reg_has(struct shim_data * data,
- const uint8_t * hash)
-{
- bool ret = false;
-
- assert(data);
- assert(hash);
-
- pthread_rwlock_rdlock(&data->reg_lock);
-
- ret = (find_reg_entry_by_hash(data, hash) != NULL);
-
- pthread_rwlock_unlock(&data->reg_lock);
-
- return ret;
-}
-
-int shim_data_dir_add_entry(struct shim_data * data,
- const uint8_t * hash,
- struct addr addr)
-{
- struct dir_entry * entry;
- uint8_t * entry_hash;
-
- assert(data);
- assert(hash);
-
- pthread_rwlock_wrlock(&data->dir_lock);
-
- if (find_dir_entry(data, hash, addr) != NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return -1;
- }
-
- entry_hash = ipcp_hash_dup(hash);
- if (entry_hash == NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return -1;
- }
-
- entry = dir_entry_create(entry_hash, addr);
- if (entry == NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return -1;
- }
-
- list_add(&entry->list,&data->directory);
-
- pthread_rwlock_unlock(&data->dir_lock);
-
- return 0;
-}
-
-int shim_data_dir_del_entry(struct shim_data * data,
- const uint8_t * hash,
- struct addr addr)
-{
- struct dir_entry * e;
- if (data == NULL)
- return -1;
-
- pthread_rwlock_wrlock(&data->dir_lock);
-
- e = find_dir_entry(data, hash, addr);
- if (e == NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return 0; /* nothing to do */
- }
-
- list_del(&e->list);
-
- pthread_rwlock_unlock(&data->dir_lock);
-
- dir_entry_destroy(e);
-
- return 0;
-}
-
-bool shim_data_dir_has(struct shim_data * data,
- const uint8_t * hash)
-{
- bool ret = false;
-
- pthread_rwlock_rdlock(&data->dir_lock);
-
- ret = (find_dir_entry_any(data, hash) != NULL);
-
- pthread_rwlock_unlock(&data->dir_lock);
-
- return ret;
-}
-
-struct addr shim_data_dir_get_addr(struct shim_data * data,
- const uint8_t * hash)
-{
- struct dir_entry * entry;
- struct addr addr = {0};
-
- pthread_rwlock_rdlock(&data->dir_lock);
-
- entry = find_dir_entry_any(data, hash);
- if (entry == NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- log_warn("No address for " HASH_FMT32 ".", HASH_VAL32(hash));
- return addr; /* undefined behaviour, 0 may be a valid address */
- }
-
- addr = entry->addr;
-
- pthread_rwlock_unlock(&data->dir_lock);
-
- return addr;
-}
-
-struct dir_query * shim_data_dir_query_create(struct shim_data * data,
- const uint8_t * hash)
-{
- struct dir_query * query;
- pthread_condattr_t cattr;
-
- query = malloc(sizeof(*query));
- if (query == NULL)
- return NULL;
-
- query->hash = ipcp_hash_dup(hash);
- if (query->hash == NULL) {
- free(query);
- return NULL;
- }
-
- query->state = QUERY_INIT;
-
- pthread_condattr_init(&cattr);
-#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
-#endif
- pthread_cond_init(&query->cond, &cattr);
- pthread_mutex_init(&query->lock, NULL);
-
- list_head_init(&query->next);
-
- pthread_mutex_lock(&data->dir_queries_lock);
- list_add(&query->next, &data->dir_queries);
- pthread_mutex_unlock(&data->dir_queries_lock);
-
- return query;
-}
-
-void shim_data_dir_query_respond(struct shim_data * data,
- const uint8_t * hash)
-{
- struct dir_query * e = NULL;
- struct list_head * pos;
- bool found = false;
-
- pthread_mutex_lock(&data->dir_queries_lock);
-
- list_for_each(pos, &data->dir_queries) {
- e = list_entry(pos, struct dir_query, next);
-
- if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- pthread_mutex_unlock(&data->dir_queries_lock);
- return;
- }
-
- pthread_mutex_lock(&e->lock);
-
- if (e->state != QUERY_PENDING) {
- pthread_mutex_unlock(&e->lock);
- pthread_mutex_unlock(&data->dir_queries_lock);
- return;
- }
-
- e->state = QUERY_RESPONSE;
- pthread_cond_broadcast(&e->cond);
-
- while (e->state == QUERY_RESPONSE)
- pthread_cond_wait(&e->cond, &e->lock);
-
- pthread_mutex_unlock(&e->lock);
-
- pthread_mutex_unlock(&data->dir_queries_lock);
-}
-
-void shim_data_dir_query_destroy(struct shim_data * data,
- struct dir_query * query)
-{
- pthread_mutex_lock(&data->dir_queries_lock);
-
- list_del(&query->next);
- destroy_dir_query(query);
-
- pthread_mutex_unlock(&data->dir_queries_lock);
-}
-
-int shim_data_dir_query_wait(struct dir_query * query,
- const struct timespec * timeout)
-{
- struct timespec abstime;
- int ret = 0;
-
- assert(query);
- assert(timeout);
-
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
-
- pthread_mutex_lock(&query->lock);
-
- if (query->state != QUERY_INIT) {
- pthread_mutex_unlock(&query->lock);
- return -EINVAL;
- }
-
- query->state = QUERY_PENDING;
-
- while (query->state == QUERY_PENDING && ret != -ETIMEDOUT)
- ret = -pthread_cond_timedwait(&query->cond,
- &query->lock,
- &abstime);
-
- if (query->state == QUERY_DESTROY)
- ret = -1;
-
- query->state = QUERY_DONE;
- pthread_cond_broadcast(&query->cond);
-
- pthread_mutex_unlock(&query->lock);
-
- return ret;
-}