summaryrefslogtreecommitdiff
path: root/src/ipcpd/broadcast
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/broadcast')
-rw-r--r--src/ipcpd/broadcast/CMakeLists.txt40
-rw-r--r--src/ipcpd/broadcast/connmgr.c2
-rw-r--r--src/ipcpd/broadcast/dt.c79
-rw-r--r--src/ipcpd/broadcast/dt.h2
-rw-r--r--src/ipcpd/broadcast/enroll.c24
-rw-r--r--src/ipcpd/broadcast/main.c172
6 files changed, 138 insertions, 181 deletions
diff --git a/src/ipcpd/broadcast/CMakeLists.txt b/src/ipcpd/broadcast/CMakeLists.txt
index afcc8696..6749f660 100644
--- a/src/ipcpd/broadcast/CMakeLists.txt
+++ b/src/ipcpd/broadcast/CMakeLists.txt
@@ -1,34 +1,20 @@
-get_filename_component(CURRENT_SOURCE_PARENT_DIR
- ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)
-get_filename_component(CURRENT_BINARY_PARENT_DIR
- ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY)
+# Broadcast IPCP build configuration
-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)
-
-set(IPCP_BROADCAST_TARGET ipcpd-broadcast CACHE INTERNAL "")
-
-set(SOURCE_FILES
- # Add source files here
+set(BROADCAST_SOURCES
connmgr.c
dt.c
- enroll.c
main.c
- )
+)
+
+add_executable(${IPCP_BROADCAST_TARGET}
+ ${BROADCAST_SOURCES}
+ ${IPCP_SOURCES}
+ ${COMMON_SOURCES}
+)
-add_executable(ipcpd-broadcast ${SOURCE_FILES} ${IPCP_SOURCES}
- ${LAYER_CONFIG_PROTO_SRCS})
-target_link_libraries(ipcpd-broadcast LINK_PUBLIC ouroboros-dev)
+target_include_directories(${IPCP_BROADCAST_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS})
+target_link_libraries(${IPCP_BROADCAST_TARGET} PRIVATE ouroboros-dev)
-include(AddCompileFlags)
-if (CMAKE_BUILD_TYPE MATCHES "Debug*")
- add_compile_flags(ipcpd-broadcast -DCONFIG_OUROBOROS_DEBUG)
-endif ()
+ouroboros_target_debug_definitions(${IPCP_BROADCAST_TARGET})
-install(TARGETS ipcpd-broadcast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
+install(TARGETS ${IPCP_BROADCAST_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR})
diff --git a/src/ipcpd/broadcast/connmgr.c b/src/ipcpd/broadcast/connmgr.c
index b65f48b0..a4d20ee7 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 - 2026
*
* Handles connections between components
*
diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c
index 00476027..30e89a4f 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 - 2026
*
* Forward loop for broadcast
*
@@ -58,14 +58,13 @@ struct nb {
};
struct {
- struct list_head nbs;
- size_t nbs_len;
- pthread_rwlock_t nbs_lock;
+ struct llist nbs;
+ pthread_rwlock_t lock;
- fset_t * set;
+ fset_t * set;
- pthread_t reader;
- pthread_t listener;
+ pthread_t reader;
+ pthread_t listener;
} fwd;
static int dt_add_nb(int fd)
@@ -73,33 +72,32 @@ static int dt_add_nb(int fd)
struct list_head * p;
struct nb * nb;
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each(p, &fwd.nbs) {
+ llist_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;
+ pthread_rwlock_unlock(&fwd.lock);
+ log_warn("Already know neighbor on fd %d.", fd);
+ return 0;
}
}
nb = malloc(sizeof(*nb));
if (nb == NULL) {
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
+ log_err("Failed to malloc neighbor struct.");
return -ENOMEM;
}
nb->fd = fd;
- list_add_tail(&nb->next, p);
+ llist_add_tail(&nb->next, &fwd.nbs);
- ++fwd.nbs_len;
+ pthread_rwlock_unlock(&fwd.lock);
log_dbg("Neighbor %d added.", fd);
- pthread_rwlock_unlock(&fwd.nbs_lock);
-
return 0;
}
@@ -108,21 +106,22 @@ static int dt_del_nb(int fd)
struct list_head * p;
struct list_head * h;
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each_safe(p, h, &fwd.nbs) {
+ llist_for_each_safe(p, h, &fwd.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->fd == fd) {
- list_del(&nb->next);
- --fwd.nbs_len;
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ llist_del(&nb->next, &fwd.nbs);
+ pthread_rwlock_unlock(&fwd.lock);
log_dbg("Neighbor %d deleted.", nb->fd);
free(nb);
return 0;
}
}
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
+
+ log_err("Neighbor not found on fd %d.", fd);
return -EPERM;
}
@@ -154,11 +153,11 @@ static void dt_packet(uint8_t * buf,
{
struct list_head * p;
- pthread_rwlock_rdlock(&fwd.nbs_lock);
+ pthread_rwlock_rdlock(&fwd.lock);
- pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.nbs_lock);
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.lock);
- list_for_each(p, &fwd.nbs) {
+ llist_for_each(p, &fwd.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
if (nb->fd != in_fd)
flow_write(nb->fd, buf, len); /* FIXME: avoid copy. */
@@ -191,7 +190,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 +225,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:
@@ -249,12 +248,12 @@ int dt_init(void)
strcpy(info.comp_name, DT);
strcpy(info.comp_name, DT_COMP);
- list_head_init(&fwd.nbs);
+ llist_init(&fwd.nbs);
if (notifier_reg(handle_event, NULL))
goto fail_notifier_reg;
- if (pthread_rwlock_init(&fwd.nbs_lock, NULL))
+ if (pthread_rwlock_init(&fwd.lock, NULL))
goto fail_lock_init;
fwd.set = fset_create();
@@ -270,8 +269,6 @@ int dt_init(void)
if (connmgr_comp_init(COMPID_DT, &info))
goto fail_connmgr_comp_init;
- fwd.nbs_len = 0;
-
return 0;
fail_connmgr_comp_init:
@@ -283,7 +280,7 @@ int dt_init(void)
fail_pthread_create_reader:
fset_destroy(fwd.set);
fail_fset_create:
- pthread_rwlock_destroy(&fwd.nbs_lock);
+ pthread_rwlock_destroy(&fwd.lock);
fail_lock_init:
notifier_unreg(handle_event);
fail_notifier_reg:
@@ -305,15 +302,15 @@ void dt_fini(void)
fset_destroy(fwd.set);
- pthread_rwlock_wrlock(&fwd.nbs_lock);
+ pthread_rwlock_wrlock(&fwd.lock);
- list_for_each_safe(p, h, &fwd.nbs) {
+ llist_for_each_safe(p, h, &fwd.nbs) {
struct nb * n = list_entry(p, struct nb, next);
- list_del(&n->next);
+ llist_del(&n->next, &fwd.nbs);
free(n);
}
- pthread_rwlock_unlock(&fwd.nbs_lock);
+ pthread_rwlock_unlock(&fwd.lock);
- pthread_rwlock_destroy(&fwd.nbs_lock);
+ pthread_rwlock_destroy(&fwd.lock);
}
diff --git a/src/ipcpd/broadcast/dt.h b/src/ipcpd/broadcast/dt.h
index 4331bd3e..2472831e 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 - 2026
*
* Forward loop for broadcast
*
diff --git a/src/ipcpd/broadcast/enroll.c b/src/ipcpd/broadcast/enroll.c
deleted file mode 100644
index 143f16d5..00000000
--- a/src/ipcpd/broadcast/enroll.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2021
- *
- * Enrollment Task
- *
- * 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/.
- */
-#define BUILD_IPCP_BROADCAST
-
-#include "common/enroll.c"
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 522d1391..b3cbdc79 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 - 2026
*
* Broadcast IPC Process
*
@@ -31,14 +31,15 @@
#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/np1_flow.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"
@@ -52,54 +53,33 @@
#include <assert.h>
#include <inttypes.h>
-struct ipcp ipcpi;
-
-static int initialize_components(const struct ipcp_config * conf)
+static int initialize_components(void)
{
- 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;
-
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 +95,56 @@ 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 ipcp_config * conf;
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.");
+ conf = enroll_get_conf();
+ *info = conf->layer_info;
+
+ if (initialize_components() < 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 (connmgr_dealloc(COMPID_ENROLL, &conn))
- log_warn("Failed to deallocate enrollment flow.");
+ if (enroll_ack(&conn, id, 0) < 0)
+ log_err_id(id, "Failed to confirm enrollment.");
- log_info("Enrolled with %s.", dst);
+ if (connmgr_dealloc(COMPID_ENROLL, &conn) < 0)
+ log_warn_id(id, "Failed to dealloc enrollment flow.");
- info->dir_hash_algo = ipcpi.dir_hash_algo;
- strcpy(info->layer_name, ipcpi.layer_name);
+ log_info_id(id, "Enrolled with %s.", dst);
return 0;
@@ -168,18 +152,19 @@ 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;
}
-static int broadcast_ipcp_bootstrap(const struct ipcp_config * conf)
+static int broadcast_ipcp_bootstrap(struct ipcp_config * conf)
{
assert(conf);
assert(conf->type == THIS_TYPE);
+ assert(conf->layer_info.dir_hash_algo == DIR_HASH_SHA3_256);
enroll_bootstrap(conf);
- if (initialize_components(conf)) {
+ if (initialize_components()) {
log_err("Failed to init IPCP components.");
goto fail_init;
}
@@ -189,8 +174,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:
@@ -203,40 +186,63 @@ static int name_check(const uint8_t * dst)
{
uint8_t * buf;
size_t len;
- int ret;
+ int err;
+ char layer[LAYER_NAME_SIZE + 1];
- len = hash_len(ipcpi.dir_hash_algo);
+ len = ipcp_dir_hash_len();
buf = malloc(len);
- if (buf == NULL)
- return -ENOMEM;
+ if (buf == NULL) {
+ log_err("Failed to malloc buffer.");
+ err = -ENOMEM;
+ goto fail_buf;
+ }
+
+ err = ipcp_get_layer_name(layer);
+ if (err < 0) {
+ log_err("Failed to get layer name.");
+ goto fail_layer;
+ }
- str_hash(ipcpi.dir_hash_algo, buf, ipcpi.layer_name);
+ str_hash(HASH_SHA3_256, buf, layer);
- ret = memcmp(buf, dst, len);
+ if (memcmp(buf, dst, len) < 0) {
+ log_err("Hash mismatch for layer %s.", layer);
+ err = -ENAME;
+ goto fail_layer;
+ }
free(buf);
- return ret;
+ return 0;
+
+ fail_layer:
+ free(buf);
+ fail_buf:
+ return err;
}
static int broadcast_ipcp_join(int fd,
- const uint8_t * dst,
- qosspec_t qs)
+ const uint8_t * dst)
{
+ int err;
struct conn conn;
-
- (void) qs;
+ time_t mpl = IPCP_BROADCAST_MPL;
+ buffer_t data = BUF_INIT;
memset(&conn, 0, sizeof(conn));
conn.flow_info.fd = fd;
+ conn.flow_info.qs = qos_np1;
- if (name_check(dst) != 0)
- return -1;
+ err = name_check(dst);
+ if (err < 0) {
+ log_err("Failed to check name.");
+ return err;
+ }
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 +257,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 +280,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 +299,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 +323,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 +332,5 @@ int main(int argc,
fail_notifier_init:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
exit(EXIT_FAILURE);
}