summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/CMakeLists.txt8
-rw-r--r--src/ipcpd/broadcast/CMakeLists.txt5
-rw-r--r--src/ipcpd/broadcast/connmgr.c2
-rw-r--r--src/ipcpd/broadcast/dt.c23
-rw-r--r--src/ipcpd/broadcast/dt.h2
-rw-r--r--src/ipcpd/broadcast/main.c119
-rw-r--r--src/ipcpd/common/comp.h4
-rw-r--r--src/ipcpd/common/connmgr.c173
-rw-r--r--src/ipcpd/common/connmgr.h4
-rw-r--r--src/ipcpd/common/enroll.c372
-rw-r--r--src/ipcpd/common/enroll.h10
-rw-r--r--src/ipcpd/config.h.in17
-rw-r--r--src/ipcpd/eth/CMakeLists.txt2
-rw-r--r--src/ipcpd/eth/dix.c2
-rw-r--r--src/ipcpd/eth/eth.c425
-rw-r--r--src/ipcpd/eth/llc.c2
-rw-r--r--src/ipcpd/ipcp.c859
-rw-r--r--src/ipcpd/ipcp.h50
-rw-r--r--src/ipcpd/local/CMakeLists.txt2
-rw-r--r--src/ipcpd/local/main.c217
-rw-r--r--src/ipcpd/shim-data.c44
-rw-r--r--src/ipcpd/shim-data.h2
-rw-r--r--src/ipcpd/udp/CMakeLists.txt2
-rw-r--r--src/ipcpd/udp/main.c410
-rw-r--r--src/ipcpd/unicast/CMakeLists.txt36
-rw-r--r--src/ipcpd/unicast/addr-auth.c (renamed from src/ipcpd/unicast/addr_auth.c)9
-rw-r--r--src/ipcpd/unicast/addr-auth.h (renamed from src/ipcpd/unicast/addr_auth.h)2
-rw-r--r--src/ipcpd/unicast/addr-auth/flat.c (renamed from src/ipcpd/unicast/pol/flat.c)28
-rw-r--r--src/ipcpd/unicast/addr-auth/flat.h (renamed from src/ipcpd/unicast/pol/flat.h)6
-rw-r--r--src/ipcpd/unicast/addr-auth/ops.h (renamed from src/ipcpd/unicast/pol-addr-auth-ops.h)10
-rw-r--r--src/ipcpd/unicast/addr-auth/pol.h (renamed from src/ipcpd/broadcast/enroll.c)7
-rw-r--r--src/ipcpd/unicast/ca.c8
-rw-r--r--src/ipcpd/unicast/ca.h2
-rw-r--r--src/ipcpd/unicast/ca/mb-ecn.c (renamed from src/ipcpd/unicast/pol/ca-mb-ecn.c)10
-rw-r--r--src/ipcpd/unicast/ca/mb-ecn.h (renamed from src/ipcpd/unicast/pol/ca-mb-ecn.h)6
-rw-r--r--src/ipcpd/unicast/ca/nop.c (renamed from src/ipcpd/unicast/pol/ca-nop.c)6
-rw-r--r--src/ipcpd/unicast/ca/nop.h (renamed from src/ipcpd/unicast/pol/ca-nop.h)6
-rw-r--r--src/ipcpd/unicast/ca/ops.h (renamed from src/ipcpd/unicast/pol-ca-ops.h)10
-rw-r--r--src/ipcpd/unicast/ca/pol.h24
-rw-r--r--src/ipcpd/unicast/connmgr.c2
-rw-r--r--src/ipcpd/unicast/dir.c55
-rw-r--r--src/ipcpd/unicast/dir.h2
-rw-r--r--src/ipcpd/unicast/dir/dht.c (renamed from src/ipcpd/unicast/dht.c)207
-rw-r--r--src/ipcpd/unicast/dir/dht.h (renamed from src/ipcpd/unicast/dht.h)34
-rw-r--r--src/ipcpd/unicast/dir/dht.proto (renamed from src/ipcpd/unicast/kademlia.proto)14
-rw-r--r--src/ipcpd/unicast/dir/ops.h46
-rw-r--r--src/ipcpd/unicast/dir/pol.h23
-rw-r--r--src/ipcpd/unicast/dir/tests/CMakeLists.txt (renamed from src/ipcpd/unicast/tests/CMakeLists.txt)5
-rw-r--r--src/ipcpd/unicast/dir/tests/dht_test.c (renamed from src/ipcpd/unicast/tests/dht_test.c)23
-rw-r--r--src/ipcpd/unicast/dt.c77
-rw-r--r--src/ipcpd/unicast/dt.h8
-rw-r--r--src/ipcpd/unicast/enroll.c3
-rw-r--r--src/ipcpd/unicast/fa.c377
-rw-r--r--src/ipcpd/unicast/fa.h18
-rw-r--r--src/ipcpd/unicast/main.c149
-rw-r--r--src/ipcpd/unicast/pff.c15
-rw-r--r--src/ipcpd/unicast/pff.h2
-rw-r--r--src/ipcpd/unicast/pff/alternate.c (renamed from src/ipcpd/unicast/pol/alternate_pff.c)6
-rw-r--r--src/ipcpd/unicast/pff/alternate.h (renamed from src/ipcpd/unicast/pol/alternate_pff.h)6
-rw-r--r--src/ipcpd/unicast/pff/multipath.c (renamed from src/ipcpd/unicast/pol/multipath_pff.c)34
-rw-r--r--src/ipcpd/unicast/pff/multipath.h (renamed from src/ipcpd/unicast/pol/multipath_pff.h)6
-rw-r--r--src/ipcpd/unicast/pff/ops.h (renamed from src/ipcpd/unicast/pol-pff-ops.h)10
-rw-r--r--src/ipcpd/unicast/pff/pft.c (renamed from src/ipcpd/unicast/pol/pft.c)16
-rw-r--r--src/ipcpd/unicast/pff/pft.h (renamed from src/ipcpd/unicast/pol/pft.h)2
-rw-r--r--src/ipcpd/unicast/pff/pol.h25
-rw-r--r--src/ipcpd/unicast/pff/simple.c (renamed from src/ipcpd/unicast/pol/simple_pff.c)6
-rw-r--r--src/ipcpd/unicast/pff/simple.h (renamed from src/ipcpd/unicast/pol/simple_pff.h)6
-rw-r--r--src/ipcpd/unicast/pff/tests/CMakeLists.txt34
-rw-r--r--src/ipcpd/unicast/pff/tests/pft_test.c (renamed from src/ipcpd/unicast/pol/tests/pft_test.c)2
-rw-r--r--src/ipcpd/unicast/psched.c9
-rw-r--r--src/ipcpd/unicast/psched.h8
-rw-r--r--src/ipcpd/unicast/routing.c6
-rw-r--r--src/ipcpd/unicast/routing.h2
-rw-r--r--src/ipcpd/unicast/routing/graph.c (renamed from src/ipcpd/unicast/pol/graph.c)2
-rw-r--r--src/ipcpd/unicast/routing/graph.h (renamed from src/ipcpd/unicast/pol/graph.h)2
-rw-r--r--src/ipcpd/unicast/routing/link-state.c (renamed from src/ipcpd/unicast/pol/link_state.c)8
-rw-r--r--src/ipcpd/unicast/routing/link-state.h (renamed from src/ipcpd/unicast/pol/link_state.h)6
-rw-r--r--src/ipcpd/unicast/routing/ops.h (renamed from src/ipcpd/unicast/pol-routing-ops.h)10
-rw-r--r--src/ipcpd/unicast/routing/pol.h23
-rw-r--r--src/ipcpd/unicast/routing/tests/CMakeLists.txt (renamed from src/ipcpd/unicast/pol/tests/CMakeLists.txt)1
-rw-r--r--src/ipcpd/unicast/routing/tests/graph_test.c (renamed from src/ipcpd/unicast/pol/tests/graph_test.c)2
81 files changed, 2206 insertions, 2012 deletions
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt
index 1ce1bc0d..54294f11 100644
--- a/src/ipcpd/CMakeLists.txt
+++ b/src/ipcpd/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(CONNMGR_RCV_TIMEOUT 1000 CACHE STRING
+ "Timeout for the connection manager to wait for OCEP info (ms).")
+set(IPCP_DEBUG_LOCAL FALSE CACHE BOOL
+ "Use PID as address for local debugging")
set(IPCP_QOS_CUBE_BE_PRIO 50 CACHE STRING
"Priority for best effort QoS cube (0-99)")
set(IPCP_QOS_CUBE_VIDEO_PRIO 90 CACHE STRING
@@ -44,6 +48,10 @@ set(IPCP_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c
)
+set (COMMON_SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/common/enroll.c
+ )
+
add_subdirectory(local)
add_subdirectory(eth)
add_subdirectory(udp)
diff --git a/src/ipcpd/broadcast/CMakeLists.txt b/src/ipcpd/broadcast/CMakeLists.txt
index afcc8696..d85f335e 100644
--- a/src/ipcpd/broadcast/CMakeLists.txt
+++ b/src/ipcpd/broadcast/CMakeLists.txt
@@ -13,16 +13,17 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
set(IPCP_BROADCAST_TARGET ipcpd-broadcast CACHE INTERNAL "")
+set(IPCP_BROADCAST_MPL 60 CACHE STRING
+ "Default maximum packet lifetime for the broadcast IPCP, in seconds")
set(SOURCE_FILES
# Add source files here
connmgr.c
dt.c
- enroll.c
main.c
)
-add_executable(ipcpd-broadcast ${SOURCE_FILES} ${IPCP_SOURCES}
+add_executable(ipcpd-broadcast ${SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES}
${LAYER_CONFIG_PROTO_SRCS})
target_link_libraries(ipcpd-broadcast LINK_PUBLIC ouroboros-dev)
diff --git a/src/ipcpd/broadcast/connmgr.c b/src/ipcpd/broadcast/connmgr.c
index b65f48b0..f297175d 100644
--- a/src/ipcpd/broadcast/connmgr.c
+++ b/src/ipcpd/broadcast/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handles connections between components
*
diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c
index 00476027..938c9085 100644
--- a/src/ipcpd/broadcast/dt.c
+++ b/src/ipcpd/broadcast/dt.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Forward loop for broadcast
*
@@ -78,15 +78,16 @@ static int dt_add_nb(int fd)
list_for_each(p, &fwd.nbs) {
struct nb * el = list_entry(p, struct nb, next);
if (el->fd == fd) {
- log_dbg("Already know neighbor.");
pthread_rwlock_unlock(&fwd.nbs_lock);
- return -EPERM;
+ log_warn("Already know neighbor on fd %d.", fd);
+ return 0;
}
}
nb = malloc(sizeof(*nb));
if (nb == NULL) {
pthread_rwlock_unlock(&fwd.nbs_lock);
+ log_err("Failed to malloc neighbor struct.");
return -ENOMEM;
}
@@ -96,10 +97,10 @@ static int dt_add_nb(int fd)
++fwd.nbs_len;
- log_dbg("Neighbor %d added.", fd);
-
pthread_rwlock_unlock(&fwd.nbs_lock);
+ log_dbg("Neighbor %d added.", fd);
+
return 0;
}
@@ -124,6 +125,8 @@ static int dt_del_nb(int fd)
pthread_rwlock_unlock(&fwd.nbs_lock);
+ log_err("Neighbor not found on fd %d.", fd);
+
return -EPERM;
}
@@ -191,7 +194,7 @@ static void * dt_reader(void * o)
while (true) {
ret = fevent(fwd.set, fq, NULL);
if (ret < 0) {
- log_warn("Event error: %d.", ret);
+ log_warn("Event warning: %d.", ret);
continue;
}
@@ -226,13 +229,13 @@ static void handle_event(void * self,
switch (event) {
case NOTIFY_DT_CONN_ADD:
- if (dt_add_nb(c->flow_info.fd))
- log_dbg("Failed to add neighbor.");
+ if (dt_add_nb(c->flow_info.fd) < 0)
+ log_err("Failed to add neighbor.");
fset_add(fwd.set, c->flow_info.fd);
break;
case NOTIFY_DT_CONN_DEL:
- if (dt_del_nb(c->flow_info.fd))
- log_dbg("Failed to delete neighbor.");
+ if (dt_del_nb(c->flow_info.fd) < 0)
+ log_err("Failed to delete neighbor.");
fset_del(fwd.set, c->flow_info.fd);
break;
default:
diff --git a/src/ipcpd/broadcast/dt.h b/src/ipcpd/broadcast/dt.h
index 4331bd3e..8d3b83f8 100644
--- a/src/ipcpd/broadcast/dt.h
+++ b/src/ipcpd/broadcast/dt.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Forward loop for broadcast
*
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 522d1391..f51fc629 100644
--- a/src/ipcpd/broadcast/main.c
+++ b/src/ipcpd/broadcast/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Broadcast IPC Process
*
@@ -31,14 +31,14 @@
#define OUROBOROS_PREFIX "broadcast-ipcp"
#define THIS_TYPE IPCP_BROADCAST
-#include <ouroboros/errno.h>
-#include <ouroboros/hash.h>
#include <ouroboros/dev.h>
+#include <ouroboros/errno.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/logs.h>
#include <ouroboros/notifier.h>
+#include <ouroboros/random.h>
#include <ouroboros/rib.h>
-#include <ouroboros/time_utils.h>
+#include <ouroboros/time.h>
#include "common/connmgr.h"
#include "common/enroll.h"
@@ -56,50 +56,34 @@ struct ipcp ipcpi;
static int initialize_components(const struct ipcp_config * conf)
{
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name.");
- goto fail_layer_name;
- }
-
- ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
+ strcpy(ipcpi.layer_name, conf->layer_info.name);
+ ipcpi.dir_hash_algo = (enum hash_algo) conf->layer_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
- if (dt_init()) {
+ if (dt_init() < 0) {
log_err("Failed to initialize forwarding component.");
- goto fail_dt;
+ return -1;
}
ipcp_set_state(IPCP_INIT);
return 0;
-
- fail_dt:
- free(ipcpi.layer_name);
- fail_layer_name:
- return -1;
}
static void finalize_components(void)
{
dt_fini();
-
- free(ipcpi.layer_name);
}
static int start_components(void)
{
- assert(ipcp_get_state() == IPCP_INIT);
-
- ipcp_set_state(IPCP_OPERATIONAL);
-
- if (enroll_start()) {
+ if (enroll_start() < 0) {
log_err("Failed to start enrollment.");
goto fail_enroll_start;
}
- if (connmgr_start()) {
+ if (connmgr_start() < 0) {
log_err("Failed to start AP connection manager.");
goto fail_connmgr_start;
}
@@ -115,52 +99,55 @@ static int start_components(void)
static void stop_components(void)
{
- assert(ipcp_get_state() == IPCP_OPERATIONAL ||
- ipcp_get_state() == IPCP_SHUTDOWN);
-
connmgr_stop();
enroll_stop();
-
- ipcp_set_state(IPCP_INIT);
}
static int broadcast_ipcp_enroll(const char * dst,
struct layer_info * info)
{
struct conn conn;
+ uint8_t id[ENROLL_ID_LEN];
- if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn)) {
- log_err("Failed to get connection.");
- goto fail_er_flow;
+ if (random_buffer(id, ENROLL_ID_LEN) < 0) {
+ log_err("Failed to generate enrollment ID.");
+ goto fail_id;
+ }
+
+ log_info_id(id, "Requesting enrollment.");
+
+ if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn) < 0) {
+ log_err_id(id, "Failed to get connection.");
+ goto fail_id;
}
/* Get boot state from peer. */
- if (enroll_boot(&conn)) {
- log_err("Failed to get boot information.");
+ if (enroll_boot(&conn, id) < 0) {
+ log_err_id(id, "Failed to get boot information.");
goto fail_enroll_boot;
}
- if (initialize_components(enroll_get_conf())) {
- log_err("Failed to initialize IPCP components.");
+ if (initialize_components(enroll_get_conf()) < 0) {
+ log_err_id(id, "Failed to initialize components.");
goto fail_enroll_boot;
}
- if (start_components()) {
- log_err("Failed to start components.");
+ if (start_components() < 0) {
+ log_err_id(id, "Failed to start components.");
goto fail_start_comp;
}
- if (enroll_done(&conn, 0))
- log_warn("Failed to confirm enrollment with peer.");
+ if (enroll_ack(&conn, id, 0) < 0)
+ log_err_id(id, "Failed to confirm enrollment.");
- if (connmgr_dealloc(COMPID_ENROLL, &conn))
- log_warn("Failed to deallocate enrollment flow.");
+ if (connmgr_dealloc(COMPID_ENROLL, &conn) < 0)
+ log_warn_id(id, "Failed to dealloc enrollment flow.");
- log_info("Enrolled with %s.", dst);
+ log_info_id(id, "Enrolled with %s.", dst);
- info->dir_hash_algo = ipcpi.dir_hash_algo;
- strcpy(info->layer_name, ipcpi.layer_name);
+ info->dir_hash_algo = (enum pol_dir_hash) ipcpi.dir_hash_algo;
+ strcpy(info->name, ipcpi.layer_name);
return 0;
@@ -168,7 +155,7 @@ static int broadcast_ipcp_enroll(const char * dst,
finalize_components();
fail_enroll_boot:
connmgr_dealloc(COMPID_ENROLL, &conn);
- fail_er_flow:
+ fail_id:
return -1;
}
@@ -176,6 +163,8 @@ static int broadcast_ipcp_bootstrap(const struct ipcp_config * conf)
{
assert(conf);
assert(conf->type == THIS_TYPE);
+ ((struct ipcp_config *) conf)->layer_info.dir_hash_algo =
+ DIR_HASH_SHA3_256;
enroll_bootstrap(conf);
@@ -189,8 +178,6 @@ static int broadcast_ipcp_bootstrap(const struct ipcp_config * conf)
goto fail_start;
}
- log_dbg("Bootstrapped in layer %s.", conf->layer_info.layer_name);
-
return 0;
fail_start:
@@ -224,6 +211,8 @@ static int broadcast_ipcp_join(int fd,
qosspec_t qs)
{
struct conn conn;
+ time_t mpl = IPCP_BROADCAST_MPL;
+ buffer_t data = {NULL, 0};
(void) qs;
@@ -231,12 +220,14 @@ static int broadcast_ipcp_join(int fd,
conn.flow_info.fd = fd;
- if (name_check(dst) != 0)
+ if (name_check(dst) != 0) {
+ log_err("Failed to check name.");
return -1;
+ }
notifier_event(NOTIFY_DT_CONN_ADD, &conn);
- ipcp_flow_alloc_reply(fd, 0, NULL, 0);
+ ipcp_flow_alloc_reply(fd, 0, mpl, &data);
return 0;
}
@@ -251,12 +242,11 @@ int broadcast_ipcp_dealloc(int fd)
notifier_event(NOTIFY_DT_CONN_DEL, &conn);
- flow_dealloc(fd);
+ ipcp_flow_dealloc(fd);
return 0;
}
-
static struct ipcp_ops broadcast_ops = {
.ipcp_bootstrap = broadcast_ipcp_bootstrap,
.ipcp_enroll = broadcast_ipcp_enroll,
@@ -275,7 +265,7 @@ int main(int argc,
char * argv[])
{
if (ipcp_init(argc, argv, &broadcast_ops, THIS_TYPE) < 0) {
- log_err("Failed to init IPCP.");
+ log_err("Failed to initialize IPCP.");
goto fail_init;
}
@@ -294,24 +284,20 @@ int main(int argc,
goto fail_enroll_init;
}
- if (ipcp_boot() < 0) {
+ if (ipcp_start() < 0) {
log_err("Failed to boot IPCP.");
- goto fail_boot;
- }
-
- if (ipcp_create_r(0)) {
- log_err("Failed to notify IRMd we are initialized.");
- ipcp_set_state(IPCP_NULL);
- goto fail_create_r;
+ goto fail_start;
}
- ipcp_shutdown();
+ ipcp_sigwait();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
stop_components();
finalize_components();
}
+ ipcp_stop();
+
enroll_fini();
connmgr_fini();
@@ -322,9 +308,7 @@ int main(int argc,
exit(EXIT_SUCCESS);
- fail_create_r:
- ipcp_shutdown();
- fail_boot:
+ fail_start:
enroll_fini();
fail_enroll_init:
connmgr_fini();
@@ -333,6 +317,5 @@ int main(int argc,
fail_notifier_init:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
exit(EXIT_FAILURE);
}
diff --git a/src/ipcpd/common/comp.h b/src/ipcpd/common/comp.h
index 95e59b24..f3790d9c 100644
--- a/src/ipcpd/common/comp.h
+++ b/src/ipcpd/common/comp.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Components for the unicast/broadcast IPC process
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_COMMON_COMP_H
#define OUROBOROS_IPCPD_COMMON_COMP_H
-#include <ouroboros/cacep.h>
+#include <ouroboros/cep.h>
#define DST_MAX_STRLEN 64
diff --git a/src/ipcpd/common/connmgr.c b/src/ipcpd/common/connmgr.c
index 53a66992..4b5fd420 100644
--- a/src/ipcpd/common/connmgr.c
+++ b/src/ipcpd/common/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handles connections between components
*
@@ -22,9 +22,10 @@
#define OUROBOROS_PREFIX "connection-manager"
+#include <ouroboros/cep.h>
#include <ouroboros/dev.h>
-#include <ouroboros/cacep.h>
#include <ouroboros/errno.h>
+#include <ouroboros/fccntl.h>
#include <ouroboros/list.h>
#include <ouroboros/logs.h>
#include <ouroboros/notifier.h>
@@ -33,9 +34,9 @@
#include "connmgr.h"
#include "ipcp.h"
-#include <string.h>
-#include <stdlib.h>
#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
enum connmgr_state {
CONNMGR_NULL = 0,
@@ -128,10 +129,12 @@ static int add_comp_conn(enum comp_id id,
static void * flow_acceptor(void * o)
{
- int fd;
- qosspec_t qs;
- struct conn_info rcv_info;
- struct conn_info fail_info;
+ int fd;
+ qosspec_t qs;
+ struct conn_info rcv_info;
+ struct conn_info fail_info;
+ struct timespec timeo = TIMESPEC_INIT_MS(CONNMGR_RCV_TIMEOUT);
+ int err;
(void) o;
@@ -143,38 +146,48 @@ static void * flow_acceptor(void * o)
fd = flow_accept(&qs, NULL);
if (fd < 0) {
if (fd != -EIRMD)
- log_warn("Flow accept failed: %d", fd);
+ log_err("Flow accept failed: %d", fd);
continue;
}
- if (cacep_rcv(fd, &rcv_info)) {
- log_dbg("Error establishing application connection.");
+ log_info("Handling incoming flow %d.",fd);
+
+ fccntl(fd, FLOWSRCVTIMEO, &timeo);
+
+ err = cep_rcv(fd, &rcv_info);
+ if (err < 0) {
+ log_err("Error receiving OCEP info: %d.", err);
flow_dealloc(fd);
continue;
}
+ log_info("Request to connect to %s.", rcv_info.comp_name);
+
id = get_id_by_name(rcv_info.comp_name);
if (id < 0) {
- log_dbg("Connection request for unknown component %s.",
+ log_err("Connection request for unknown component %s.",
rcv_info.comp_name);
- cacep_snd(fd, &fail_info);
+ cep_snd(fd, &fail_info);
flow_dealloc(fd);
continue;
}
- assert(id < COMPID_MAX);
-
- if (cacep_snd(fd, &connmgr.comps[id].info)) {
- log_dbg("Failed to respond to request.");
+ err = cep_snd(fd, &connmgr.comps[id].info);
+ if (err < 0) {
+ log_err("Failed responding to OCEP request: %d.", err);
flow_dealloc(fd);
continue;
}
- if (add_comp_conn(id, fd, qs, &rcv_info)) {
- log_dbg("Failed to add new connection.");
+ err = add_comp_conn(id, fd, qs, &rcv_info);
+ if (err < 0) {
+ log_err("Failed to add new connection: %d.", err);
flow_dealloc(fd);
continue;
}
+
+ log_info("Finished handling incoming flow %d for %s.",
+ fd, rcv_info.comp_name);
}
return (void *) 0;
@@ -215,8 +228,10 @@ int connmgr_init(void)
{
connmgr.state = CONNMGR_INIT;
- if (notifier_reg(handle_event, NULL))
+ if (notifier_reg(handle_event, NULL)) {
+ log_err("Failed to register notifier.");
return -1;
+ }
return 0;
}
@@ -236,8 +251,10 @@ void connmgr_fini(void)
int connmgr_start(void)
{
- if (pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL))
+ if (pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL)) {
+ log_err("Failed to create pthread: %s.", strerror(errno));
return -1;
+ }
connmgr.state = CONNMGR_RUNNING;
@@ -259,12 +276,14 @@ int connmgr_comp_init(enum comp_id id,
comp = connmgr.comps + id;
- if (pthread_mutex_init(&comp->lock, NULL))
- return -1;
+ if (pthread_mutex_init(&comp->lock, NULL)) {
+ log_err("Failed to initialize mutex: %s.", strerror(errno));
+ goto fail_mutex;
+ }
if (pthread_cond_init(&comp->cond, NULL)) {
- pthread_mutex_destroy(&comp->lock);
- return -1;
+ log_err("Failed to initialize condvar: %s.", strerror(errno));
+ goto fail_cond;
}
list_head_init(&comp->conns);
@@ -273,6 +292,11 @@ int connmgr_comp_init(enum comp_id id,
memcpy(&connmgr.comps[id].info, info, sizeof(connmgr.comps[id].info));
return 0;
+
+ fail_cond:
+ pthread_mutex_destroy(&comp->lock);
+ fail_mutex:
+ return -1;
}
void connmgr_comp_fini(enum comp_id id)
@@ -316,26 +340,32 @@ int connmgr_ipcp_connect(const char * dst,
{
struct conn_el * ce;
int id;
+ int ret;
assert(dst);
assert(component);
ce = malloc(sizeof(*ce));
if (ce == NULL) {
- log_dbg("Out of memory.");
- return -1;
+ log_err("Out of memory.");
+ goto fail_malloc;
}
id = get_id_by_name(component);
if (id < 0) {
- log_dbg("No such component: %s", component);
- free(ce);
- return -1;
+ log_err("No such component: %s", component);
+ goto fail_id;
}
- if (connmgr_alloc(id, dst, &qs, &ce->conn)) {
- free(ce);
- return -1;
+ pthread_cleanup_push(free, ce);
+
+ ret = connmgr_alloc(id, dst, &qs, &ce->conn);
+
+ pthread_cleanup_pop(false);
+
+ if (ret < 0) {
+ log_err("Failed to allocate flow.");
+ goto fail_id;
}
if (strlen(dst) > DST_MAX_STRLEN) {
@@ -353,6 +383,11 @@ int connmgr_ipcp_connect(const char * dst,
pthread_mutex_unlock(&connmgr.comps[id].lock);
return 0;
+
+ fail_id:
+ free(ce);
+ fail_malloc:
+ return -1;
}
int connmgr_ipcp_disconnect(const char * dst,
@@ -366,8 +401,10 @@ int connmgr_ipcp_disconnect(const char * dst,
assert(component);
id = get_id_by_name(component);
- if (id < 0)
+ if (id < 0) {
+ log_err("No such component: %s.", component);
return -1;
+ }
pthread_mutex_lock(&connmgr.comps[id].lock);
@@ -393,54 +430,58 @@ int connmgr_alloc(enum comp_id id,
qosspec_t * qs,
struct conn * conn)
{
+ struct comp * comp;
+ int fd;
+ struct timespec timeo = TIMESPEC_INIT_MS(CONNMGR_RCV_TIMEOUT);
+
assert(id >= 0 && id < COMPID_MAX);
assert(dst);
- conn->flow_info.fd = flow_alloc(dst, qs, NULL);
- if (conn->flow_info.fd < 0) {
- log_dbg("Failed to allocate flow to %s.", dst);
- return -1;
+ comp = connmgr.comps + id;
+
+ fd = flow_alloc(dst, qs, NULL);
+ if (fd < 0) {
+ log_err("Failed to allocate flow to %s.", dst);
+ goto fail_alloc;
}
+ conn->flow_info.fd = fd;
+
if (qs != NULL)
conn->flow_info.qs = *qs;
else
memset(&conn->flow_info.qs, 0, sizeof(conn->flow_info.qs));
- log_dbg("Sending cacep info for protocol %s to fd %d.",
- connmgr.comps[id].info.protocol, conn->flow_info.fd);
+ log_dbg("Sending OCEP info for protocol %s to fd %d.",
+ comp->info.protocol, conn->flow_info.fd);
- if (cacep_snd(conn->flow_info.fd, &connmgr.comps[id].info)) {
- log_dbg("Failed to create application connection.");
- flow_dealloc(conn->flow_info.fd);
- return -1;
+ fccntl(fd, FLOWSRCVTIMEO, &timeo);
+
+ if (cep_snd(fd, &comp->info)) {
+ log_err("Failed to send OCEP info.");
+ goto fail_cep;
}
- if (cacep_rcv(conn->flow_info.fd, &conn->conn_info)) {
- log_dbg("Failed to connect to application.");
- flow_dealloc(conn->flow_info.fd);
- return -1;
+ if (cep_rcv(fd, &conn->conn_info)) {
+ log_err("Failed to receive OCEP info.");
+ goto fail_cep;
}
- if (strcmp(connmgr.comps[id].info.protocol, conn->conn_info.protocol)) {
- log_dbg("Unknown protocol (requested %s, got %s).",
- connmgr.comps[id].info.protocol,
- conn->conn_info.protocol);
- flow_dealloc(conn->flow_info.fd);
- return -1;
+ if (strcmp(comp->info.protocol, conn->conn_info.protocol)) {
+ log_err("Unknown protocol (requested %s, got %s).",
+ comp->info.protocol, conn->conn_info.protocol);
+ goto fail_cep;
}
- if (connmgr.comps[id].info.pref_version !=
- conn->conn_info.pref_version) {
- log_dbg("Unknown protocol version.");
- flow_dealloc(conn->flow_info.fd);
- return -1;
+ if (comp->info.pref_version != conn->conn_info.pref_version) {
+ log_err("Unknown protocol version %d.",
+ conn->conn_info.pref_version);
+ goto fail_cep;
}
- if (connmgr.comps[id].info.pref_syntax != conn->conn_info.pref_syntax) {
- log_dbg("Unknown protocol syntax.");
- flow_dealloc(conn->flow_info.fd);
- return -1;
+ if (comp->info.pref_syntax != conn->conn_info.pref_syntax) {
+ log_err("Unknown protocol syntax.");
+ goto fail_cep;
}
switch (id) {
@@ -458,6 +499,11 @@ int connmgr_alloc(enum comp_id id,
}
return 0;
+
+ fail_cep:
+ flow_dealloc(conn->flow_info.fd);
+ fail_alloc:
+ return -1;
}
int connmgr_dealloc(enum comp_id id,
@@ -503,6 +549,7 @@ int connmgr_wait(enum comp_id id,
el = list_first_entry((&comp->pending), struct conn_el, next);
if (el == NULL) {
pthread_mutex_unlock(&comp->lock);
+ log_err("Failed to get connection element.");
return -1;
}
diff --git a/src/ipcpd/common/connmgr.h b/src/ipcpd/common/connmgr.h
index 5f7b557f..0710dbbf 100644
--- a/src/ipcpd/common/connmgr.h
+++ b/src/ipcpd/common/connmgr.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handles the different AP connections
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_COMMON_CONNMGR_H
#define OUROBOROS_IPCPD_COMMON_CONNMGR_H
-#include <ouroboros/cacep.h>
+#include <ouroboros/cep.h>
#include <ouroboros/qos.h>
#include "comp.h"
diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c
index 090067d8..5e35ce37 100644
--- a/src/ipcpd/common/enroll.c
+++ b/src/ipcpd/common/enroll.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Enrollment Task
*
@@ -28,13 +28,11 @@
#define OUROBOROS_PREFIX "enrollment"
-#include <ouroboros/endian.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/time_utils.h>
#include <ouroboros/dev.h>
-#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
-#include <ouroboros/sockets.h>
+#include <ouroboros/logs.h>
+#include <ouroboros/serdes-oep.h>
+#include <ouroboros/time.h>
#include "common/connmgr.h"
#include "common/enroll.h"
@@ -45,9 +43,6 @@
#include <string.h>
#include <pthread.h>
-#include "ipcp_config.pb-c.h"
-typedef EnrollMsg enroll_msg_t;
-
#define ENROLL_COMP "Enrollment"
#define ENROLL_PROTO "OEP" /* Ouroboros enrollment protocol */
#define ENROLL_WARN_TIME_OFFSET 20
@@ -65,261 +60,218 @@ struct {
pthread_t listener;
} enroll;
-static int send_rcv_enroll_msg(int fd)
+static void * enroll_handle(void * o)
{
- enroll_msg_t req = ENROLL_MSG__INIT;
- enroll_msg_t * reply;
- uint8_t buf[ENROLL_BUF_LEN];
- ssize_t len;
- ssize_t delta_t;
- struct timespec t0;
- struct timespec rtt;
-
- req.code = ENROLL_CODE__ENROLL_REQ;
-
- len = enroll_msg__get_packed_size(&req);
- if (len < 0) {
- log_dbg("Failed pack request message.");
- return -1;
- }
-
- enroll_msg__pack(&req, buf);
+ struct enroll_req req;
+ struct enroll_resp resp;
+ struct enroll_ack ack;
+ struct conn conn;
+ uint8_t __buf[ENROLL_BUF_LEN];
+ buffer_t buf;
+ ssize_t len;
- clock_gettime(CLOCK_REALTIME, &t0);
-
- if (flow_write(fd, buf, len) < 0) {
- log_dbg("Failed to send request message.");
- return -1;
- }
-
- len = flow_read(fd, buf, ENROLL_BUF_LEN);
- if (len < 0) {
- log_dbg("No enrollment reply received.");
- return -1;
- }
-
- log_dbg("Received enrollment info (%zd bytes).", len);
-
- reply = enroll_msg__unpack(NULL, len, buf);
- if (reply == NULL) {
- log_dbg("No enrollment response.");
- return -1;
- }
+ (void) o;
- if (reply->code != ENROLL_CODE__ENROLL_BOOT) {
- log_dbg("Failed to unpack enrollment response.");
- enroll_msg__free_unpacked(reply, NULL);
- return -1;
- }
+ buf.data = __buf;
+ buf.len = sizeof(__buf);
- if (!(reply->has_t_sec && reply->has_t_nsec)) {
- log_dbg("No time in response message.");
- enroll_msg__free_unpacked(reply, NULL);
- return -1;
- }
+ resp.response = 0;
+ resp.conf = enroll.conf;
- clock_gettime(CLOCK_REALTIME, &rtt);
+ while (true) {
+ buffer_t msg;
+ int fd;
- delta_t = ts_diff_ms(&t0, &rtt);
+ if (connmgr_wait(COMPID_ENROLL, &conn)) {
+ log_err("Failed to get next connection.");
+ continue;
+ }
- rtt.tv_sec = reply->t_sec;
- rtt.tv_nsec = reply->t_nsec;
+ fd = conn.flow_info.fd;
- if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET)
- log_warn("Clock offset above threshold.");
-
- strcpy(enroll.conf.layer_info.layer_name,
- reply->conf->layer_info->layer_name);
- enroll.conf.type = reply->conf->ipcp_type;
-#ifdef BUILD_IPCP_UNICAST
- enroll.conf.addr_size = reply->conf->addr_size;
- enroll.conf.eid_size = reply->conf->eid_size;
- enroll.conf.max_ttl = reply->conf->max_ttl;
- enroll.conf.addr_auth_type = reply->conf->addr_auth_type;
- enroll.conf.routing_type = reply->conf->routing_type;
- enroll.conf.cong_avoid = reply->conf->cong_avoid;
-#endif
- enroll.conf.layer_info.dir_hash_algo
- = reply->conf->layer_info->dir_hash_algo;
- enroll_msg__free_unpacked(reply, NULL);
+ log_info("Incoming enrollment connection on flow %d.", fd);
- return 0;
-}
+ len = flow_read(fd, buf.data, buf.len);
+ if (len < 0) {
+ log_err("Failed to read from flow %d.", fd);
+ goto finish_flow;
+ }
-static ssize_t enroll_pack(uint8_t ** buf)
-{
- enroll_msg_t msg = ENROLL_MSG__INIT;
- ipcp_config_msg_t config = IPCP_CONFIG_MSG__INIT;
- layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
- struct timespec now;
- ssize_t len;
+ msg.data = buf.data;
+ msg.len = (size_t) len;
- clock_gettime(CLOCK_REALTIME, &now);
-
- msg.code = ENROLL_CODE__ENROLL_BOOT;
- msg.has_t_sec = true;
- msg.t_sec = now.tv_sec;
- msg.has_t_nsec = true;
- msg.t_nsec = now.tv_nsec;
- msg.conf = &config;
-
- config.ipcp_type = enroll.conf.type;
-#ifdef BUILD_IPCP_UNICAST
- config.has_addr_size = true;
- config.addr_size = enroll.conf.addr_size;
- config.has_eid_size = true;
- config.eid_size = enroll.conf.eid_size;
- config.has_max_ttl = true;
- config.max_ttl = enroll.conf.max_ttl;
- config.has_addr_auth_type = true;
- config.addr_auth_type = enroll.conf.addr_auth_type;
- config.has_routing_type = true;
- config.routing_type = enroll.conf.routing_type;
- config.has_cong_avoid = true;
- config.cong_avoid = enroll.conf.cong_avoid;
-#endif
- config.layer_info = &layer_info;
+ if (enroll_req_des(&req, msg) < 0) {
+ log_err("Failed to unpack request message.");
+ goto finish_flow;
+ }
- layer_info.layer_name = (char *) enroll.conf.layer_info.layer_name;
- layer_info.dir_hash_algo = enroll.conf.layer_info.dir_hash_algo;
+ log_info_id(req.id, "Handling incoming enrollment.");
- len = enroll_msg__get_packed_size(&msg);
+ /* TODO: authentication, timezone handling (UTC). */
- *buf = malloc(len);
- if (*buf == NULL)
- return -1;
+ ack.result = -100;
- enroll_msg__pack(&msg, *buf);
+ clock_gettime(CLOCK_REALTIME, &resp.t);
- return len;
-}
+ memcpy(resp.id, req.id, ENROLL_ID_LEN);
-static void * enroll_handle(void * o)
-{
- struct conn conn;
- uint8_t buf[ENROLL_BUF_LEN];
- uint8_t * reply;
- ssize_t len;
- enroll_msg_t * msg;
+ len = enroll_resp_ser(&resp, buf);
+ if (len < 0) {
+ log_err_id(req.id, "Failed to pack reply.");
+ goto finish_enroll;
+ }
- (void) o;
+ log_dbg_id(req.id, "Sending enrollment info (%zd bytes).", len);
- while (true) {
- if (connmgr_wait(COMPID_ENROLL, &conn)) {
- log_err("Failed to get next connection.");
- continue;
+ if (flow_write(conn.flow_info.fd, buf.data, len) < 0) {
+ log_err_id(req.id, "Failed te send response.");
+ goto finish_enroll;
}
- len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN);
+ len = flow_read(conn.flow_info.fd, buf.data, buf.len);
if (len < 0) {
- log_err("Failed to read from flow.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
+ log_err_id(req.id, "Failed to read from flow.");
+ goto finish_enroll;
}
- msg = enroll_msg__unpack(NULL, len, buf);
- if (msg == NULL) {
- log_err("Failed to unpack message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
+ msg.data = buf.data;
+ msg.len = (size_t) len;
- if (msg->code != ENROLL_CODE__ENROLL_REQ) {
- log_err("Wrong message type.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- enroll_msg__free_unpacked(msg, NULL);
- continue;
+ if (enroll_ack_des(&ack, msg) < 0) {
+ log_err_id(req.id, "Failed to unpack ack.");
+ goto finish_enroll;
}
- log_dbg("Enrolling a new neighbor.");
-
- enroll_msg__free_unpacked(msg, NULL);
-
- len = enroll_pack(&reply);
- if (reply == NULL) {
- log_err("Failed to pack enrollment message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
+ if (memcmp(req.id, ack.id, ENROLL_ID_LEN) != 0)
+ log_warn_id(req.id, "Enrollment ID mismatch.");
+
+ finish_enroll:
+ switch(ack.result) {
+ case 0:
+ log_info_id(req.id, "Enrollment completed.");
+ break;
+ case -100:
+ log_warn_id(req.id, "Enrollment failed.");
+ break;
+ default:
+ log_warn_id(req.id, "Enrollment failed at remote.");
}
+ finish_flow:
+ connmgr_dealloc(COMPID_ENROLL, &conn);
- log_dbg("Sending enrollment info (%zd bytes).", len);
+ log_info("Enrollment flow %d closed.", fd);
+ }
- if (flow_write(conn.flow_info.fd, reply, len) < 0) {
- log_err("Failed respond to enrollment request.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- free(reply);
- continue;
- }
+ return 0;
+}
- free(reply);
+int enroll_boot(struct conn * conn,
+ const uint8_t * id)
+{
+ uint8_t __buf[ENROLL_BUF_LEN];
+ buffer_t buf;
+ buffer_t msg;
+ ssize_t len;
+ ssize_t delta_t;
+ struct timespec t0;
+ struct timespec rtt;
+ int fd;
+ int ret;
+ struct enroll_req req;
+ struct enroll_resp resp;
+
+ fd = conn->flow_info.fd;
+
+ buf.data = __buf;
+ buf.len = sizeof(__buf);
+
+ memcpy(req.id, id, ENROLL_ID_LEN);
+
+ len = enroll_req_ser(&req, buf);
+ if (len < 0) {
+ log_err_id(id, "Failed to pack request message.");
+ return -1;
+ }
- len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN);
- if (len < 0) {
- log_err("Failed to read from flow.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
+ clock_gettime(CLOCK_REALTIME, &t0);
- msg = enroll_msg__unpack(NULL, len, buf);
- if (msg == NULL) {
- log_err("Failed to unpack message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
+ if (flow_write(fd, buf.data, len) < 0) {
+ log_err_id(id, "Failed to send request message.");
+ return -1;
+ }
- if (msg->code != ENROLL_CODE__ENROLL_DONE || !msg->has_result) {
- log_err("Wrong message type.");
- enroll_msg__free_unpacked(msg, NULL);
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
+ len = flow_read(fd, buf.data, buf.len);
+ if (len < 0) {
+ log_err_id(id, "No reply received.");
+ return -1;
+ }
- if (msg->result == 0)
- log_dbg("Neighbor enrollment successful.");
- else
- log_dbg("Neigbor reported failed enrollment.");
+ log_dbg_id(id, "Received configuration info (%zd bytes).", len);
- enroll_msg__free_unpacked(msg, NULL);
+ msg.data = buf.data;
+ msg.len = len;
- connmgr_dealloc(COMPID_ENROLL, &conn);
+ ret = enroll_resp_des(&resp, msg);
+ if (ret < 0) {
+ log_err_id(id, "Failed to unpack response message.");
+ return -1;
}
- return 0;
-}
+ if (memcmp(resp.id, id, ENROLL_ID_LEN) != 0) {
+ log_err_id(id, "Enrollment ID mismatch.");
+ return -1;
+ }
-int enroll_boot(struct conn * conn)
-{
- log_dbg("Getting boot information.");
+ if (resp.response < 0) {
+ log_warn_id(id, "Remote denied request: %d.", resp.response);
+ return -1;
+ }
- if (send_rcv_enroll_msg(conn->flow_info.fd)) {
- log_err("Failed to enroll.");
+ if (resp.conf.type != ipcpi.type) {
+ log_err_id(id, "Wrong type in enrollment response %d (%d).",
+ resp.conf.type, ipcpi.type);
return -1;
}
+ clock_gettime(CLOCK_REALTIME, &rtt);
+
+ delta_t = ts_diff_ms(&t0, &rtt);
+
+ rtt.tv_sec = resp.t.tv_sec;
+ rtt.tv_nsec = resp.t.tv_nsec;
+
+ if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET)
+ log_warn_id(id, "Clock offset above threshold.");
+
+ enroll.conf = resp.conf;
+
return 0;
}
-int enroll_done(struct conn * conn,
- int result)
+int enroll_ack(struct conn * conn,
+ const uint8_t * id,
+ const int result)
{
- enroll_msg_t msg = ENROLL_MSG__INIT;
- uint8_t buf[ENROLL_BUF_LEN];
- ssize_t len;
+ struct enroll_ack ack;
+ uint8_t __buf[ENROLL_BUF_LEN];
+ buffer_t buf;
+ ssize_t len;
- msg.code = ENROLL_CODE__ENROLL_DONE;
- msg.has_result = true;
- msg.result = result;
+ buf.data = __buf;
+ buf.len = sizeof(__buf);
- len = enroll_msg__get_packed_size(&msg);
+ ack.result = result;
+
+ memcpy(ack.id, id, ENROLL_ID_LEN);
+
+ len = enroll_ack_ser(&ack, buf);
if (len < 0) {
- log_dbg("Failed pack request message.");
+ log_err_id(id, "Failed to pack acknowledgement.");
return -1;
}
- enroll_msg__pack(&msg, buf);
-
- if (flow_write(conn->flow_info.fd, buf, len) < 0) {
- log_dbg("Failed to send acknowledgment.");
+ if (flow_write(conn->flow_info.fd, buf.data, len) < 0) {
+ log_err_id(id, "Failed to send acknowledgment.");
return -1;
}
diff --git a/src/ipcpd/common/enroll.h b/src/ipcpd/common/enroll.h
index fb866416..f26c31a3 100644
--- a/src/ipcpd/common/enroll.h
+++ b/src/ipcpd/common/enroll.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Enrollment Task
*
@@ -37,10 +37,12 @@ void enroll_stop(void);
void enroll_bootstrap(const struct ipcp_config * conf);
-int enroll_boot(struct conn * conn);
+int enroll_boot(struct conn * conn,
+ const uint8_t * id);
-int enroll_done(struct conn * conn,
- int result);
+int enroll_ack(struct conn * conn,
+ const uint8_t * id,
+ const int result);
struct ipcp_config * enroll_get_conf(void);
diff --git a/src/ipcpd/config.h.in b/src/ipcpd/config.h.in
index 0bf3ad69..fe4f5fd2 100644
--- a/src/ipcpd/config.h.in
+++ b/src/ipcpd/config.h.in
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC process configuration
*
@@ -41,6 +41,8 @@
#define IPCP_LINUX_SLACK_NS @IPCP_LINUX_TIMERSLACK_NS@
+#cmakedefine IPCP_DEBUG_LOCAL
+
/* unicast IPCP */
#define QOS_PRIO_BE @IPCP_QOS_CUBE_BE_PRIO@
#define QOS_PRIO_VIDEO @IPCP_QOS_CUBE_VIDEO_PRIO@
@@ -48,6 +50,8 @@
#define IPCP_SCHED_THR_MUL @IPCP_SCHED_THR_MUL@
#define PFT_SIZE @PFT_SIZE@
#define DHT_ENROLL_SLACK @DHT_ENROLL_SLACK@
+#define IPCP_UNICAST_MPL @IPCP_UNICAST_MPL@
+#define CONNMGR_RCV_TIMEOUT @CONNMGR_RCV_TIMEOUT@
#cmakedefine IPCP_CONN_WAIT_DIR
#cmakedefine DISABLE_CORE_LOCK
@@ -59,8 +63,9 @@
#define NSLOOKUP_EXEC "@NSLOOKUP_EXECUTABLE@"
#define IPCP_UDP_RD_THR @IPCP_UDP_RD_THR@
#define IPCP_UDP_WR_THR @IPCP_UDP_WR_THR@
+#define IPCP_UDP_MPL @IPCP_UDP_MPL@
-/* eth-llc */
+/* eth */
#cmakedefine HAVE_NETMAP
#cmakedefine HAVE_BPF
#cmakedefine HAVE_RAW_SOCKETS
@@ -68,3 +73,11 @@
#define IPCP_ETH_RD_THR @IPCP_ETH_RD_THR@
#define IPCP_ETH_WR_THR @IPCP_ETH_WR_THR@
#define IPCP_ETH_LO_MTU @IPCP_ETH_LO_MTU@
+#define IPCP_ETH_MPL @IPCP_ETH_MPL@
+
+/* local */
+#define IPCP_LOCAL_MPL @IPCP_LOCAL_MPL@
+
+/* broadcast */
+/* local */
+#define IPCP_BROADCAST_MPL @IPCP_BROADCAST_MPL@
diff --git a/src/ipcpd/eth/CMakeLists.txt b/src/ipcpd/eth/CMakeLists.txt
index d7105b4f..d57e1848 100644
--- a/src/ipcpd/eth/CMakeLists.txt
+++ b/src/ipcpd/eth/CMakeLists.txt
@@ -85,6 +85,8 @@ if (HAVE_ETH)
"Bypass the Qdisc in the kernel when using raw sockets")
set(IPCP_ETH_LO_MTU 1500 CACHE STRING
"Restrict Ethernet MTU over loopback interfaces")
+ set(IPCP_ETH_MPL 5 CACHE STRING
+ "Default maximum packet lifetime for the Ethernet IPCPs, in seconds")
set(ETH_LLC_SOURCES
# Add source files here
diff --git a/src/ipcpd/eth/dix.c b/src/ipcpd/eth/dix.c
index ac117e37..37b9896d 100644
--- a/src/ipcpd/eth/dix.c
+++ b/src/ipcpd/eth/dix.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC processes over Ethernet - DIX
*
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 932034d5..ea6e0f1c 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC processes over Ethernet
*
@@ -37,6 +37,7 @@
#include "config.h"
+#include <ouroboros/endian.h>
#include <ouroboros/hash.h>
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
@@ -46,7 +47,7 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/logs.h>
-#include <ouroboros/time_utils.h>
+#include <ouroboros/time.h>
#include <ouroboros/fccntl.h>
#include <ouroboros/pthread.h>
@@ -135,7 +136,6 @@
#define ETH_FRAME_SIZE (ETH_HEADER_SIZE + ETH_MTU_MAX)
#endif
-#define ALLOC_TIMEO 10 /* ms */
#define NAME_QUERY_TIMEO 2000 /* ms */
#define MGMT_TIMEO 100 /* ms */
#define MGMT_FRAME_SIZE 2048
@@ -164,6 +164,7 @@ struct mgmt_msg {
uint32_t ber;
uint32_t max_gap;
uint32_t delay;
+ uint32_t timeout;
uint16_t cypher_s;
uint8_t in_order;
#if defined (BUILD_ETH_DIX)
@@ -454,16 +455,15 @@ static int eth_ipcp_send_frame(const uint8_t * dst_addr,
return 0;
}
-static int eth_ipcp_alloc(const uint8_t * dst_addr,
+static int eth_ipcp_alloc(const uint8_t * dst_addr,
#if defined(BUILD_ETH_DIX)
- uint16_t eid,
+ uint16_t eid,
#elif defined(BUILD_ETH_LLC)
- uint8_t ssap,
+ uint8_t ssap,
#endif
- const uint8_t * hash,
- qosspec_t qs,
- const void * data,
- size_t dlen)
+ const uint8_t * hash,
+ qosspec_t qs,
+ const buffer_t * data)
{
uint8_t * buf;
struct mgmt_msg * msg;
@@ -472,7 +472,7 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
len = sizeof(*msg) + ipcp_dir_hash_len();
- buf = malloc(len + ETH_HEADER_TOT_SIZE + dlen);
+ buf = malloc(len + ETH_HEADER_TOT_SIZE + data->len);
if (buf == NULL)
return -1;
@@ -492,9 +492,11 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
msg->in_order = qs.in_order;
msg->max_gap = hton32(qs.max_gap);
msg->cypher_s = hton16(qs.cypher_s);
+ msg->timeout = hton32(qs.timeout);
memcpy(msg + 1, hash, ipcp_dir_hash_len());
- memcpy(buf + len + ETH_HEADER_TOT_SIZE, data, dlen);
+ if (data->len > 0)
+ memcpy(buf + len + ETH_HEADER_TOT_SIZE, data->data, data->len);
ret = eth_ipcp_send_frame(dst_addr,
#if defined(BUILD_ETH_DIX)
@@ -503,28 +505,27 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr,
reverse_bits(MGMT_SAP),
reverse_bits(MGMT_SAP),
#endif
- buf, len + dlen);
+ buf, len + data->len);
free(buf);
return ret;
}
-static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
+static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
#if defined(BUILD_ETH_DIX)
- uint16_t seid,
- uint16_t deid,
+ uint16_t seid,
+ uint16_t deid,
#elif defined(BUILD_ETH_LLC)
- uint8_t ssap,
- uint8_t dsap,
+ uint8_t ssap,
+ uint8_t dsap,
#endif
- int response,
- const void * data,
- size_t len)
+ int response,
+ const buffer_t * data)
{
struct mgmt_msg * msg;
uint8_t * buf;
- buf = malloc(sizeof(*msg) + ETH_HEADER_TOT_SIZE + len);
+ buf = malloc(sizeof(*msg) + ETH_HEADER_TOT_SIZE + data->len);
if (buf == NULL)
return -1;
@@ -540,7 +541,8 @@ static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
#endif
msg->response = response;
- memcpy(msg + 1, data, len);
+ if (data->len > 0)
+ memcpy(msg + 1, data->data, data->len);
if (eth_ipcp_send_frame(dst_addr,
#if defined(BUILD_ETH_DIX)
@@ -549,7 +551,7 @@ static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
reverse_bits(MGMT_SAP),
reverse_bits(MGMT_SAP),
#endif
- buf, sizeof(*msg) + len)) {
+ buf, sizeof(*msg) + data->len)) {
free(buf);
return -1;
}
@@ -559,42 +561,20 @@ static int eth_ipcp_alloc_resp(uint8_t * dst_addr,
return 0;
}
-static int eth_ipcp_req(uint8_t * r_addr,
+static int eth_ipcp_req(uint8_t * r_addr,
#if defined(BUILD_ETH_DIX)
- uint16_t r_eid,
+ uint16_t r_eid,
#elif defined(BUILD_ETH_LLC)
- uint8_t r_sap,
+ uint8_t r_sap,
#endif
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t len)
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
- struct timespec ts = {0, ALLOC_TIMEO * MILLION};
- struct timespec abstime;
- int fd;
+ int fd;
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != -1 && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_dbg("Won't allocate over non-operational IPCP.");
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- return -1;
- }
-
- /* reply to IRM, called under lock to prevent race */
- fd = ipcp_flow_req_arr(dst, ipcp_dir_hash_len(), qs, data, len);
+ fd = ipcp_wait_flow_req_arr(dst, qs, IPCP_ETH_MPL, data);
if (fd < 0) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
return -1;
}
@@ -609,11 +589,6 @@ static int eth_ipcp_req(uint8_t * r_addr,
pthread_rwlock_unlock(&eth_data.flows_lock);
- ipcpi.alloc_id = fd;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
#if defined(BUILD_ETH_DIX)
log_dbg("New flow request, fd %d, remote endpoint %d.", fd, r_eid);
#elif defined(BUILD_ETH_LLC)
@@ -622,20 +597,20 @@ static int eth_ipcp_req(uint8_t * r_addr,
return 0;
}
-static int eth_ipcp_alloc_reply(uint8_t * r_addr,
+static int eth_ipcp_alloc_reply(uint8_t * r_addr,
#if defined(BUILD_ETH_DIX)
- uint16_t seid,
- uint16_t deid,
+ uint16_t seid,
+ uint16_t deid,
#elif defined(BUILD_ETH_LLC)
- uint8_t ssap,
- int dsap,
+ uint8_t ssap,
+ int dsap,
#endif
- int response,
- const void * data,
- size_t len)
+ int response,
+ const buffer_t * data)
{
- int ret = 0;
- int fd = -1;
+ int ret = 0;
+ int fd = -1;
+ time_t mpl = IPCP_ETH_MPL;
pthread_rwlock_wrlock(&eth_data.flows_lock);
@@ -670,11 +645,12 @@ static int eth_ipcp_alloc_reply(uint8_t * r_addr,
#elif defined(BUILD_ETH_LLC)
log_dbg("Flow reply, fd %d, SSAP %d, DSAP %d.", fd, ssap, dsap);
#endif
- if ((ret = ipcp_flow_alloc_reply(fd, response, data, len)) < 0)
+ if ((ret = ipcp_flow_alloc_reply(fd, response, mpl, data)) < 0) {
+ log_err("Failed to reply to flow allocation.");
return -1;
+ }
return ret;
-
}
static int eth_ipcp_name_query_req(const uint8_t * hash,
@@ -736,6 +712,7 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
struct mgmt_msg * msg;
size_t msg_len;
qosspec_t qs;
+ buffer_t data;
msg = (struct mgmt_msg *) buf;
@@ -753,6 +730,10 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
qs.in_order = msg->in_order;
qs.max_gap = ntoh32(msg->max_gap);
qs.cypher_s = ntoh16(msg->cypher_s);
+ qs.timeout = ntoh32(msg->timeout);
+
+ data.data = (uint8_t *) buf + msg_len;
+ data.len = len - msg_len;
if (shim_data_reg_has(eth_data.shim_data,
buf + sizeof(*msg))) {
@@ -764,13 +745,15 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
#endif
buf + sizeof(*msg),
qs,
- buf + msg_len,
- len - msg_len);
+ &data);
}
break;
case FLOW_REPLY:
assert(len >= sizeof(*msg));
+ data.data = (uint8_t *) buf + sizeof(*msg);
+ data.len = len - sizeof(*msg);
+
eth_ipcp_alloc_reply(r_addr,
#if defined(BUILD_ETH_DIX)
ntohs(msg->seid),
@@ -780,8 +763,7 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
msg->dsap,
#endif
msg->response,
- buf + sizeof(*msg),
- len - sizeof(*msg));
+ &data);
break;
case NAME_QUERY_REQ:
eth_ipcp_name_query_req(buf + sizeof(*msg), r_addr);
@@ -799,18 +781,15 @@ static int eth_ipcp_mgmt_frame(const uint8_t * buf,
static void * eth_ipcp_mgmt_handler(void * o)
{
- int ret;
- struct timespec timeout = {(MGMT_TIMEO / 1000),
- (MGMT_TIMEO % 1000) * MILLION};
- struct timespec abstime;
- struct mgmt_frame * frame;
-
(void) o;
pthread_cleanup_push(__cleanup_mutex_unlock, &eth_data.mgmt_lock);
while (true) {
- ret = 0;
+ int ret = 0;
+ struct timespec timeout = TIMESPEC_INIT_MS(MGMT_TIMEO);
+ struct timespec abstime;
+ struct mgmt_frame * frame = NULL;
clock_gettime(PTHREAD_COND_CLOCK, &abstime);
ts_add(&abstime, &timeout, &abstime);
@@ -822,23 +801,19 @@ static void * eth_ipcp_mgmt_handler(void * o)
ret = -pthread_cond_timedwait(&eth_data.mgmt_cond,
&eth_data.mgmt_lock,
&abstime);
+ if (ret != -ETIMEDOUT)
+ frame = list_first_entry((&eth_data.mgmt_frames),
+ struct mgmt_frame, next);
+ if (frame != NULL)
+ list_del(&frame->next);
- if (ret == -ETIMEDOUT) {
- pthread_mutex_unlock(&eth_data.mgmt_lock);
- continue;
- }
+ pthread_mutex_unlock(&eth_data.mgmt_lock);
- frame = list_first_entry((&eth_data.mgmt_frames),
- struct mgmt_frame, next);
- if (frame == NULL) {
- pthread_mutex_unlock(&eth_data.mgmt_lock);
+ if (frame == NULL)
continue;
- }
-
- list_del(&frame->next);
- pthread_mutex_unlock(&eth_data.mgmt_lock);
eth_ipcp_mgmt_frame(frame->buf, frame->len, frame->r_addr);
+
free(frame);
}
@@ -884,7 +859,7 @@ static void * eth_ipcp_packet_reader(void * o)
buf = nm_nextpkt(eth_data.nmd, &hdr);
if (buf == NULL) {
- log_err("Bad read from netmap device.");
+ log_dbg("Bad read from netmap device.");
continue;
}
#else
@@ -915,6 +890,7 @@ static void * eth_ipcp_packet_reader(void * o)
ETH_MTU + ETH_HEADER_TOT_SIZE, 0);
#endif
if (frame_len <= 0) {
+ log_dbg("Failed to receive frame.");
ipcp_sdb_release(sdb);
continue;
}
@@ -941,22 +917,14 @@ static void * eth_ipcp_packet_reader(void * o)
#endif
length = ntohs(e_frame->length);
#if defined(BUILD_ETH_DIX)
- if (e_frame->ethertype != eth_data.ethertype) {
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
- continue;
- }
+ if (e_frame->ethertype != eth_data.ethertype)
+ goto fail_frame;
deid = ntohs(e_frame->eid);
if (deid == MGMT_EID) {
#elif defined (BUILD_ETH_LLC)
- if (length > 0x05FF) {/* DIX */
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
- continue;
- }
+ if (length > 0x05FF) /* DIX */
+ goto fail_frame;
length -= LLC_HEADER_SIZE;
@@ -965,12 +933,12 @@ static void * eth_ipcp_packet_reader(void * o)
if (ssap == MGMT_SAP && dsap == MGMT_SAP) {
#endif
+ ipcp_sdb_release(sdb); /* No need for the N+1 buffer. */
+
frame = malloc(sizeof(*frame));
if (frame == NULL) {
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
- continue;
+ log_err("Failed to allocate frame.");
+ goto fail_frame;
}
memcpy(frame->buf, &e_frame->payload, length);
@@ -981,10 +949,6 @@ static void * eth_ipcp_packet_reader(void * o)
list_add(&frame->next, &eth_data.mgmt_frames);
pthread_cond_signal(&eth_data.mgmt_cond);
pthread_mutex_unlock(&eth_data.mgmt_lock);
-
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
} else {
pthread_rwlock_rdlock(&eth_data.flows_lock);
@@ -995,10 +959,7 @@ static void * eth_ipcp_packet_reader(void * o)
#endif
if (fd < 0) {
pthread_rwlock_unlock(&eth_data.flows_lock);
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
- continue;
+ goto fail_frame;
}
#ifdef BUILD_ETH_LLC
@@ -1006,10 +967,7 @@ static void * eth_ipcp_packet_reader(void * o)
|| memcmp(eth_data.fd_to_ef[fd].r_addr,
e_frame->src_hwaddr, MAC_SIZE)) {
pthread_rwlock_unlock(&eth_data.flows_lock);
-#ifndef HAVE_NETMAP
- ipcp_sdb_release(sdb);
-#endif
- continue;
+ goto fail_frame;
}
#endif
pthread_rwlock_unlock(&eth_data.flows_lock);
@@ -1017,9 +975,20 @@ static void * eth_ipcp_packet_reader(void * o)
#ifndef HAVE_NETMAP
shm_du_buff_head_release(sdb, ETH_HEADER_TOT_SIZE);
shm_du_buff_truncate(sdb, length);
- ipcp_flow_write(fd, sdb);
#else
- flow_write(fd, &e_frame->payload, length);
+ if (ipcp_sdb_reserve(&sdb, length))
+ continue;
+
+ buf = shm_du_buff_head(sdb);
+ memcpy(buf, &e_frame->payload, length);
+#endif
+ if (np1_flow_write(fd, sdb) < 0)
+ ipcp_sdb_release(sdb);
+
+ continue;
+ fail_frame:
+#ifndef HAVE_NETMAP
+ ipcp_sdb_release(sdb);
#endif
}
}
@@ -1053,27 +1022,28 @@ static void * eth_ipcp_packet_writer(void * o)
(void) o;
- pthread_cleanup_push(cleanup_writer, fq);
-
ipcp_lock_to_core();
+ pthread_cleanup_push(cleanup_writer, fq);
+
while (true) {
fevent(eth_data.np1_flows, fq, NULL);
while ((fd = fqueue_next(fq)) >= 0) {
if (fqueue_type(fq) != FLOW_PKT)
continue;
- if (ipcp_flow_read(fd, &sdb)) {
+ if (np1_flow_read(fd, &sdb)) {
log_dbg("Bad read from fd %d.", fd);
continue;
}
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
if (shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE)
== NULL) {
log_dbg("Failed to allocate header.");
ipcp_sdb_release(sdb);
+ continue;
}
pthread_rwlock_rdlock(&eth_data.flows_lock);
@@ -1089,14 +1059,15 @@ static void * eth_ipcp_packet_writer(void * o)
pthread_rwlock_unlock(&eth_data.flows_lock);
- eth_ipcp_send_frame(r_addr,
+ if (eth_ipcp_send_frame(r_addr,
#if defined(BUILD_ETH_DIX)
deid,
#elif defined(BUILD_ETH_LLC)
dsap, ssap,
#endif
shm_du_buff_head(sdb),
- len);
+ len))
+ log_dbg("Failed to send frame.");
ipcp_sdb_release(sdb);
}
}
@@ -1276,32 +1247,23 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
assert(conf);
assert(conf->type == THIS_TYPE);
- ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name");
- return -ENOMEM;
- }
-
- if (conf->dev == NULL) {
- log_err("Device name is NULL.");
- return -1;
- }
+ ipcpi.dir_hash_algo = (enum hash_algo) conf->layer_info.dir_hash_algo;
+ strcpy(ipcpi.layer_name, conf->layer_info.name);
- if (strlen(conf->dev) >= IFNAMSIZ) {
- log_err("Invalid device name: %s.", conf->dev);
+ if (strlen(conf->eth.dev) >= IFNAMSIZ) {
+ log_err("Invalid device name: %s.", conf->eth.dev);
return -1;
}
memset(&ifr, 0, sizeof(ifr));
- strcpy(ifr.ifr_name, conf->dev);
+ strcpy(ifr.ifr_name, conf->eth.dev);
#ifdef BUILD_ETH_DIX
- if (conf->ethertype < 0x0600 || conf->ethertype == 0xFFFF) {
- log_err("Invalid Ethertype.");
+ if (conf->eth.ethertype < 0x0600 || conf->eth.ethertype == 0xFFFF) {
+ log_err("Invalid Ethertype: %d.", conf->eth.ethertype);
return -1;
}
- eth_data.ethertype = htons(conf->ethertype);
+ eth_data.ethertype = htons(conf->eth.ethertype);
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
@@ -1311,9 +1273,9 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
}
for (ifa = ifaddr, idx = 0; ifa != NULL; ifa = ifa->ifa_next, ++idx) {
- if (strcmp(ifa->ifa_name, conf->dev))
+ if (strcmp(ifa->ifa_name, conf->eth.dev))
continue;
- log_dbg("Interface %s found.", conf->dev);
+ log_dbg("Interface %s found.", conf->eth.dev);
#if defined(HAVE_NETMAP) || defined(HAVE_BPF)
memcpy(eth_data.hw_addr,
@@ -1348,7 +1310,8 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
log_dbg("Device MTU is %d.", ifr.ifr_mtu);
eth_data.mtu = MIN((int) ETH_MTU_MAX, ifr.ifr_mtu);
- if (memcmp(conf->dev, "lo", 2) == 0 && eth_data.mtu > IPCP_ETH_LO_MTU) {
+ if (memcmp(conf->eth.dev, "lo", 2) == 0 &&
+ eth_data.mtu > IPCP_ETH_LO_MTU) {
log_dbg("Using loopback interface. MTU restricted to %d.",
IPCP_ETH_LO_MTU);
eth_data.mtu = IPCP_ETH_LO_MTU;
@@ -1372,7 +1335,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
close(skfd);
- idx = if_nametoindex(conf->dev);
+ idx = if_nametoindex(conf->eth.dev);
if (idx == 0) {
log_err("Failed to retrieve interface index.");
return -1;
@@ -1382,7 +1345,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#if defined(HAVE_NETMAP)
strcpy(ifn, "netmap:");
- strcat(ifn, conf->dev);
+ strcat(ifn, conf->eth.dev);
eth_data.nmd = nm_open(ifn, NULL, 0, NULL);
if (eth_data.nmd == NULL) {
@@ -1452,7 +1415,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
if (eth_data.s_fd < 0) {
log_err("Failed to create socket.");
- return -1;
+ goto fail_socket;
}
flags = fcntl(eth_data.s_fd, F_GETFL, 0);
@@ -1474,60 +1437,52 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#endif
if (bind(eth_data.s_fd, (struct sockaddr *) &eth_data.device,
- sizeof(eth_data.device))) {
+ sizeof(eth_data.device)) < 0) {
log_err("Failed to bind socket to interface.");
goto fail_device;
}
-
#endif /* HAVE_NETMAP */
- ipcp_set_state(IPCP_OPERATIONAL);
-
#if defined(__linux__)
- if (pthread_create(&eth_data.if_monitor,
- NULL,
- eth_ipcp_if_monitor,
- NULL)) {
- ipcp_set_state(IPCP_INIT);
+ if (pthread_create(&eth_data.if_monitor, NULL,
+ eth_ipcp_if_monitor, NULL)) {
+ log_err("Failed to create monitor thread: %s.",
+ strerror(errno));
goto fail_device;
}
#endif
- if (pthread_create(&eth_data.mgmt_handler,
- NULL,
- eth_ipcp_mgmt_handler,
- NULL)) {
- ipcp_set_state(IPCP_INIT);
+ if (pthread_create(&eth_data.mgmt_handler, NULL,
+ eth_ipcp_mgmt_handler, NULL)) {
+ log_err("Failed to create mgmt handler thread: %s.",
+ strerror(errno));
goto fail_mgmt_handler;
}
for (idx = 0; idx < IPCP_ETH_RD_THR; ++idx) {
- if (pthread_create(&eth_data.packet_reader[idx],
- NULL,
- eth_ipcp_packet_reader,
- NULL)) {
- ipcp_set_state(IPCP_INIT);
+ if (pthread_create(&eth_data.packet_reader[idx], NULL,
+ eth_ipcp_packet_reader, NULL)) {
+ log_err("Failed to create packet reader thread: %s",
+ strerror(errno));
goto fail_packet_reader;
}
}
for (idx = 0; idx < IPCP_ETH_WR_THR; ++idx) {
- if (pthread_create(&eth_data.packet_writer[idx],
- NULL,
- eth_ipcp_packet_writer,
- NULL)) {
- ipcp_set_state(IPCP_INIT);
+ if (pthread_create(&eth_data.packet_writer[idx], NULL,
+ eth_ipcp_packet_writer, NULL)) {
+ log_err("Failed to create packet writer thread: %s",
+ strerror(errno));
goto fail_packet_writer;
}
}
#if defined(BUILD_ETH_DIX)
log_dbg("Bootstrapped IPCP over DIX Ethernet with pid %d "
- "and Ethertype 0x%X.", getpid(), conf->ethertype);
+ "and Ethertype 0x%X.", getpid(), conf->eth.ethertype);
#elif defined(BUILD_ETH_LLC)
log_dbg("Bootstrapped IPCP over Ethernet with LLC with pid %d.",
getpid());
#endif
-
return 0;
fail_packet_writer:
@@ -1558,19 +1513,18 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#elif defined(HAVE_RAW_SOCKETS)
close(eth_data.s_fd);
#endif
+ fail_socket:
return -1;
}
static int eth_ipcp_reg(const uint8_t * hash)
{
if (shim_data_reg_add_entry(eth_data.shim_data, hash)) {
- log_err("Failed to add " HASH_FMT " to local registry.",
- HASH_VAL(hash));
+ log_err("Failed to add " HASH_FMT32 " to local registry.",
+ HASH_VAL32(hash));
return -1;
}
- log_dbg("Registered " HASH_FMT ".", HASH_VAL(hash));
-
return 0;
}
@@ -1584,8 +1538,7 @@ static int eth_ipcp_unreg(const uint8_t * hash)
static int eth_ipcp_query(const uint8_t * hash)
{
uint8_t r_addr[MAC_SIZE];
- struct timespec timeout = {(NAME_QUERY_TIMEO / 1000),
- (NAME_QUERY_TIMEO % 1000) * MILLION};
+ struct timespec timeout = TIMESPEC_INIT_MS(NAME_QUERY_TIMEO);
struct dir_query * query;
int ret;
uint8_t * buf;
@@ -1637,11 +1590,10 @@ static int eth_ipcp_query(const uint8_t * hash)
return ret;
}
-static int eth_ipcp_flow_alloc(int fd,
- const uint8_t * hash,
- qosspec_t qs,
- const void * data,
- size_t len)
+static int eth_ipcp_flow_alloc(int fd,
+ const uint8_t * hash,
+ qosspec_t qs,
+ const buffer_t * data)
{
#ifdef BUILD_ETH_LLC
uint8_t ssap = 0;
@@ -1649,12 +1601,11 @@ static int eth_ipcp_flow_alloc(int fd,
uint8_t r_addr[MAC_SIZE];
uint64_t addr = 0;
- log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(hash));
-
assert(hash);
if (!shim_data_dir_has(eth_data.shim_data, hash)) {
- log_err("Destination unreachable.");
+ log_err("Destination "HASH_FMT32 "unreachable.",
+ HASH_VAL32(hash));
return -1;
}
addr = shim_data_dir_get_addr(eth_data.shim_data, hash);
@@ -1664,6 +1615,7 @@ static int eth_ipcp_flow_alloc(int fd,
ssap = bmp_allocate(eth_data.saps);
if (!bmp_is_id_valid(eth_data.saps, ssap)) {
pthread_rwlock_unlock(&eth_data.flows_lock);
+ log_err("Failed to allocate SSAP.");
return -1;
}
@@ -1682,34 +1634,29 @@ static int eth_ipcp_flow_alloc(int fd,
#endif
hash,
qs,
- data,
- len) < 0) {
+ data) < 0) {
#ifdef BUILD_ETH_LLC
pthread_rwlock_wrlock(&eth_data.flows_lock);
bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
eth_data.fd_to_ef[fd].sap = -1;
eth_data.ef_to_fd[ssap] = -1;
pthread_rwlock_unlock(&eth_data.flows_lock);
+ log_err("Failed to allocate with peer.");
#endif
return -1;
}
fset_add(eth_data.np1_flows, fd);
-#if defined(BUILD_ETH_DIX)
- log_dbg("Pending flow with fd %d.", fd);
-#elif defined(BUILD_ETH_LLC)
- log_dbg("Pending flow with fd %d on SAP %d.", fd, ssap);
+#if defined(BUILD_ETH_LLC)
+ log_dbg("Assigned SAP %d for fd %d.", ssap, fd);
#endif
return 0;
}
-static int eth_ipcp_flow_alloc_resp(int fd,
- int response,
- const void * data,
- size_t len)
+static int eth_ipcp_flow_alloc_resp(int fd,
+ int response,
+ const buffer_t * data)
{
- struct timespec ts = {0, ALLOC_TIMEO * MILLION};
- struct timespec abstime;
#if defined(BUILD_ETH_DIX)
uint16_t r_eid;
#elif defined(BUILD_ETH_LLC)
@@ -1718,27 +1665,11 @@ static int eth_ipcp_flow_alloc_resp(int fd,
#endif
uint8_t r_addr[MAC_SIZE];
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
+ if (ipcp_wait_flow_resp(fd) < 0) {
+ log_err("Failed to wait for flow response.");
return -1;
}
- ipcpi.alloc_id = -1;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
pthread_rwlock_wrlock(&eth_data.flows_lock);
#if defined(BUILD_ETH_DIX)
r_eid = eth_data.fd_to_ef[fd].r_eid;
@@ -1746,6 +1677,7 @@ static int eth_ipcp_flow_alloc_resp(int fd,
ssap = bmp_allocate(eth_data.saps);
if (!bmp_is_id_valid(eth_data.saps, ssap)) {
pthread_rwlock_unlock(&eth_data.flows_lock);
+ log_err("Failed to allocate SSAP.");
return -1;
}
@@ -1764,21 +1696,19 @@ static int eth_ipcp_flow_alloc_resp(int fd,
ssap, r_sap,
#endif
response,
- data,
- len) < 0) {
+ data) < 0) {
#ifdef BUILD_ETH_LLC
pthread_rwlock_wrlock(&eth_data.flows_lock);
bmp_release(eth_data.saps, eth_data.fd_to_ef[fd].sap);
pthread_rwlock_unlock(&eth_data.flows_lock);
#endif
+ log_err("Failed to respond to peer.");
return -1;
}
fset_add(eth_data.np1_flows, fd);
-#if defined(BUILD_ETH_DIX)
- log_dbg("Accepted flow, fd %d.", fd);
-#elif defined(BUILD_ETH_LLC)
- log_dbg("Accepted flow, fd %d, SAP %d.", fd, (uint8_t)ssap);
+#if defined(BUILD_ETH_LLC)
+ log_dbg("Assigned SAP %d for fd %d.", ssap, fd);
#endif
return 0;
}
@@ -1807,9 +1737,7 @@ static int eth_ipcp_flow_dealloc(int fd)
pthread_rwlock_unlock(&eth_data.flows_lock);
- flow_dealloc(fd);
-
- log_dbg("Flow with fd %d deallocated.", fd);
+ ipcp_flow_dealloc(fd);
return 0;
}
@@ -1833,9 +1761,6 @@ int main(int argc,
{
int i;
- if (ipcp_init(argc, argv, &eth_ops, THIS_TYPE) < 0)
- goto fail_init;
-
if (eth_data_init() < 0) {
#if defined(BUILD_ETH_DIX)
log_err("Failed to init eth-llc data.");
@@ -1845,18 +1770,17 @@ int main(int argc,
goto fail_data_init;
}
- if (ipcp_boot() < 0) {
- log_err("Failed to boot IPCP.");
- goto fail_boot;
+ if (ipcp_init(argc, argv, &eth_ops, THIS_TYPE) < 0) {
+ log_err("Failed to initialize IPCP.");
+ goto fail_init;
}
- if (ipcp_create_r(0)) {
- log_err("Failed to notify IRMd we are initialized.");
- ipcp_set_state(IPCP_NULL);
- goto fail_create_r;
+ if (ipcp_start() < 0) {
+ log_err("Failed to start IPCP.");
+ goto fail_start;
}
- ipcp_shutdown();
+ ipcp_sigwait();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
for (i = 0; i < IPCP_ETH_WR_THR; ++i)
@@ -1879,19 +1803,18 @@ int main(int argc,
#endif
}
- eth_data_fini();
+ ipcp_stop();
ipcp_fini();
+ eth_data_fini();
+
exit(EXIT_SUCCESS);
- fail_create_r:
- ipcp_shutdown();
- fail_boot:
- eth_data_fini();
- fail_data_init:
+ fail_start:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
+ eth_data_fini();
+ fail_data_init:
exit(EXIT_FAILURE);
}
diff --git a/src/ipcpd/eth/llc.c b/src/ipcpd/eth/llc.c
index d1e8bbdc..c900dcab 100644
--- a/src/ipcpd/eth/llc.c
+++ b/src/ipcpd/eth/llc.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC processes over Ethernet - LLC
*
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index e3e4221a..966c4920 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC process main loop
*
@@ -35,18 +35,21 @@
#define OUROBOROS_PREFIX "ipcpd/ipcp"
#define IPCP_INFO "info"
+#define ALLOC_TIMEOUT 50 /* ms */
+#include <ouroboros/bitmap.h>
+#include <ouroboros/dev.h>
+#include <ouroboros/errno.h>
#include <ouroboros/hash.h>
+#include <ouroboros/ipcp-dev.h>
#include <ouroboros/logs.h>
-#include <ouroboros/time_utils.h>
-#include <ouroboros/utils.h>
-#include <ouroboros/sockets.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/dev.h>
-#include <ouroboros/bitmap.h>
#include <ouroboros/np1_flow.h>
-#include <ouroboros/rib.h>
+#include <ouroboros/protobuf.h>
#include <ouroboros/pthread.h>
+#include <ouroboros/rib.h>
+#include <ouroboros/sockets.h>
+#include <ouroboros/time.h>
+#include <ouroboros/utils.h>
#include "ipcp.h"
@@ -173,15 +176,15 @@ static int ipcp_rib_readdir(char *** buf)
while (info[i] != NULL) {
(*buf)[i] = strdup(info[i]);
- if (*buf == NULL)
+ if ((*buf)[i] == NULL)
goto fail_dup;
i++;
}
return i;
fail_dup:
- while (--i > 0)
- free((*buf)[i]);
+ while (i > 0)
+ free((*buf)[--i]);
fail:
free(*buf);
@@ -191,9 +194,13 @@ static int ipcp_rib_readdir(char *** buf)
static int ipcp_rib_getattr(const char * path,
struct rib_attr * attr)
{
- (void) path;
+ char buf[LAYER_NAME_SIZE + 2];
+ struct timespec now;
- attr->size = LAYER_NAME_SIZE;
+ clock_gettime(CLOCK_REALTIME_COARSE, &now);
+
+ attr->size = ipcp_rib_read(path, buf, LAYER_NAME_SIZE + 2);
+ attr->mtime = now.tv_sec;
return 0;
}
@@ -206,9 +213,7 @@ static struct rib_ops r_ops = {
static void * acceptloop(void * o)
{
- int csockfd;
- struct timeval tv = {(SOCKET_TIMEOUT / 1000),
- (SOCKET_TIMEOUT % 1000) * 1000};
+ int csockfd;
(void) o;
@@ -220,10 +225,6 @@ static void * acceptloop(void * o)
if (csockfd < 0)
continue;
- if (setsockopt(csockfd, SOL_SOCKET, SO_RCVTIMEO,
- (void *) &tv, sizeof(tv)))
- log_warn("Failed to set timeout on socket.");
-
cmd = malloc(sizeof(*cmd));
if (cmd == NULL) {
log_err("Out of memory");
@@ -260,28 +261,395 @@ static void * acceptloop(void * o)
return (void *) 0;
}
+int ipcp_wait_flow_req_arr(const uint8_t * dst,
+ qosspec_t qs,
+ time_t mpl,
+ const buffer_t * data)
+{
+ struct timespec ts = TIMESPEC_INIT_MS(ALLOC_TIMEOUT);
+ struct timespec abstime;
+ int fd;
+ buffer_t hash;
+
+ hash.data = (uint8_t *) dst;
+ hash.len = ipcp_dir_hash_len();
+
+ clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+
+ pthread_mutex_lock(&ipcpi.alloc_lock);
+
+ while (ipcpi.alloc_id != -1 && ipcp_get_state() == IPCP_OPERATIONAL) {
+ ts_add(&abstime, &ts, &abstime);
+ pthread_cond_timedwait(&ipcpi.alloc_cond,
+ &ipcpi.alloc_lock,
+ &abstime);
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ pthread_mutex_unlock(&ipcpi.alloc_lock);
+ log_err("Won't allocate over non-operational IPCP.");
+ return -EIPCPSTATE;
+ }
+
+ assert(ipcpi.alloc_id == -1);
+
+ fd = ipcp_flow_req_arr(&hash, qs, mpl, data);
+ if (fd < 0) {
+ pthread_mutex_unlock(&ipcpi.alloc_lock);
+ log_err("Failed to get fd for flow.");
+ return fd;
+ }
+
+ ipcpi.alloc_id = fd;
+ pthread_cond_broadcast(&ipcpi.alloc_cond);
+
+ pthread_mutex_unlock(&ipcpi.alloc_lock);
+
+ return fd;
+
+}
+
+int ipcp_wait_flow_resp(const int fd)
+{
+ struct timespec ts = TIMESPEC_INIT_MS(ALLOC_TIMEOUT);
+ struct timespec abstime;
+
+ clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+
+ pthread_mutex_lock(&ipcpi.alloc_lock);
+
+ while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) {
+ ts_add(&abstime, &ts, &abstime);
+ pthread_cond_timedwait(&ipcpi.alloc_cond,
+ &ipcpi.alloc_lock,
+ &abstime);
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ pthread_mutex_unlock(&ipcpi.alloc_lock);
+ return -1;
+ }
+
+ assert(ipcpi.alloc_id == fd);
+
+ ipcpi.alloc_id = -1;
+ pthread_cond_broadcast(&ipcpi.alloc_cond);
+
+ pthread_mutex_unlock(&ipcpi.alloc_lock);
+
+ return 0;
+}
+
static void free_msg(void * o)
{
ipcp_msg__free_unpacked((ipcp_msg_t *) o, NULL);
}
+
+static void do_bootstrap(ipcp_config_msg_t * conf_msg,
+ ipcp_msg_t * ret_msg)
+{
+ struct ipcp_config conf;
+
+ log_info("Bootstrapping...");
+
+ if (ipcpi.ops->ipcp_bootstrap == NULL) {
+ log_err("Bootstrap unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ conf = ipcp_config_msg_to_s(conf_msg);
+ ret_msg->result = ipcpi.ops->ipcp_bootstrap(&conf);
+ if (ret_msg->result == 0) {
+ ret_msg->layer_info = layer_info_s_to_msg(&conf.layer_info);
+ ipcp_set_state(IPCP_OPERATIONAL);
+ }
+ finish:
+ log_info("Finished bootstrapping: %d.", ret_msg->result);
+}
+
+static void do_enroll(const char * dst,
+ ipcp_msg_t * ret_msg)
+{
+ struct layer_info info;
+
+ log_info("Enrolling with %s...", dst);
+
+ if (ipcpi.ops->ipcp_enroll == NULL) {
+ log_err("Enroll unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_enroll(dst, &info);
+ if (ret_msg->result == 0) {
+ ret_msg->layer_info = layer_info_s_to_msg(&info);
+ ipcp_set_state(IPCP_OPERATIONAL);
+ }
+ finish:
+ log_info("Finished enrolling with %s: %d.", dst, ret_msg->result);
+}
+
+static void do_connect(const char * dst,
+ const char * comp,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ log_info("Connecting %s to %s...", comp, dst);
+
+ if (ipcpi.ops->ipcp_connect == NULL) {
+ log_err("Connect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_connect(dst, comp, qs);
+ finish:
+ log_info("Finished connecting: %d.", ret_msg->result);
+}
+
+static void do_disconnect(const char * dst,
+ const char * comp,
+ ipcp_msg_t * ret_msg)
+{
+ log_info("Disconnecting %s from %s...", comp, dst);
+
+ if (ipcpi.ops->ipcp_disconnect == NULL) {
+ log_err("Disconnect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_disconnect(dst, comp);
+
+ finish:
+ log_info("Finished disconnecting %s from %s: %d.",
+ comp, dst, ret_msg->result);
+}
+
+static void do_reg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+
+ log_info("Registering " HASH_FMT32 "...", HASH_VAL32(hash));
+
+ if (ipcpi.ops->ipcp_reg == NULL) {
+ log_err("Registration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_reg(hash);
+ finish:
+ log_info("Finished registering " HASH_FMT32 " : %d.",
+ HASH_VAL32(hash), ret_msg->result);
+}
+
+static void do_unreg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ log_info("Unregistering " HASH_FMT32 "...", HASH_VAL32(hash));
+
+ if (ipcpi.ops->ipcp_unreg == NULL) {
+ log_err("Unregistration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_unreg(hash);
+ finish:
+ log_info("Finished unregistering " HASH_FMT32 ": %d.",
+ HASH_VAL32(hash), ret_msg->result);
+}
+
+static void do_query(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ /* TODO: Log this operation when IRMd has internal caches. */
+
+ if (ipcpi.ops->ipcp_query == NULL) {
+ log_err("Directory query unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_query(hash);
+}
+
+static void do_flow_alloc(pid_t pid,
+ int flow_id,
+ uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ log_info("Allocating flow %d for %d to " HASH_FMT32 ".",
+ flow_id, pid, HASH_VAL32(dst));
+
+ if (ipcpi.ops->ipcp_flow_alloc == NULL) {
+ log_err("Flow allocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating n + 1 fd on flow_id %d: %d",
+ flow_id, fd);
+ ret_msg->result = -EFLOWDOWN;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc(fd, dst, qs, data);
+ finish:
+ log_info("Finished allocating flow %d to " HASH_FMT32 ": %d.",
+ flow_id, HASH_VAL32(dst), ret_msg->result);
+}
+
+
+static void do_flow_join(pid_t pid,
+ int flow_id,
+ const uint8_t * dst,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ log_info("Joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
+
+ if (ipcpi.ops->ipcp_flow_join == NULL) {
+ log_err("Broadcast unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating n + 1 fd on flow_id %d.", flow_id);
+ ret_msg->result = -1;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_join(fd, dst, qs);
+ finish:
+ log_info("Finished joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
+}
+
+static void do_flow_alloc_resp(int resp,
+ int flow_id,
+ const buffer_t * data,
+ ipcp_msg_t * ret_msg)
+{
+ int fd = -1;
+
+ log_info("Responding %d to alloc on flow_id %d.", resp, flow_id);
+
+ if (ipcpi.ops->ipcp_flow_alloc_resp == NULL) {
+ log_err("Flow_alloc_resp unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ if (resp == 0) {
+ fd = np1_flow_resp(flow_id);
+ if (fd < 0) {
+ log_warn("Flow_id %d is not known.", flow_id);
+ ret_msg->result = -1;
+ goto finish;
+ }
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc_resp(fd, resp, data);
+ finish:
+ log_info("Finished responding to allocation request: %d",
+ ret_msg->result);
+}
+
+static void do_flow_dealloc(int flow_id,
+ int timeo_sec,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ log_info("Deallocating flow %d.", flow_id);
+
+ if (ipcpi.ops->ipcp_flow_dealloc == NULL) {
+ log_err("Flow deallocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ goto finish;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ goto finish;
+ }
+
+ fd = np1_flow_dealloc(flow_id, timeo_sec);
+ if (fd < 0) {
+ log_warn("Could not deallocate flow_id %d.", flow_id);
+ ret_msg->result = -1;
+ goto finish;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_dealloc(fd);
+ finish:
+ log_info("Finished deallocating flow %d: %d.",
+ flow_id, ret_msg->result);
+}
+
static void * mainloop(void * o)
{
int sfd;
buffer_t buffer;
- struct ipcp_config conf;
- struct layer_info info;
- ipcp_config_msg_t * conf_msg;
ipcp_msg_t * msg;
(void) o;
while (true) {
- ipcp_msg_t ret_msg = IPCP_MSG__INIT;
- layer_info_msg_t layer_info = LAYER_INFO_MSG__INIT;
- int fd = -1;
- struct cmd * cmd;
- qosspec_t qs;
+ ipcp_msg_t ret_msg = IPCP_MSG__INIT;
+ qosspec_t qs;
+ struct cmd * cmd;
+ buffer_t data;
ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY;
@@ -312,329 +680,68 @@ static void * mainloop(void * o)
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
pthread_cleanup_push(free_msg, msg);
+ ret_msg.has_result = true;
+
switch (msg->code) {
case IPCP_MSG_CODE__IPCP_BOOTSTRAP:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_bootstrap == NULL) {
- log_err("Bootstrap unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- conf_msg = msg->conf;
- conf.type = conf_msg->ipcp_type;
- strcpy(conf.layer_info.layer_name,
- conf_msg->layer_info->layer_name);
-
- switch(conf_msg->ipcp_type) {
- case IPCP_LOCAL:
- break;
- case IPCP_UNICAST:
- conf.addr_size = conf_msg->addr_size;
- conf.eid_size = conf_msg->eid_size;
- conf.max_ttl = conf_msg->max_ttl;
- conf.addr_auth_type = conf_msg->addr_auth_type;
- conf.routing_type = conf_msg->routing_type;
- conf.cong_avoid = conf_msg->cong_avoid;
- break;
- case IPCP_ETH_DIX:
- conf.ethertype = conf_msg->ethertype;
- /* FALLTHRU */
- case IPCP_ETH_LLC:
- conf.dev = conf_msg->dev;
- break;
- case IPCP_UDP:
- conf.ip_addr = conf_msg->ip_addr;
- conf.dns_addr = conf_msg->dns_addr;
- conf.port = conf_msg->port;
- conf.layer_info.dir_hash_algo = HASH_MD5;
- layer_info.dir_hash_algo = HASH_MD5;
- break;
- case IPCP_BROADCAST:
- conf.layer_info.dir_hash_algo = HASH_SHA3_256;
- layer_info.dir_hash_algo = HASH_SHA3_256;
- break;
- default:
- log_err("Unknown IPCP type: %d.",
- conf_msg->ipcp_type);
- ret_msg.result = -EIPCP;
- goto exit; /* break from outer switch/case */
- }
-
- /* UDP and broadcast use fixed hash algorithm. */
- if (conf_msg->ipcp_type != IPCP_UDP &&
- conf_msg->ipcp_type != IPCP_BROADCAST) {
- switch(conf_msg->layer_info->dir_hash_algo) {
- case DIR_HASH_SHA3_224:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_224;
- break;
- case DIR_HASH_SHA3_256:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_256;
- break;
- case DIR_HASH_SHA3_384:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_384;
- break;
- case DIR_HASH_SHA3_512:
- conf.layer_info.dir_hash_algo =
- HASH_SHA3_512;
- break;
- default:
- assert(false);
- }
-
- layer_info.dir_hash_algo =
- conf.layer_info.dir_hash_algo;
- }
-
- ret_msg.result = ipcpi.ops->ipcp_bootstrap(&conf);
- if (ret_msg.result == 0) {
- ret_msg.layer_info = &layer_info;
- layer_info.layer_name =
- conf.layer_info.layer_name;
- }
+ do_bootstrap(msg->conf, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_ENROLL:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_enroll == NULL) {
- log_err("Enroll unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst,
- &info);
- if (ret_msg.result == 0) {
- ret_msg.layer_info = &layer_info;
- layer_info.dir_hash_algo = info.dir_hash_algo;
- layer_info.layer_name = info.layer_name;
- }
+ do_enroll(msg->dst, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_CONNECT:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_connect == NULL) {
- log_err("Connect unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- qs = msg_to_spec(msg->qosspec);
- ret_msg.result = ipcpi.ops->ipcp_connect(msg->dst,
- msg->comp,
- qs);
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ do_connect(msg->dst, msg->comp, qs, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_DISCONNECT:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_disconnect == NULL) {
- log_err("Disconnect unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- ret_msg.result = ipcpi.ops->ipcp_disconnect(msg->dst,
- msg->comp);
+ do_disconnect(msg->dst, msg->comp, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_REG:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_reg == NULL) {
- log_err("Registration unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- ret_msg.result =
- ipcpi.ops->ipcp_reg(msg->hash.data);
+ do_reg(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_UNREG:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_unreg == NULL) {
- log_err("Unregistration unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- ret_msg.result =
- ipcpi.ops->ipcp_unreg(msg->hash.data);
+ do_unreg(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_QUERY:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_query == NULL) {
- log_err("Directory query unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_query(msg->hash.data);
+ do_query(msg->hash.data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_flow_alloc == NULL) {
- log_err("Flow allocation unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
assert(msg->pk.len > 0 ? msg->pk.data != NULL
: msg->pk.data == NULL);
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- qs = msg_to_spec(msg->qosspec);
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id,
- qs);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc(fd,
- msg->hash.data,
- qs,
- msg->pk.data,
- msg->pk.len);
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ do_flow_alloc(msg->pid, msg->flow_id,
+ msg->hash.data, qs,
+ &data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_JOIN:
- ret_msg.has_result = true;
-
- if (ipcpi.ops->ipcp_flow_join == NULL) {
- log_err("Broadcast unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
assert(msg->hash.len == ipcp_dir_hash_len());
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- qs = msg_to_spec(msg->qosspec);
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id,
- qs);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_flow_join(fd,
- msg->hash.data,
- qs);
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ do_flow_join(msg->pid, msg->flow_id,
+ msg->hash.data, qs, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP:
- ret_msg.has_result = true;
- if (ipcpi.ops->ipcp_flow_alloc_resp == NULL) {
- log_err("Flow_alloc_resp unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- if (!msg->response) {
- fd = np1_flow_resp(msg->flow_id);
- if (fd < 0) {
- log_warn("Port_id %d is not known.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
- }
-
assert(msg->pk.len > 0 ? msg->pk.data != NULL
- : msg->pk.data == NULL);
-
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc_resp(fd,
- msg->response,
- msg->pk.data,
- msg->pk.len);
+ : msg->pk.data == NULL);
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ do_flow_alloc_resp(msg->response, msg->flow_id,
+ &data, &ret_msg);
break;
case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC:
- ret_msg.has_result = true;
- if (ipcpi.ops->ipcp_flow_dealloc == NULL) {
- log_err("Flow deallocation unsupported.");
- ret_msg.result = -ENOTSUP;
- break;
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
- ret_msg.result = -EIPCPSTATE;
- break;
- }
-
- fd = np1_flow_dealloc(msg->flow_id);
- if (fd < 0) {
- log_warn("Could not deallocate flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
- ret_msg.result =
- ipcpi.ops->ipcp_flow_dealloc(fd);
+ do_flow_dealloc(msg->flow_id, msg->timeo_sec, &ret_msg);
break;
default:
- ret_msg.has_result = true;
- ret_msg.result = -1;
- log_err("Don't know that message code");
+ ret_msg.result = -1;
+ log_err("Unknown message code: %d.", msg->code);
break;
}
- exit:
+
pthread_cleanup_pop(true);
pthread_cleanup_pop(false);
@@ -656,12 +763,16 @@ static void * mainloop(void * o)
ipcp_msg__pack(&ret_msg, buffer.data);
+ if (ret_msg.layer_info != NULL)
+ layer_info_msg__free_unpacked(ret_msg.layer_info, NULL);
+
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
+ pthread_cleanup_push(free, buffer.data)
if (write(sfd, buffer.data, buffer.len) == -1)
log_warn("Failed to send reply message");
- free(buffer.data);
+ pthread_cleanup_pop(true);
pthread_cleanup_pop(true);
tpm_inc(ipcpi.tpm);
@@ -771,14 +882,32 @@ int ipcp_init(int argc,
goto fail_rib_init;
}
+ if (rib_reg(IPCP_INFO, &r_ops)) {
+ log_err("Failed to register rib.");
+ goto fail_rib_reg;
+ }
+
+ ipcpi.tpm = tpm_create(IPCP_MIN_THREADS, IPCP_ADD_THREADS,
+ mainloop, NULL);
+ if (ipcpi.tpm == NULL) {
+ log_err("Failed to create threadpool manager.");
+ goto fail_tpm_create;
+ }
+
list_head_init(&ipcpi.cmds);
ipcpi.alloc_id = -1;
pthread_condattr_destroy(&cattr);
+ ipcp_set_state(IPCP_INIT);
+
return 0;
+ fail_tpm_create:
+ rib_unreg(IPCP_INFO);
+ fail_rib_reg:
+ rib_fini();
fail_rib_init:
pthread_cond_destroy(&ipcpi.cmd_cond);
fail_cmd_cond:
@@ -801,50 +930,55 @@ int ipcp_init(int argc,
return ret;
}
-int ipcp_boot()
+int ipcp_start(void)
{
- sigset_t sigset;
+ sigset_t sigset;
+ struct ipcp_info info;
+
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGQUIT);
sigaddset(&sigset, SIGHUP);
sigaddset(&sigset, SIGPIPE);
- ipcpi.tpm = tpm_create(IPCP_MIN_THREADS, IPCP_ADD_THREADS,
- mainloop, NULL);
- if (ipcpi.tpm == NULL)
- goto fail_tpm_create;
-
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+ info.pid = getpid();
+ info.type = ipcpi.type;
+ strcpy(info.name, ipcpi.name);
+ info.state = IPCP_OPERATIONAL;
+
if (tpm_start(ipcpi.tpm))
goto fail_tpm_start;
- ipcp_set_state(IPCP_INIT);
-
- if (rib_reg(IPCP_INFO, &r_ops))
- goto fail_rib_reg;
-
if (pthread_create(&ipcpi.acceptor, NULL, acceptloop, NULL)) {
log_err("Failed to create acceptor thread.");
- ipcp_set_state(IPCP_NULL);
goto fail_acceptor;
}
- return 0;
+ info.state = IPCP_OPERATIONAL;
+ if (ipcp_create_r(&info)) {
+ log_err("Failed to notify IRMd we are initialized.");
+ goto fail_create_r;
+ }
+ return 0;
+
+ fail_create_r:
+ pthread_cancel(ipcpi.acceptor);
+ pthread_join(ipcpi.acceptor, NULL);
fail_acceptor:
- rib_unreg(IPCP_INFO);
- fail_rib_reg:
tpm_stop(ipcpi.tpm);
fail_tpm_start:
tpm_destroy(ipcpi.tpm);
- fail_tpm_create:
+ ipcp_set_state(IPCP_NULL);
+ info.state = IPCP_NULL;
+ ipcp_create_r(&info);
return -1;
}
-void ipcp_shutdown()
+void ipcp_sigwait(void)
{
siginfo_t info;
@@ -877,8 +1011,11 @@ void ipcp_shutdown()
#endif
switch(info.si_signo) {
case SIGINT:
+ /* FALLTHRU */
case SIGTERM:
+ /* FALLTHRU */
case SIGHUP:
+ /* FALLTHRU */
case SIGQUIT:
if (info.si_pid == ipcpi.irmd_pid) {
if (ipcp_get_state() == IPCP_INIT)
@@ -890,23 +1027,30 @@ void ipcp_shutdown()
break;
case SIGPIPE:
log_dbg("Ignored SIGPIPE.");
+ continue;
default:
continue;
}
}
+}
- pthread_cancel(ipcpi.acceptor);
+void ipcp_stop(void)
+{
+ log_info("IPCP %d shutting down.", getpid());
+ pthread_cancel(ipcpi.acceptor);
pthread_join(ipcpi.acceptor, NULL);
- tpm_stop(ipcpi.tpm);
- tpm_destroy(ipcpi.tpm);
- log_info("IPCP %d shutting down.", getpid());
+ tpm_stop(ipcpi.tpm);
}
-void ipcp_fini()
+void ipcp_fini(void)
{
+ tpm_destroy(ipcpi.tpm);
+
+ rib_unreg(IPCP_INFO);
+
rib_fini();
close(ipcpi.sockfd);
@@ -937,7 +1081,7 @@ void ipcp_set_state(enum ipcp_state state)
pthread_mutex_unlock(&ipcpi.state_mtx);
}
-enum ipcp_state ipcp_get_state()
+enum ipcp_state ipcp_get_state(void)
{
enum ipcp_state state;
@@ -950,37 +1094,6 @@ enum ipcp_state ipcp_get_state()
return state;
}
-int ipcp_wait_state(enum ipcp_state state,
- const struct timespec * timeout)
-{
- struct timespec abstime;
- int ret = 0;
-
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
- ts_add(&abstime, timeout, &abstime);
-
- pthread_mutex_lock(&ipcpi.state_mtx);
-
- pthread_cleanup_push(__cleanup_mutex_unlock, &ipcpi.state_mtx);
-
- while (ipcpi.state != state
- && ipcpi.state != IPCP_SHUTDOWN
- && ipcpi.state != IPCP_NULL
- && ret != -ETIMEDOUT) {
- if (timeout == NULL)
- ret = -pthread_cond_wait(&ipcpi.state_cond,
- &ipcpi.state_mtx);
- else
- ret = -pthread_cond_timedwait(&ipcpi.state_cond,
- &ipcpi.state_mtx,
- &abstime);
- }
-
- pthread_cleanup_pop(true);
-
- return ret;
-}
-
void ipcp_lock_to_core(void)
{
#if defined(__linux__) && !defined(DISABLE_CORE_LOCK)
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index eff2ae12..aab490c7 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC process structure
*
@@ -26,20 +26,14 @@
#include <ouroboros/hash.h>
#include <ouroboros/ipcp.h>
#include <ouroboros/list.h>
+#include <ouroboros/protobuf.h>
+#include <ouroboros/qos.h>
#include <ouroboros/sockets.h>
#include <ouroboros/tpm.h>
#include <pthread.h>
#include <time.h>
-enum ipcp_state {
- IPCP_NULL = 0,
- IPCP_INIT,
- /* Layer name must be set for states below. */
- IPCP_OPERATIONAL,
- IPCP_SHUTDOWN
-};
-
struct ipcp_ops {
int (* ipcp_bootstrap)(const struct ipcp_config * conf);
@@ -59,20 +53,18 @@ struct ipcp_ops {
int (* ipcp_query)(const uint8_t * hash);
- int (* ipcp_flow_alloc)(int fd,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t len);
+ int (* ipcp_flow_alloc)(int fd,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data);
int (* ipcp_flow_join)(int fd,
const uint8_t * dst,
qosspec_t qs);
- int (* ipcp_flow_alloc_resp)(int fd,
- int response,
- const void * data,
- size_t len);
+ int (* ipcp_flow_alloc_resp)(int fd,
+ int response,
+ const buffer_t * data);
int (* ipcp_flow_dealloc)(int fd);
};
@@ -85,7 +77,7 @@ extern struct ipcp {
char * name;
enum ipcp_type type;
- char * layer_name;
+ char layer_name[LAYER_NAME_SIZE + 1];
uint64_t dt_addr;
@@ -95,9 +87,8 @@ extern struct ipcp {
int irmd_fd;
enum ipcp_state state;
- pthread_rwlock_t state_lock;
- pthread_mutex_t state_mtx;
pthread_cond_t state_cond;
+ pthread_mutex_t state_mtx;
int sockfd;
char * sock_path;
@@ -120,9 +111,11 @@ int ipcp_init(int argc,
struct ipcp_ops * ops,
enum ipcp_type type);
-int ipcp_boot(void);
+int ipcp_start(void);
-void ipcp_shutdown(void);
+void ipcp_sigwait(void);
+
+void ipcp_stop(void);
void ipcp_fini(void);
@@ -130,12 +123,17 @@ void ipcp_set_state(enum ipcp_state state);
enum ipcp_state ipcp_get_state(void);
-int ipcp_wait_state(enum ipcp_state state,
- const struct timespec * timeout);
-
int ipcp_parse_arg(int argc,
char * argv[]);
+/* Helper functions to handle races during flow allocation */
+int ipcp_wait_flow_req_arr(const uint8_t * dst,
+ qosspec_t qs,
+ time_t mpl,
+ const buffer_t * data);
+
+int ipcp_wait_flow_resp(const int fd);
+
/* Helper functions for directory entries, could be moved */
uint8_t * ipcp_hash_dup(const uint8_t * hash);
diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt
index a84f4f1b..10fd0120 100644
--- a/src/ipcpd/local/CMakeLists.txt
+++ b/src/ipcpd/local/CMakeLists.txt
@@ -13,6 +13,8 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
set(IPCP_LOCAL_TARGET ipcpd-local CACHE INTERNAL "")
+set(IPCP_LOCAL_MPL 2 CACHE STRING
+ "Default maximum packet lifetime for the Ethernet IPCPs, in seconds")
set(LOCAL_SOURCES
# Add source files here
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 9c62c3cc..160e07e0 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Local IPC process
*
@@ -48,8 +48,7 @@
#include <sys/wait.h>
#include <assert.h>
-#define THIS_TYPE IPCP_LOCAL
-#define ALLOC_TIMEOUT 10 /* ms */
+#define THIS_TYPE IPCP_LOCAL
struct ipcp ipcpi;
@@ -72,34 +71,39 @@ static int local_data_init(void)
local_data.flows = fset_create();
if (local_data.flows == NULL)
- return -ENFILE;
+ goto fail_fset;
local_data.fq = fqueue_create();
- if (local_data.fq == NULL) {
- fset_destroy(local_data.flows);
- return -ENOMEM;
- }
+ if (local_data.fq == NULL)
+ goto fail_fqueue;
local_data.shim_data = shim_data_create();
- if (local_data.shim_data == NULL) {
- fqueue_destroy(local_data.fq);
- fset_destroy(local_data.flows);
- return -ENOMEM;
- }
+ if (local_data.shim_data == NULL)
+ goto fail_shim_data;
- pthread_rwlock_init(&local_data.lock, NULL);
+ if (pthread_rwlock_init(&local_data.lock, NULL) < 0)
+ goto fail_rwlock_init;
return 0;
+
+ fail_rwlock_init:
+ shim_data_destroy(local_data.shim_data);
+ fail_shim_data:
+ fqueue_destroy(local_data.fq);
+ fail_fqueue:
+ fset_destroy(local_data.flows);
+ fail_fset:
+ return -ENOMEM;
}
static void local_data_fini(void){
+ pthread_rwlock_destroy(&local_data.lock);
shim_data_destroy(local_data.shim_data);
- fset_destroy(local_data.flows);
fqueue_destroy(local_data.fq);
- pthread_rwlock_destroy(&local_data.lock);
+ fset_destroy(local_data.flows);
}
-static void * ipcp_local_packet_loop(void * o)
+static void * local_ipcp_packet_loop(void * o)
{
(void) o;
@@ -135,54 +139,45 @@ static void * ipcp_local_packet_loop(void * o)
return (void *) 0;
}
-static int ipcp_local_bootstrap(const struct ipcp_config * conf)
+static int local_ipcp_bootstrap(const struct ipcp_config * conf)
{
assert(conf);
assert(conf->type == THIS_TYPE);
- ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name");
- return -ENOMEM;
- }
-
- ipcp_set_state(IPCP_OPERATIONAL);
+ ipcpi.dir_hash_algo = (enum hash_algo) conf->layer_info.dir_hash_algo;
+ strcpy(ipcpi.layer_name,conf->layer_info.name);
if (pthread_create(&local_data.packet_loop, NULL,
- ipcp_local_packet_loop, NULL)) {
+ local_ipcp_packet_loop, NULL)) {
+ log_err("Failed to create pthread: %s", strerror(errno));
ipcp_set_state(IPCP_INIT);
return -1;
}
- log_info("Bootstrapped local IPCP with pid %d.", getpid());
-
return 0;
}
-static int ipcp_local_reg(const uint8_t * hash)
+static int local_ipcp_reg(const uint8_t * hash)
{
if (shim_data_reg_add_entry(local_data.shim_data, hash)) {
- log_dbg("Failed to add " HASH_FMT " to local registry.",
- HASH_VAL(hash));
+ log_err("Failed to add " HASH_FMT32 " to local registry.",
+ HASH_VAL32(hash));
return -1;
}
- log_info("Registered " HASH_FMT ".", HASH_VAL(hash));
-
return 0;
}
-static int ipcp_local_unreg(const uint8_t * hash)
+static int local_ipcp_unreg(const uint8_t * hash)
{
shim_data_reg_del_entry(local_data.shim_data, hash);
- log_info("Unregistered " HASH_FMT ".", HASH_VAL(hash));
+ log_info("Unregistered " HASH_FMT32 ".", HASH_VAL32(hash));
return 0;
}
-static int ipcp_local_query(const uint8_t * hash)
+static int local_ipcp_query(const uint8_t * hash)
{
int ret;
@@ -191,41 +186,19 @@ static int ipcp_local_query(const uint8_t * hash)
return ret;
}
-static int ipcp_local_flow_alloc(int fd,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t len)
+static int local_ipcp_flow_alloc(int fd,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
- struct timespec ts = {0, ALLOC_TIMEOUT * MILLION};
- struct timespec abstime;
- int out_fd = -1;
+ int out_fd = -1;
- log_dbg("Allocating flow to " HASH_FMT " on fd %d.", HASH_VAL(dst), fd);
+ log_dbg("Allocating flow to " HASH_FMT32 " on fd %d.",
+ HASH_VAL32(dst), fd);
assert(dst);
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != -1 && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_dbg("Won't allocate over non-operational IPCP.");
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- return -1;
- }
-
- assert(ipcpi.alloc_id == -1);
-
- out_fd = ipcp_flow_req_arr(dst, ipcp_dir_hash_len(), qs, data, len);
+ out_fd = ipcp_wait_flow_req_arr(dst, qs, IPCP_LOCAL_MPL, data);
if (out_fd < 0) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
log_dbg("Flow allocation failed: %d", out_fd);
return -1;
}
@@ -237,11 +210,6 @@ static int ipcp_local_flow_alloc(int fd,
pthread_rwlock_unlock(&local_data.lock);
- ipcpi.alloc_id = out_fd;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
fset_add(local_data.flows, fd);
log_info("Pending local allocation request on fd %d.", fd);
@@ -249,39 +217,21 @@ static int ipcp_local_flow_alloc(int fd,
return 0;
}
-static int ipcp_local_flow_alloc_resp(int fd,
- int response,
- const void * data,
- size_t len)
+static int local_ipcp_flow_alloc_resp(int fd,
+ int response,
+ const buffer_t * data)
{
- struct timespec ts = {0, ALLOC_TIMEOUT * MILLION};
- struct timespec abstime;
- int out_fd = -1;
+ struct timespec wait = TIMESPEC_INIT_MS(1);
+ time_t mpl = IPCP_LOCAL_MPL;
+ int out_fd;
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
+ if (ipcp_wait_flow_resp(fd) < 0) {
+ log_err("Failed waiting for IRMd response.");
return -1;
}
- ipcpi.alloc_id = -1;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
- pthread_rwlock_wrlock(&local_data.lock);
-
- if (response) {
+ if (response < 0) {
+ pthread_rwlock_wrlock(&local_data.lock);
if (local_data.in_out[fd] != -1)
local_data.in_out[local_data.in_out[fd]] = fd;
local_data.in_out[fd] = -1;
@@ -289,25 +239,38 @@ static int ipcp_local_flow_alloc_resp(int fd,
return 0;
}
+ pthread_rwlock_rdlock(&local_data.lock);
+
out_fd = local_data.in_out[fd];
if (out_fd == -1) {
pthread_rwlock_unlock(&local_data.lock);
- return -1;
+ log_dbg("Potential race detected");
+ nanosleep(&wait, NULL);
+ pthread_rwlock_rdlock(&local_data.lock);
+ out_fd = local_data.in_out[fd];
}
pthread_rwlock_unlock(&local_data.lock);
+ if (out_fd == -1) {
+ log_err("Invalid out_fd.");
+ return -1;
+ }
+
fset_add(local_data.flows, fd);
- if (ipcp_flow_alloc_reply(out_fd, response, data, len) < 0)
+ if (ipcp_flow_alloc_reply(out_fd, response, mpl, data) < 0) {
+ log_err("Failed to reply to allocation");
+ fset_del(local_data.flows, fd);
return -1;
+ }
log_info("Flow allocation completed, fds (%d, %d).", out_fd, fd);
return 0;
}
-static int ipcp_local_flow_dealloc(int fd)
+static int local_ipcp_flow_dealloc(int fd)
{
assert(!(fd < 0));
@@ -321,7 +284,7 @@ static int ipcp_local_flow_dealloc(int fd)
pthread_rwlock_unlock(&local_data.lock);
- flow_dealloc(fd);
+ ipcp_flow_dealloc(fd);
log_info("Flow with fd %d deallocated.", fd);
@@ -329,60 +292,54 @@ static int ipcp_local_flow_dealloc(int fd)
}
static struct ipcp_ops local_ops = {
- .ipcp_bootstrap = ipcp_local_bootstrap,
+ .ipcp_bootstrap = local_ipcp_bootstrap,
.ipcp_enroll = NULL,
.ipcp_connect = NULL,
.ipcp_disconnect = NULL,
- .ipcp_reg = ipcp_local_reg,
- .ipcp_unreg = ipcp_local_unreg,
- .ipcp_query = ipcp_local_query,
- .ipcp_flow_alloc = ipcp_local_flow_alloc,
+ .ipcp_reg = local_ipcp_reg,
+ .ipcp_unreg = local_ipcp_unreg,
+ .ipcp_query = local_ipcp_query,
+ .ipcp_flow_alloc = local_ipcp_flow_alloc,
.ipcp_flow_join = NULL,
- .ipcp_flow_alloc_resp = ipcp_local_flow_alloc_resp,
- .ipcp_flow_dealloc = ipcp_local_flow_dealloc
+ .ipcp_flow_alloc_resp = local_ipcp_flow_alloc_resp,
+ .ipcp_flow_dealloc = local_ipcp_flow_dealloc
};
int main(int argc,
char * argv[])
{
- if (ipcp_init(argc, argv, &local_ops, THIS_TYPE) < 0)
- goto fail_init;
-
if (local_data_init() < 0) {
log_err("Failed to init local data.");
goto fail_data_init;
}
- if (ipcp_boot() < 0) {
- log_err("Failed to boot IPCP.");
- goto fail_boot;
- }
+ if (ipcp_init(argc, argv, &local_ops, THIS_TYPE) < 0)
+ goto fail_init;
- if (ipcp_create_r(0)) {
- log_err("Failed to notify IRMd we are initialized.");
- goto fail_create_r;
+ if (ipcp_start() < 0) {
+ log_err("Failed to start IPCP.");
+ goto fail_start;
}
- ipcp_shutdown();
+ ipcp_sigwait();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
pthread_cancel(local_data.packet_loop);
pthread_join(local_data.packet_loop, NULL);
}
- local_data_fini();
+ ipcp_stop();
ipcp_fini();
- exit(EXIT_SUCCESS);
- fail_create_r:
- ipcp_set_state(IPCP_NULL);
- ipcp_shutdown();
- fail_boot:
local_data_fini();
- fail_data_init:
+
+ exit(EXIT_SUCCESS);
+
+ fail_start:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
+ local_data_fini();
+ fail_data_init:
exit(EXIT_FAILURE);
}
diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c
index ade157ce..1fac63ac 100644
--- a/src/ipcpd/shim-data.c
+++ b/src/ipcpd/shim-data.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC process utilities
*
@@ -30,18 +30,18 @@
#define OUROBOROS_PREFIX "shim-data"
-#include <ouroboros/endian.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/list.h>
-#include <ouroboros/time_utils.h>
#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 <string.h>
-#include <stdlib.h>
#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
struct reg_entry {
struct list_head list;
@@ -139,9 +139,11 @@ static void dir_entry_destroy(struct dir_entry * entry)
free(entry);
}
-struct shim_data * shim_data_create()
+struct shim_data * shim_data_create(void)
{
- struct shim_data * sd = malloc(sizeof(*sd));
+ struct shim_data * sd;
+
+ sd = malloc(sizeof(*sd));
if (sd == NULL)
return NULL;
@@ -151,11 +153,23 @@ struct shim_data * shim_data_create()
list_head_init(&sd->dir_queries);
/* init the locks */
- pthread_rwlock_init(&sd->reg_lock, NULL);
- pthread_rwlock_init(&sd->dir_lock, NULL);
- pthread_mutex_init(&sd->dir_queries_lock, NULL);
+ 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)
@@ -283,8 +297,8 @@ int shim_data_reg_add_entry(struct shim_data * data,
if (find_reg_entry_by_hash(data, hash)) {
pthread_rwlock_unlock(&data->reg_lock);
- log_dbg(HASH_FMT " was already in the directory.",
- HASH_VAL(hash));
+ log_dbg(HASH_FMT32 " was already in the directory.",
+ HASH_VAL32(hash));
return 0;
}
@@ -432,9 +446,9 @@ uint64_t shim_data_dir_get_addr(struct shim_data * data,
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 0; /* undefined behaviour, 0 may be a valid address */
}
diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h
index 12a4b02e..372b4ea7 100644
--- a/src/ipcpd/shim-data.h
+++ b/src/ipcpd/shim-data.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Utitilies for building IPC processes
*
diff --git a/src/ipcpd/udp/CMakeLists.txt b/src/ipcpd/udp/CMakeLists.txt
index f1a29ef6..8ae5518e 100644
--- a/src/ipcpd/udp/CMakeLists.txt
+++ b/src/ipcpd/udp/CMakeLists.txt
@@ -58,6 +58,8 @@ set(IPCP_UDP_RD_THR 3 CACHE STRING
"Number of reader threads in UDP IPCP")
set(IPCP_UDP_WR_THR 3 CACHE STRING
"Number of writer threads in UDP IPCP")
+set(IPCP_UDP_MPL 60 CACHE STRING
+ "Default maximum packet lifetime for the UDP IPCP, in seconds")
include(AddCompileFlags)
if (CMAKE_BUILD_TYPE MATCHES "Debug*")
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c
index 6a3fb24a..2e8d84ce 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* IPC process over UDP
*
@@ -31,6 +31,7 @@
#define OUROBOROS_PREFIX "ipcpd/udp"
#include <ouroboros/bitmap.h>
+#include <ouroboros/endian.h>
#include <ouroboros/hash.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
@@ -65,7 +66,6 @@
#define IPCP_UDP_BUF_SIZE 8980
#define IPCP_UDP_MSG_SIZE 8980
#define DNS_TTL 86400
-#define FD_UPDATE_TIMEOUT 100 /* microseconds */
#define SADDR ((struct sockaddr *) &udp_data.s_saddr)
#define SADDR_SIZE (sizeof(udp_data.s_saddr))
@@ -98,7 +98,9 @@ struct mgmt_msg {
uint32_t loss;
uint32_t ber;
uint32_t max_gap;
+ uint32_t timeout;
uint16_t cypher_s;
+
} __attribute__((packed));
struct mgmt_frame {
@@ -138,12 +140,18 @@ struct {
static int udp_data_init(void)
{
- int i;
+ int i;
+ pthread_condattr_t cattr;
if (pthread_rwlock_init(&udp_data.flows_lock, NULL))
goto fail_rwlock_init;
- if (pthread_cond_init(&udp_data.mgmt_cond, NULL))
+ if (pthread_condattr_init(&cattr))
+ goto fail_condattr;
+#ifndef __APPLE__
+ pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
+#endif
+ if (pthread_cond_init(&udp_data.mgmt_cond, &cattr))
goto fail_mgmt_cond;
if (pthread_mutex_init(&udp_data.mgmt_lock, NULL))
@@ -160,9 +168,12 @@ static int udp_data_init(void)
if (udp_data.shim_data == NULL)
goto fail_data;
+ pthread_condattr_destroy(&cattr);
+
list_head_init(&udp_data.mgmt_frames);
return 0;
+
fail_data:
fset_destroy(udp_data.np1_flows);
fail_fset:
@@ -170,6 +181,8 @@ static int udp_data_init(void)
fail_mgmt_lock:
pthread_cond_destroy(&udp_data.mgmt_cond);
fail_mgmt_cond:
+ pthread_condattr_destroy(&cattr);
+ fail_condattr:
pthread_rwlock_destroy(&udp_data.flows_lock);
fail_rwlock_init:
return -1;
@@ -186,22 +199,21 @@ static void udp_data_fini(void)
pthread_mutex_destroy(&udp_data.mgmt_lock);
}
-static int ipcp_udp_port_alloc(const struct sockaddr_in * r_saddr,
+static int udp_ipcp_port_alloc(const struct sockaddr_in * r_saddr,
uint32_t s_eid,
const uint8_t * dst,
qosspec_t qs,
- const void * data,
- size_t dlen)
+ const buffer_t * data)
{
uint8_t * buf;
struct mgmt_msg * msg;
size_t len;
- assert(dlen > 0 ? data != NULL : data == NULL);
+ assert(data->len > 0 ? data->data != NULL : data->data == NULL);
len = sizeof(*msg) + ipcp_dir_hash_len();
- buf = malloc(len + dlen);
+ buf = malloc(len + data->len);
if (buf == NULL)
return -1;
@@ -217,11 +229,13 @@ static int ipcp_udp_port_alloc(const struct sockaddr_in * r_saddr,
msg->in_order = qs.in_order;
msg->max_gap = hton32(qs.max_gap);
msg->cypher_s = hton16(qs.cypher_s);
+ msg->timeout = hton32(qs.timeout);
memcpy(msg + 1, dst, ipcp_dir_hash_len());
- memcpy(buf + len, data, dlen);
+ if (data->len > 0)
+ memcpy(buf + len, data->data, data->len);
- if (sendto(udp_data.s_fd, msg, len + dlen,
+ if (sendto(udp_data.s_fd, msg, len + data->len,
SENDTO_FLAGS,
(const struct sockaddr *) r_saddr, sizeof(*r_saddr)) < 0) {
free(buf);
@@ -233,16 +247,15 @@ static int ipcp_udp_port_alloc(const struct sockaddr_in * r_saddr,
return 0;
}
-static int ipcp_udp_port_alloc_resp(const struct sockaddr_in * r_saddr,
+static int udp_ipcp_port_alloc_resp(const struct sockaddr_in * r_saddr,
uint32_t s_eid,
uint32_t d_eid,
int8_t response,
- const void * data,
- size_t len)
+ const buffer_t * data)
{
struct mgmt_msg * msg;
- msg = malloc(sizeof(*msg) + len);
+ msg = malloc(sizeof(*msg) + data->len);
if (msg == NULL)
return -1;
@@ -252,9 +265,10 @@ static int ipcp_udp_port_alloc_resp(const struct sockaddr_in * r_saddr,
msg->d_eid = hton32(d_eid);
msg->response = response;
- memcpy(msg + 1, data, len);
+ if (data->len > 0)
+ memcpy(msg + 1, data->data, data->len);
- if (sendto(udp_data.s_fd, msg, sizeof(*msg) + len,
+ if (sendto(udp_data.s_fd, msg, sizeof(*msg) + data->len,
SENDTO_FLAGS,
(const struct sockaddr *) r_saddr, sizeof(*r_saddr)) < 0 ) {
free(msg);
@@ -266,37 +280,16 @@ static int ipcp_udp_port_alloc_resp(const struct sockaddr_in * r_saddr,
return 0;
}
-static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
+static int udp_ipcp_port_req(struct sockaddr_in * c_saddr,
int d_eid,
const uint8_t * dst,
qosspec_t qs,
- const void * data,
- size_t len)
+ const buffer_t * data)
{
- struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
- struct timespec abstime;
- int fd;
-
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != -1 && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond, &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_dbg("Won't allocate over non-operational IPCP.");
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- return -1;
- }
+ int fd;
- /* reply to IRM */
- fd = ipcp_flow_req_arr(dst, ipcp_dir_hash_len(), qs, data, len);
+ fd = ipcp_wait_flow_req_arr(dst, qs, IPCP_UDP_MPL, data);
if (fd < 0) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
log_err("Could not get new flow from IRMd.");
return -1;
}
@@ -308,30 +301,26 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr,
pthread_rwlock_unlock(&udp_data.flows_lock);
- ipcpi.alloc_id = fd;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
log_dbg("Pending allocation request, fd %d, remote eid %d.",
fd, d_eid);
return 0;
}
-static int ipcp_udp_port_alloc_reply(const struct sockaddr_in * saddr,
+static int udp_ipcp_port_alloc_reply(const struct sockaddr_in * saddr,
uint32_t s_eid,
uint32_t d_eid,
int8_t response,
- const void * data,
- size_t len)
+ const buffer_t * data)
{
+ time_t mpl = IPCP_UDP_MPL;
+
pthread_rwlock_wrlock(&udp_data.flows_lock);
if (memcmp(&udp_data.fd_to_uf[s_eid].r_saddr, saddr, sizeof(*saddr))) {
pthread_rwlock_unlock(&udp_data.flows_lock);
- log_warn("Flow allocation reply for %u from wrong source.",
- s_eid);
+ log_err("Flow allocation reply for %u from wrong source.",
+ s_eid);
return -1;
}
@@ -340,8 +329,8 @@ static int ipcp_udp_port_alloc_reply(const struct sockaddr_in * saddr,
pthread_rwlock_unlock(&udp_data.flows_lock);
- if (ipcp_flow_alloc_reply(s_eid, response, data, len) < 0) {
- log_dbg("Failed to reply to flow allocation.");
+ if (ipcp_flow_alloc_reply(s_eid, response, mpl, data) < 0) {
+ log_err("Failed to reply to flow allocation.");
return -1;
}
@@ -351,13 +340,14 @@ static int ipcp_udp_port_alloc_reply(const struct sockaddr_in * saddr,
return 0;
}
-static int ipcp_udp_mgmt_frame(const uint8_t * buf,
+static int udp_ipcp_mgmt_frame(const uint8_t * buf,
size_t len,
struct sockaddr_in c_saddr)
{
struct mgmt_msg * msg;
size_t msg_len;
qosspec_t qs;
+ buffer_t data;
msg = (struct mgmt_msg *) buf;
@@ -367,6 +357,10 @@ static int ipcp_udp_mgmt_frame(const uint8_t * buf,
assert(len >= msg_len);
+ data.len = len - msg_len;
+ data.data = (uint8_t *) buf + msg_len;
+
+
qs.delay = ntoh32(msg->delay);
qs.bandwidth = ntoh64(msg->bandwidth);
qs.availability = msg->availability;
@@ -375,27 +369,29 @@ static int ipcp_udp_mgmt_frame(const uint8_t * buf,
qs.in_order = msg->in_order;
qs.max_gap = ntoh32(msg->max_gap);
qs.cypher_s = ntoh16(msg->cypher_s);
+ qs.timeout = ntoh32(msg->timeout);
- return ipcp_udp_port_req(&c_saddr, ntoh32(msg->s_eid),
+ return udp_ipcp_port_req(&c_saddr, ntoh32(msg->s_eid),
(uint8_t *) (msg + 1), qs,
- buf + msg_len,
- len - msg_len);
+ &data);
case FLOW_REPLY:
assert(len >= sizeof(*msg));
- return ipcp_udp_port_alloc_reply(&c_saddr,
+ data.len = len - sizeof(*msg);
+ data.data = (uint8_t *) buf + sizeof(*msg);
+
+ return udp_ipcp_port_alloc_reply(&c_saddr,
ntoh32(msg->s_eid),
ntoh32(msg->d_eid),
msg->response,
- buf + sizeof(*msg),
- len - sizeof(*msg));
+ &data);
default:
log_err("Unknown message received %d.", msg->code);
return -1;
}
}
-static void * ipcp_udp_mgmt_handler(void * o)
+static void * udp_ipcp_mgmt_handler(void * o)
{
(void) o;
@@ -417,7 +413,7 @@ static void * ipcp_udp_mgmt_handler(void * o)
pthread_mutex_unlock(&udp_data.mgmt_lock);
- ipcp_udp_mgmt_frame(frame->buf, frame->len, frame->r_saddr);
+ udp_ipcp_mgmt_frame(frame->buf, frame->len, frame->r_saddr);
free(frame);
}
@@ -427,7 +423,7 @@ static void * ipcp_udp_mgmt_handler(void * o)
return (void *) 0;
}
-static void * ipcp_udp_packet_reader(void * o)
+static void * udp_ipcp_packet_reader(void * o)
{
uint8_t buf[IPCP_UDP_MAX_PACKET_SIZE];
uint8_t * data;
@@ -437,13 +433,17 @@ static void * ipcp_udp_packet_reader(void * o)
(void) o;
+ ipcp_lock_to_core();
+
data = buf + sizeof(uint32_t);
eid_p = (uint32_t *) buf;
while (true) {
- struct mgmt_frame * frame;
- struct sockaddr_in r_saddr;
- socklen_t len;
+ struct mgmt_frame * frame;
+ struct sockaddr_in r_saddr;
+ socklen_t len;
+ struct shm_du_buff * sdb;
+ uint8_t * head;
len = sizeof(r_saddr);
@@ -484,10 +484,18 @@ static void * ipcp_udp_packet_reader(void * o)
continue;
}
- flow_write(eid, data, n - sizeof(eid));
+ n-= sizeof(eid);
+
+ if (ipcp_sdb_reserve(&sdb, n))
+ continue;
+
+ head = shm_du_buff_head(sdb);
+ memcpy(head, data, n);
+ if (np1_flow_write(eid, sdb) < 0)
+ ipcp_sdb_release(sdb);
}
- return 0;
+ return (void *) 0;
}
static void cleanup_fqueue(void * fq)
@@ -500,7 +508,7 @@ static void cleanup_sdb(void * sdb)
ipcp_sdb_release((struct shm_du_buff *) sdb);
}
-static void * ipcp_udp_packet_writer(void * o)
+static void * udp_ipcp_packet_writer(void * o)
{
fqueue_t * fq;
@@ -527,12 +535,12 @@ static void * ipcp_udp_packet_writer(void * o)
if (fqueue_type(fq) != FLOW_PKT)
continue;
- if (ipcp_flow_read(fd, &sdb)) {
+ if (np1_flow_read(fd, &sdb)) {
log_dbg("Bad read from fd %d.", fd);
continue;
}
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
if (len > IPCP_UDP_MAX_PACKET_SIZE) {
log_dbg("Packet length exceeds MTU.");
ipcp_sdb_release(sdb);
@@ -572,37 +580,36 @@ static void * ipcp_udp_packet_writer(void * o)
return (void *) 1;
}
-static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
+static const char * inet4_ntop(const void * addr,
+ char * buf)
+{
+ return inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
+}
+
+static int udp_ipcp_bootstrap(const struct ipcp_config * conf)
{
char ipstr[INET_ADDRSTRLEN];
char dnsstr[INET_ADDRSTRLEN];
- char portstr[128]; /* port is max 64535 = 5 chars */
int i = 1;
assert(conf);
assert(conf->type == THIS_TYPE);
- ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name");
- return -ENOMEM;
- }
+ ipcpi.dir_hash_algo = HASH_MD5;
+ strcpy(ipcpi.layer_name, conf->layer_info.name);
- if (inet_ntop(AF_INET, &conf->ip_addr, ipstr, INET_ADDRSTRLEN)
- == NULL) {
- log_err("Failed to convert IP address");
+ if (inet4_ntop(&conf->udp.ip_addr, ipstr) == NULL) {
+ log_err("Failed to convert IP address.");
return -1;
}
- if (conf->dns_addr != 0) {
- if (inet_ntop(AF_INET, &conf->dns_addr, dnsstr, INET_ADDRSTRLEN)
- == NULL) {
- log_err("Failed to convert DNS address");
+ if (conf->udp.dns_addr != 0) {
+ if (inet4_ntop(&conf->udp.dns_addr, dnsstr) == NULL) {
+ log_err("Failed to convert DNS address.");
return -1;
}
#ifndef HAVE_DDNS
- log_warn("DNS disabled at compile time, address ignored");
+ log_warn("DNS disabled at compile time, address ignored.");
#endif
} else {
strcpy(dnsstr, "not set");
@@ -617,46 +624,46 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
memset((char *) &udp_data.s_saddr, 0, sizeof(udp_data.s_saddr));
udp_data.s_saddr.sin_family = AF_INET;
- udp_data.s_saddr.sin_addr.s_addr = conf->ip_addr;
- udp_data.s_saddr.sin_port = htons(conf->port);
+ udp_data.s_saddr.sin_addr.s_addr = conf->udp.ip_addr;
+ udp_data.s_saddr.sin_port = htons(conf->udp.port);
if (bind(udp_data.s_fd, SADDR, SADDR_SIZE) < 0) {
- log_err("Couldn't bind to %s.", ipstr);
+ log_err("Couldn't bind to %s:%d. %s.",
+ ipstr, conf->udp.port, strerror(errno));
goto fail_bind;
}
- udp_data.dns_addr = conf->dns_addr;
-
- ipcp_set_state(IPCP_OPERATIONAL);
+ udp_data.dns_addr = conf->udp.dns_addr;
if (pthread_create(&udp_data.mgmt_handler, NULL,
- ipcp_udp_mgmt_handler, NULL)) {
- ipcp_set_state(IPCP_INIT);
+ udp_ipcp_mgmt_handler, NULL)) {
+ log_err("Failed to create management thread.");
goto fail_bind;
}
for (i = 0; i < IPCP_UDP_RD_THR; ++i) {
if (pthread_create(&udp_data.packet_reader[i], NULL,
- ipcp_udp_packet_reader, NULL)) {
- ipcp_set_state(IPCP_INIT);
+ udp_ipcp_packet_reader, NULL)) {
+ log_err("Failed to create reader thread.");
goto fail_packet_reader;
}
}
for (i = 0; i < IPCP_UDP_WR_THR; ++i) {
if (pthread_create(&udp_data.packet_writer[i], NULL,
- ipcp_udp_packet_writer, NULL)) {
- ipcp_set_state(IPCP_INIT);
+ udp_ipcp_packet_writer, NULL)) {
+ log_err("Failed to create writer thread.");
goto fail_packet_writer;
}
}
- sprintf(portstr, "%d", conf->port);
-
log_dbg("Bootstrapped IPCP over UDP with pid %d.", getpid());
log_dbg("Bound to IP address %s.", ipstr);
- log_dbg("Using port %u.", conf->port);
- log_dbg("DNS server address is %s.", dnsstr);
+ log_dbg("Using port %u.", conf->udp.port);
+ if (conf->udp.dns_addr != 0)
+ log_dbg("DNS server address is %s.", dnsstr);
+ else
+ log_dbg("DNS server not in use.");
return 0;
@@ -684,20 +691,22 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
/* NOTE: Disgusted with this crap */
static int ddns_send(char * cmd)
{
- pid_t pid = -1;
+ pid_t pid;
int wstatus;
int pipe_fd[2];
char * argv[] = {NSUPDATE_EXEC, 0};
char * envp[] = {0};
if (pipe(pipe_fd)) {
- log_err("Failed to create pipe.");
+ log_err("Failed to create pipe: %s.", strerror(errno));
return -1;
}
pid = fork();
if (pid == -1) {
- log_err("Failed to fork.");
+ log_err("Failed to fork: %s.", strerror(errno));
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
return -1;
}
@@ -705,12 +714,15 @@ static int ddns_send(char * cmd)
close(pipe_fd[1]);
dup2(pipe_fd[0], 0);
execve(argv[0], &argv[0], envp);
+ log_err("Failed to execute: %s", strerror(errno));
+ exit(1);
}
close(pipe_fd[0]);
if (write(pipe_fd[1], cmd, strlen(cmd)) == -1) {
- log_err("Failed to communicate with nsupdate.");
+ log_err("Failed to communicate with nsupdate: %s.",
+ strerror(errno));
close(pipe_fd[1]);
return -1;
}
@@ -740,18 +752,20 @@ static uint32_t ddns_resolve(char * name,
char * addr_str = "Address:";
uint32_t ip_addr = 0;
- if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN) == NULL)
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL)
return 0;
if (pipe(pipe_fd)) {
- log_err("Failed to create pipe.");
+ log_err("Failed to create pipe: %s.", strerror(errno));
return 0;
}
pid = fork();
if (pid == -1) {
- log_err("Failed to fork.");
- return 0;
+ log_err("Failed to fork: %s.", strerror(errno));
+ close(pipe_fd[0]);
+ close(pipe_fd[1]);
+ return -1;
}
if (pid == 0) {
@@ -761,11 +775,13 @@ static uint32_t ddns_resolve(char * name,
close(pipe_fd[0]);
dup2(pipe_fd[1], 1);
execve(argv[0], &argv[0], envp);
+ log_err("Failed to execute: %s", strerror(errno));
+ exit(1);
}
close(pipe_fd[1]);
- count = read(pipe_fd[0], buf, IPCP_UDP_BUF_SIZE);
+ count = read(pipe_fd[0], buf, IPCP_UDP_BUF_SIZE - 1);
if (count <= 0) {
log_err("Failed to communicate with nslookup.");
close(pipe_fd[0]);
@@ -776,7 +792,7 @@ static uint32_t ddns_resolve(char * name,
waitpid(pid, &wstatus, 0);
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) == 0 &&
- count != IPCP_UDP_BUF_SIZE)
+ count != IPCP_UDP_BUF_SIZE - 1)
log_dbg("Succesfully communicated with nslookup.");
else
log_err("Failed to resolve DNS address.");
@@ -802,7 +818,7 @@ static uint32_t ddns_resolve(char * name,
}
#endif
-static int ipcp_udp_reg(const uint8_t * hash)
+static int udp_ipcp_reg(const uint8_t * hash)
{
#ifdef HAVE_DDNS
char ipstr[INET_ADDRSTRLEN];
@@ -814,16 +830,18 @@ static int ipcp_udp_reg(const uint8_t * hash)
char * hashstr;
hashstr = malloc(ipcp_dir_hash_strlen() + 1);
- if (hashstr == NULL)
+ if (hashstr == NULL) {
+ log_err("Failed to malloc hashstr.");
return -1;
+ }
assert(hash);
ipcp_hash_str(hashstr, hash);
if (shim_data_reg_add_entry(udp_data.shim_data, hash)) {
- log_err("Failed to add " HASH_FMT " to local registry.",
- HASH_VAL(hash));
+ log_err("Failed to add " HASH_FMT32 " to local registry.",
+ HASH_VAL32(hash));
free(hashstr);
return -1;
}
@@ -836,14 +854,14 @@ static int ipcp_udp_reg(const uint8_t * hash)
if (dns_addr != 0) {
ip_addr = udp_data.s_saddr.sin_addr.s_addr;
- if (inet_ntop(AF_INET, &ip_addr,
- ipstr, INET_ADDRSTRLEN) == NULL) {
+ if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ log_err("Failed to convert IP address to string.");
free(hashstr);
return -1;
}
- if (inet_ntop(AF_INET, &dns_addr,
- dnsstr, INET_ADDRSTRLEN) == NULL) {
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
+ log_err("Failed to convert DNS address to string.");
free(hashstr);
return -1;
}
@@ -852,20 +870,19 @@ static int ipcp_udp_reg(const uint8_t * hash)
dnsstr, hashstr, DNS_TTL, ipstr);
if (ddns_send(cmd)) {
+ log_err("Failed to send DDNS message.");
shim_data_reg_del_entry(udp_data.shim_data, hash);
free(hashstr);
return -1;
}
}
#endif
- log_dbg("Registered " HASH_FMT ".", HASH_VAL(hash));
-
free(hashstr);
return 0;
}
-static int ipcp_udp_unreg(const uint8_t * hash)
+static int udp_ipcp_unreg(const uint8_t * hash)
{
#ifdef HAVE_DDNS
char dnsstr[INET_ADDRSTRLEN];
@@ -878,8 +895,10 @@ static int ipcp_udp_unreg(const uint8_t * hash)
assert(hash);
hashstr = malloc(ipcp_dir_hash_strlen() + 1);
- if (hashstr == NULL)
+ if (hashstr == NULL) {
+ log_err("Failed to malloc hashstr.");
return -1;
+ }
ipcp_hash_str(hashstr, hash);
@@ -889,8 +908,8 @@ static int ipcp_udp_unreg(const uint8_t * hash)
dns_addr = udp_data.dns_addr;
if (dns_addr != 0) {
- if (inet_ntop(AF_INET, &dns_addr, dnsstr, INET_ADDRSTRLEN)
- == NULL) {
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
+ log_err("Failed to convert DNS address to string.");
free(hashstr);
return -1;
}
@@ -903,14 +922,12 @@ static int ipcp_udp_unreg(const uint8_t * hash)
shim_data_reg_del_entry(udp_data.shim_data, hash);
- log_dbg("Unregistered " HASH_FMT ".", HASH_VAL(hash));
-
free(hashstr);
return 0;
}
-static int ipcp_udp_query(const uint8_t * hash)
+static int udp_ipcp_query(const uint8_t * hash)
{
uint32_t ip_addr = 0;
char * hashstr;
@@ -921,8 +938,10 @@ static int ipcp_udp_query(const uint8_t * hash)
assert(hash);
hashstr = malloc(ipcp_dir_hash_strlen() + 1);
- if (hashstr == NULL)
+ if (hashstr == NULL) {
+ log_err("Failed to malloc hashstr.");
return -ENOMEM;
+ }
ipcp_hash_str(hashstr, hash);
@@ -937,7 +956,7 @@ static int ipcp_udp_query(const uint8_t * hash)
if (dns_addr != 0) {
ip_addr = ddns_resolve(hashstr, dns_addr);
if (ip_addr == 0) {
- log_dbg("Could not resolve %s.", hashstr);
+ log_err("Could not resolve %s.", hashstr);
free(hashstr);
return -1;
}
@@ -945,7 +964,7 @@ static int ipcp_udp_query(const uint8_t * hash)
#endif
h = gethostbyname(hashstr);
if (h == NULL) {
- log_dbg("Could not resolve %s.", hashstr);
+ log_err("Could not resolve %s.", hashstr);
free(hashstr);
return -1;
}
@@ -966,38 +985,40 @@ static int ipcp_udp_query(const uint8_t * hash)
return 0;
}
-static int ipcp_udp_flow_alloc(int fd,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t len)
+static int udp_ipcp_flow_alloc(int fd,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
struct sockaddr_in r_saddr; /* Server address */
uint32_t ip_addr = 0;
char ipstr[INET_ADDRSTRLEN];
- log_dbg("Allocating flow to " HASH_FMT ".", HASH_VAL(dst));
-
(void) qs;
assert(dst);
if (!shim_data_dir_has(udp_data.shim_data, dst)) {
- log_dbg("Could not resolve destination.");
+ log_err("Could not resolve destination.");
return -1;
}
ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);
- inet_ntop(AF_INET, &ip_addr, ipstr, INET_ADDRSTRLEN);
- log_dbg("Destination UDP ipcp resolved at %s.", ipstr);
+ if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ log_err("Could not convert IP address.");
+ return -1;
+ }
+
+ log_dbg("Destination " HASH_FMT32 " resolved at IP %s.",
+ HASH_VAL32(dst), ipstr);
memset((char *) &r_saddr, 0, sizeof(r_saddr));
r_saddr.sin_family = AF_INET;
r_saddr.sin_addr.s_addr = ip_addr;
r_saddr.sin_port = udp_data.s_saddr.sin_port;
- if (ipcp_udp_port_alloc(&r_saddr, fd, dst, qs, data, len) < 0) {
+ if (udp_ipcp_port_alloc(&r_saddr, fd, dst, qs, data) < 0) {
log_err("Could not allocate port.");
return -1;
}
@@ -1011,45 +1032,21 @@ static int ipcp_udp_flow_alloc(int fd,
fset_add(udp_data.np1_flows, fd);
- log_dbg("Flow to %s pending on fd %d.", ipstr, fd);
-
return 0;
}
-static int ipcp_udp_flow_alloc_resp(int fd,
- int resp,
- const void * data,
- size_t len)
+static int udp_ipcp_flow_alloc_resp(int fd,
+ int resp,
+ const buffer_t * data)
{
- struct timespec ts = {0, FD_UPDATE_TIMEOUT * 1000};
- struct timespec abstime;
struct sockaddr_in saddr;
int d_eid;
- if (resp)
- return 0;
-
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
-
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
+ if (ipcp_wait_flow_resp(fd) < 0) {
+ log_err("Failed to wait for flow response.");
return -1;
}
- ipcpi.alloc_id = -1;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
pthread_rwlock_rdlock(&udp_data.flows_lock);
saddr = udp_data.fd_to_uf[fd].r_saddr;
@@ -1057,7 +1054,7 @@ static int ipcp_udp_flow_alloc_resp(int fd,
pthread_rwlock_unlock(&udp_data.flows_lock);
- if (ipcp_udp_port_alloc_resp(&saddr, d_eid, fd, resp, data, len) < 0) {
+ if (udp_ipcp_port_alloc_resp(&saddr, d_eid, fd, resp, data) < 0) {
fset_del(udp_data.np1_flows, fd);
log_err("Failed to respond to flow request.");
return -1;
@@ -1065,13 +1062,10 @@ static int ipcp_udp_flow_alloc_resp(int fd,
fset_add(udp_data.np1_flows, fd);
- log_dbg("Accepted flow, fd %d on eid %d.",
- fd, d_eid);
-
return 0;
}
-static int ipcp_udp_flow_dealloc(int fd)
+static int udp_ipcp_flow_dealloc(int fd)
{
ipcp_flow_fini(fd);
@@ -1084,25 +1078,23 @@ static int ipcp_udp_flow_dealloc(int fd)
pthread_rwlock_unlock(&udp_data.flows_lock);
- flow_dealloc(fd);
-
- log_dbg("Flow with fd %d deallocated.", fd);
+ ipcp_flow_dealloc(fd);
return 0;
}
static struct ipcp_ops udp_ops = {
- .ipcp_bootstrap = ipcp_udp_bootstrap,
+ .ipcp_bootstrap = udp_ipcp_bootstrap,
.ipcp_enroll = NULL,
.ipcp_connect = NULL,
.ipcp_disconnect = NULL,
- .ipcp_reg = ipcp_udp_reg,
- .ipcp_unreg = ipcp_udp_unreg,
- .ipcp_query = ipcp_udp_query,
- .ipcp_flow_alloc = ipcp_udp_flow_alloc,
+ .ipcp_reg = udp_ipcp_reg,
+ .ipcp_unreg = udp_ipcp_unreg,
+ .ipcp_query = udp_ipcp_query,
+ .ipcp_flow_alloc = udp_ipcp_flow_alloc,
.ipcp_flow_join = NULL,
- .ipcp_flow_alloc_resp = ipcp_udp_flow_alloc_resp,
- .ipcp_flow_dealloc = ipcp_udp_flow_dealloc
+ .ipcp_flow_alloc_resp = udp_ipcp_flow_alloc_resp,
+ .ipcp_flow_dealloc = udp_ipcp_flow_dealloc
};
int main(int argc,
@@ -1110,53 +1102,51 @@ int main(int argc,
{
int i;
- if (ipcp_init(argc, argv, &udp_ops, THIS_TYPE) < 0)
- goto fail_init;
if (udp_data_init() < 0) {
log_err("Failed to init udp data.");
goto fail_data_init;
}
- if (ipcp_boot() < 0) {
- log_err("Failed to boot IPCP.");
- goto fail_boot;
+ if (ipcp_init(argc, argv, &udp_ops, THIS_TYPE) < 0) {
+ log_err("Failed to initialize IPCP.");
+ goto fail_init;
}
- if (ipcp_create_r(0)) {
- log_err("Failed to notify IRMd we are initialized.");
- goto fail_create_r;
+ if (ipcp_start() < 0) {
+ log_err("Failed to start IPCP.");
+ goto fail_start;
}
- ipcp_shutdown();
+ ipcp_sigwait();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
- for (i = 0; i < IPCP_UDP_RD_THR; ++i)
- pthread_cancel(udp_data.packet_reader[i]);
for (i = 0; i < IPCP_UDP_WR_THR; ++i)
pthread_cancel(udp_data.packet_writer[i]);
+ for (i = 0; i < IPCP_UDP_RD_THR; ++i)
+ pthread_cancel(udp_data.packet_reader[i]);
pthread_cancel(udp_data.mgmt_handler);
- for (i = 0; i < IPCP_UDP_RD_THR; ++i)
- pthread_join(udp_data.packet_reader[i], NULL);
for (i = 0; i < IPCP_UDP_WR_THR; ++i)
pthread_join(udp_data.packet_writer[i], NULL);
+ for (i = 0; i < IPCP_UDP_RD_THR; ++i)
+ pthread_join(udp_data.packet_reader[i], NULL);
pthread_join(udp_data.mgmt_handler, NULL);
+ close(udp_data.s_fd);
}
- udp_data_fini();
+ ipcp_stop();
ipcp_fini();
- exit(EXIT_SUCCESS);
- fail_create_r:
- ipcp_set_state(IPCP_NULL);
- ipcp_shutdown();
- fail_boot:
udp_data_fini();
- fail_data_init:
+
+ exit(EXIT_SUCCESS);
+
+ fail_start:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
+ udp_data_fini();
+ fail_data_init:
exit(EXIT_FAILURE);
}
diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt
index 07f12540..ca742871 100644
--- a/src/ipcpd/unicast/CMakeLists.txt
+++ b/src/ipcpd/unicast/CMakeLists.txt
@@ -13,8 +13,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_BINARY_DIR}/include)
set(IPCP_UNICAST_TARGET ipcpd-unicast CACHE INTERNAL "")
+set(IPCP_UNICAST_MPL 60 CACHE STRING
+ "Default maximum packet lifetime for the unicast IPCP, in seconds")
-protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)
+protobuf_generate_c(DHT_PROTO_SRCS DHT_PROTO_HDRS dir/dht.proto)
math(EXPR PFT_EXPR "1 << 12")
set(PFT_SIZE ${PFT_EXPR} CACHE STRING
@@ -31,32 +33,31 @@ endif ()
set(SOURCE_FILES
# Add source files here
- addr_auth.c
+ addr-auth.c
ca.c
connmgr.c
- dht.c
dir.c
dt.c
- enroll.c
fa.c
main.c
pff.c
routing.c
psched.c
# Add policies last
- pol/pft.c
- pol/flat.c
- pol/link_state.c
- pol/graph.c
- pol/simple_pff.c
- pol/alternate_pff.c
- pol/multipath_pff.c
- pol/ca-mb-ecn.c
- pol/ca-nop.c
+ addr-auth/flat.c
+ ca/mb-ecn.c
+ ca/nop.c
+ dir/dht.c
+ pff/simple.c
+ pff/alternate.c
+ pff/multipath.c
+ pff/pft.c
+ routing/link-state.c
+ routing/graph.c
)
-add_executable(ipcpd-unicast ${SOURCE_FILES} ${IPCP_SOURCES}
- ${KAD_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS})
+add_executable(ipcpd-unicast ${SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES}
+ ${DHT_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS})
target_link_libraries(ipcpd-unicast LINK_PUBLIC ouroboros-dev)
include(AddCompileFlags)
@@ -66,8 +67,9 @@ endif ()
install(TARGETS ipcpd-unicast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
-add_subdirectory(pol/tests)
+add_subdirectory(pff/tests)
+add_subdirectory(routing/tests)
if (NOT GNU)
- add_subdirectory(tests)
+ add_subdirectory(dir/tests)
endif ()
diff --git a/src/ipcpd/unicast/addr_auth.c b/src/ipcpd/unicast/addr-auth.c
index e508d0cb..908a4aa1 100644
--- a/src/ipcpd/unicast/addr_auth.c
+++ b/src/ipcpd/unicast/addr-auth.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Address authority
*
@@ -24,13 +24,12 @@
#include <ouroboros/logs.h>
-#include "addr_auth.h"
-#include "pol-addr-auth-ops.h"
-#include "pol/flat.h"
+#include "addr-auth.h"
+#include "addr-auth/pol.h"
#include <stdlib.h>
-struct pol_addr_auth_ops * ops;
+struct addr_auth_ops * ops;
int addr_auth_init(enum pol_addr_auth type,
const void * info)
diff --git a/src/ipcpd/unicast/addr_auth.h b/src/ipcpd/unicast/addr-auth.h
index d26d3eb7..e119dff3 100644
--- a/src/ipcpd/unicast/addr_auth.h
+++ b/src/ipcpd/unicast/addr-auth.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Address authority
*
diff --git a/src/ipcpd/unicast/pol/flat.c b/src/ipcpd/unicast/addr-auth/flat.c
index f869f761..c4562935 100644
--- a/src/ipcpd/unicast/pol/flat.c
+++ b/src/ipcpd/unicast/addr-auth/flat.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for flat addresses in a distributed way
*
@@ -29,19 +29,11 @@
#define OUROBOROS_PREFIX "flat-addr-auth"
#include <ouroboros/logs.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/time_utils.h>
-#include <ouroboros/utils.h>
+#include <ouroboros/random.h>
#include "ipcp.h"
#include "flat.h"
-#include <time.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-#include <assert.h>
-
#define NAME_LEN 8
struct {
@@ -50,7 +42,7 @@ struct {
#define INVALID_ADDRESS 0
-struct pol_addr_auth_ops flat_ops = {
+struct addr_auth_ops flat_ops = {
.init = flat_init,
.fini = flat_fini,
.address = flat_address
@@ -75,13 +67,13 @@ int flat_fini(void)
uint64_t flat_address(void)
{
- struct timespec t;
- uint32_t addr;
-
- clock_gettime(CLOCK_REALTIME, &t);
- srand(t.tv_nsec);
-
- addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF;
+ uint32_t addr = INVALID_ADDRESS;
+#if defined (CONFIG_OUROBOROS_DEBUG) && defined (IPCP_DEBUG_LOCAL)
+ addr = getpid();
+#else
+ while (addr == INVALID_ADDRESS)
+ random_buffer(&addr,sizeof(addr));
+#endif
return addr;
}
diff --git a/src/ipcpd/unicast/pol/flat.h b/src/ipcpd/unicast/addr-auth/flat.h
index 21f7721a..d4b672c7 100644
--- a/src/ipcpd/unicast/pol/flat.h
+++ b/src/ipcpd/unicast/addr-auth/flat.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for flat addresses in a distributed way
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_FLAT_H
#define OUROBOROS_IPCPD_UNICAST_FLAT_H
-#include "pol-addr-auth-ops.h"
+#include "ops.h"
int flat_init(const void * info);
@@ -31,6 +31,6 @@ int flat_fini(void);
uint64_t flat_address(void);
-extern struct pol_addr_auth_ops flat_ops;
+extern struct addr_auth_ops flat_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_FLAT_H */
diff --git a/src/ipcpd/unicast/pol-addr-auth-ops.h b/src/ipcpd/unicast/addr-auth/ops.h
index 395a5675..06b24cec 100644
--- a/src/ipcpd/unicast/pol-addr-auth-ops.h
+++ b/src/ipcpd/unicast/addr-auth/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Address authority policy ops
*
@@ -20,10 +20,10 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H
-#define OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H
+#ifndef OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H
+#define OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H
-struct pol_addr_auth_ops {
+struct addr_auth_ops {
int (* init)(const void * info);
int (* fini)(void);
@@ -31,4 +31,4 @@ struct pol_addr_auth_ops {
uint64_t (* address)(void);
};
-#endif /* OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H */
+#endif /* OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H */
diff --git a/src/ipcpd/broadcast/enroll.c b/src/ipcpd/unicast/addr-auth/pol.h
index 143f16d5..844308c6 100644
--- a/src/ipcpd/broadcast/enroll.c
+++ b/src/ipcpd/unicast/addr-auth/pol.h
@@ -1,7 +1,7 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Enrollment Task
+ * Address Authority policies
*
* Dimitri Staessens <dimitri@ouroboros.rocks>
* Sander Vrijders <sander@ouroboros.rocks>
@@ -19,6 +19,5 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#define BUILD_IPCP_BROADCAST
-#include "common/enroll.c"
+#include "flat.h"
diff --git a/src/ipcpd/unicast/ca.c b/src/ipcpd/unicast/ca.c
index ddeb2849..287eaf41 100644
--- a/src/ipcpd/unicast/ca.c
+++ b/src/ipcpd/unicast/ca.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Congestion Avoidance
*
@@ -25,12 +25,10 @@
#include <ouroboros/logs.h>
#include "ca.h"
-#include "pol-ca-ops.h"
-#include "pol/ca-mb-ecn.h"
-#include "pol/ca-nop.h"
+#include "ca/pol.h"
struct {
- struct pol_ca_ops * ops;
+ struct ca_ops * ops;
} ca;
int ca_init(enum pol_cong_avoid pol)
diff --git a/src/ipcpd/unicast/ca.h b/src/ipcpd/unicast/ca.h
index 8b221790..ea803e17 100644
--- a/src/ipcpd/unicast/ca.h
+++ b/src/ipcpd/unicast/ca.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Congestion avoidance
*
diff --git a/src/ipcpd/unicast/pol/ca-mb-ecn.c b/src/ipcpd/unicast/ca/mb-ecn.c
index 7a88718f..d9a204b0 100644
--- a/src/ipcpd/unicast/pol/ca-mb-ecn.c
+++ b/src/ipcpd/unicast/ca/mb-ecn.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Multi-bit ECN Congestion Avoidance
*
@@ -29,9 +29,9 @@
#include "config.h"
#include <ouroboros/ipcp-dev.h>
-#include <ouroboros/time_utils.h>
+#include <ouroboros/time.h>
-#include "ca-mb-ecn.h"
+#include "mb-ecn.h"
#include <inttypes.h>
#include <stdlib.h>
@@ -65,7 +65,7 @@ struct mb_ecn_ctx {
size_t tx_slot;
};
-struct pol_ca_ops mb_ecn_ca_ops = {
+struct ca_ops mb_ecn_ca_ops = {
.ctx_create = mb_ecn_ctx_create,
.ctx_destroy = mb_ecn_ctx_destroy,
.ctx_update_snd = mb_ecn_ctx_update_snd,
@@ -187,7 +187,7 @@ ca_wnd_t mb_ecn_ctx_update_snd(void * _ctx,
void mb_ecn_wnd_wait(ca_wnd_t wnd)
{
if (wnd.wait > 0) {
- struct timespec s = {0, 0};
+ struct timespec s = TIMESPEC_INIT_S(0);
if (wnd.wait > BILLION) /* Don't care throttling < 1s */
s.tv_sec = 1;
else
diff --git a/src/ipcpd/unicast/pol/ca-mb-ecn.h b/src/ipcpd/unicast/ca/mb-ecn.h
index a90ae3e2..9a2c8b49 100644
--- a/src/ipcpd/unicast/pol/ca-mb-ecn.h
+++ b/src/ipcpd/unicast/ca/mb-ecn.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Multi-bit ECN Congestion Avoidance
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H
#define OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H
-#include "pol-ca-ops.h"
+#include "ops.h"
void * mb_ecn_ctx_create(void);
@@ -51,6 +51,6 @@ ssize_t mb_ecn_print_stats(void * ctx,
char * buf,
size_t len);
-extern struct pol_ca_ops mb_ecn_ca_ops;
+extern struct ca_ops mb_ecn_ca_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H */
diff --git a/src/ipcpd/unicast/pol/ca-nop.c b/src/ipcpd/unicast/ca/nop.c
index db908c5c..617fc15b 100644
--- a/src/ipcpd/unicast/pol/ca-nop.c
+++ b/src/ipcpd/unicast/ca/nop.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Dummy Congestion Avoidance
*
@@ -20,11 +20,11 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#include "ca-nop.h"
+#include "nop.h"
#include <string.h>
-struct pol_ca_ops nop_ca_ops = {
+struct ca_ops nop_ca_ops = {
.ctx_create = nop_ctx_create,
.ctx_destroy = nop_ctx_destroy,
.ctx_update_snd = nop_ctx_update_snd,
diff --git a/src/ipcpd/unicast/pol/ca-nop.h b/src/ipcpd/unicast/ca/nop.h
index 7b9d318f..248b198d 100644
--- a/src/ipcpd/unicast/pol/ca-nop.h
+++ b/src/ipcpd/unicast/ca/nop.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Dummy Congestion Avoidance
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_CA_NOP_H
#define OUROBOROS_IPCPD_UNICAST_CA_NOP_H
-#include "pol-ca-ops.h"
+#include "ops.h"
void * nop_ctx_create(void);
@@ -47,6 +47,6 @@ int nop_calc_ecn(int fd,
qoscube_t qc,
size_t len);
-extern struct pol_ca_ops nop_ca_ops;
+extern struct ca_ops nop_ca_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_CA_NOP_H */
diff --git a/src/ipcpd/unicast/pol-ca-ops.h b/src/ipcpd/unicast/ca/ops.h
index 88f6cf61..3a7b7248 100644
--- a/src/ipcpd/unicast/pol-ca-ops.h
+++ b/src/ipcpd/unicast/ca/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Congestion avoidance policy ops
*
@@ -20,12 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H
-#define OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H
+#ifndef OUROBOROS_IPCPD_UNICAST_CA_OPS_H
+#define OUROBOROS_IPCPD_UNICAST_CA_OPS_H
#include "ca.h"
-struct pol_ca_ops {
+struct ca_ops {
void * (* ctx_create)(void);
void (* ctx_destroy)(void * ctx);
@@ -55,4 +55,4 @@ struct pol_ca_ops {
};
-#endif /* OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H */
+#endif /* OUROBOROS_IPCPD_UNICAST_CA_OPS_H */
diff --git a/src/ipcpd/unicast/ca/pol.h b/src/ipcpd/unicast/ca/pol.h
new file mode 100644
index 00000000..db0a1a11
--- /dev/null
+++ b/src/ipcpd/unicast/ca/pol.h
@@ -0,0 +1,24 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Congestion avoidance policies
+ *
+ * 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/.
+ */
+
+#include "mb-ecn.h"
+#include "nop.h"
diff --git a/src/ipcpd/unicast/connmgr.c b/src/ipcpd/unicast/connmgr.c
index 904deff8..11c5d5b6 100644
--- a/src/ipcpd/unicast/connmgr.c
+++ b/src/ipcpd/unicast/connmgr.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handles connections between components
*
diff --git a/src/ipcpd/unicast/dir.c b/src/ipcpd/unicast/dir.c
index a30908b8..e0cb09fc 100644
--- a/src/ipcpd/unicast/dir.c
+++ b/src/ipcpd/unicast/dir.c
@@ -1,7 +1,7 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * Directory
+ * Directory Management
*
* Dimitri Staessens <dimitri@ouroboros.rocks>
* Sander Vrijders <sander@ouroboros.rocks>
@@ -34,8 +34,7 @@
#include <ouroboros/utils.h>
#include "dir.h"
-#include "dht.h"
-#include "ipcp.h"
+#include "dir/pol.h"
#include <stdlib.h>
#include <string.h>
@@ -43,60 +42,52 @@
#include <inttypes.h>
#include <limits.h>
-#define KAD_B (hash_len(ipcpi.dir_hash_algo) * CHAR_BIT)
-
-struct ipcp icpci;
-struct dht * dht;
+struct {
+ struct dir_ops * ops;
+ void * dir;
+} dirmgr;
int dir_init(void)
{
- dht = dht_create(ipcpi.dt_addr);
- if (dht == NULL)
+ dirmgr.ops = &dht_dir_ops;
+
+ dirmgr.dir = dirmgr.ops->create();
+ if (dirmgr.dir == NULL) {
+ dirmgr.ops = NULL;
return -ENOMEM;
+ }
return 0;
}
void dir_fini(void)
{
- dht_destroy(dht);
+ dirmgr.ops->destroy(dirmgr.dir);
+ dirmgr.ops = NULL;
+ dirmgr.dir = NULL;
}
-int dir_bootstrap(void) {
- log_dbg("Bootstrapping directory.");
-
- /* TODO: get parameters for bootstrap from IRM tool. */
- if (dht_bootstrap(dht, KAD_B, 86400)) {
- dht_destroy(dht);
- return -ENOMEM;
- }
-
- log_info("Directory bootstrapped.");
-
- return 0;
+int dir_bootstrap(void)
+{
+ return dirmgr.ops->bootstrap(dirmgr.dir);
}
int dir_reg(const uint8_t * hash)
{
- return dht_reg(dht, hash);
+ return dirmgr.ops->reg(dirmgr.dir, hash);
}
int dir_unreg(const uint8_t * hash)
{
- return dht_unreg(dht, hash);
+ return dirmgr.ops->unreg(dirmgr.dir, hash);
}
uint64_t dir_query(const uint8_t * hash)
{
- return dht_query(dht, hash);
+ return dirmgr.ops->query(dirmgr.dir, hash);
}
int dir_wait_running(void)
{
- if (dht_wait_running(dht)) {
- log_warn("Directory did not bootstrap.");
- return -1;
- }
-
- return 0;
+ return dirmgr.ops->wait_running(dirmgr.dir);
}
diff --git a/src/ipcpd/unicast/dir.h b/src/ipcpd/unicast/dir.h
index 8aa79638..b261ea2c 100644
--- a/src/ipcpd/unicast/dir.h
+++ b/src/ipcpd/unicast/dir.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Directory
*
diff --git a/src/ipcpd/unicast/dht.c b/src/ipcpd/unicast/dir/dht.c
index 2b668f9f..08a5a5a9 100644
--- a/src/ipcpd/unicast/dht.c
+++ b/src/ipcpd/unicast/dir/dht.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Distributed Hash Table based on Kademlia
*
@@ -31,6 +31,7 @@
#define DHT "dht"
#define OUROBOROS_PREFIX DHT
+#include <ouroboros/endian.h>
#include <ouroboros/hash.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/bitmap.h>
@@ -39,7 +40,7 @@
#include <ouroboros/list.h>
#include <ouroboros/notifier.h>
#include <ouroboros/random.h>
-#include <ouroboros/time_utils.h>
+#include <ouroboros/time.h>
#include <ouroboros/tpm.h>
#include <ouroboros/utils.h>
#include <ouroboros/pthread.h>
@@ -47,6 +48,8 @@
#include "common/connmgr.h"
#include "dht.h"
#include "dt.h"
+#include "ipcp.h"
+#include "ops.h"
#include <stdlib.h>
#include <string.h>
@@ -54,9 +57,9 @@
#include <inttypes.h>
#include <limits.h>
-#include "kademlia.pb-c.h"
-typedef KadMsg kad_msg_t;
-typedef KadContactMsg kad_contact_msg_t;
+#include "dht.pb-c.h"
+typedef DhtMsg dht_msg_t;
+typedef DhtContactMsg dht_contact_msg_t;
#ifndef CLOCK_REALTIME_COARSE
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
@@ -208,6 +211,16 @@ struct cmd {
struct shm_du_buff * sdb;
};
+struct dir_ops dht_dir_ops = {
+ .create = dht_create,
+ .destroy = dht_destroy,
+ .bootstrap = dht_bootstrap,
+ .reg = dht_reg,
+ .unreg = dht_unreg,
+ .query = dht_query,
+ .wait_running = dht_wait_running
+};
+
struct dht {
size_t alpha;
size_t b;
@@ -302,9 +315,12 @@ static int dht_set_state(struct dht * dht,
return 0;
}
-int dht_wait_running(struct dht * dht)
+int dht_wait_running(void * dir)
{
- int ret = 0;
+ struct dht * dht;
+ int ret = 0;
+
+ dht = (struct dht *) dir;
pthread_mutex_lock(&dht->mtx);
@@ -338,7 +354,7 @@ static uint8_t * create_id(size_t len)
}
static void kad_req_create(struct dht * dht,
- kad_msg_t * msg,
+ dht_msg_t * msg,
uint64_t addr)
{
struct kad_req * req;
@@ -346,14 +362,14 @@ static void kad_req_create(struct dht * dht,
struct timespec t;
size_t b;
+ clock_gettime(CLOCK_REALTIME_COARSE, &t);
+
req = malloc(sizeof(*req));
if (req == NULL)
- return;
+ goto fail_malloc;
list_head_init(&req->next);
- clock_gettime(CLOCK_REALTIME_COARSE, &t);
-
req->t_exp = t.tv_sec + KAD_T_RESP;
req->addr = addr;
req->state = REQ_INIT;
@@ -367,30 +383,22 @@ static void kad_req_create(struct dht * dht,
if (msg->has_key) {
req->key = dht_dup_key(msg->key.data, b);
- if (req->key == NULL) {
- free(req);
- return;
- }
+ if (req->key == NULL)
+ goto fail_dup_key;
}
- if (pthread_mutex_init(&req->lock, NULL)) {
- free(req->key);
- free(req);
- return;
- }
+ if (pthread_mutex_init(&req->lock, NULL))
+ goto fail_mutex;
- pthread_condattr_init(&cattr);
+
+ if (pthread_condattr_init(&cattr))
+ goto fail_condattr;
#ifndef __APPLE__
pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
#endif
- if (pthread_cond_init(&req->cond, &cattr)) {
- pthread_condattr_destroy(&cattr);
- pthread_mutex_destroy(&req->lock);
- free(req->key);
- free(req);
- return;
- }
+ if (pthread_cond_init(&req->cond, &cattr))
+ goto fail_cond_init;
pthread_condattr_destroy(&cattr);
@@ -399,6 +407,19 @@ static void kad_req_create(struct dht * dht,
list_add(&req->next, &dht->requests);
pthread_rwlock_unlock(&dht->lock);
+
+ return;
+
+ fail_cond_init:
+ pthread_condattr_destroy(&cattr);
+ fail_condattr:
+ pthread_mutex_destroy(&req->lock);
+ fail_mutex:
+ free(req->key);
+ fail_dup_key:
+ free(req);
+ fail_malloc:
+ return;
}
static void cancel_req_destroy(void * o)
@@ -428,7 +449,7 @@ static void kad_req_destroy(struct kad_req * req)
return;
case REQ_PENDING:
req->state = REQ_DESTROY;
- pthread_cond_signal(&req->cond);
+ pthread_cond_broadcast(&req->cond);
break;
case REQ_INIT:
case REQ_DONE:
@@ -451,12 +472,14 @@ static void kad_req_destroy(struct kad_req * req)
static int kad_req_wait(struct kad_req * req,
time_t t)
{
- struct timespec timeo = {t, 0};
+ struct timespec timeo = TIMESPEC_INIT_S(0);
struct timespec abs;
int ret = 0;
assert(req);
+ timeo.tv_sec = t;
+
clock_gettime(PTHREAD_COND_CLOCK, &abs);
ts_add(&abs, &timeo, &abs);
@@ -772,7 +795,7 @@ static void lookup_destroy(struct lookup * lu)
static void lookup_update(struct dht * dht,
struct lookup * lu,
- kad_msg_t * msg)
+ dht_msg_t * msg)
{
struct list_head * p = NULL;
struct list_head * h;
@@ -974,7 +997,7 @@ static void cancel_lookup_wait(void * o)
static enum lookup_state lookup_wait(struct lookup * lu)
{
- struct timespec timeo = {KAD_T_RESP, 0};
+ struct timespec timeo = TIMESPEC_INIT_S(KAD_T_RESP);
struct timespec abs;
enum lookup_state state;
int ret = 0;
@@ -1006,7 +1029,7 @@ static enum lookup_state lookup_wait(struct lookup * lu)
}
static struct kad_req * dht_find_request(struct dht * dht,
- kad_msg_t * msg)
+ dht_msg_t * msg)
{
struct list_head * p;
@@ -1254,7 +1277,7 @@ static void bucket_refresh(struct dht * dht,
struct contact * d;
c = list_first_entry(&b->contacts, struct contact, next);
d = contact_create(c->id, dht->b, c->addr);
- if (c != NULL)
+ if (d != NULL)
list_add(&d->next, r);
return;
}
@@ -1443,7 +1466,7 @@ static int dht_update_bucket(struct dht * dht,
}
static int send_msg(struct dht * dht,
- kad_msg_t * msg,
+ dht_msg_t * msg,
uint64_t addr)
{
#ifndef __DHT_TEST__
@@ -1476,7 +1499,7 @@ static int send_msg(struct dht * dht,
pthread_rwlock_unlock(&dht->lock);
#ifndef __DHT_TEST__
- len = kad_msg__get_packed_size(msg);
+ len = dht_msg__get_packed_size(msg);
if (len == 0)
goto fail_msg;
@@ -1484,7 +1507,7 @@ static int send_msg(struct dht * dht,
if (ipcp_sdb_reserve(&sdb, len))
goto fail_msg;
- kad_msg__pack(msg, shm_du_buff_head(sdb));
+ dht_msg__pack(msg, shm_du_buff_head(sdb));
if (dt_write_packet(addr, QOS_CUBE_BE, dht->eid, sdb) == 0)
break;
@@ -1531,7 +1554,7 @@ static struct dht_entry * dht_find_entry(struct dht * dht,
}
static int kad_add(struct dht * dht,
- const kad_contact_msg_t * contacts,
+ const dht_contact_msg_t * contacts,
ssize_t n,
time_t exp)
{
@@ -1570,7 +1593,7 @@ static int kad_add(struct dht * dht,
}
static int wait_resp(struct dht * dht,
- kad_msg_t * msg,
+ dht_msg_t * msg,
time_t timeo)
{
struct kad_req * req;
@@ -1597,9 +1620,9 @@ static int kad_store(struct dht * dht,
uint64_t r_addr,
time_t ttl)
{
- kad_msg_t msg = KAD_MSG__INIT;
- kad_contact_msg_t cmsg = KAD_CONTACT_MSG__INIT;
- kad_contact_msg_t * cmsgp[1];
+ dht_msg_t msg = DHT_MSG__INIT;
+ dht_contact_msg_t cmsg = DHT_CONTACT_MSG__INIT;
+ dht_contact_msg_t * cmsgp[1];
cmsg.id.data = (uint8_t *) key;
cmsg.addr = addr;
@@ -1629,7 +1652,7 @@ static ssize_t kad_find(struct dht * dht,
const uint64_t * addrs,
enum kad_code code)
{
- kad_msg_t msg = KAD_MSG__INIT;
+ dht_msg_t msg = DHT_MSG__INIT;
ssize_t sent = 0;
assert(dht);
@@ -1769,7 +1792,7 @@ static void kad_publish(struct dht * dht,
while (n-- > 0) {
if (addrs[n] == dht->addr) {
- kad_contact_msg_t msg = KAD_CONTACT_MSG__INIT;
+ dht_contact_msg_t msg = DHT_CONTACT_MSG__INIT;
msg.id.data = (uint8_t *) key;
msg.id.len = dht->b;
msg.addr = addr;
@@ -1788,7 +1811,7 @@ static void kad_publish(struct dht * dht,
static int kad_join(struct dht * dht,
uint64_t addr)
{
- kad_msg_t msg = KAD_MSG__INIT;
+ dht_msg_t msg = DHT_MSG__INIT;
msg.code = KAD_JOIN;
@@ -1868,18 +1891,13 @@ static int dht_del(struct dht * dht,
{
struct dht_entry * e;
- pthread_rwlock_wrlock(&dht->lock);
-
e = dht_find_entry(dht, key);
if (e == NULL) {
- pthread_rwlock_unlock(&dht->lock);
return -EPERM;
}
dht_entry_del_addr(e, addr);
- pthread_rwlock_unlock(&dht->lock);
-
return 0;
}
@@ -1921,14 +1939,14 @@ static buffer_t dht_retrieve(struct dht * dht,
fail:
pthread_rwlock_unlock(&dht->lock);
- buf.len = 0;
-
+ buf.len = 0;
+ buf.data = NULL;
return buf;
}
static ssize_t dht_get_contacts(struct dht * dht,
const uint8_t * key,
- kad_contact_msg_t *** msgs)
+ dht_contact_msg_t *** msgs)
{
struct list_head l;
struct list_head * p;
@@ -1965,7 +1983,7 @@ static ssize_t dht_get_contacts(struct dht * dht,
return 0;
}
- kad_contact_msg__init((*msgs)[i]);
+ dht_contact_msg__init((*msgs)[i]);
(*msgs)[i]->id.data = c->id;
(*msgs)[i]->id.len = dht->b;
@@ -2102,7 +2120,7 @@ static void * work(void * o)
static int kad_handle_join_resp(struct dht * dht,
struct kad_req * req,
- kad_msg_t * msg)
+ dht_msg_t * msg)
{
assert(dht);
assert(req);
@@ -2162,7 +2180,7 @@ static int kad_handle_join_resp(struct dht * dht,
static int kad_handle_find_resp(struct dht * dht,
struct kad_req * req,
- kad_msg_t * msg)
+ dht_msg_t * msg)
{
struct lookup * lu;
@@ -2186,7 +2204,7 @@ static int kad_handle_find_resp(struct dht * dht,
}
static void kad_handle_response(struct dht * dht,
- kad_msg_t * msg)
+ dht_msg_t * msg)
{
struct kad_req * req;
@@ -2224,15 +2242,23 @@ static void kad_handle_response(struct dht * dht,
kad_req_destroy(req);
}
-int dht_bootstrap(struct dht * dht,
- size_t b,
- time_t t_expire)
+int dht_bootstrap(void * dir)
{
+ struct dht * dht;
+
+ dht = (struct dht *) dir;
+
assert(dht);
pthread_rwlock_wrlock(&dht->lock);
- dht->id = create_id(b);
+#ifndef __DHT_TEST__
+ dht->b = hash_len(ipcpi.dir_hash_algo);
+#else
+ dht->b = DHT_TEST_KEY_LEN;
+#endif
+
+ dht->id = create_id(dht->b);
if (dht->id == NULL)
goto fail_id;
@@ -2243,9 +2269,8 @@ int dht_bootstrap(struct dht * dht,
dht->buckets->depth = 0;
dht->buckets->mask = 0;
- dht->b = b / CHAR_BIT;
- dht->t_expire = MAX(2, t_expire);
- dht->t_repub = MAX(1, t_expire - 10);
+ dht->t_expire = 86400; /* 1 day */
+ dht->t_repub = dht->t_expire - 10;
dht->k = KAD_K;
if (pthread_create(&dht->worker, NULL, work, dht))
@@ -2284,13 +2309,16 @@ static struct ref_entry * ref_entry_get(struct dht * dht,
return NULL;
}
-int dht_reg(struct dht * dht,
+int dht_reg(void * dir,
const uint8_t * key)
{
+ struct dht * dht;
struct ref_entry * e;
uint64_t addr;
time_t t_expire;
+ dht = (struct dht *) dir;
+
assert(dht);
assert(key);
assert(dht->addr != 0);
@@ -2324,12 +2352,15 @@ int dht_reg(struct dht * dht,
return 0;
}
-int dht_unreg(struct dht * dht,
+int dht_unreg(void * dir,
const uint8_t * key)
{
+ struct dht * dht;
struct list_head * p;
struct list_head * h;
+ dht = (struct dht *) dir;
+
assert(dht);
assert(key);
@@ -2353,14 +2384,19 @@ int dht_unreg(struct dht * dht,
return 0;
}
-uint64_t dht_query(struct dht * dht,
+uint64_t dht_query(void * dir,
const uint8_t * key)
{
+ struct dht * dht;
struct dht_entry * e;
struct lookup * lu;
uint64_t addrs[KAD_K];
size_t n;
+ dht = (struct dht *) dir;
+
+ assert(dht);
+
addrs[0] = 0;
if (dht_wait_running(dht))
@@ -2406,9 +2442,9 @@ static void * dht_handle_packet(void * o)
assert(dht);
while (true) {
- kad_msg_t * msg;
- kad_contact_msg_t ** cmsgs;
- kad_msg_t resp_msg = KAD_MSG__INIT;
+ dht_msg_t * msg;
+ dht_contact_msg_t ** cmsgs;
+ dht_msg_t resp_msg = DHT_MSG__INIT;
uint64_t addr;
buffer_t buf;
size_t i;
@@ -2428,9 +2464,9 @@ static void * dht_handle_packet(void * o)
pthread_cleanup_pop(true);
- i = shm_du_buff_tail(cmd->sdb) - shm_du_buff_head(cmd->sdb);
+ i = shm_du_buff_len(cmd->sdb);
- msg = kad_msg__unpack(NULL, i, shm_du_buff_head(cmd->sdb));
+ msg = dht_msg__unpack(NULL, i, shm_du_buff_head(cmd->sdb));
#ifndef __DHT_TEST__
ipcp_sdb_release(cmd->sdb);
#endif
@@ -2442,7 +2478,7 @@ static void * dht_handle_packet(void * o)
}
if (msg->code != KAD_RESPONSE && dht_wait_running(dht)) {
- kad_msg__free_unpacked(msg, NULL);
+ dht_msg__free_unpacked(msg, NULL);
log_dbg("Got a request message when not running.");
continue;
}
@@ -2455,13 +2491,13 @@ static void * dht_handle_packet(void * o)
pthread_rwlock_unlock(&dht->lock);
if (msg->has_key && msg->key.len != b) {
- kad_msg__free_unpacked(msg, NULL);
+ dht_msg__free_unpacked(msg, NULL);
log_warn("Bad key in message.");
continue;
}
if (msg->has_s_id && !msg->has_b && msg->s_id.len != b) {
- kad_msg__free_unpacked(msg, NULL);
+ dht_msg__free_unpacked(msg, NULL);
log_warn("Bad source ID in message of type %d.",
msg->code);
continue;
@@ -2562,7 +2598,7 @@ static void * dht_handle_packet(void * o)
log_warn("Failed to send response.");
finish:
- kad_msg__free_unpacked(msg, NULL);
+ dht_msg__free_unpacked(msg, NULL);
if (resp_msg.n_addrs > 0)
free(resp_msg.addrs);
@@ -2573,7 +2609,7 @@ static void * dht_handle_packet(void * o)
}
for (i = 0; i < resp_msg.n_contacts; ++i)
- kad_contact_msg__free_unpacked(resp_msg.contacts[i],
+ dht_contact_msg__free_unpacked(resp_msg.contacts[i],
NULL);
free(resp_msg.contacts);
@@ -2613,11 +2649,13 @@ static void dht_post_packet(void * comp,
pthread_mutex_unlock(&dht->mtx);
}
-void dht_destroy(struct dht * dht)
+void dht_destroy(void * dir)
{
+ struct dht * dht;
struct list_head * p;
struct list_head * h;
+ dht = (struct dht *) dir;
if (dht == NULL)
return;
@@ -2728,7 +2766,7 @@ static void handle_event(void * self,
pthread_t thr;
struct join_info * inf;
struct conn * c = (struct conn *) o;
- struct timespec slack = {0, DHT_ENROLL_SLACK * MILLION};
+ struct timespec slack = TIMESPEC_INIT_MS(DHT_ENROLL_SLACK);
/* Give the pff some time to update for the new link. */
nanosleep(&slack, NULL);
@@ -2770,7 +2808,7 @@ static void handle_event(void * self,
}
}
-struct dht * dht_create(uint64_t addr)
+void * dht_create(void)
{
struct dht * dht;
@@ -2800,9 +2838,9 @@ struct dht * dht_create(uint64_t addr)
goto fail_bmp;
dht->b = 0;
- dht->addr = addr;
dht->id = NULL;
#ifndef __DHT_TEST__
+ dht->addr = ipcpi.dt_addr;
dht->tpm = tpm_create(2, 1, dht_handle_packet, dht);
if (dht->tpm == NULL)
goto fail_tpm_create;
@@ -2814,7 +2852,8 @@ struct dht * dht_create(uint64_t addr)
if ((int) dht->eid < 0)
goto fail_tpm_start;
- notifier_reg(handle_event, dht);
+ if (notifier_reg(handle_event, dht))
+ goto fail_notifier_reg;
#else
(void) handle_event;
(void) dht_handle_packet;
@@ -2822,8 +2861,10 @@ struct dht * dht_create(uint64_t addr)
#endif
dht->state = DHT_INIT;
- return dht;
+ return (void *) dht;
#ifndef __DHT_TEST__
+ fail_notifier_reg:
+ tpm_stop(dht->tpm);
fail_tpm_start:
tpm_destroy(dht->tpm);
fail_tpm_create:
diff --git a/src/ipcpd/unicast/dht.h b/src/ipcpd/unicast/dir/dht.h
index df394714..311c6b23 100644
--- a/src/ipcpd/unicast/dht.h
+++ b/src/ipcpd/unicast/dir/dht.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Distributed Hash Table based on Kademlia
*
@@ -20,33 +20,33 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_UNICAST_DHT_H
-#define OUROBOROS_IPCPD_UNICAST_DHT_H
+#ifndef OUROBOROS_IPCPD_UNICAST_DIR_DHT_H
+#define OUROBOROS_IPCPD_UNICAST_DIR_DHT_H
#include <ouroboros/ipcp-dev.h>
+#include "ops.h"
+
#include <stdint.h>
#include <sys/types.h>
-struct dht;
+void * dht_create(void);
-struct dht * dht_create(uint64_t addr);
+void dht_destroy(void * dir);
-int dht_bootstrap(struct dht * dht,
- size_t b,
- time_t t_expire);
+int dht_bootstrap(void * dir);
-void dht_destroy(struct dht * dht);
+int dht_reg(void * dir,
+ const uint8_t * key);
-int dht_reg(struct dht * dht,
- const uint8_t * key);
+int dht_unreg(void * dir,
+ const uint8_t * key);
-int dht_unreg(struct dht * dht,
- const uint8_t * key);
+uint64_t dht_query(void * dir,
+ const uint8_t * key);
-uint64_t dht_query(struct dht * dht,
- const uint8_t * key);
+int dht_wait_running(void * dir);
-int dht_wait_running(struct dht * dht);
+extern struct dir_ops dht_dir_ops;
-#endif /* OUROBOROS_IPCPD_UNICAST_DHT_H */
+#endif /* OUROBOROS_IPCPD_UNICAST_DIR_DHT_H */
diff --git a/src/ipcpd/unicast/kademlia.proto b/src/ipcpd/unicast/dir/dht.proto
index 58f5e787..4c5b06db 100644
--- a/src/ipcpd/unicast/kademlia.proto
+++ b/src/ipcpd/unicast/dir/dht.proto
@@ -1,7 +1,7 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
- * KAD protocol
+ * DHT protocol, based on Kademlia
*
* Dimitri Staessens <dimitri@ouroboros.rocks>
* Sander Vrijders <sander@ouroboros.rocks>
@@ -22,19 +22,19 @@
syntax = "proto2";
-message kad_contact_msg {
+message dht_contact_msg {
required bytes id = 1;
required uint64 addr = 2;
-};
+}
-message kad_msg {
+message dht_msg {
required uint32 code = 1;
required uint32 cookie = 2;
required uint64 s_addr = 3;
optional bytes s_id = 4;
optional bytes key = 5;
repeated uint64 addrs = 6;
- repeated kad_contact_msg contacts = 7;
+ repeated dht_contact_msg contacts = 7;
// enrolment parameters
optional uint32 alpha = 8;
optional uint32 b = 9;
@@ -42,4 +42,4 @@ message kad_msg {
optional uint32 t_expire = 11;
optional uint32 t_refresh = 12;
optional uint32 t_replicate = 13;
-}; \ No newline at end of file
+}
diff --git a/src/ipcpd/unicast/dir/ops.h b/src/ipcpd/unicast/dir/ops.h
new file mode 100644
index 00000000..6ff61ce6
--- /dev/null
+++ b/src/ipcpd/unicast/dir/ops.h
@@ -0,0 +1,46 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Directory policy ops
+ *
+ * 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_UNICAST_DIR_OPS_H
+#define OUROBOROS_IPCPD_UNICAST_DIR_OPS_H
+
+
+struct dir_ops {
+ void * (* create)(void);
+
+ void (* destroy)(void * dir);
+
+ int (* bootstrap)(void * dir);
+
+ int (* reg)(void * dir,
+ const uint8_t * hash);
+
+ int (* unreg)(void * dir,
+ const uint8_t * hash);
+
+ uint64_t (* query)(void * dir,
+ const uint8_t * hash);
+
+ int (* wait_running)(void * dir);
+};
+
+#endif /* OUROBOROS_IPCPD_UNICAST_DIR_OPS_H */
diff --git a/src/ipcpd/unicast/dir/pol.h b/src/ipcpd/unicast/dir/pol.h
new file mode 100644
index 00000000..eae4b2e7
--- /dev/null
+++ b/src/ipcpd/unicast/dir/pol.h
@@ -0,0 +1,23 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Directory policies
+ *
+ * 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/.
+ */
+
+#include "dht.h"
diff --git a/src/ipcpd/unicast/tests/CMakeLists.txt b/src/ipcpd/unicast/dir/tests/CMakeLists.txt
index 482711d5..c850e41d 100644
--- a/src/ipcpd/unicast/tests/CMakeLists.txt
+++ b/src/ipcpd/unicast/dir/tests/CMakeLists.txt
@@ -20,10 +20,9 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
dht_test.c
)
-protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS ../kademlia.proto)
-
+protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ../dht.proto)
add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}
- ${KAD_PROTO_SRCS})
+ ${DHT_PROTO_SRCS})
target_link_libraries(${PARENT_DIR}_test ouroboros-common)
add_dependencies(check ${PARENT_DIR}_test)
diff --git a/src/ipcpd/unicast/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c
index 552af75c..bea2c3e7 100644
--- a/src/ipcpd/unicast/tests/dht_test.c
+++ b/src/ipcpd/unicast/dir/tests/dht_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unit tests of the DHT
*
@@ -21,6 +21,7 @@
*/
#define __DHT_TEST__
+#define DHT_TEST_KEY_LEN 32
#include "dht.c"
@@ -29,23 +30,19 @@
#include <stdlib.h>
#include <stdio.h>
-#define KEY_LEN 32
-
-#define EXP 86400
-#define CONTACTS 1000
+#define CONTACTS 1000
int dht_test(int argc,
char ** argv)
{
struct dht * dht;
- uint64_t addr = 0x0D1F;
- uint8_t key[KEY_LEN];
+ uint8_t key[DHT_TEST_KEY_LEN];
size_t i;
(void) argc;
(void) argv;
- dht = dht_create(addr);
+ dht = dht_create();
if (dht == NULL) {
printf("Failed to create dht.\n");
return -1;
@@ -53,13 +50,13 @@ int dht_test(int argc,
dht_destroy(dht);
- dht = dht_create(addr);
+ dht = dht_create();
if (dht == NULL) {
printf("Failed to re-create dht.\n");
return -1;
}
- if (dht_bootstrap(dht, KEY_LEN, EXP)) {
+ if (dht_bootstrap(dht)) {
printf("Failed to bootstrap dht.\n");
dht_destroy(dht);
return -1;
@@ -67,13 +64,13 @@ int dht_test(int argc,
dht_destroy(dht);
- dht = dht_create(addr);
+ dht = dht_create();
if (dht == NULL) {
printf("Failed to re-create dht.\n");
return -1;
}
- if (dht_bootstrap(dht, KEY_LEN, EXP)) {
+ if (dht_bootstrap(dht)) {
printf("Failed to bootstrap dht.\n");
dht_destroy(dht);
return -1;
@@ -82,7 +79,7 @@ int dht_test(int argc,
for (i = 0; i < CONTACTS; ++i) {
uint64_t addr;
random_buffer(&addr, sizeof(addr));
- random_buffer(key, KEY_LEN);
+ random_buffer(key, DHT_TEST_KEY_LEN);
pthread_rwlock_wrlock(&dht->lock);
if (dht_update_bucket(dht, key, addr)) {
pthread_rwlock_unlock(&dht->lock);
diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c
index 0f504daa..2bb5ed2f 100644
--- a/src/ipcpd/unicast/dt.c
+++ b/src/ipcpd/unicast/dt.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Data Transfer Component
*
@@ -312,7 +312,7 @@ static int dt_rib_readdir(char *** buf)
if ((*buf)[idx] == NULL) {
while (idx-- > 0)
free((*buf)[idx]);
- free(buf);
+ free(*buf);
pthread_mutex_unlock(&dt.stat[i].lock);
pthread_rwlock_unlock(&dt.lock);
return -ENOMEM;
@@ -399,6 +399,7 @@ static void handle_event(void * self,
const void * o)
{
struct conn * c;
+ int fd;
(void) self;
@@ -406,19 +407,20 @@ static void handle_event(void * self,
switch (event) {
case NOTIFY_DT_CONN_ADD:
+ fd = c->flow_info.fd;
#ifdef IPCP_FLOW_STATS
- stat_used(c->flow_info.fd, c->conn_info.addr);
+ stat_used(fd, c->conn_info.addr);
#endif
- psched_add(dt.psched, c->flow_info.fd);
- log_dbg("Added fd %d to packet scheduler.", c->flow_info.fd);
+ psched_add(dt.psched, fd);
+ log_dbg("Added fd %d to packet scheduler.", fd);
break;
case NOTIFY_DT_CONN_DEL:
+ fd = c->flow_info.fd;
#ifdef IPCP_FLOW_STATS
- stat_used(c->flow_info.fd, INVALID_ADDR);
+ stat_used(fd, INVALID_ADDR);
#endif
- psched_del(dt.psched, c->flow_info.fd);
- log_dbg("Removed fd %d from "
- "packet scheduler.", c->flow_info.fd);
+ psched_del(dt.psched, fd);
+ log_dbg("Removed fd %d from packet scheduler.", fd);
break;
default:
break;
@@ -435,7 +437,7 @@ static void packet_handler(int fd,
uint8_t * head;
size_t len;
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
#ifndef IPCP_FLOW_STATS
(void) fd;
@@ -563,10 +565,7 @@ static void * dt_conn_handle(void * o)
return 0;
}
-int dt_init(enum pol_routing pr,
- uint8_t addr_size,
- uint8_t eid_size,
- uint8_t max_ttl)
+int dt_init(struct dt_config cfg)
{
int i;
int j;
@@ -582,14 +581,14 @@ int dt_init(enum pol_routing pr,
info.pref_syntax = PROTO_FIXED;
info.addr = ipcpi.dt_addr;
- if (eid_size != 8) { /* only support 64 bits from now */
+ if (cfg.eid_size != 8) { /* only support 64 bits from now */
log_warn("Invalid EID size. Only 64 bit is supported.");
- eid_size = 8;
+ cfg.eid_size = 8;
}
- dt_pci_info.addr_size = addr_size;
- dt_pci_info.eid_size = eid_size;
- dt_pci_info.max_ttl = max_ttl;
+ dt_pci_info.addr_size = cfg.addr_size;
+ dt_pci_info.eid_size = cfg.eid_size;
+ dt_pci_info.max_ttl = cfg.max_ttl;
dt_pci_info.qc_o = dt_pci_info.addr_size;
dt_pci_info.ttl_o = dt_pci_info.qc_o + QOS_LEN;
@@ -597,17 +596,12 @@ int dt_init(enum pol_routing pr,
dt_pci_info.eid_o = dt_pci_info.ecn_o + ECN_LEN;
dt_pci_info.head_size = dt_pci_info.eid_o + dt_pci_info.eid_size;
- if (notifier_reg(handle_event, NULL)) {
- log_err("Failed to register with notifier.");
- goto fail_notifier_reg;
- }
-
if (connmgr_comp_init(COMPID_DT, &info)) {
log_err("Failed to register with connmgr.");
goto fail_connmgr_comp_init;
}
- pp = routing_init(pr);
+ pp = routing_init(cfg.routing_type);
if (pp < 0) {
log_err("Failed to init routing.");
goto fail_routing;
@@ -645,6 +639,7 @@ int dt_init(enum pol_routing pr,
for (i = 0; i < PROG_MAX_FLOWS; ++i)
if (pthread_mutex_init(&dt.stat[i].lock, NULL)) {
+ log_err("Failed to init mutex for flow %d.", i);
for (j = 0; j < i; ++j)
pthread_mutex_destroy(&dt.stat[j].lock);
goto fail_stat_lock;
@@ -653,8 +648,10 @@ int dt_init(enum pol_routing pr,
dt.n_flows = 0;
#endif
sprintf(dtstr, "%s.%" PRIu64, DT, ipcpi.dt_addr);
- if (rib_reg(dtstr, &r_ops))
+ if (rib_reg(dtstr, &r_ops)) {
+ log_err("Failed to register RIB.");
goto fail_rib_reg;
+ }
return 0;
@@ -678,8 +675,6 @@ int dt_init(enum pol_routing pr,
fail_routing:
connmgr_comp_fini(COMPID_DT);
fail_connmgr_comp_init:
- notifier_unreg(&handle_event);
- fail_notifier_reg:
return -1;
}
@@ -707,16 +702,19 @@ void dt_fini(void)
routing_fini();
connmgr_comp_fini(COMPID_DT);
-
- notifier_unreg(&handle_event);
}
int dt_start(void)
{
- dt.psched = psched_create(packet_handler);
+ dt.psched = psched_create(packet_handler, ipcp_flow_read);
if (dt.psched == NULL) {
log_err("Failed to create N-1 packet scheduler.");
- return -1;
+ goto fail_psched;
+ }
+
+ if (notifier_reg(handle_event, NULL)) {
+ log_err("Failed to register with notifier.");
+ goto fail_notifier_reg;
}
if (pthread_create(&dt.listener, NULL, dt_conn_handle, NULL)) {
@@ -726,12 +724,21 @@ int dt_start(void)
}
return 0;
+
+ fail_notifier_reg:
+ psched_destroy(dt.psched);
+ fail_psched:
+ return -1;
+
}
void dt_stop(void)
{
pthread_cancel(dt.listener);
pthread_join(dt.listener, NULL);
+
+ notifier_unreg(&handle_event);
+
psched_destroy(dt.psched);
}
@@ -747,7 +754,7 @@ int dt_reg_comp(void * comp,
eid = bmp_allocate(dt.res_fds);
if (!bmp_is_id_valid(dt.res_fds, eid)) {
- log_warn("Reserved EIDs depleted.");
+ log_err("Cannot allocate EID.");
pthread_rwlock_unlock(&dt.lock);
return -EBADF;
}
@@ -781,7 +788,7 @@ int dt_write_packet(uint64_t dst_addr,
assert(sdb);
assert(dst_addr != ipcpi.dt_addr);
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
#ifdef IPCP_FLOW_STATS
if (eid < PROG_RES_FDS) {
@@ -815,7 +822,7 @@ int dt_write_packet(uint64_t dst_addr,
goto fail_write;
}
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
dt_pci.dst_addr = dst_addr;
dt_pci.qc = qc;
diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h
index e1abbe28..7198a013 100644
--- a/src/ipcpd/unicast/dt.h
+++ b/src/ipcpd/unicast/dt.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Data Transfer component
*
@@ -31,11 +31,7 @@
#define DT_PROTO "dtp"
#define INVALID_ADDR 0
-int dt_init(enum pol_routing pr,
- uint8_t addr_size,
- uint8_t eid_size,
- uint8_t max_ttl
-);
+int dt_init(struct dt_config cfg);
void dt_fini(void);
diff --git a/src/ipcpd/unicast/enroll.c b/src/ipcpd/unicast/enroll.c
deleted file mode 100644
index 500a3895..00000000
--- a/src/ipcpd/unicast/enroll.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define BUILD_IPCP_UNICAST
-
-#include "common/enroll.c"
diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c
index 6e6d52f0..3631fd7b 100644
--- a/src/ipcpd/unicast/fa.c
+++ b/src/ipcpd/unicast/fa.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Flow allocator of the IPC Process
*
@@ -31,6 +31,7 @@
#define FA "flow-allocator"
#define OUROBOROS_PREFIX FA
+#include <ouroboros/endian.h>
#include <ouroboros/logs.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/errno.h>
@@ -55,7 +56,7 @@
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
#endif
-#define TIMEOUT 10000 /* nanoseconds */
+#define TIMEOUT 10 * MILLION /* nanoseconds */
#define FLOW_REQ 0
#define FLOW_REPLY 1
@@ -72,14 +73,15 @@ struct fa_msg {
int8_t response;
uint16_t ece;
/* QoS parameters from spec, aligned */
- uint8_t availability;
- uint8_t in_order;
uint32_t delay;
uint64_t bandwidth;
uint32_t loss;
uint32_t ber;
uint32_t max_gap;
+ uint32_t timeout;
uint16_t cypher_s;
+ uint8_t availability;
+ uint8_t in_order;
} __attribute__((packed));
struct cmd {
@@ -143,7 +145,7 @@ static int fa_rib_read(const char * path,
fd = atoi(entry);
- if (fd < 0 || fd > PROG_MAX_FLOWS)
+ if (fd < 0 || fd >= PROG_MAX_FLOWS)
return -1;
if (len < 1536)
@@ -238,7 +240,7 @@ static int fa_rib_readdir(char *** buf)
if ((*buf)[idx] == NULL) {
while (idx-- > 0)
free((*buf)[idx]);
- free(buf);
+ free(*buf);
pthread_rwlock_unlock(&fa.flows_lock);
return -ENOMEM;
}
@@ -303,7 +305,7 @@ static int eid_to_fd(uint64_t eid)
fd = eid & 0xFFFFFFFF;
- if (fd < 0 || fd > PROG_MAX_FLOWS)
+ if (fd < 0 || fd >= PROG_MAX_FLOWS)
return -1;
flow = &fa.flows[fd];
@@ -340,7 +342,7 @@ static void packet_handler(int fd,
pthread_rwlock_wrlock(&fa.flows_lock);
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
#ifdef IPCP_FLOW_STATS
++flow->p_snd;
@@ -357,7 +359,7 @@ static void packet_handler(int fd,
if (dt_write_packet(r_addr, qc, r_eid, sdb)) {
ipcp_sdb_release(sdb);
- log_warn("Failed to forward packet.");
+ log_dbg("Failed to forward packet.");
#ifdef IPCP_FLOW_STATS
pthread_rwlock_wrlock(&fa.flows_lock);
++flow->p_snd_f;
@@ -435,167 +437,190 @@ static void fa_post_packet(void * comp,
pthread_mutex_unlock(&fa.mtx);
}
-static void * fa_handle_packet(void * o)
+static size_t fa_wait_for_fa_msg(struct fa_msg * msg)
{
- struct timespec ts = {0, TIMEOUT * 1000};
-
- (void) o;
+ struct cmd * cmd;
+ size_t len;
- while (true) {
- struct timespec abstime;
- int fd;
- uint8_t buf[MSGBUFSZ];
- struct fa_msg * msg;
- qosspec_t qs;
- struct cmd * cmd;
- size_t len;
- size_t msg_len;
- struct fa_flow * flow;
+ pthread_mutex_lock(&fa.mtx);
- pthread_mutex_lock(&fa.mtx);
+ pthread_cleanup_push(__cleanup_mutex_unlock, &fa.mtx);
- pthread_cleanup_push(__cleanup_mutex_unlock, &fa.mtx);
+ while (list_is_empty(&fa.cmds))
+ pthread_cond_wait(&fa.cond, &fa.mtx);
- while (list_is_empty(&fa.cmds))
- pthread_cond_wait(&fa.cond, &fa.mtx);
+ cmd = list_last_entry(&fa.cmds, struct cmd, next);
+ list_del(&cmd->next);
- cmd = list_last_entry(&fa.cmds, struct cmd, next);
- list_del(&cmd->next);
+ pthread_cleanup_pop(true);
- pthread_cleanup_pop(true);
+ len = shm_du_buff_len(cmd->sdb);
+ if (len > MSGBUFSZ || len < sizeof(*msg)) {
+ log_warn("Invalid flow allocation message (len: %zd).", len);
+ free(cmd);
+ return 0; /* No valid message */
+ }
- len = shm_du_buff_tail(cmd->sdb) - shm_du_buff_head(cmd->sdb);
+ memcpy(msg, shm_du_buff_head(cmd->sdb), len);
- if (len > MSGBUFSZ) {
- log_err("Message over buffer size.");
- free(cmd);
- continue;
- }
+ ipcp_sdb_release(cmd->sdb);
- msg = (struct fa_msg *) buf;
+ free(cmd);
- /* Depending on the message call the function in ipcp-dev.h */
+ return len;
+}
- memcpy(msg, shm_du_buff_head(cmd->sdb), len);
+static int fa_handle_flow_req(struct fa_msg * msg,
+ size_t len)
+{
+ size_t msg_len;
+ int fd;
+ qosspec_t qs;
+ struct fa_flow * flow;
+ uint8_t * dst;
+ buffer_t data; /* Piggbacked data on flow alloc request. */
- ipcp_sdb_release(cmd->sdb);
+ msg_len = sizeof(*msg) + ipcp_dir_hash_len();
+ if (len < msg_len) {
+ log_err("Invalid flow allocation request");
+ return -EPERM;
+ }
- free(cmd);
+ dst = (uint8_t *)(msg + 1);
+ data.data = (uint8_t *) msg + msg_len;
+ data.len = len - msg_len;
+
+ qs.delay = ntoh32(msg->delay);
+ qs.bandwidth = ntoh64(msg->bandwidth);
+ qs.availability = msg->availability;
+ qs.loss = ntoh32(msg->loss);
+ qs.ber = ntoh32(msg->ber);
+ qs.in_order = msg->in_order;
+ qs.max_gap = ntoh32(msg->max_gap);
+ qs.cypher_s = ntoh16(msg->cypher_s);
+ qs.timeout = ntoh32(msg->timeout);
+
+ fd = ipcp_wait_flow_req_arr(dst, qs, IPCP_UNICAST_MPL, &data);
+ if (fd < 0)
+ return fd;
- switch (msg->code) {
- case FLOW_REQ:
- msg_len = sizeof(*msg) + ipcp_dir_hash_len();
+ flow = &fa.flows[fd];
- assert(len >= msg_len);
+ pthread_rwlock_wrlock(&fa.flows_lock);
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+ fa_flow_init(flow);
- pthread_mutex_lock(&ipcpi.alloc_lock);
+ flow->s_eid = gen_eid(fd);
+ flow->r_eid = ntoh64(msg->s_eid);
+ flow->r_addr = ntoh64(msg->s_addr);
- while (ipcpi.alloc_id != -1 &&
- ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
- }
+ pthread_rwlock_unlock(&fa.flows_lock);
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- log_dbg("Won't allocate over non-operational"
- "IPCP.");
- continue;
- }
+ return fd;
+}
- assert(ipcpi.alloc_id == -1);
+static int fa_handle_flow_reply(struct fa_msg * msg,
+ size_t len)
+{
+ int fd;
+ struct fa_flow * flow;
+ buffer_t data; /* Piggbacked data on flow alloc request. */
+ time_t mpl = IPCP_UNICAST_MPL;
- qs.delay = ntoh32(msg->delay);
- qs.bandwidth = ntoh64(msg->bandwidth);
- qs.availability = msg->availability;
- qs.loss = ntoh32(msg->loss);
- qs.ber = ntoh32(msg->ber);
- qs.in_order = msg->in_order;
- qs.max_gap = ntoh32(msg->max_gap);
- qs.cypher_s = ntoh16(msg->cypher_s);
+ assert(len >= sizeof(*msg));
- fd = ipcp_flow_req_arr((uint8_t *) (msg + 1),
- ipcp_dir_hash_len(),
- qs,
- buf + msg_len,
- len - msg_len);
- if (fd < 0) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- log_err("Failed to get fd for flow.");
- continue;
- }
+ data.data = (uint8_t *) msg + sizeof(*msg);
+ data.len = len - sizeof(*msg);
- flow = &fa.flows[fd];
+ pthread_rwlock_wrlock(&fa.flows_lock);
- pthread_rwlock_wrlock(&fa.flows_lock);
+ fd = eid_to_fd(ntoh64(msg->r_eid));
+ if (fd < 0) {
+ pthread_rwlock_unlock(&fa.flows_lock);
+ log_err("Flow reply for unknown EID %" PRIu64 ".",
+ ntoh64(msg->r_eid));
+ return -ENOTALLOC;
+ }
- fa_flow_init(flow);
+ flow = &fa.flows[fd];
- flow->s_eid = gen_eid(fd);
- flow->r_eid = ntoh64(msg->s_eid);
- flow->r_addr = ntoh64(msg->s_addr);
+ flow->r_eid = ntoh64(msg->s_eid);
- pthread_rwlock_unlock(&fa.flows_lock);
+ if (msg->response < 0)
+ fa_flow_fini(flow);
+ else
+ psched_add(fa.psched, fd);
- ipcpi.alloc_id = fd;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
+ pthread_rwlock_unlock(&fa.flows_lock);
- pthread_mutex_unlock(&ipcpi.alloc_lock);
+ if (ipcp_flow_alloc_reply(fd, msg->response, mpl, &data) < 0) {
+ log_err("Failed to reply for flow allocation on fd %d.", fd);
+ return -EIRMD;
+ }
- break;
- case FLOW_REPLY:
- assert(len >= sizeof(*msg));
+ return 0;
+}
- pthread_rwlock_wrlock(&fa.flows_lock);
+static int fa_handle_flow_update(struct fa_msg * msg,
+ size_t len)
+{
+ struct fa_flow * flow;
+ int fd;
- fd = eid_to_fd(ntoh64(msg->r_eid));
- if (fd < 0) {
- pthread_rwlock_unlock(&fa.flows_lock);
- break;
- }
+ (void) len;
+ assert(len >= sizeof(*msg));
- flow = &fa.flows[fd];
+ pthread_rwlock_wrlock(&fa.flows_lock);
- flow->r_eid = ntoh64(msg->s_eid);
+ fd = eid_to_fd(ntoh64(msg->r_eid));
+ if (fd < 0) {
+ pthread_rwlock_unlock(&fa.flows_lock);
+ log_err("Flow update for unknown EID %" PRIu64 ".",
+ ntoh64(msg->r_eid));
+ return -EPERM;
+ }
- if (msg->response < 0)
- fa_flow_fini(flow);
- else
- psched_add(fa.psched, fd);
+ flow = &fa.flows[fd];
+#ifdef IPCP_FLOW_STATS
+ flow->u_rcv++;
+#endif
+ ca_ctx_update_ece(flow->ctx, ntoh16(msg->ece));
- pthread_rwlock_unlock(&fa.flows_lock);
+ pthread_rwlock_unlock(&fa.flows_lock);
- ipcp_flow_alloc_reply(fd,
- msg->response,
- buf + sizeof(*msg),
- len - sizeof(*msg));
- break;
- case FLOW_UPDATE:
- assert(len >= sizeof(*msg));
+ return 0;
+}
- pthread_rwlock_wrlock(&fa.flows_lock);
+static void * fa_handle_packet(void * o)
+{
+ (void) o;
- fd = eid_to_fd(ntoh64(msg->r_eid));
- if (fd < 0) {
- pthread_rwlock_unlock(&fa.flows_lock);
- break;
- }
+ while (true) {
+ uint8_t buf[MSGBUFSZ];
+ struct fa_msg * msg;
+ size_t len;
- flow = &fa.flows[fd];
-#ifdef IPCP_FLOW_STATS
- flow->u_rcv++;
-#endif
- ca_ctx_update_ece(flow->ctx, ntoh16(msg->ece));
+ msg = (struct fa_msg *) buf;
- pthread_rwlock_unlock(&fa.flows_lock);
+ len = fa_wait_for_fa_msg(msg);
+ if (len == 0)
+ continue;
+ switch (msg->code) {
+ case FLOW_REQ:
+ if (fa_handle_flow_req(msg, len) < 0)
+ log_err("Error handling flow alloc request.");
+ break;
+ case FLOW_REPLY:
+ if (fa_handle_flow_reply(msg, len) < 0)
+ log_err("Error handling flow reply.");
+ break;
+ case FLOW_UPDATE:
+ if (fa_handle_flow_update(msg, len) < 0)
+ log_err("Error handling flow update.");
break;
default:
- log_err("Got an unknown flow allocation message.");
+ log_warn("Recieved unknown flow allocation message.");
break;
}
}
@@ -644,7 +669,7 @@ int fa_init(void)
fail_mtx:
pthread_rwlock_destroy(&fa.flows_lock);
fail_rwlock:
- log_err("Failed to initialize flow allocator.");
+
return -1;
}
@@ -663,7 +688,7 @@ int fa_start(void)
int pol;
int max;
- fa.psched = psched_create(packet_handler);
+ fa.psched = psched_create(packet_handler, np1_flow_read);
if (fa.psched == NULL) {
log_err("Failed to start packet scheduler.");
goto fail_psched;
@@ -700,7 +725,6 @@ int fa_start(void)
fail_thread:
psched_destroy(fa.psched);
fail_psched:
- log_err("Failed to start flow allocator.");
return -1;
}
@@ -712,11 +736,10 @@ void fa_stop(void)
psched_destroy(fa.psched);
}
-int fa_alloc(int fd,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t dlen)
+int fa_alloc(int fd,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data)
{
struct fa_msg * msg;
struct shm_du_buff * sdb;
@@ -732,7 +755,7 @@ int fa_alloc(int fd,
len = sizeof(*msg) + ipcp_dir_hash_len();
- if (ipcp_sdb_reserve(&sdb, len + dlen))
+ if (ipcp_sdb_reserve(&sdb, len + data->len))
return -1;
msg = (struct fa_msg *) shm_du_buff_head(sdb);
@@ -751,11 +774,14 @@ int fa_alloc(int fd,
msg->in_order = qs.in_order;
msg->max_gap = hton32(qs.max_gap);
msg->cypher_s = hton16(qs.cypher_s);
+ msg->timeout = hton32(qs.timeout);
memcpy(msg + 1, dst, ipcp_dir_hash_len());
- memcpy(shm_du_buff_head(sdb) + len, data, dlen);
+ if (data->len > 0)
+ memcpy(shm_du_buff_head(sdb) + len, data->data, data->len);
if (dt_write_packet(addr, qc, fa.eid, sdb)) {
+ log_err("Failed to send flow allocation request packet.");
ipcp_sdb_release(sdb);
return -1;
}
@@ -773,75 +799,66 @@ int fa_alloc(int fd,
return 0;
}
-int fa_alloc_resp(int fd,
- int response,
- const void * data,
- size_t len)
+int fa_alloc_resp(int fd,
+ int response,
+ const buffer_t * data)
{
- struct timespec ts = {0, TIMEOUT * 1000};
- struct timespec abstime;
struct fa_msg * msg;
struct shm_du_buff * sdb;
struct fa_flow * flow;
qoscube_t qc = QOS_CUBE_BE;
- clock_gettime(PTHREAD_COND_CLOCK, &abstime);
-
flow = &fa.flows[fd];
- pthread_mutex_lock(&ipcpi.alloc_lock);
-
- while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) {
- ts_add(&abstime, &ts, &abstime);
- pthread_cond_timedwait(&ipcpi.alloc_cond,
- &ipcpi.alloc_lock,
- &abstime);
+ if (ipcp_wait_flow_resp(fd) < 0) {
+ log_err("Failed to wait for flow response.");
+ goto fail_alloc_resp;
}
- if (ipcp_get_state() != IPCP_OPERATIONAL) {
- pthread_mutex_unlock(&ipcpi.alloc_lock);
- return -1;
- }
-
- ipcpi.alloc_id = -1;
- pthread_cond_broadcast(&ipcpi.alloc_cond);
-
- pthread_mutex_unlock(&ipcpi.alloc_lock);
-
- if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + len)) {
- fa_flow_fini(flow);
- return -1;
+ if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + data->len)) {
+ log_err("Failed to reserve sdb (%zu bytes).",
+ sizeof(*msg) + data->len);
+ goto fail_reserve;
}
msg = (struct fa_msg *) shm_du_buff_head(sdb);
memset(msg, 0, sizeof(*msg));
- pthread_rwlock_wrlock(&fa.flows_lock);
-
msg->code = FLOW_REPLY;
+ msg->response = response;
+ if (data->len > 0)
+ memcpy(msg + 1, data->data, data->len);
+
+ pthread_rwlock_rdlock(&fa.flows_lock);
+
msg->r_eid = hton64(flow->r_eid);
msg->s_eid = hton64(flow->s_eid);
- msg->response = response;
- memcpy(msg + 1, data, len);
+ pthread_rwlock_unlock(&fa.flows_lock);
+
+ if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) {
+ log_err("Failed to send flow allocation response packet.");
+ goto fail_packet;
+ }
if (response < 0) {
+ pthread_rwlock_rdlock(&fa.flows_lock);
fa_flow_fini(flow);
- ipcp_sdb_release(sdb);
+ pthread_rwlock_unlock(&fa.flows_lock);
} else {
psched_add(fa.psched, fd);
}
- if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) {
- fa_flow_fini(flow);
- pthread_rwlock_unlock(&fa.flows_lock);
- ipcp_sdb_release(sdb);
- return -1;
- }
+ return 0;
+ fail_packet:
+ ipcp_sdb_release(sdb);
+ fail_reserve:
+ pthread_rwlock_wrlock(&fa.flows_lock);
+ fa_flow_fini(flow);
pthread_rwlock_unlock(&fa.flows_lock);
-
- return 0;
+ fail_alloc_resp:
+ return -1;
}
int fa_dealloc(int fd)
@@ -857,7 +874,7 @@ int fa_dealloc(int fd)
pthread_rwlock_unlock(&fa.flows_lock);
- flow_dealloc(fd);
+ ipcp_flow_dealloc(fd);
return 0;
}
@@ -872,6 +889,7 @@ static int fa_update_remote(int fd,
uint64_t r_addr;
if (ipcp_sdb_reserve(&sdb, sizeof(*msg))) {
+ log_err("Failed to reserve sdb (%zu bytes).", sizeof(*msg));
return -1;
}
@@ -895,6 +913,7 @@ static int fa_update_remote(int fd,
if (dt_write_packet(r_addr, qc, fa.eid, sdb)) {
+ log_err("Failed to send flow update packet.");
ipcp_sdb_release(sdb);
return -1;
}
@@ -912,13 +931,14 @@ void fa_np1_rcv(uint64_t eid,
int fd;
size_t len;
- len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb);
+ len = shm_du_buff_len(sdb);
pthread_rwlock_wrlock(&fa.flows_lock);
fd = eid_to_fd(eid);
if (fd < 0) {
pthread_rwlock_unlock(&fa.flows_lock);
+ log_dbg("Received packet for unknown EID %" PRIu64 ".", eid);
ipcp_sdb_release(sdb);
return;
}
@@ -934,6 +954,7 @@ void fa_np1_rcv(uint64_t eid,
pthread_rwlock_unlock(&fa.flows_lock);
if (ipcp_flow_write(fd, sdb) < 0) {
+ log_dbg("Failed to write to flow %d.", fd);
ipcp_sdb_release(sdb);
#ifdef IPCP_FLOW_STATS
pthread_rwlock_wrlock(&fa.flows_lock);
diff --git a/src/ipcpd/unicast/fa.h b/src/ipcpd/unicast/fa.h
index 376fdb20..1e716966 100644
--- a/src/ipcpd/unicast/fa.h
+++ b/src/ipcpd/unicast/fa.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Flow allocator of the IPC Process
*
@@ -34,16 +34,14 @@ int fa_start(void);
void fa_stop(void);
-int fa_alloc(int fd,
- const uint8_t * dst,
- qosspec_t qs,
- const void * data,
- size_t len);
+int fa_alloc(int fd,
+ const uint8_t * dst,
+ qosspec_t qs,
+ const buffer_t * data);
-int fa_alloc_resp(int fd,
- int response,
- const void * data,
- size_t len);
+int fa_alloc_resp(int fd,
+ int response,
+ const buffer_t * data);
int fa_dealloc(int fd);
diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c
index 018dd1c6..e6cb2994 100644
--- a/src/ipcpd/unicast/main.c
+++ b/src/ipcpd/unicast/main.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Unicast IPC Process
*
@@ -32,16 +32,16 @@
#define THIS_TYPE IPCP_UNICAST
#include <ouroboros/errno.h>
-#include <ouroboros/hash.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/logs.h>
#include <ouroboros/notifier.h>
+#include <ouroboros/random.h>
#include <ouroboros/rib.h>
-#include <ouroboros/time_utils.h>
+#include <ouroboros/time.h>
#include "common/connmgr.h"
#include "common/enroll.h"
-#include "addr_auth.h"
+#include "addr-auth.h"
#include "ca.h"
#include "dir.h"
#include "dt.h"
@@ -59,18 +59,13 @@ struct ipcp ipcpi;
static int initialize_components(const struct ipcp_config * conf)
{
- ipcpi.layer_name = strdup(conf->layer_info.layer_name);
- if (ipcpi.layer_name == NULL) {
- log_err("Failed to set layer name.");
- goto fail_layer_name;
- }
-
- ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
+ strcpy(ipcpi.layer_name, conf->layer_info.name);
+ ipcpi.dir_hash_algo = (enum hash_algo) conf->layer_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
- if (addr_auth_init(conf->addr_auth_type,
- &conf->addr_size)) {
+ if (addr_auth_init(conf->unicast.addr_auth_type,
+ &conf->unicast.dt.addr_size)) {
log_err("Failed to init address authority.");
goto fail_addr_auth;
}
@@ -81,17 +76,14 @@ static int initialize_components(const struct ipcp_config * conf)
goto fail_addr_auth;
}
- log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr);
+ log_info("IPCP got address %" PRIu64 ".", ipcpi.dt_addr);
- if (ca_init(conf->cong_avoid)) {
+ if (ca_init(conf->unicast.cong_avoid)) {
log_err("Failed to initialize congestion avoidance.");
goto fail_ca;
}
- if (dt_init(conf->routing_type,
- conf->addr_size,
- conf->eid_size,
- conf->max_ttl)) {
+ if (dt_init(conf->unicast.dt)) {
log_err("Failed to initialize data transfer component.");
goto fail_dt;
}
@@ -119,8 +111,6 @@ static int initialize_components(const struct ipcp_config * conf)
fail_ca:
addr_auth_fini();
fail_addr_auth:
- free(ipcpi.layer_name);
- fail_layer_name:
return -1;
}
@@ -135,27 +125,26 @@ static void finalize_components(void)
ca_fini();
addr_auth_fini();
-
- free(ipcpi.layer_name);
}
static int start_components(void)
{
- assert(ipcp_get_state() == IPCP_INIT);
-
- ipcp_set_state(IPCP_OPERATIONAL);
+ if (dt_start() < 0) {
+ log_err("Failed to start data transfer.");
+ goto fail_dt_start;
+ }
- if (fa_start()) {
+ if (fa_start() < 0) {
log_err("Failed to start flow allocator.");
goto fail_fa_start;
}
- if (enroll_start()) {
+ if (enroll_start() < 0) {
log_err("Failed to start enrollment.");
goto fail_enroll_start;
}
- if (connmgr_start()) {
+ if (connmgr_start() < 0) {
log_err("Failed to start AP connection manager.");
goto fail_connmgr_start;
}
@@ -167,21 +156,22 @@ static int start_components(void)
fail_enroll_start:
fa_stop();
fail_fa_start:
+ dt_stop();
+ fail_dt_start:
ipcp_set_state(IPCP_INIT);
return -1;
}
static void stop_components(void)
{
- assert(ipcp_get_state() == IPCP_OPERATIONAL ||
- ipcp_get_state() == IPCP_SHUTDOWN);
-
connmgr_stop();
enroll_stop();
fa_stop();
+ dt_stop();
+
ipcp_set_state(IPCP_INIT);
}
@@ -189,7 +179,6 @@ static int bootstrap_components(void)
{
if (dir_bootstrap()) {
log_err("Failed to bootstrap directory.");
- dt_stop();
return -1;
}
@@ -200,53 +189,54 @@ static int unicast_ipcp_enroll(const char * dst,
struct layer_info * info)
{
struct conn conn;
+ uint8_t id[ENROLL_ID_LEN];
- if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn)) {
- log_err("Failed to get connection.");
- goto fail_er_flow;
+ if (random_buffer(id, ENROLL_ID_LEN) < 0) {
+ log_err("Failed to generate enrollment ID.");
+ goto fail_id;
}
- /* Get boot state from peer. */
- if (enroll_boot(&conn)) {
- log_err("Failed to get boot information.");
- goto fail_enroll_boot;
+ log_info_id(id, "Requesting enrollment.");
+
+ if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn) < 0) {
+ log_err_id(id, "Failed to get connection.");
+ goto fail_id;
}
- if (initialize_components(enroll_get_conf())) {
- log_err("Failed to initialize IPCP components.");
+ /* Get boot state from peer. */
+ if (enroll_boot(&conn, id) < 0) {
+ log_err_id(id, "Failed to get boot information.");
goto fail_enroll_boot;
}
- if (dt_start()) {
- log_err("Failed to initialize IPCP components.");
- goto fail_dt_start;
+ if (initialize_components(enroll_get_conf()) < 0) {
+ log_err_id(id, "Failed to initialize components.");
+ goto fail_enroll_boot;
}
- if (start_components()) {
- log_err("Failed to start components.");
+ if (start_components() < 0) {
+ log_err_id(id, "Failed to start components.");
goto fail_start_comp;
}
- if (enroll_done(&conn, 0))
- log_warn("Failed to confirm enrollment with peer.");
+ if (enroll_ack(&conn, id, 0) < 0)
+ log_err_id(id, "Failed to confirm enrollment.");
- if (connmgr_dealloc(COMPID_ENROLL, &conn))
- log_warn("Failed to deallocate enrollment flow.");
+ if (connmgr_dealloc(COMPID_ENROLL, &conn) < 0)
+ log_warn_id(id, "Failed to dealloc enrollment flow.");
- log_info("Enrolled with %s.", dst);
+ log_info_id(id, "Enrolled with %s.", dst);
- info->dir_hash_algo = ipcpi.dir_hash_algo;
- strcpy(info->layer_name, ipcpi.layer_name);
+ info->dir_hash_algo = (enum pol_dir_hash) ipcpi.dir_hash_algo;
+ strcpy(info->name, ipcpi.layer_name);
return 0;
fail_start_comp:
- dt_stop();
- fail_dt_start:
finalize_components();
fail_enroll_boot:
connmgr_dealloc(COMPID_ENROLL, &conn);
- fail_er_flow:
+ fail_id:
return -1;
}
@@ -257,35 +247,26 @@ static int unicast_ipcp_bootstrap(const struct ipcp_config * conf)
enroll_bootstrap(conf);
- if (initialize_components(conf)) {
+ if (initialize_components(conf) < 0) {
log_err("Failed to init IPCP components.");
goto fail_init;
}
- if (dt_start()) {
- log_err("Failed to initialize IPCP components.");
- goto fail_dt_start;
- };
-
- if (start_components()) {
+ if (start_components() < 0) {
log_err("Failed to init IPCP components.");
goto fail_start;
}
- if (bootstrap_components()) {
+ if (bootstrap_components() < 0) {
log_err("Failed to bootstrap IPCP components.");
goto fail_bootstrap;
}
- log_dbg("Bootstrapped in layer %s.", conf->layer_info.layer_name);
-
return 0;
fail_bootstrap:
stop_components();
fail_start:
- dt_stop();
- fail_dt_start:
finalize_components();
fail_init:
return -1;
@@ -318,40 +299,35 @@ int main(int argc,
goto fail_init;
}
- if (notifier_init()) {
+ if (notifier_init() < 0) {
log_err("Failed to initialize notifier component.");
goto fail_notifier_init;
}
- if (connmgr_init()) {
+ if (connmgr_init() < 0) {
log_err("Failed to initialize connection manager.");
goto fail_connmgr_init;
}
- if (enroll_init()) {
+ if (enroll_init() < 0) {
log_err("Failed to initialize enrollment component.");
goto fail_enroll_init;
}
- if (ipcp_boot() < 0) {
- log_err("Failed to boot IPCP.");
- goto fail_boot;
- }
-
- if (ipcp_create_r(0)) {
- log_err("Failed to notify IRMd we are initialized.");
- ipcp_set_state(IPCP_NULL);
- goto fail_create_r;
+ if (ipcp_start() < 0) {
+ log_err("Failed to start IPCP.");
+ goto fail_start;
}
- ipcp_shutdown();
+ ipcp_sigwait();
if (ipcp_get_state() == IPCP_SHUTDOWN) {
- dt_stop();
stop_components();
finalize_components();
}
+ ipcp_stop();
+
enroll_fini();
connmgr_fini();
@@ -362,17 +338,14 @@ int main(int argc,
exit(EXIT_SUCCESS);
- fail_create_r:
- ipcp_shutdown();
- fail_boot:
+ fail_start:
enroll_fini();
fail_enroll_init:
connmgr_fini();
fail_connmgr_init:
notifier_fini();
fail_notifier_init:
- ipcp_fini();
+ ipcp_fini();
fail_init:
- ipcp_create_r(-1);
exit(EXIT_FAILURE);
}
diff --git a/src/ipcpd/unicast/pff.c b/src/ipcpd/unicast/pff.c
index 03682184..9b2aa2b4 100644
--- a/src/ipcpd/unicast/pff.c
+++ b/src/ipcpd/unicast/pff.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* PDU Forwarding Function
*
@@ -26,14 +26,11 @@
#include <ouroboros/logs.h>
#include "pff.h"
-#include "pol-pff-ops.h"
-#include "pol/alternate_pff.h"
-#include "pol/multipath_pff.h"
-#include "pol/simple_pff.h"
+#include "pff/pol.h"
struct pff {
- struct pol_pff_ops * ops;
- struct pff_i * pff_i;
+ struct pff_ops * ops;
+ struct pff_i * pff_i;
};
struct pff * pff_create(enum pol_pff pol)
@@ -62,8 +59,10 @@ struct pff * pff_create(enum pol_pff pol)
}
pff->pff_i = pff->ops->create();
- if (pff->pff_i == NULL)
+ if (pff->pff_i == NULL) {
+ log_err("Failed to create PFF instance.");
goto err;
+ }
return pff;
err:
diff --git a/src/ipcpd/unicast/pff.h b/src/ipcpd/unicast/pff.h
index 3ac9d5fb..f44e5531 100644
--- a/src/ipcpd/unicast/pff.h
+++ b/src/ipcpd/unicast/pff.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* PDU Forwarding Function
*
diff --git a/src/ipcpd/unicast/pol/alternate_pff.c b/src/ipcpd/unicast/pff/alternate.c
index 18d3dfed..85e85914 100644
--- a/src/ipcpd/unicast/pol/alternate_pff.c
+++ b/src/ipcpd/unicast/pff/alternate.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for PFF with alternate next hops
*
@@ -28,7 +28,7 @@
#include <ouroboros/list.h>
#include "pft.h"
-#include "alternate_pff.h"
+#include "alternate.h"
#include <string.h>
#include <assert.h>
@@ -54,7 +54,7 @@ struct pff_i {
pthread_rwlock_t lock;
};
-struct pol_pff_ops alternate_pff_ops = {
+struct pff_ops alternate_pff_ops = {
.create = alternate_pff_create,
.destroy = alternate_pff_destroy,
.lock = alternate_pff_lock,
diff --git a/src/ipcpd/unicast/pol/alternate_pff.h b/src/ipcpd/unicast/pff/alternate.h
index 9c7cc08f..96207e74 100644
--- a/src/ipcpd/unicast/pol/alternate_pff.h
+++ b/src/ipcpd/unicast/pff/alternate.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for PFF with alternate next hops
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H
#define OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H
-#include "pol-pff-ops.h"
+#include "ops.h"
struct pff_i * alternate_pff_create(void);
@@ -56,6 +56,6 @@ int alternate_flow_state_change(struct pff_i * pff_i,
int fd,
bool up);
-extern struct pol_pff_ops alternate_pff_ops;
+extern struct pff_ops alternate_pff_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H */
diff --git a/src/ipcpd/unicast/pol/multipath_pff.c b/src/ipcpd/unicast/pff/multipath.c
index 0d759ec4..cbab0f5f 100644
--- a/src/ipcpd/unicast/pol/multipath_pff.c
+++ b/src/ipcpd/unicast/pff/multipath.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for PFF supporting multipath routing
*
@@ -28,7 +28,7 @@
#include <ouroboros/errno.h>
#include "pft.h"
-#include "multipath_pff.h"
+#include "multipath.h"
#include <string.h>
#include <assert.h>
@@ -39,7 +39,7 @@ struct pff_i {
pthread_rwlock_t lock;
};
-struct pol_pff_ops multipath_pff_ops = {
+struct pff_ops multipath_pff_ops = {
.create = multipath_pff_create,
.destroy = multipath_pff_destroy,
.lock = multipath_pff_lock,
@@ -58,21 +58,23 @@ struct pff_i * multipath_pff_create(void)
tmp = malloc(sizeof(*tmp));
if (tmp == NULL)
- return NULL;
+ goto fail_malloc;
- if (pthread_rwlock_init(&tmp->lock, NULL)) {
- free(tmp);
- return NULL;
- }
+ if (pthread_rwlock_init(&tmp->lock, NULL))
+ goto fail_rwlock;
tmp->pft = pft_create(PFT_SIZE, false);
- if (tmp->pft == NULL) {
- pthread_rwlock_destroy(&tmp->lock);
- free(tmp);
- return NULL;
- }
+ if (tmp->pft == NULL)
+ goto fail_pft;
return tmp;
+
+ fail_pft:
+ pthread_rwlock_destroy(&tmp->lock);
+ fail_rwlock:
+ free(tmp);
+ fail_malloc:
+ return NULL;
}
void multipath_pff_destroy(struct pff_i * pff_i)
@@ -80,8 +82,8 @@ void multipath_pff_destroy(struct pff_i * pff_i)
assert(pff_i);
pft_destroy(pff_i->pft);
-
pthread_rwlock_destroy(&pff_i->lock);
+
free(pff_i);
}
@@ -177,7 +179,7 @@ int multipath_pff_nhop(struct pff_i * pff_i,
assert(pff_i);
- pthread_rwlock_rdlock(&pff_i->lock);
+ pthread_rwlock_wrlock(&pff_i->lock);
if (pft_lookup(pff_i->pft, addr, &fds, &len)) {
pthread_rwlock_unlock(&pff_i->lock);
@@ -189,7 +191,7 @@ int multipath_pff_nhop(struct pff_i * pff_i,
assert(len > 0);
/* Rotate fds left. */
- memcpy(fds, fds + 1, (len - 1) * sizeof(*fds));
+ memmove(fds, fds + 1, (len - 1) * sizeof(*fds));
fds[len - 1] = fd;
pthread_rwlock_unlock(&pff_i->lock);
diff --git a/src/ipcpd/unicast/pol/multipath_pff.h b/src/ipcpd/unicast/pff/multipath.h
index 8168995e..0eb03476 100644
--- a/src/ipcpd/unicast/pol/multipath_pff.h
+++ b/src/ipcpd/unicast/pff/multipath.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Policy for PFF supporting multipath routing
*
@@ -24,7 +24,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H
#define OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H
-#include "pol-pff-ops.h"
+#include "ops.h"
struct pff_i * multipath_pff_create(void);
@@ -53,6 +53,6 @@ void multipath_pff_flush(struct pff_i * pff_i);
int multipath_pff_nhop(struct pff_i * pff_i,
uint64_t addr);
-extern struct pol_pff_ops multipath_pff_ops;
+extern struct pff_ops multipath_pff_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H */
diff --git a/src/ipcpd/unicast/pol-pff-ops.h b/src/ipcpd/unicast/pff/ops.h
index 85615a1f..16a31273 100644
--- a/src/ipcpd/unicast/pol-pff-ops.h
+++ b/src/ipcpd/unicast/pff/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Pff policy ops
*
@@ -20,14 +20,14 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H
-#define OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H
+#ifndef OUROBOROS_IPCPD_UNICAST_PFF_OPS_H
+#define OUROBOROS_IPCPD_UNICAST_PFF_OPS_H
#include <stdbool.h>
struct pff_i;
-struct pol_pff_ops {
+struct pff_ops {
struct pff_i * (* create)(void);
void (* destroy)(struct pff_i * pff_i);
@@ -60,4 +60,4 @@ struct pol_pff_ops {
bool up);
};
-#endif /* OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H */
+#endif /* OUROBOROS_IPCPD_UNICAST_PFF_OPS_H */
diff --git a/src/ipcpd/unicast/pol/pft.c b/src/ipcpd/unicast/pff/pft.c
index e42b4a98..8c436113 100644
--- a/src/ipcpd/unicast/pol/pft.c
+++ b/src/ipcpd/unicast/pff/pft.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Packet forwarding table (PFT) with chaining on collisions
*
@@ -115,19 +115,11 @@ void pft_flush(struct pft * pft)
static uint64_t hash(uint64_t key)
{
- void * res;
- uint64_t ret;
- uint8_t keys[4];
+ uint64_t res[2];
- memcpy(keys, &key, 4);
+ mem_hash(HASH_MD5, res, (uint8_t *) &key, sizeof(key));
- mem_hash(HASH_MD5, &res, keys, 4);
-
- ret = (* (uint64_t *) res);
-
- free(res);
-
- return ret;
+ return res[0];
}
static uint64_t calc_key(struct pft * pft,
diff --git a/src/ipcpd/unicast/pol/pft.h b/src/ipcpd/unicast/pff/pft.h
index 011ad414..711dabcb 100644
--- a/src/ipcpd/unicast/pol/pft.h
+++ b/src/ipcpd/unicast/pff/pft.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Packet forwarding table (PFT) with chaining on collisions
*
diff --git a/src/ipcpd/unicast/pff/pol.h b/src/ipcpd/unicast/pff/pol.h
new file mode 100644
index 00000000..245b03c4
--- /dev/null
+++ b/src/ipcpd/unicast/pff/pol.h
@@ -0,0 +1,25 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * PDU Forwarding Function policies
+ *
+ * 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/.
+ */
+
+#include "alternate.h"
+#include "multipath.h"
+#include "simple.h"
diff --git a/src/ipcpd/unicast/pol/simple_pff.c b/src/ipcpd/unicast/pff/simple.c
index 13944aed..5f95e3ce 100644
--- a/src/ipcpd/unicast/pol/simple_pff.c
+++ b/src/ipcpd/unicast/pff/simple.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Simple PDU Forwarding Function
*
@@ -27,7 +27,7 @@
#include <ouroboros/errno.h>
#include "pft.h"
-#include "simple_pff.h"
+#include "simple.h"
#include <assert.h>
#include <pthread.h>
@@ -37,7 +37,7 @@ struct pff_i {
pthread_rwlock_t lock;
};
-struct pol_pff_ops simple_pff_ops = {
+struct pff_ops simple_pff_ops = {
.create = simple_pff_create,
.destroy = simple_pff_destroy,
.lock = simple_pff_lock,
diff --git a/src/ipcpd/unicast/pol/simple_pff.h b/src/ipcpd/unicast/pff/simple.h
index 2b22c130..0966a186 100644
--- a/src/ipcpd/unicast/pol/simple_pff.h
+++ b/src/ipcpd/unicast/pff/simple.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Simple policy for PFF
*
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H
#define OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H
-#include "pol-pff-ops.h"
+#include "ops.h"
struct pff_i * simple_pff_create(void);
@@ -52,6 +52,6 @@ void simple_pff_flush(struct pff_i * pff_i);
int simple_pff_nhop(struct pff_i * pff_i,
uint64_t addr);
-extern struct pol_pff_ops simple_pff_ops;
+extern struct pff_ops simple_pff_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H */
diff --git a/src/ipcpd/unicast/pff/tests/CMakeLists.txt b/src/ipcpd/unicast/pff/tests/CMakeLists.txt
new file mode 100644
index 00000000..e7082372
--- /dev/null
+++ b/src/ipcpd/unicast/pff/tests/CMakeLists.txt
@@ -0,0 +1,34 @@
+get_filename_component(CURRENT_SOURCE_PARENT_DIR
+ ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+get_filename_component(CURRENT_BINARY_PARENT_DIR
+ ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+include_directories(${CURRENT_SOURCE_PARENT_DIR})
+include_directories(${CURRENT_BINARY_PARENT_DIR})
+
+include_directories(${CMAKE_SOURCE_DIR}/include)
+include_directories(${CMAKE_BINARY_DIR}/include)
+
+get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
+get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
+
+create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
+ # Add new tests here
+ pft_test.c
+ )
+
+add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests})
+target_link_libraries(${PARENT_DIR}_test ouroboros-common)
+
+add_dependencies(check ${PARENT_DIR}_test)
+
+set(tests_to_run ${${PARENT_DIR}_tests})
+remove(tests_to_run test_suite.c)
+
+foreach (test ${tests_to_run})
+ get_filename_component(test_name ${test} NAME_WE)
+ add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name})
+endforeach (test)
diff --git a/src/ipcpd/unicast/pol/tests/pft_test.c b/src/ipcpd/unicast/pff/tests/pft_test.c
index c48267eb..18287fb8 100644
--- a/src/ipcpd/unicast/pol/tests/pft_test.c
+++ b/src/ipcpd/unicast/pff/tests/pft_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Test of the hash table
*
diff --git a/src/ipcpd/unicast/psched.c b/src/ipcpd/unicast/psched.c
index 33ac5afe..7e12148b 100644
--- a/src/ipcpd/unicast/psched.c
+++ b/src/ipcpd/unicast/psched.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Packet scheduler component
*
@@ -50,6 +50,7 @@ static int qos_prio [] = {
struct psched {
fset_t * set[QOS_CUBE_MAX];
next_packet_fn_t callback;
+ read_fn_t read;
pthread_t readers[QOS_CUBE_MAX * IPCP_SCHED_THR_MUL];
};
@@ -101,7 +102,7 @@ static void * packet_reader(void * o)
notifier_event(NOTIFY_DT_FLOW_UP, &fd);
break;
case FLOW_PKT:
- if (ipcp_flow_read(fd, &sdb))
+ if (sched->read(fd, &sdb) < 0)
continue;
sched->callback(fd, qc, sdb);
@@ -117,7 +118,8 @@ static void * packet_reader(void * o)
return (void *) 0;
}
-struct psched * psched_create(next_packet_fn_t callback)
+struct psched * psched_create(next_packet_fn_t callback,
+ read_fn_t read)
{
struct psched * psched;
struct sched_info * infos[QOS_CUBE_MAX * IPCP_SCHED_THR_MUL];
@@ -131,6 +133,7 @@ struct psched * psched_create(next_packet_fn_t callback)
goto fail_malloc;
psched->callback = callback;
+ psched->read = read;
for (i = 0; i < QOS_CUBE_MAX; ++i) {
psched->set[i] = fset_create();
diff --git a/src/ipcpd/unicast/psched.h b/src/ipcpd/unicast/psched.h
index 1f22b34b..831f8084 100644
--- a/src/ipcpd/unicast/psched.h
+++ b/src/ipcpd/unicast/psched.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Packet scheduler component
*
@@ -30,7 +30,11 @@ typedef void (* next_packet_fn_t)(int fd,
qoscube_t qc,
struct shm_du_buff * sdb);
-struct psched * psched_create(next_packet_fn_t callback);
+typedef int (* read_fn_t)(int fd,
+ struct shm_du_buff ** sdb);
+
+struct psched * psched_create(next_packet_fn_t callback,
+ read_fn_t read);
void psched_destroy(struct psched * psched);
diff --git a/src/ipcpd/unicast/routing.c b/src/ipcpd/unicast/routing.c
index 1b13ae0e..f5417c24 100644
--- a/src/ipcpd/unicast/routing.c
+++ b/src/ipcpd/unicast/routing.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Routing component of the IPCP
*
@@ -26,9 +26,9 @@
#include "pff.h"
#include "routing.h"
-#include "pol/link_state.h"
+#include "routing/pol.h"
-struct pol_routing_ops * r_ops;
+struct routing_ops * r_ops;
int routing_init(enum pol_routing pr)
{
diff --git a/src/ipcpd/unicast/routing.h b/src/ipcpd/unicast/routing.h
index 2eaaeb68..d5d833ae 100644
--- a/src/ipcpd/unicast/routing.h
+++ b/src/ipcpd/unicast/routing.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Routing component of the IPCP
*
diff --git a/src/ipcpd/unicast/pol/graph.c b/src/ipcpd/unicast/routing/graph.c
index 6ea5c507..32f3e6fb 100644
--- a/src/ipcpd/unicast/pol/graph.c
+++ b/src/ipcpd/unicast/routing/graph.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Undirected graph structure
*
diff --git a/src/ipcpd/unicast/pol/graph.h b/src/ipcpd/unicast/routing/graph.h
index 632cc5a0..8190cc6c 100644
--- a/src/ipcpd/unicast/pol/graph.h
+++ b/src/ipcpd/unicast/routing/graph.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Undirected graph structure
*
diff --git a/src/ipcpd/unicast/pol/link_state.c b/src/ipcpd/unicast/routing/link-state.c
index 08d39372..57c0c7cb 100644
--- a/src/ipcpd/unicast/pol/link_state.c
+++ b/src/ipcpd/unicast/routing/link-state.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Link state routing policy
*
@@ -46,7 +46,7 @@
#include "common/connmgr.h"
#include "graph.h"
#include "ipcp.h"
-#include "link_state.h"
+#include "link-state.h"
#include "pff.h"
#include <assert.h>
@@ -127,7 +127,7 @@ struct {
enum routing_algo routing_algo;
} ls;
-struct pol_routing_ops link_state_ops = {
+struct routing_ops link_state_ops = {
.init = link_state_init,
.fini = link_state_fini,
.routing_i_create = link_state_routing_i_create,
@@ -273,7 +273,7 @@ static int lsdb_rib_readdir(char *** buf)
if ((*buf)[idx] == NULL) {
while (idx-- > 0)
free((*buf)[idx]);
- free(buf);
+ free(*buf);
pthread_rwlock_unlock(&ls.db_lock);
return -ENOMEM;
}
diff --git a/src/ipcpd/unicast/pol/link_state.h b/src/ipcpd/unicast/routing/link-state.h
index 05b0ae5d..d77d72df 100644
--- a/src/ipcpd/unicast/pol/link_state.h
+++ b/src/ipcpd/unicast/routing/link-state.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Link state routing policy
*
@@ -26,7 +26,7 @@
#define LS_COMP "Management"
#define LS_PROTO "LSP"
-#include "pol-routing-ops.h"
+#include "ops.h"
int link_state_init(enum pol_routing pr);
@@ -36,6 +36,6 @@ struct routing_i * link_state_routing_i_create(struct pff * pff);
void link_state_routing_i_destroy(struct routing_i * instance);
-extern struct pol_routing_ops link_state_ops;
+extern struct routing_ops link_state_ops;
#endif /* OUROBOROS_IPCPD_UNICAST_POL_LINK_STATE_H */
diff --git a/src/ipcpd/unicast/pol-routing-ops.h b/src/ipcpd/unicast/routing/ops.h
index cea88582..8a79b7ec 100644
--- a/src/ipcpd/unicast/pol-routing-ops.h
+++ b/src/ipcpd/unicast/routing/ops.h
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Routing policy ops
*
@@ -20,12 +20,12 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H
-#define OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H
+#ifndef OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H
+#define OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H
#include "pff.h"
-struct pol_routing_ops {
+struct routing_ops {
int (* init)(enum pol_routing pr);
void (* fini)(void);
@@ -35,4 +35,4 @@ struct pol_routing_ops {
void (* routing_i_destroy)(struct routing_i * instance);
};
-#endif /* OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H */
+#endif /* OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H */
diff --git a/src/ipcpd/unicast/routing/pol.h b/src/ipcpd/unicast/routing/pol.h
new file mode 100644
index 00000000..b6a6f150
--- /dev/null
+++ b/src/ipcpd/unicast/routing/pol.h
@@ -0,0 +1,23 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Routing policies
+ *
+ * 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/.
+ */
+
+#include "link-state.h"
diff --git a/src/ipcpd/unicast/pol/tests/CMakeLists.txt b/src/ipcpd/unicast/routing/tests/CMakeLists.txt
index 34d80e8d..d0652533 100644
--- a/src/ipcpd/unicast/pol/tests/CMakeLists.txt
+++ b/src/ipcpd/unicast/routing/tests/CMakeLists.txt
@@ -18,7 +18,6 @@ get_filename_component(PARENT_DIR ${PARENT_PATH} NAME)
create_test_sourcelist(${PARENT_DIR}_tests test_suite.c
# Add new tests here
graph_test.c
- pft_test.c
)
add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests})
diff --git a/src/ipcpd/unicast/pol/tests/graph_test.c b/src/ipcpd/unicast/routing/tests/graph_test.c
index 217c7eab..d805640c 100644
--- a/src/ipcpd/unicast/pol/tests/graph_test.c
+++ b/src/ipcpd/unicast/routing/tests/graph_test.c
@@ -1,5 +1,5 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2021
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Test of the graph structure
*