summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/CMakeLists.txt11
-rw-r--r--src/lib/cdap.c868
-rw-r--r--src/lib/cdap.proto32
-rw-r--r--src/lib/cdap_req.c208
-rw-r--r--src/lib/cdap_req.h74
-rw-r--r--src/lib/hashtable.c3
-rw-r--r--src/lib/notifier.c128
-rw-r--r--src/lib/rib.c1431
-rw-r--r--src/lib/ro.proto31
-rw-r--r--src/lib/tests/CMakeLists.txt1
-rw-r--r--src/lib/tests/rib_test.c289
11 files changed, 132 insertions, 2944 deletions
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index eeb7966b..f126a52a 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -8,8 +8,6 @@ protobuf_generate_c(IRM_PROTO_SRCS IRM_PROTO_HDRS irmd_messages.proto)
protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto)
protobuf_generate_c(DIF_CONFIG_PROTO_SRCS DIF_CONFIG_PROTO_HDRS
ipcp_config.proto)
-protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto)
-protobuf_generate_c(RO_PROTO_SRCS RO_PROTO_HDRS ro.proto)
protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)
if (NOT APPLE)
@@ -134,8 +132,6 @@ else ()
endif ()
set(SOCKET_TIMEOUT 1000 CACHE STRING
"Default timeout for responses from IPCPs (ms)")
-set(CDAP_REPLY_TIMEOUT 6000 CACHE STRING
- "Timeout for CDAP to wait for reply")
set(SHM_PREFIX "ouroboros" CACHE STRING
"String to prepend to POSIX shared memory filenames")
set(SHM_RBUFF_PREFIX "/${SHM_PREFIX}.rbuff." CACHE INTERNAL
@@ -154,8 +150,6 @@ set(SOURCE_FILES
bitmap.c
btree.c
cacep.c
- cdap.c
- cdap_req.c
crc32.c
dev.c
frct_pci.c
@@ -166,10 +160,10 @@ set(SOURCE_FILES
lockfile.c
logs.c
md5.c
+ notifier.c
qos.c
qoscube.c
random.c
- rib.c
sha3.c
shm_flow_set.c
shm_rbuff.c
@@ -185,8 +179,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS}
- ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS}
- ${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS})
+ ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} ${CACEP_PROTO_SRCS})
include(AddCompileFlags)
if (CMAKE_BUILD_TYPE MATCHES Debug)
diff --git a/src/lib/cdap.c b/src/lib/cdap.c
deleted file mode 100644
index d9cb2036..00000000
--- a/src/lib/cdap.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * The Common Distributed Application Protocol
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200809L
-
-#include <ouroboros/cdap.h>
-#include <ouroboros/bitmap.h>
-#include <ouroboros/dev.h>
-#include <ouroboros/fqueue.h>
-#include <ouroboros/errno.h>
-
-#include "cdap_req.h"
-
-#include <stdlib.h>
-#include <pthread.h>
-#include <string.h>
-#include <assert.h>
-
-#include "cdap.pb-c.h"
-typedef Cdap cdap_t;
-
-#define CDAP_REPLY (CDAP_DELETE + 1)
-
-#define INVALID_ID -1
-#define IDS_SIZE 2048
-#define BUF_SIZE 2048
-
-struct fd_el {
- struct list_head next;
-
- int fd;
-};
-
-struct cdap {
- fset_t * set;
- fqueue_t * fq;
-
- bool proc;
- pthread_mutex_t mtx;
- pthread_cond_t cond;
-
- size_t n_flows;
- struct list_head flows;
- pthread_rwlock_t flows_lock;
-
- struct bmp * ids;
- pthread_mutex_t ids_lock;
-
- struct list_head sent;
- pthread_rwlock_t sent_lock;
-
- struct list_head rcvd;
- pthread_cond_t rcvd_cond;
- pthread_mutex_t rcvd_lock;
-
- pthread_t reader;
-};
-
-struct cdap_rcvd {
- struct list_head next;
-
- int fd;
- bool proc;
-
- invoke_id_t iid;
- cdap_key_t key;
-
- enum cdap_opcode opcode;
- char * name;
- void * data;
- size_t len;
- uint32_t flags;
-};
-
-static int next_id(struct cdap * instance)
-{
- int ret;
-
- assert(instance);
-
- pthread_mutex_lock(&instance->ids_lock);
-
- ret = bmp_allocate(instance->ids);
- if (!bmp_is_id_valid(instance->ids, ret))
- ret = INVALID_ID;
-
- pthread_mutex_unlock(&instance->ids_lock);
-
- return ret;
-}
-
-static int release_id(struct cdap * instance,
- int32_t id)
-{
- int ret;
-
- assert(instance);
-
- pthread_mutex_lock(&instance->ids_lock);
-
- ret = bmp_release(instance->ids, id);
-
- pthread_mutex_unlock(&instance->ids_lock);
-
- return ret;
-}
-
-#define cdap_sent_has_key(i, key) (cdap_sent_get_by_key(i, key) != NULL)
-
-static struct cdap_req * cdap_sent_get_by_key(struct cdap * instance,
- cdap_key_t key)
-{
- struct list_head * p = NULL;
- struct cdap_req * req = NULL;
-
- assert(instance);
-
- pthread_rwlock_rdlock(&instance->sent_lock);
-
- list_for_each(p, &instance->sent) {
- req = list_entry(p, struct cdap_req, next);
- if (req->key == key) {
- pthread_rwlock_unlock(&instance->sent_lock);
- return req;
- }
- }
-
- pthread_rwlock_unlock(&instance->sent_lock);
-
- return NULL;
-}
-
-static struct cdap_req * cdap_sent_get_by_iid(struct cdap * instance,
- invoke_id_t iid)
-{
- struct list_head * p = NULL;
- struct cdap_req * req = NULL;
-
- assert(instance);
-
- pthread_rwlock_rdlock(&instance->sent_lock);
-
- list_for_each(p, &instance->sent) {
- req = list_entry(p, struct cdap_req, next);
- if (req->iid == iid) {
- pthread_rwlock_unlock(&instance->sent_lock);
- return req;
- }
- }
-
- pthread_rwlock_unlock(&instance->sent_lock);
-
- return NULL;
-}
-
-static struct cdap_rcvd * cdap_rcvd_get_by_key(struct cdap * instance,
- cdap_key_t key)
-{
- struct list_head * p = NULL;
- struct list_head * h = NULL;
- struct cdap_rcvd * rcvd = NULL;
-
- assert(instance);
-
- pthread_mutex_lock(&instance->rcvd_lock);
-
- list_for_each_safe(p, h, &instance->rcvd) {
- rcvd = list_entry(p, struct cdap_rcvd, next);
- if (rcvd->key == key) {
- list_del(&rcvd->next);
- pthread_mutex_unlock(&instance->rcvd_lock);
- return rcvd;
- }
- }
-
- pthread_mutex_unlock(&instance->rcvd_lock);
-
- assert(false);
-
- return NULL;
-}
-
-static struct cdap_req * cdap_sent_add(struct cdap * instance,
- int fd,
- invoke_id_t iid,
- cdap_key_t key)
-{
- struct cdap_req * req;
-
- assert(instance);
- assert(!cdap_sent_has_key(instance, key));
-
- req = cdap_req_create(fd, iid, key);
- if (req == NULL)
- return NULL;
-
- pthread_rwlock_wrlock(&instance->sent_lock);
-
- list_add(&req->next, &instance->sent);
-
- pthread_rwlock_unlock(&instance->sent_lock);
-
- return req;
-}
-
-static void cdap_sent_del(struct cdap * instance,
- struct cdap_req * req)
-{
- assert(instance);
- assert(req);
-
- assert(cdap_sent_has_key(instance, req->key));
-
- pthread_rwlock_wrlock(&instance->sent_lock);
-
- list_del(&req->next);
-
- pthread_rwlock_unlock(&instance->sent_lock);
-
- cdap_req_destroy(req);
-}
-
-static void cdap_sent_destroy(struct cdap * instance)
-{
- struct list_head * p = NULL;
- struct list_head * h = NULL;
-
- assert(instance);
-
- pthread_rwlock_wrlock(&instance->sent_lock);
-
- list_for_each_safe(p, h, &instance->sent) {
- struct cdap_req * req = list_entry(p, struct cdap_req, next);
- list_del(&req->next);
- cdap_req_cancel(req);
- cdap_req_destroy(req);
- }
-
- pthread_rwlock_unlock(&instance->sent_lock);
-}
-
-static void cdap_rcvd_destroy(struct cdap * instance)
-{
- struct list_head * p = NULL;
- struct list_head * h = NULL;
-
- assert(instance);
-
- pthread_mutex_lock(&instance->rcvd_lock);
-
- list_for_each_safe(p, h, &instance->rcvd) {
- struct cdap_rcvd * r = list_entry(p, struct cdap_rcvd, next);
- list_del(&r->next);
- if (r->data != NULL)
- free(r->data);
- if (r->name != NULL)
- free(r->name);
- free(r);
- }
-
- pthread_cond_broadcast(&instance->rcvd_cond);
-
- pthread_mutex_unlock(&instance->rcvd_lock);
-}
-
-static void set_proc(struct cdap * instance,
- bool status)
-{
- pthread_mutex_lock(&instance->mtx);
-
- instance->proc = status;
- pthread_cond_signal(&instance->cond);
-
- pthread_mutex_unlock(&instance->mtx);
-}
-
-static void * sdu_reader(void * o)
-{
- struct cdap * instance = (struct cdap *) o;
- struct cdap_req * req;
- struct cdap_rcvd * rcvd;
- cdap_t * msg;
- uint8_t buf[BUF_SIZE];
- ssize_t len;
- buffer_t data;
-
- while (fevent(instance->set, instance->fq, NULL)) {
- int fd;
- set_proc(instance, true);
- fd = fqueue_next(instance->fq);
- len = flow_read(fd, buf, BUF_SIZE);
- if (len < 0) {
- set_proc(instance, false);
- continue;
- }
-
- msg = cdap__unpack(NULL, len, buf);
- if (msg == NULL) {
- set_proc(instance, false);
- continue;
- }
-
- if (msg->opcode != CDAP_REPLY) {
- rcvd = malloc(sizeof(*rcvd));
- if (rcvd == NULL) {
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- continue;
- }
-
- assert(msg->name);
-
- rcvd->opcode = msg->opcode;
- rcvd->fd = fd;
- rcvd->iid = msg->invoke_id;
- rcvd->key = next_id(instance);
- if (rcvd->key == INVALID_ID) {
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- free(rcvd);
- continue;
- }
-
- rcvd->flags = msg->flags;
- rcvd->proc = false;
- rcvd->name = strdup(msg->name);
- if (rcvd->name == NULL) {
- release_id(instance, rcvd->key);
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- free(rcvd);
- continue;
- }
-
- if (msg->has_value) {
- rcvd->len = msg->value.len;
- rcvd->data = malloc(rcvd->len);
- if (rcvd->data == NULL) {
- release_id(instance, rcvd->key);
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- free(rcvd->name);
- free(rcvd);
- continue;
- }
- memcpy(rcvd->data, msg->value.data, rcvd->len);
- } else {
- rcvd->len = 0;
- rcvd->data = NULL;
- }
-
- pthread_mutex_lock(&instance->rcvd_lock);
-
- list_add(&rcvd->next, &instance->rcvd);
-
- pthread_cond_signal(&instance->rcvd_cond);
- pthread_mutex_unlock(&instance->rcvd_lock);
- } else {
- req = cdap_sent_get_by_iid(instance, msg->invoke_id);
- if (req == NULL) {
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- continue;
- }
-
- if (msg->has_value) {
- data.len = msg->value.len;
- data.data = malloc(data.len);
- if (data.data == NULL) {
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- continue;
- }
- memcpy(data.data, msg->value.data, data.len);
- } else {
- data.len = 0;
- data.data = NULL;
- }
-
- cdap_req_respond(req, msg->result, data);
- }
-
- cdap__free_unpacked(msg, NULL);
- set_proc(instance, false);
- }
-
- return (void *) 0;
-}
-
-struct cdap * cdap_create()
-{
- struct cdap * instance = NULL;
-
- instance = malloc(sizeof(*instance));
- if (instance == NULL)
- goto fail_malloc;
-
- if (pthread_rwlock_init(&instance->flows_lock, NULL))
- goto fail_flows_lock;
-
- if (pthread_mutex_init(&instance->ids_lock, NULL))
- goto fail_ids_lock;
-
- if (pthread_mutex_init(&instance->rcvd_lock, NULL))
- goto fail_rcvd_lock;
-
- if (pthread_rwlock_init(&instance->sent_lock, NULL))
- goto fail_sent_lock;
-
- if (pthread_cond_init(&instance->rcvd_cond, NULL))
- goto fail_rcvd_cond;
-
- if (pthread_mutex_init(&instance->mtx, NULL))
- goto fail_mtx;
-
- if (pthread_cond_init(&instance->cond, NULL))
- goto fail_cond;
-
- instance->ids = bmp_create(IDS_SIZE, 0);
- if (instance->ids == NULL)
- goto fail_bmp_create;
-
- instance->set = fset_create();
- if (instance->set == NULL)
- goto fail_set_create;
-
- instance->fq = fqueue_create();
- if (instance->fq == NULL)
- goto fail_fqueue_create;
-
- instance->n_flows = 0;
- instance->proc = false;
-
- list_head_init(&instance->flows);
- list_head_init(&instance->sent);
- list_head_init(&instance->rcvd);
-
- if (pthread_create(&instance->reader, NULL, sdu_reader, instance))
- goto fail_pthread_create;
-
- return instance;
-
- fail_pthread_create:
- fqueue_destroy(instance->fq);
- fail_fqueue_create:
- fset_destroy(instance->set);
- fail_set_create:
- bmp_destroy(instance->ids);
- fail_bmp_create:
- pthread_cond_destroy(&instance->cond);
- fail_cond:
- pthread_mutex_destroy(&instance->mtx);
- fail_mtx:
- pthread_cond_destroy(&instance->rcvd_cond);
- fail_rcvd_cond:
- pthread_rwlock_destroy(&instance->sent_lock);
- fail_sent_lock:
- pthread_mutex_destroy(&instance->rcvd_lock);
- fail_rcvd_lock:
- pthread_mutex_destroy(&instance->ids_lock);
- fail_ids_lock:
- pthread_rwlock_destroy(&instance->flows_lock);
- fail_flows_lock:
- free(instance);
- fail_malloc:
- return NULL;
-}
-
-int cdap_destroy(struct cdap * instance)
-{
- struct list_head * p;
- struct list_head * h;
-
- if (instance == NULL)
- return 0;
-
- pthread_cancel(instance->reader);
- pthread_join(instance->reader, NULL);
-
- fqueue_destroy(instance->fq);
-
- fset_destroy(instance->set);
-
- pthread_cond_destroy(&instance->cond);
- pthread_mutex_destroy(&instance->mtx);
-
- pthread_rwlock_wrlock(&instance->flows_lock);
-
- list_for_each_safe(p,h, &instance->flows) {
- struct fd_el * e = list_entry(p, struct fd_el, next);
- list_del(&e->next);
- free(e);
- }
-
- pthread_rwlock_unlock(&instance->flows_lock);
-
- pthread_rwlock_destroy(&instance->flows_lock);
-
- pthread_mutex_lock(&instance->ids_lock);
-
- bmp_destroy(instance->ids);
-
- pthread_mutex_unlock(&instance->ids_lock);
-
- pthread_mutex_destroy(&instance->ids_lock);
-
- cdap_sent_destroy(instance);
-
- pthread_rwlock_destroy(&instance->sent_lock);
-
- cdap_rcvd_destroy(instance);
-
- pthread_mutex_destroy(&instance->rcvd_lock);
-
- free(instance);
-
- return 0;
-}
-
-int cdap_add_flow(struct cdap * instance,
- int fd)
-{
- struct fd_el * e;
-
- if (fd < 0)
- return -EINVAL;
-
- e = malloc(sizeof(*e));
- if (e == NULL)
- return -ENOMEM;
-
- e->fd = fd;
-
- pthread_rwlock_wrlock(&instance->flows_lock);
-
- if (fset_add(instance->set, fd)) {
- pthread_rwlock_unlock(&instance->flows_lock);
- free(e);
- return -1;
- }
-
- list_add(&e->next, &instance->flows);
-
- ++instance->n_flows;
-
- pthread_rwlock_unlock(&instance->flows_lock);
-
- return 0;
-}
-
-int cdap_del_flow(struct cdap * instance,
- int fd)
-{
- struct list_head * p;
- struct list_head * h;
-
- if (fd < 0)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&instance->flows_lock);
-
- fset_del(instance->set, fd);
-
- list_for_each_safe(p, h, &instance->flows) {
- struct fd_el * e = list_entry(p, struct fd_el, next);
- if (e->fd == fd) {
- list_del(&e->next);
- free(e);
- break;
- }
- }
-
- --instance->n_flows;
-
- pthread_rwlock_unlock(&instance->flows_lock);
-
- pthread_mutex_lock(&instance->mtx);
-
- pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
- (void *) &instance->mtx);
-
- while (instance->proc)
- pthread_cond_wait(&instance->cond, &instance->mtx);
-
- pthread_cleanup_pop(true);
-
- return 0;
-}
-
-static int write_msg(int fd,
- cdap_t * msg)
-{
- uint8_t * data;
- size_t len;
-
- assert(msg);
-
- len = cdap__get_packed_size(msg);
- if (len == 0)
- return -1;
-
- data = malloc(len);
- if (data == NULL)
- return -ENOMEM;
-
- cdap__pack(msg, data);
-
- if (flow_write(fd, data, len)) {
- free(data);
- return -1;
- }
-
- free(data);
-
- return 0;
-}
-
-cdap_key_t * cdap_request_send(struct cdap * instance,
- enum cdap_opcode code,
- const char * name,
- const void * data,
- size_t len,
- uint32_t flags)
-{
- cdap_key_t * keys;
- cdap_key_t * key;
- cdap_t msg = CDAP__INIT;
- struct list_head * p;
- int ret;
-
- if (instance == NULL || name == NULL || code > CDAP_DELETE)
- return NULL;
-
- pthread_rwlock_rdlock(&instance->flows_lock);
-
- keys = malloc(sizeof(*keys) * (instance->n_flows + 1));
- if (keys == NULL) {
- pthread_rwlock_unlock(&instance->flows_lock);
- return NULL;
- }
-
- memset(keys, INVALID_CDAP_KEY, sizeof(*keys) * (instance->n_flows + 1));
-
- key = keys;
-
- cdap__init(&msg);
-
- msg.opcode = code;
- msg.name = (char *) name;
- msg.has_flags = true;
- msg.flags = flags;
-
- if (data != NULL) {
- msg.has_value = true;
- msg.value.data = (uint8_t *) data;
- msg.value.len = len;
- }
-
- list_for_each(p, &instance->flows) {
- struct cdap_req * req;
- invoke_id_t iid;
- struct fd_el * e;
-
- iid = next_id(instance);
- if (iid == INVALID_ID) {
- pthread_rwlock_unlock(&instance->flows_lock);
- return keys;
- }
-
- msg.invoke_id = iid;
-
- e = list_entry(p, struct fd_el, next);
-
- *key = next_id(instance);
- if (*key == INVALID_ID) {
- release_id(instance, iid);
- pthread_rwlock_unlock(&instance->flows_lock);
- return keys;
- }
-
- req = cdap_sent_add(instance, e->fd, iid, *key);
- if (req == NULL) {
- release_id(instance, *key);
- release_id(instance, iid);
- pthread_rwlock_unlock(&instance->flows_lock);
- *key = INVALID_CDAP_KEY;
- return keys;
- }
-
- ret = write_msg(e->fd, &msg);
- if (ret == -ENOMEM) {
- cdap_sent_del(instance, req);
- release_id(instance, *key);
- release_id(instance, iid);
- pthread_rwlock_unlock(&instance->flows_lock);
- *key = INVALID_CDAP_KEY;
- return keys;
- }
-
- if (ret < 0) {
- cdap_sent_del(instance, req);
- release_id(instance, *key);
- release_id(instance, iid);
- pthread_rwlock_unlock(&instance->flows_lock);
- *key = INVALID_CDAP_KEY;
- return keys;
- }
-
- ++key;
- }
-
- pthread_rwlock_unlock(&instance->flows_lock);
-
- return keys;
-}
-
-int cdap_reply_wait(struct cdap * instance,
- cdap_key_t key,
- uint8_t ** data,
- size_t * len)
-{
- int ret;
- struct cdap_req * r;
- invoke_id_t iid;
-
- if (instance == NULL || (data != NULL && len == NULL))
- return -EINVAL;
-
- r = cdap_sent_get_by_key(instance, key);
- if (r == NULL)
- return -EINVAL;
-
- iid = r->iid;
-
- ret = cdap_req_wait(r);
- if (ret < 0) {
- cdap_sent_del(instance, r);
- release_id(instance, iid);
- release_id(instance, key);
- return ret;
- }
-
- assert(ret == 0);
-
- if (data != NULL) {
- *data = r->data.data;
- *len = r->data.len;
- }
-
- ret = r->response;
-
- cdap_sent_del(instance, r);
- release_id(instance, iid);
- release_id(instance, key);
-
- return ret;
-}
-
-cdap_key_t cdap_request_wait(struct cdap * instance,
- enum cdap_opcode * opcode,
- char ** name,
- uint8_t ** data,
- size_t * len,
- uint32_t * flags)
-{
- struct cdap_rcvd * rcv = NULL;
-
- if (instance == NULL || opcode == NULL || name == NULL || data == NULL
- || len == NULL || flags == NULL)
- return -EINVAL;
-
- pthread_mutex_lock(&instance->rcvd_lock);
-
- pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
- (void *) &instance->rcvd_lock);
-
- while (rcv == NULL) {
- while (list_is_empty(&instance->rcvd))
- pthread_cond_wait(&instance->rcvd_cond,
- &instance->rcvd_lock);
-
- rcv = list_first_entry(&instance->rcvd, struct cdap_rcvd, next);
- if (rcv->proc) {
- rcv = NULL;
- pthread_cond_wait(&instance->rcvd_cond,
- &instance->rcvd_lock);
- }
- }
-
- assert(rcv->proc == false);
-
- rcv->proc = true;
- list_del(&rcv->next);
- list_add_tail(&rcv->next, &instance->rcvd);
-
- pthread_cleanup_pop(true);
-
- *opcode = rcv->opcode;
- *name = rcv->name;
- *data = rcv->data;
- *len = rcv->len;
- *flags = rcv->flags;
-
- rcv->name = NULL;
- rcv->data = NULL;
-
- return rcv->key;
-}
-
-int cdap_reply_send(struct cdap * instance,
- cdap_key_t key,
- int result,
- const void * data,
- size_t len)
-{
- int fd;
- cdap_t msg = CDAP__INIT;
- struct cdap_rcvd * rcvd;
-
- if (instance == NULL)
- return -EINVAL;
-
- rcvd = cdap_rcvd_get_by_key(instance, key);
- if (rcvd == NULL)
- return -1;
-
- msg.opcode = CDAP_REPLY;
- msg.invoke_id = rcvd->iid;
- msg.has_result = true;
- msg.result = result;
-
- if (data != NULL) {
- msg.has_value = true;
- msg.value.data = (uint8_t *) data;
- msg.value.len = len;
- }
-
- fd = rcvd->fd;
-
- release_id(instance, rcvd->key);
-
- assert(rcvd->data == NULL);
- assert(rcvd->name == NULL);
- assert(rcvd->proc);
-
- free(rcvd);
-
- return write_msg(fd, &msg);
-}
diff --git a/src/lib/cdap.proto b/src/lib/cdap.proto
deleted file mode 100644
index 29effc9a..00000000
--- a/src/lib/cdap.proto
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016- 2017
- *
- * CDAP message
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-syntax = "proto2";
-
-message cdap {
- required uint32 opcode = 1;
- required uint32 invoke_id = 2;
- optional uint32 flags = 3;
- optional string name = 4;
- optional bytes value = 5;
- optional int32 result = 6;
-}
diff --git a/src/lib/cdap_req.c b/src/lib/cdap_req.c
deleted file mode 100644
index a9b85525..00000000
--- a/src/lib/cdap_req.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * CDAP - CDAP request management
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200809L
-
-#include "config.h"
-
-#include <ouroboros/time_utils.h>
-#include <ouroboros/errno.h>
-
-#include "cdap_req.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-struct cdap_req * cdap_req_create(int fd,
- invoke_id_t iid,
- cdap_key_t key)
-{
- struct cdap_req * creq = malloc(sizeof(*creq));
- pthread_condattr_t cattr;
-
- if (creq == NULL)
- return NULL;
-
- creq->fd = fd;
- creq->iid = iid;
- creq->key = key;
- creq->state = REQ_INIT;
- creq->response = -1;
- creq->data.data = NULL;
- creq->data.len = 0;
-
- if (pthread_mutex_init(&creq->lock, NULL)) {
- free(creq);
- return NULL;
- }
-
- pthread_condattr_init(&cattr);
-#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
-#endif
- if (pthread_cond_init(&creq->cond, &cattr)) {
- pthread_condattr_destroy(&cattr);
- pthread_mutex_destroy(&creq->lock);
- free(creq);
- return NULL;
- }
-
- pthread_condattr_destroy(&cattr);
-
- list_head_init(&creq->next);
-
- clock_gettime(PTHREAD_COND_CLOCK, &creq->birth);
-
- return creq;
-}
-
-void cdap_req_destroy(struct cdap_req * creq)
-{
- assert(creq);
-
- pthread_mutex_lock(&creq->lock);
-
- switch(creq->state) {
- case REQ_DESTROY:
- pthread_mutex_unlock(&creq->lock);
- return;
- case REQ_INIT:
- creq->state = REQ_NULL;
- pthread_cond_broadcast(&creq->cond);
- break;
- case REQ_INIT_PENDING:
- case REQ_PENDING:
- case REQ_RESPONSE:
- creq->state = REQ_DESTROY;
- pthread_cond_broadcast(&creq->cond);
- break;
- default:
- break;
- }
-
- while (creq->state != REQ_NULL)
- pthread_cond_wait(&creq->cond, &creq->lock);
-
- pthread_mutex_unlock(&creq->lock);
-
- pthread_cond_destroy(&creq->cond);
- pthread_mutex_destroy(&creq->lock);
-
- free(creq);
-}
-
-int cdap_req_wait(struct cdap_req * creq)
-{
- struct timespec timeout = {(CDAP_REPLY_TIMEOUT / 1000),
- (CDAP_REPLY_TIMEOUT % 1000) * MILLION};
- struct timespec abstime;
- int ret = -1;
-
- assert(creq);
-
- ts_add(&creq->birth, &timeout, &abstime);
-
- pthread_mutex_lock(&creq->lock);
-
- if (creq->state != REQ_INIT) {
- pthread_mutex_unlock(&creq->lock);
- return -EINVAL;
- }
-
- creq->state = REQ_PENDING;
- pthread_cond_broadcast(&creq->cond);
-
- while (creq->state == REQ_PENDING && ret != -ETIMEDOUT)
- ret = -pthread_cond_timedwait(&creq->cond,
- &creq->lock,
- &abstime);
-
- switch(creq->state) {
- case REQ_DESTROY:
- ret = -1;
- /* FALLTHRU */
- case REQ_PENDING:
- creq->state = REQ_NULL;
- pthread_cond_broadcast(&creq->cond);
- break;
- case REQ_RESPONSE:
- creq->state = REQ_DONE;
- pthread_cond_broadcast(&creq->cond);
- break;
- default:
- assert(false);
- break;
- }
-
- pthread_mutex_unlock(&creq->lock);
-
- return ret;
-}
-
-void cdap_req_respond(struct cdap_req * creq,
- int response,
- buffer_t data)
-{
- assert(creq);
-
- pthread_mutex_lock(&creq->lock);
-
- if (creq->state == REQ_INIT)
- creq->state = REQ_INIT_PENDING;
-
- while (creq->state == REQ_INIT_PENDING)
- pthread_cond_wait(&creq->cond, &creq->lock);
-
- if (creq->state != REQ_PENDING) {
- creq->state = REQ_NULL;
- pthread_cond_broadcast(&creq->cond);
- pthread_mutex_unlock(&creq->lock);
- return;
- }
-
- creq->state = REQ_RESPONSE;
- creq->response = response;
- creq->data = data;
-
- pthread_cond_broadcast(&creq->cond);
-
- while (creq->state == REQ_RESPONSE)
- pthread_cond_wait(&creq->cond, &creq->lock);
-
- creq->state = REQ_NULL;
- pthread_cond_broadcast(&creq->cond);
-
- pthread_mutex_unlock(&creq->lock);
-}
-
-
-void cdap_req_cancel(struct cdap_req * creq)
-{
- assert(creq);
-
- pthread_mutex_lock(&creq->lock);
-
- creq->state = REQ_NULL;
- pthread_cond_broadcast(&creq->cond);
-
- pthread_mutex_unlock(&creq->lock);
-}
diff --git a/src/lib/cdap_req.h b/src/lib/cdap_req.h
deleted file mode 100644
index 4c9cd15b..00000000
--- a/src/lib/cdap_req.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * CDAP - CDAP request management
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_CDAP_REQ_H
-#define OUROBOROS_CDAP_REQ_H
-
-#include <ouroboros/cdap.h>
-#include <ouroboros/list.h>
-#include <ouroboros/utils.h>
-
-#include <pthread.h>
-
-typedef cdap_key_t invoke_id_t;
-
-enum creq_state {
- REQ_NULL = 0,
- REQ_INIT,
- REQ_INIT_PENDING,
- REQ_PENDING,
- REQ_RESPONSE,
- REQ_DONE,
- REQ_DESTROY
-};
-
-struct cdap_req {
- struct list_head next;
-
- int fd;
- struct timespec birth;
- cdap_key_t key;
- invoke_id_t iid;
-
- int response;
- buffer_t data;
-
- enum creq_state state;
- pthread_cond_t cond;
- pthread_mutex_t lock;
-};
-
-struct cdap_req * cdap_req_create(int fd,
- cdap_key_t key,
- invoke_id_t iid);
-
-void cdap_req_destroy(struct cdap_req * creq);
-
-int cdap_req_wait(struct cdap_req * creq);
-
-void cdap_req_respond(struct cdap_req * creq,
- int response,
- buffer_t data);
-
-void cdap_req_cancel(struct cdap_req * creq);
-
-#endif /* OUROBOROS_CDAP_REQ_H */
diff --git a/src/lib/hashtable.c b/src/lib/hashtable.c
index 75cdee84..2aa248ba 100644
--- a/src/lib/hashtable.c
+++ b/src/lib/hashtable.c
@@ -38,7 +38,8 @@ struct htable {
uint64_t buckets_size;
};
-struct htable * htable_create(uint64_t buckets, bool hash_key)
+struct htable * htable_create(uint64_t buckets,
+ bool hash_key)
{
struct htable * tmp;
unsigned int i;
diff --git a/src/lib/notifier.c b/src/lib/notifier.c
new file mode 100644
index 00000000..cfd383d4
--- /dev/null
+++ b/src/lib/notifier.c
@@ -0,0 +1,128 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2017
+ *
+ * Notifier event system using callbacks
+ *
+ * Dimitri Staessens <dimitri.staessens@ugent.be>
+ * Sander Vrijders <sander.vrijders@ugent.be>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#include <ouroboros/errno.h>
+#include <ouroboros/notifier.h>
+#include <ouroboros/list.h>
+
+#include <pthread.h>
+#include <stdlib.h>
+
+struct listener {
+ struct list_head next;
+ notifier_fn_t callback;
+};
+
+struct {
+ struct list_head listeners;
+ pthread_mutex_t lock;
+} notifier;
+
+int notifier_init(void)
+{
+ if (pthread_mutex_init(&notifier.lock, NULL))
+ return -1;
+
+ list_head_init(&notifier.listeners);
+
+ return 0;
+}
+
+void notifier_fini(void)
+{
+ struct list_head * p;
+ struct list_head * h;
+
+ pthread_mutex_lock(&notifier.lock);
+
+ list_for_each_safe(p, h, &notifier.listeners) {
+ struct listener * l = list_entry(p, struct listener, next);
+ list_del(&l->next);
+ free(l);
+ }
+
+ pthread_mutex_unlock(&notifier.lock);
+
+ pthread_mutex_destroy(&notifier.lock);
+}
+
+void notifier_event(int event,
+ const void * o)
+{
+ struct list_head * p;
+
+ pthread_mutex_lock(&notifier.lock);
+
+ list_for_each(p, &notifier.listeners)
+ list_entry(p, struct listener, next)->callback(event, o);
+
+ pthread_mutex_unlock(&notifier.lock);
+}
+
+int notifier_reg(notifier_fn_t callback)
+{
+ struct listener * l;
+ struct list_head * p;
+
+ pthread_mutex_lock(&notifier.lock);
+
+ list_for_each(p, &notifier.listeners) {
+ struct listener * l = list_entry(p, struct listener, next);
+ if (l->callback == callback) {
+ pthread_mutex_unlock(&notifier.lock);
+ return -EPERM;
+ }
+ }
+
+ l = malloc(sizeof(*l));
+ if (l == NULL) {
+ pthread_mutex_unlock(&notifier.lock);
+ return -ENOMEM;
+ }
+
+ l->callback = callback;
+
+ list_add(&l->next, &notifier.listeners);
+
+ pthread_mutex_unlock(&notifier.lock);
+
+ return 0;
+}
+
+void notifier_unreg(notifier_fn_t callback)
+{
+ struct list_head * p;
+ struct list_head * h;
+
+ pthread_mutex_lock(&notifier.lock);
+
+ list_for_each_safe(p, h, &notifier.listeners) {
+ struct listener * l = list_entry(p, struct listener, next);
+ if (l->callback == callback) {
+ list_del(&l->next);
+ free(l);
+ break;
+ }
+ }
+
+ pthread_mutex_unlock(&notifier.lock);
+}
diff --git a/src/lib/rib.c b/src/lib/rib.c
deleted file mode 100644
index 9e45a302..00000000
--- a/src/lib/rib.c
+++ /dev/null
@@ -1,1431 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Resource Information Base
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#define _POSIX_C_SOURCE 200809L
-
-#include "config.h"
-
-#include <ouroboros/errno.h>
-#include <ouroboros/list.h>
-#include <ouroboros/rib.h>
-#include <ouroboros/rqueue.h>
-#include <ouroboros/bitmap.h>
-#include <ouroboros/crc32.h>
-#include <ouroboros/time_utils.h>
-#include <ouroboros/sha3.h>
-#include <ouroboros/btree.h>
-
-#include "ro.pb-c.h"
-typedef RoMsg ro_msg_t;
-
-#include <pthread.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define RIB_PATH_DLR "/"
-#define RIB_BTREE_ORDER 64
-#define GEN_NAME_SIZE 8
-
-struct revent {
- struct list_head next;
-
- char * path;
- int32_t flags;
-};
-
-struct rqueue {
- struct list_head events;
-};
-
-struct ro_set {
- uint32_t sid;
-};
-
-struct rn_ptr {
- struct list_head next;
-
- struct rnode * node;
-};
-
-struct rib_sub {
- struct list_head next;
-
- uint32_t sid;
-
- struct list_head rnodes;
-
- struct list_head events;
-
- pthread_cond_t cond;
- pthread_mutex_t lock;
-};
-
-struct rn_sub {
- struct list_head next;
-
- struct rib_sub * sub;
- int32_t flags;
-};
-
-struct rnode {
- char * path;
- char * name;
-
- uint8_t * data;
- size_t len;
-
- uint8_t sha3[SHA3_256_HASH_LEN];
-
- struct rnode * parent;
-
- size_t chlen;
- struct list_head children;
-
- struct list_head subs;
-};
-
-struct child {
- struct list_head next;
-
- struct rnode * node;
-};
-
-struct rib {
- struct rnode * root;
-
- struct btree * idx;
-
- pthread_rwlock_t lock;
-
- struct bmp * sids;
-
- struct list_head subs;
-
- pthread_rwlock_t s_lock;
-} rib;
-
-static void rnode_hash(struct rnode * node)
-{
- struct sha3_ctx ctx;
- struct list_head * p;
-
- assert(node);
- assert(node->path);
- assert(node->name);
-
- rhash_sha3_256_init(&ctx);
-
- rhash_sha3_update(&ctx, (uint8_t *) node->path, strlen(node->path));
-
- if (node->data != NULL)
- rhash_sha3_update(&ctx, node->data, node->len);
-
- list_for_each(p, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- rhash_sha3_update(&ctx, c->node->sha3, SHA3_256_HASH_LEN);
- }
-
- rhash_sha3_final(&ctx, node->sha3);
-}
-
-static void branch_hash(struct rnode * node)
-{
- assert(node);
-
- do {
- rnode_hash(node);
- node = node->parent;
- } while (node != NULL);
-}
-
-static struct revent * revent_dup(struct revent * ev)
-{
- struct revent * re;
-
- assert(ev);
- assert(ev->path);
-
- re = malloc(sizeof(*re));
- if (re == NULL)
- return NULL;
-
- re->path = strdup(ev->path);
- if (re->path == NULL) {
- free(re);
- return NULL;
- }
-
- re->flags = ev->flags;
-
- list_head_init(&re->next);
-
- return re;
-}
-
-/* defined below but needed here */
-static void rib_sub_del_rnode(struct rib_sub * sub,
- struct rnode * node);
-
-static void rnode_notify_subs(struct rnode * node,
- struct rnode * ch,
- struct revent * ev)
-{
- struct list_head * p;
-
- assert(node);
-
- list_for_each(p, &node->subs) {
- struct rn_sub * s = list_entry(p, struct rn_sub, next);
- if (s->flags & ev->flags) {
- struct revent * e = revent_dup(ev);
- if (e == NULL)
- continue;
-
- pthread_mutex_lock(&s->sub->lock);
- list_add_tail(&e->next, &s->sub->events);
- pthread_cond_signal(&s->sub->cond);
- pthread_mutex_unlock(&s->sub->lock);
- }
-
- if (ev->flags & RO_DELETE)
- rib_sub_del_rnode(s->sub, ch);
- }
-}
-
-static int rnode_throw_event(struct rnode * node,
- int32_t flags)
-{
- struct revent * ev = malloc(sizeof(*ev));
- struct rnode * rn = node;
-
- assert(node);
- assert(node->path);
-
- if (ev == NULL)
- return -ENOMEM;
-
- list_head_init(&ev->next);
-
- ev->path = strdup(node->path);
- if (ev->path == NULL) {
- free(ev);
- return -ENOMEM;
- }
-
- ev->flags = flags;
-
- do {
- rnode_notify_subs(rn, node, ev);
- rn = rn->parent;
- } while (rn != NULL);
-
- free(ev->path);
- free(ev);
-
- return 0;
-}
-
-static int rnode_add_child(struct rnode * node,
- struct rnode * child)
-{
- struct child * c;
- struct list_head * p;
- struct child * n;
-
- assert(node);
- assert(child);
-
- c = malloc(sizeof(*c));
- if (c == NULL)
- return -ENOMEM;
-
- c->node = child;
-
- list_for_each(p, &node->children) {
- n = list_entry(p, struct child, next);
- if (strcmp(n->node->name, child->name) > 0)
- break;
- }
-
- list_add_tail(&c->next, p);
-
- ++node->chlen;
-
- return 0;
-}
-
-static void rnode_remove_child(struct rnode * node,
- struct rnode * child)
-{
- struct list_head * p;
- struct list_head * h;
-
- assert(node);
- assert(child);
-
- list_for_each_safe(p, h, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- if (c->node == child) {
- list_del(&c->next);
- free(c);
- --node->chlen;
- return;
- }
- }
-}
-
-static struct rnode * rnode_create(struct rnode * parent,
- const char * name)
-{
- struct rnode * node;
- char * parent_path;
-
- uint32_t crc = 0;
-
- assert(name);
-
- node = malloc(sizeof(*node));
- if (node == NULL)
- return NULL;
-
- list_head_init(&node->children);
- list_head_init(&node->subs);
-
- if (parent == NULL)
- parent_path = "";
- else
- parent_path = parent->path;
-
- node->path = malloc(strlen(parent_path)
- + strlen(RIB_PATH_DLR)
- + strlen(name)
- + 1);
- if (node->path == NULL) {
- free(node);
- return NULL;
- }
-
- strcpy(node->path, parent_path);
- node->name = node->path + strlen(parent_path);
- if (parent != NULL) {
- strcpy(node->name, RIB_PATH_DLR);
- node->name += strlen(RIB_PATH_DLR);
- }
-
- strcpy(node->name, name);
-
- if (parent != NULL) {
- if (rnode_add_child(parent, node)) {
- free(node->path);
- free(node);
- return NULL;
- }
- }
-
- node->data = NULL;
- node->len = 0;
-
- node->parent = parent;
-
- node->chlen = 0;
-
- crc32(&crc, node->path, strlen(node->path));
- btree_insert(rib.idx, crc, node);
-
- branch_hash(node);
- rnode_throw_event(node, RO_CREATE);
-
- return node;
-}
-
-static void destroy_rnode(struct rnode * node)
-{
- struct list_head * p;
- struct list_head * h;
-
- uint32_t crc = 0;
-
- assert(node);
-
- if (node != rib.root) {
- rnode_remove_child(node->parent, node);
- branch_hash(node->parent);
- }
-
- if (node->parent != NULL)
- rnode_throw_event(node->parent, RO_DELETE);
-
- list_for_each_safe(p, h, &node->subs) {
- struct rn_sub * s = list_entry(p, struct rn_sub, next);
- list_del(&s->next);
- free(s);
- }
-
- crc32(&crc, node->path, strlen(node->path));
- btree_remove(rib.idx, crc);
-
- free(node->path);
- if (node->data != NULL)
- free(node->data);
-
- free(node);
-}
-
-static void destroy_rtree(struct rnode * node)
-{
- struct list_head * p;
- struct list_head * h;
-
- assert(node);
-
- list_for_each_safe(p, h, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- destroy_rtree(c->node);
- }
-
- destroy_rnode(node);
-}
-
-static void rnode_update(struct rnode * node,
- uint8_t * data,
- size_t len)
-{
- assert(node);
- assert(!(data == NULL && len != 0));
- assert(!(data != NULL && len == 0));
-
- if (node->data != NULL)
- free(node->data);
-
- node->data = data;
- node->len = len;
-
- rnode_throw_event(node, RO_MODIFY);
-
- branch_hash(node);
-}
-
-static struct rn_sub * rnode_get_sub(struct rnode * node,
- struct rib_sub * sub)
-{
- struct list_head * p;
-
- list_for_each(p, &node->subs) {
- struct rn_sub * r = list_entry(p, struct rn_sub, next);
- if (r->sub == sub)
- return r;
- }
-
- return NULL;
-}
-
-static int rnode_add_sub(struct rnode * node,
- struct rib_sub * sub,
- int32_t flags)
-{
- struct rn_sub * rs;
-
- assert(node);
- assert(sub);
-
- rs = rnode_get_sub(node, sub);
- if (rs != NULL)
- return -EPERM;
-
- rs = malloc(sizeof(*rs));
- if (rs == NULL)
- return -ENOMEM;
-
- rs->sub = sub;
- rs->flags = flags;
-
- list_add(&rs->next, &node->subs);
-
- return 0;
-}
-
-static int rnode_del_sub(struct rnode * node,
- struct rib_sub * sub)
-{
- struct rn_sub * rs;
-
- assert(node);
- assert(sub);
-
- rs = rnode_get_sub(node, sub);
- if (rs == NULL)
- return 0;
-
- list_del(&rs->next);
- free(rs);
-
- return 0;
-}
-
-static struct rnode * find_rnode_by_path(const char * path)
-{
- uint32_t crc = 0;
-
- if (strcmp(path, RIB_ROOT) == 0)
- return rib.root;
-
- crc32(&crc, path, strlen(path));
-
- return (struct rnode *) btree_search(rib.idx, crc);
-}
-
-int rib_init(void)
-{
- if (rib.root != NULL)
- return -EPERM;
-
- rib.idx = btree_create(RIB_BTREE_ORDER);
- if (rib.idx == NULL) {
- destroy_rtree(rib.root);
- rib.root = NULL;
- return -1;
- }
-
- rib.root = rnode_create(NULL, "");
- if (rib.root == NULL)
- return -ENOMEM;
-
- rib.sids = bmp_create(32, 1);
- if (rib.sids == NULL) {
- btree_destroy(rib.idx);
- destroy_rtree(rib.root);
- rib.root = NULL;
- return -1;
- }
-
- if (pthread_rwlock_init(&rib.lock, NULL)) {
- bmp_destroy(rib.sids);
- btree_destroy(rib.idx);
- destroy_rtree(rib.root);
- rib.root = NULL;
- return -1;
- }
-
- if (pthread_rwlock_init(&rib.s_lock, NULL)) {
- pthread_rwlock_destroy(&rib.lock);
- bmp_destroy(rib.sids);
- btree_destroy(rib.idx);
- destroy_rtree(rib.root);
- rib.root = NULL;
- return -1;
- }
-
- list_head_init(&rib.subs);
-
- assert(rib.root);
-
- return 0;
-}
-
-void rib_fini(void)
-{
- if (rib.root == NULL)
- return;
-
- bmp_destroy(rib.sids);
-
- destroy_rtree(rib.root);
- rib.root = NULL;
-
- btree_destroy(rib.idx);
-
- pthread_rwlock_destroy(&rib.lock);
-}
-
-int rib_add(const char * path,
- const char * name)
-{
- struct rnode * parent;
- struct rnode * node;
-
- if (name == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- parent = find_rnode_by_path(path);
- if (parent == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- node = rnode_create(parent, name);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -ENOMEM;
- }
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-int rib_del(char * path)
-{
- struct rnode * node;
-
- if (path == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EINVAL;
- }
-
- destroy_rtree(node);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-ssize_t rib_read(const char * path,
- void * data,
- size_t len)
-{
- struct rnode * node;
- ssize_t rlen;
-
- if (path == NULL || data == NULL)
- return -EINVAL;
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- if (len < node->len) {
- pthread_rwlock_unlock(&rib.lock);
- return -EFBIG;
- }
-
- if (node->data == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return 0;
- }
-
- assert(node->len > 0);
-
- memcpy(data, node->data, node->len);
- rlen = node->len;
-
- rnode_throw_event(node, RO_READ);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return rlen;
-}
-
-int rib_write(const char * path,
- const void * data,
- size_t len)
-{
- struct rnode * node;
-
- uint8_t * cdata;
-
- if (path == NULL || data == NULL || len == 0)
- return -EINVAL;
-
- cdata = malloc(len);
- if (cdata == NULL)
- return -ENOMEM;
-
- memcpy(cdata, data, len);
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- free(cdata);
- return -1;
- }
-
- rnode_update(node, cdata, len);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-int rib_put(const char * path,
- void * data,
- size_t len)
-{
- struct rnode * node;
-
- if (path == NULL)
- return -EINVAL;
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node != NULL)
- rnode_update(node, (uint8_t *) data, len);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-bool rib_has(const char * path)
-{
- struct rnode * node;
-
- if (path == NULL)
- return -EINVAL;
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return node != NULL;
-}
-
-ssize_t rib_children(const char * path,
- char *** children)
-{
- struct list_head * p;
-
- struct rnode * node;
-
- ssize_t i = 0;
-
- if (path == NULL)
- return -EINVAL;
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- if (children == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- assert((ssize_t) node->chlen >= 0);
- return (ssize_t) node->chlen;
- }
-
- if (node->chlen == 0) {
- pthread_rwlock_unlock(&rib.lock);
- *children = NULL;
- return 0;
- }
-
- *children = malloc(sizeof(**children) * node->chlen);
- if (*children == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -ENOMEM;
- }
-
- list_for_each(p, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- (*children)[i] = strdup(c->node->name);
- if ((*children)[i] == NULL) {
- ssize_t j;
- pthread_rwlock_unlock(&rib.lock);
- for (j = 0; j < i; ++j)
- free((*children)[j]);
- free(*children);
- return -ENOMEM;
- }
- ++i;
- }
-
- assert(i > 0);
- assert((size_t) i == node->chlen);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return i;
-}
-
-static struct rib_sub * rib_get_sub(uint32_t sid)
-{
- struct list_head * p;
- struct list_head * h;
-
- list_for_each_safe(p, h, &rib.subs) {
- struct rib_sub * r = list_entry(p, struct rib_sub, next);
- if (r->sid == sid)
- return r;
- }
-
- return NULL;
-}
-
-static struct rib_sub * rib_sub_create(uint32_t sid)
-{
- pthread_condattr_t cattr;
- struct rib_sub * sub = malloc(sizeof(*sub));
- if (sub == NULL)
- return NULL;
-
- if (pthread_condattr_init(&cattr)) {
- free(sub);
- return NULL;
- }
-#ifndef __APPLE__
- pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
-#endif
- if (pthread_cond_init(&sub->cond, &cattr)) {
- free(sub);
- return NULL;
- }
-
- if (pthread_mutex_init(&sub->lock, NULL)) {
- pthread_cond_destroy(&sub->cond);
- free(sub);
- return NULL;
- }
-
- list_head_init(&sub->rnodes);
- list_head_init(&sub->events);
-
- sub->sid = sid;
-
- return sub;
-}
-
-static void rib_sub_zero(struct rib_sub * sub)
-{
- struct list_head * p;
- struct list_head * h;
-
- assert(sub);
-
- list_for_each_safe(p, h, &sub->rnodes) {
- struct rn_ptr * r = list_entry(p, struct rn_ptr, next);
- assert(r->node);
- rnode_del_sub(r->node, sub);
- list_del(&r->next);
- free(r);
- }
-
- list_for_each_safe(p, h, &sub->events) {
- struct revent * r = list_entry(p, struct revent, next);
- list_del(&r->next);
- assert(r->path);
- free(r->path);
- free(r);
- }
-}
-
-static struct rn_ptr * rib_sub_get_rn_ptr(struct rib_sub * sub,
- struct rnode * node)
-{
- struct list_head * p;
-
- list_for_each(p, &sub->rnodes) {
- struct rn_ptr * r = list_entry(p, struct rn_ptr, next);
- assert(r->node);
- if (r->node == node)
- return r;
- }
-
- return NULL;
-}
-
-static int rib_sub_add_rnode(struct rib_sub * sub,
- struct rnode * node)
-{
- struct rn_ptr * rn;
-
- assert(sub);
- assert(node);
-
- if (rib_sub_get_rn_ptr(sub, node) != NULL)
- return 0;
-
- rn = malloc(sizeof(*rn));
- if (rn == NULL)
- return -ENOMEM;
-
- rn->node = node;
-
- list_add(&rn->next, &sub->rnodes);
-
- return 0;
-}
-
-static void rib_sub_del_rnode(struct rib_sub * sub,
- struct rnode * node)
-{
- struct rn_ptr * rn;
-
- assert(sub);
- assert(node);
-
- rn = rib_sub_get_rn_ptr(sub, node);
- if (rn == NULL)
- return;
-
- list_del(&rn->next);
-
- free(rn);
-}
-
-static void rib_sub_destroy(struct rib_sub * sub)
-{
- assert(sub);
-
- rib_sub_zero(sub);
-
- free(sub);
-}
-
-/* Event calls from rqueue.h. */
-ro_set_t * ro_set_create(void)
-{
- ro_set_t * set;
- struct rib_sub * sub;
-
- set = malloc(sizeof(*set));
- if (set == NULL)
- return NULL;
-
- pthread_rwlock_wrlock(&rib.s_lock);
-
- set->sid = bmp_allocate(rib.sids);
- if (!bmp_is_id_valid(rib.sids, set->sid)) {
- pthread_rwlock_unlock(&rib.s_lock);
- free(set);
- return NULL;
- }
-
- pthread_rwlock_unlock(&rib.s_lock);
-
- pthread_rwlock_wrlock(&rib.lock);
-
- sub = rib_sub_create(set->sid);
- if (sub == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- free(set);
- return NULL;
- }
-
- list_add(&sub->next, &rib.subs);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return set;
-}
-
-void ro_set_destroy(ro_set_t * set)
-{
- struct rib_sub * sub = NULL;
-
- struct list_head * p;
- struct list_head * h;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- list_for_each_safe(p, h, &rib.subs) {
- struct rib_sub * r = list_entry(p, struct rib_sub, next);
- if (r->sid == set->sid) {
- sub = r;
- break;
- }
- }
-
- if (sub != NULL)
- rib_sub_destroy(sub);
-
- pthread_rwlock_unlock(&rib.lock);
-
- pthread_rwlock_wrlock(&rib.s_lock);
-
- bmp_release(rib.sids, set->sid);
-
- pthread_rwlock_unlock(&rib.s_lock);
-
- free(set);
-}
-
-rqueue_t * rqueue_create(void)
-{
- rqueue_t * rq = malloc(sizeof(*rq));
- if (rq == NULL)
- return NULL;
-
- list_head_init(&rq->events);
-
- return rq;
-}
-
-int rqueue_destroy(struct rqueue * rq)
-{
- struct list_head * p;
- struct list_head * h;
-
- list_for_each_safe(p, h, &rq->events) {
- struct revent * e = list_entry(p, struct revent, next);
- list_del(&e->next);
- free(e->path);
- free(e);
- }
-
- free(rq);
-
- return 0;
-}
-
-int ro_set_zero(ro_set_t * set)
-{
- struct rib_sub * sub;
-
- if (set == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- sub = rib_get_sub(set->sid);
-
- assert(sub);
-
- rib_sub_zero(sub);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-int ro_set_add(ro_set_t * set,
- const char * path,
- int32_t flags)
-{
- struct rib_sub * sub;
- struct rnode * node;
-
- if (set == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- sub = rib_get_sub(set->sid);
-
- assert(sub);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -1;
- }
-
- if (rnode_add_sub(node, sub, flags)) {
- pthread_rwlock_unlock(&rib.lock);
- return -ENOMEM;
- }
-
- if (rib_sub_add_rnode(sub, node)) {
- pthread_rwlock_unlock(&rib.lock);
- return -ENOMEM;
- }
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-int ro_set_del(ro_set_t * set,
- const char * path)
-{
- struct rib_sub * sub;
- struct rnode * node;
-
- if (set == NULL)
- return -EINVAL;
-
- pthread_rwlock_wrlock(&rib.lock);
-
- sub = rib_get_sub(set->sid);
-
- assert(sub);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -1;
- }
-
- rnode_del_sub(node, sub);
-
- rib_sub_del_rnode(sub, node);
-
- pthread_rwlock_unlock(&rib.lock);
-
- return 0;
-}
-
-int32_t rqueue_next(rqueue_t * rq,
- char * path)
-{
- struct revent * ev;
- int32_t ret;
-
- if (list_is_empty(&rq->events))
- return -1;
-
- ev = list_first_entry(&rq->events, struct revent, next);
- list_del(&ev->next);
-
- strcpy(path, ev->path);
- ret = ev->flags;
-
- free(ev->path);
- free(ev);
-
- return ret;
-}
-
-int rib_event_wait(ro_set_t * set,
- rqueue_t * rq,
- const struct timespec * timeout)
-{
- struct rib_sub * sub;
- struct timespec abstime;
- struct revent * ev;
-
- ssize_t ret = 0;
-
- if (set == NULL || rq == NULL)
- return -EINVAL;
-
- if (!list_is_empty(&rq->events))
- return 0;
-
- if (timeout != NULL) {
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
- }
-
- pthread_rwlock_rdlock(&rib.lock);
-
- sub = rib_get_sub(set->sid);
-
- assert(sub);
-
- pthread_rwlock_unlock(&rib.lock);
-
- pthread_mutex_lock(&sub->lock);
-
- pthread_cleanup_push((void(*)(void *)) pthread_mutex_unlock,
- (void *) &sub->lock);
-
- while (list_is_empty(&sub->events) && ret != -ETIMEDOUT) {
- if (timeout != NULL)
- ret = -pthread_cond_timedwait(&sub->cond,
- &sub->lock,
- &abstime);
- else
- ret = -pthread_cond_wait(&sub->cond, &sub->lock);
- }
-
- pthread_cleanup_pop(true);
-
- pthread_rwlock_wrlock(&rib.lock);
-
- if (ret != -ETIMEDOUT) {
- ev = list_first_entry(&sub->events, struct revent, next);
- list_move(&ev->next, &rq->events);
- }
-
- pthread_rwlock_unlock(&rib.lock);
-
- return ret;
-}
-
-/* Path name management. */
-char * rib_path_append(char * path,
- const char * name)
-{
- char * pos;
-
- if (path == NULL || name == NULL || strstr(name, RIB_PATH_DLR))
- return NULL;
-
- pos = path + strlen(path);
- memcpy(pos++, RIB_PATH_DLR, 1);
- strcpy(pos, name);
-
- return path;
-}
-
-char * rib_name_gen(void * data,
- size_t len)
-{
- uint32_t crc = 0;
- char * name;
-
- if (data == NULL || len == 0)
- return NULL;
-
- name= malloc(GEN_NAME_SIZE + 1);
- if (name == NULL)
- return NULL;
-
- crc32(&crc, data, len);
-
- sprintf(name, "%08x", crc);
-
- return name;
-}
-
-static ro_msg_t * rnode_pack(struct rnode * node,
- uint32_t flags,
- bool root)
-{
- ro_msg_t * msg;
-
- assert(node);
-
- if (node->parent == NULL)
- return NULL;
-
- msg = malloc(sizeof(*msg));
- if (msg == NULL)
- return NULL;
-
- ro_msg__init(msg);
-
- msg->name = node->name;
- if (root) {
- assert(node->parent->path);
- msg->parent = node->parent->path;
- }
-
- if ((root && (flags & PACK_HASH_ROOT)) ||
- (flags & PACK_HASH_ALL)) {
- msg->has_hash = true;
- msg->hash.data = node->sha3;
- msg->hash.len = SHA3_256_HASH_LEN;
- }
-
- if (node->data != NULL) {
- msg->has_data = true;
- msg->data.data = node->data;
- msg->data.len = node->len;
- }
-
- if (node->chlen > 0) {
- int n = 0;
- struct list_head * p;
- ro_msg_t ** msgs = malloc(sizeof(*msgs) * node->chlen);
- if (msgs == NULL) {
- free(msg);
- return NULL;
- }
-
- msg->n_children = node->chlen;
-
- list_for_each(p, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- msgs[n] = rnode_pack(c->node, flags, false);
- if (msgs[n] == NULL) {
- int i;
- for (i = 0; i < n; ++i)
- free(msgs[i]);
- free(msgs);
- free(msg);
- return NULL;
- }
- ++n;
- }
- msg->children = msgs;
- }
-
- return msg;
-}
-
-static void free_ro_msg(ro_msg_t * msg)
-{
- size_t n = 0;
- while (n < msg->n_children)
- free_ro_msg(msg->children[n++]);
-
- free(msg->children);
- free(msg);
-}
-
-ssize_t rib_pack(const char * path,
- uint8_t ** buf,
- uint32_t flags)
-{
- struct rnode * node;
- ro_msg_t * msg;
- ssize_t len;
-
- if (path == NULL)
- return -EINVAL;
-
- pthread_rwlock_rdlock(&rib.lock);
-
- node = find_rnode_by_path(path);
- if (node == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- msg = rnode_pack(node, flags, true);
- if (msg == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- len = ro_msg__get_packed_size(msg);
- if (len == 0) {
- pthread_rwlock_unlock(&rib.lock);
- free_ro_msg(msg);
- return 0;
- }
-
- *buf = malloc(len);
- if (*buf == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- free_ro_msg(msg);
- return -ENOMEM;
- }
-
- ro_msg__pack(msg, *buf);
-
- pthread_rwlock_unlock(&rib.lock);
-
- free_ro_msg(msg);
-
- return len;
-}
-
-static struct rnode * rnode_get_child(struct rnode * node,
- const char * name)
-{
- struct list_head * p;
-
- list_for_each(p, &node->children) {
- struct child * c = list_entry(p, struct child, next);
- if (strcmp(c->node->name, name) == 0)
- return c->node;
- }
-
- return NULL;
-}
-
-static int rnode_unpack(ro_msg_t * msg,
- struct rnode * parent,
- uint32_t flags)
-{
- struct rnode * node;
-
- size_t i;
-
- assert(msg);
- assert(parent);
-
- node = rnode_get_child(parent, msg->name);
- if (node == NULL) {
- if (flags & UNPACK_CREATE)
- node = rnode_create(parent, msg->name);
- else
- return -EPERM;
- }
-
- if (node == NULL)
- return -ENOMEM;
-
- /* Unpack in reverse order for faster insertion */
- i = msg->n_children;
- while (i > 0)
- rnode_unpack(msg->children[--i], node, flags);
-
- if (msg->has_data) {
- uint8_t * data = malloc(msg->data.len);
- if (data == NULL)
- return -ENOMEM;
-
- memcpy(data, msg->data.data, msg->data.len);
- rnode_update(node, data, msg->data.len);
- }
-
- return 0;
-}
-
-int rib_unpack(uint8_t * packed,
- size_t len,
- uint32_t flags)
-{
- ro_msg_t * msg;
- struct rnode * root;
- int ret;
-
- if (packed == NULL)
- return -EINVAL;
-
- msg = ro_msg__unpack(NULL, len, packed);
- if (msg == NULL)
- return -EPERM;
-
- assert(msg->parent);
-
- pthread_rwlock_wrlock(&rib.lock);
-
- root = find_rnode_by_path(msg->parent);
- if (root == NULL) {
- pthread_rwlock_unlock(&rib.lock);
- return -EPERM;
- }
-
- ret = rnode_unpack(msg, root, flags);
-
- if (ret == 0 && msg->has_hash) {
- root = rnode_get_child(root, msg->name);
- if (memcmp(msg->hash.data, root->sha3, SHA3_256_HASH_LEN)) {
- ro_msg__free_unpacked(msg, NULL);
- pthread_rwlock_unlock(&rib.lock);
- return -EFAULT;
- }
- }
-
- pthread_rwlock_unlock(&rib.lock);
-
- ro_msg__free_unpacked(msg, NULL);
-
- free(packed);
-
- return ret;
-}
diff --git a/src/lib/ro.proto b/src/lib/ro.proto
deleted file mode 100644
index 8c547f14..00000000
--- a/src/lib/ro.proto
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * RIB object message
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-syntax = "proto2";
-
-message ro_msg {
- required string name = 1;
- optional string parent = 2;
- optional bytes data = 3;
- optional bytes hash = 4;
- repeated ro_msg children = 5;
-} \ No newline at end of file
diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt
index 0223262a..a93bf321 100644
--- a/src/lib/tests/CMakeLists.txt
+++ b/src/lib/tests/CMakeLists.txt
@@ -14,7 +14,6 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
crc32_test.c
hashtable_test.c
md5_test.c
- rib_test.c
sha3_test.c
time_utils_test.c
${TIMERWHEEL_TEST}
diff --git a/src/lib/tests/rib_test.c b/src/lib/tests/rib_test.c
deleted file mode 100644
index 6a2446b9..00000000
--- a/src/lib/tests/rib_test.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2017
- *
- * Test of the RIB
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * 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/.
- */
-
-#define _POSIX_C_SOURCE 199309L
-
-#include <ouroboros/time_utils.h>
-#include <ouroboros/rib.h>
-#include <ouroboros/rqueue.h>
-#include <ouroboros/errno.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define RIB_MAX_PATH_LEN 256
-
-int rib_test(int argc,
- char ** argv)
-{
- uint64_t * address;
-
- size_t addr_size = 8;
- size_t addr_chk;
-
- char * addr_name;
-
- ro_set_t * set;
- rqueue_t * rq;
-
- int ret;
-
- char tmp[RIB_MAX_PATH_LEN];
-
- char ** kids;
- ssize_t ch;
-
- uint8_t * buf;
- ssize_t buf_len;
-
- struct timespec t = {0, 100 * MILLION};
-
- (void) argc;
- (void) argv;
-
- address = malloc(sizeof(*address));
- if (address == NULL)
- return -ENOMEM;
-
- if (rib_init()) {
- printf("Failed to initialize rib.\n");
- return -1;
- }
-
- rib_fini();
-
- if (rib_init()) {
- printf("Failed to re-initialize rib.\n");
- return -1;
- }
-
- if (rib_add(RIB_ROOT, "static_info")) {
- printf("Failed to add element to rib.\n");
- rib_fini();
- return -1;
- }
-
- ch = rib_children("/static_info", &kids);
- if (ch != 0) {
- printf("Wrong number of children returned.\n");
- rib_fini();
- while (ch > 0)
- free(kids[--ch]);
- free(kids);
- return -1;
- }
-
- if (!rib_has("/static_info")) {
- printf("Failed to find added element.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_add(RIB_ROOT, "dynamic_info")) {
- printf("Failed to add element to rib.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_add("/static_info", "addr_size")) {
- printf("Failed to add sub-element to rib.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_write("/static_info/addr_size",
- &addr_size, sizeof(addr_size))) {
- printf("Failed to add sub-element to rib.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_add("/static_info", "addresses")) {
- printf("Failed to add sub-element to rib.\n");
- rib_fini();
- return -1;
- }
-
- if (!rib_has("/static_info/addr_size")) {
- printf("Failed to find added subelement.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_read("/static_info/addr_size",
- &addr_chk, sizeof(addr_chk))
- != sizeof(addr_chk)) {
- printf("Failed to read added element.\n");
- rib_fini();
- return -1;
- }
-
- ch = rib_children("/static_info", &kids);
- if (ch != 2) {
- printf("Wrong number of children returned.\n");
- rib_fini();
- return -1;
- }
-
- while (ch > 0)
- free(kids[--ch]);
- free(kids);
-
- if (addr_chk != addr_size) {
- printf("Failed to verify added element contents.\n");
- rib_fini();
- return -1;
- }
-
- addr_size = 16;
-
- if (rib_write("/static_info/addr_size",
- &addr_size, sizeof(addr_size))) {
- printf("Failed to write into added element.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_read("/static_info/addr_size",
- &addr_chk, sizeof(addr_chk))
- != sizeof(addr_chk)) {
- printf("Failed to verify added element update size.\n");
- rib_fini();
- return -1;
- }
-
- if (addr_chk != addr_size) {
- printf("Failed to verify added element update size.\n");
- rib_fini();
- return -1;
- }
-
- addr_name = rib_name_gen(address, sizeof(*address));
- if (addr_name == NULL) {
- printf("Failed to create a name.\n");
- rib_fini();
- return -1;
- }
-
- strcpy(tmp, "/dynamic_info");
-
- if (rib_add(tmp, addr_name)) {
- free(addr_name);
- printf("Failed to add address.\n");
- rib_fini();
- return -1;
- }
-
- rib_path_append(tmp, addr_name);
-
- if (rib_put(tmp, address, sizeof(*address))) {
- free(addr_name);
- printf("Failed to add address.\n");
- rib_fini();
- return -1;
- }
-
- free(addr_name);
-
- buf_len = rib_pack("/static_info", &buf, PACK_HASH_ALL);
- if (buf_len < 0) {
- printf("Failed pack.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_del("/static_info")) {
- printf("Failed to delete.\n");
- rib_fini();
- return -1;
- }
-
- if (rib_unpack(buf, buf_len, UNPACK_CREATE)) {
- printf("Failed to unpack.\n");
- rib_fini();
- return -1;
- }
-
- if (!rib_has("/static_info")) {
- printf("Failed to find unpacked element.\n");
- rib_fini();
- return -1;
- }
-
- ch = rib_children("/static_info", &kids);
- if (ch != 2) {
- printf("Wrong number of children returned.\n");
- rib_fini();
- return -1;
- }
-
- while (ch > 0)
- free(kids[--ch]);
- free(kids);
-
- set = ro_set_create();
- if (set == NULL) {
- printf("Failed to create ro_set.\n");
- rib_fini();
- return -1;
- }
-
- rq = rqueue_create();
- if (rq == NULL) {
- printf("Failed to create rqueue.\n");
- ro_set_destroy(set);
- rib_fini();
- return -1;
- }
-
- if (ro_set_add(set, "/static_info", RO_ALL_OPS)) {
- printf("Failed to add to rqueue.\n");
- ro_set_destroy(set);
- rqueue_destroy(rq);
- rib_fini();
- return -1;
- }
-
- ret = rib_event_wait(set, rq, &t);
- if (ret != -ETIMEDOUT) {
- printf("Wait failed to timeout: %d.\n", ret);
- ro_set_destroy(set);
- rqueue_destroy(rq);
- rib_fini();
- return -1;
- }
-
- if (rib_del("/static_info")) {
- printf("Failed to delete rib subtree.\n");
- rib_fini();
- return -1;
- }
-
- ro_set_destroy(set);
-
- rqueue_destroy(rq);
-
- rib_fini();
-
- return 0;
-}