summaryrefslogtreecommitdiff
path: root/src/ipcpd/broadcast
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/broadcast')
-rw-r--r--src/ipcpd/broadcast/CMakeLists.txt5
-rw-r--r--src/ipcpd/broadcast/comp.h45
-rw-r--r--src/ipcpd/broadcast/connmgr.c496
-rw-r--r--src/ipcpd/broadcast/connmgr.h71
-rw-r--r--src/ipcpd/broadcast/dt.c46
-rw-r--r--src/ipcpd/broadcast/dt.h6
-rw-r--r--src/ipcpd/broadcast/enroll.c363
-rw-r--r--src/ipcpd/broadcast/enroll.h47
-rw-r--r--src/ipcpd/broadcast/main.c142
9 files changed, 97 insertions, 1124 deletions
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/comp.h b/src/ipcpd/broadcast/comp.h
deleted file mode 100644
index 07983978..00000000
--- a/src/ipcpd/broadcast/comp.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2020
- *
- * Components for the broadcast IPC process
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_IPCPD_BROADCAST_COMP_H
-#define OUROBOROS_IPCPD_BROADCAST_COMP_H
-
-#include <ouroboros/cacep.h>
-
-#define DST_MAX_STRLEN 64
-
-enum comp_id {
- COMPID_DT = 0,
- COMPID_ENROLL,
- COMPID_MAX
-};
-
-struct conn {
- struct conn_info conn_info;
- struct {
- char dst[DST_MAX_STRLEN + 1];
- int fd;
- qosspec_t qs;
- } flow_info;
-};
-
-#endif /* OUROBOROS_IPCPD_BROADCAST_COMP_H */
diff --git a/src/ipcpd/broadcast/connmgr.c b/src/ipcpd/broadcast/connmgr.c
index b023584a..f297175d 100644
--- a/src/ipcpd/broadcast/connmgr.c
+++ b/src/ipcpd/broadcast/connmgr.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2020
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Handles connections between components
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * 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
@@ -20,496 +20,16 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
+#include "config.h"
+
#if defined(__linux__) || defined(__CYGWIN__)
#define _DEFAULT_SOURCE
#else
#define _POSIX_C_SOURCE 200112L
#endif
-#define OUROBOROS_PREFIX "connection-manager"
-
-#include <ouroboros/dev.h>
-#include <ouroboros/cacep.h>
-#include <ouroboros/errno.h>
-#include <ouroboros/list.h>
-#include <ouroboros/logs.h>
-#include <ouroboros/notifier.h>
-
-#include "comp.h"
-#include "connmgr.h"
-#include "enroll.h"
-#include "ipcp.h"
-
-#include <pthread.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-enum connmgr_state {
- CONNMGR_NULL = 0,
- CONNMGR_INIT,
- CONNMGR_RUNNING
-};
-
-struct conn_el {
- struct list_head next;
- struct conn conn;
-};
-
-struct comp {
- struct conn_info info;
-
- struct list_head conns;
- struct list_head pending;
-
- pthread_cond_t cond;
- pthread_mutex_t lock;
-};
-
-struct {
- struct comp comps[COMPID_MAX];
- enum connmgr_state state;
-
- pthread_t acceptor;
-} connmgr;
-
-static int get_id_by_name(const char * name)
-{
- enum comp_id i;
-
- for (i = 0; i < COMPID_MAX; ++i)
- if (strcmp(name, connmgr.comps[i].info.comp_name) == 0)
- return i;
-
- return -1;
-}
-
-static int get_conn_by_fd(int fd,
- enum comp_id id,
- struct conn * conn)
-{
- struct list_head * p;
-
- pthread_mutex_lock(&connmgr.comps[id].lock);
-
- list_for_each(p, &connmgr.comps[id].conns) {
- struct conn_el * c =
- list_entry(p, struct conn_el, next);
- if (c->conn.flow_info.fd == fd) {
- *conn = c->conn;
- pthread_mutex_unlock(&connmgr.comps[id].lock);
- return 0;
- }
- }
-
- pthread_mutex_unlock(&connmgr.comps[id].lock);
-
- return -1;
-}
-
-static int add_comp_conn(enum comp_id id,
- int fd,
- qosspec_t qs,
- struct conn_info * rcv_info)
-{
- struct conn_el * el;
-
- el = malloc(sizeof(*el));
- if (el == NULL) {
- log_err("Not enough memory.");
- return -1;
- }
-
- el->conn.conn_info = *rcv_info;
- el->conn.flow_info.fd = fd;
- el->conn.flow_info.qs = qs;
-
- pthread_mutex_lock(&connmgr.comps[id].lock);
-
- list_add(&el->next, &connmgr.comps[id].pending);
- pthread_cond_signal(&connmgr.comps[id].cond);
-
- pthread_mutex_unlock(&connmgr.comps[id].lock);
-
- return 0;
-}
-
-static void * flow_acceptor(void * o)
-{
- int fd;
- qosspec_t qs;
- struct conn_info rcv_info;
- struct conn_info fail_info;
-
- (void) o;
-
- memset(&fail_info, 0, sizeof(fail_info));
-
- while (true) {
- int id;
-
- fd = flow_accept(&qs, NULL);
- if (fd < 0) {
- if (fd != -EIRMD)
- log_warn("Flow accept failed: %d", fd);
- continue;
- }
-
- if (cacep_rcv(fd, &rcv_info)) {
- log_dbg("Error establishing application connection.");
- flow_dealloc(fd);
- continue;
- }
-
- id = get_id_by_name(rcv_info.comp_name);
- if (id < 0) {
- log_dbg("Connection request for unknown component %s.",
- rcv_info.comp_name);
- cacep_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.");
- flow_dealloc(fd);
- continue;
- }
-
- if (add_comp_conn(id, fd, qs, &rcv_info)) {
- log_dbg("Failed to add new connection.");
- flow_dealloc(fd);
- continue;
- }
- }
-
- return (void *) 0;
-}
-
-static void handle_event(void * self,
- int event,
- const void * o)
-{
- struct conn conn;
-
- (void) self;
-
- if (!(event == NOTIFY_DT_FLOW_UP ||
- event == NOTIFY_DT_FLOW_DOWN ||
- event == NOTIFY_DT_FLOW_DEALLOC))
- return;
-
- if (get_conn_by_fd(*((int *) o), COMPID_DT, &conn))
- return;
-
- switch (event) {
- case NOTIFY_DT_FLOW_UP:
- notifier_event(NOTIFY_DT_CONN_UP, &conn);
- break;
- case NOTIFY_DT_FLOW_DOWN:
- notifier_event(NOTIFY_DT_CONN_DOWN, &conn);
- break;
- case NOTIFY_DT_FLOW_DEALLOC:
- notifier_event(NOTIFY_DT_CONN_DEL, &conn);
- break;
- default:
- break;
- }
-}
-
-int connmgr_init(void)
-{
- connmgr.state = CONNMGR_INIT;
-
- if (notifier_reg(handle_event, NULL))
- return -1;
-
- return 0;
-}
-
-void connmgr_fini(void)
-{
- int i;
-
- notifier_unreg(handle_event);
-
- if (connmgr.state == CONNMGR_RUNNING)
- pthread_join(connmgr.acceptor, NULL);
-
- for (i = 0; i < COMPID_MAX; ++i)
- connmgr_comp_fini(i);
-}
-
-int connmgr_start(void)
-{
- if (pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL))
- return -1;
-
- connmgr.state = CONNMGR_RUNNING;
-
- return 0;
-}
-
-void connmgr_stop(void)
-{
- if (connmgr.state == CONNMGR_RUNNING)
- pthread_cancel(connmgr.acceptor);
-}
-
-int connmgr_comp_init(enum comp_id id,
- const struct conn_info * info)
-{
- struct comp * comp;
-
- assert(id >= 0 && id < COMPID_MAX);
-
- comp = connmgr.comps + id;
-
- if (pthread_mutex_init(&comp->lock, NULL))
- return -1;
-
- if (pthread_cond_init(&comp->cond, NULL)) {
- pthread_mutex_destroy(&comp->lock);
- return -1;
- }
-
- list_head_init(&comp->conns);
- list_head_init(&comp->pending);
-
- memcpy(&connmgr.comps[id].info, info, sizeof(connmgr.comps[id].info));
-
- return 0;
-}
-
-void connmgr_comp_fini(enum comp_id id)
-{
- struct list_head * p;
- struct list_head * h;
- struct comp * comp;
-
- assert(id >= 0 && id < COMPID_MAX);
-
- if (strlen(connmgr.comps[id].info.comp_name) == 0)
- return;
-
- comp = connmgr.comps + id;
-
- pthread_mutex_lock(&comp->lock);
-
- list_for_each_safe(p, h, &comp->conns) {
- struct conn_el * e = list_entry(p, struct conn_el, next);
- list_del(&e->next);
- free(e);
- }
-
- list_for_each_safe(p, h, &comp->pending) {
- struct conn_el * e = list_entry(p, struct conn_el, next);
- list_del(&e->next);
- free(e);
- }
-
- pthread_mutex_unlock(&comp->lock);
-
- pthread_cond_destroy(&comp->cond);
- pthread_mutex_destroy(&comp->lock);
-
- memset(&connmgr.comps[id].info, 0, sizeof(connmgr.comps[id].info));
-}
-
-int connmgr_ipcp_connect(const char * dst,
- const char * component,
- qosspec_t qs)
-{
- struct conn_el * ce;
- int id;
-
- assert(dst);
- assert(component);
-
- ce = malloc(sizeof(*ce));
- if (ce == NULL) {
- log_dbg("Out of memory.");
- return -1;
- }
-
- id = get_id_by_name(component);
- if (id < 0) {
- log_dbg("No such component: %s", component);
- free(ce);
- return -1;
- }
-
- if (connmgr_alloc(id, dst, &qs, &ce->conn)) {
- free(ce);
- return -1;
- }
-
- if (strlen(dst) > DST_MAX_STRLEN) {
- log_warn("Truncating dst length for connection.");
- memcpy(ce->conn.flow_info.dst, dst, DST_MAX_STRLEN);
- ce->conn.flow_info.dst[DST_MAX_STRLEN] = '\0';
- } else {
- strcpy(ce->conn.flow_info.dst, dst);
- }
-
- pthread_mutex_lock(&connmgr.comps[id].lock);
-
- list_add(&ce->next, &connmgr.comps[id].conns);
-
- pthread_mutex_unlock(&connmgr.comps[id].lock);
-
- return 0;
-}
-
-int connmgr_ipcp_disconnect(const char * dst,
- const char * component)
-{
- struct list_head * p;
- struct list_head * h;
- int id;
-
- assert(dst);
- assert(component);
-
- id = get_id_by_name(component);
- if (id < 0)
- return -1;
-
- pthread_mutex_lock(&connmgr.comps[id].lock);
-
- list_for_each_safe(p,h, &connmgr.comps[id].conns) {
- struct conn_el * el = list_entry(p, struct conn_el, next);
- if (strcmp(el->conn.flow_info.dst, dst) == 0) {
- int ret;
- pthread_mutex_unlock(&connmgr.comps[id].lock);
- list_del(&el->next);
- ret = connmgr_dealloc(id, &el->conn);
- free(el);
- return ret;
- }
- }
-
- pthread_mutex_unlock(&connmgr.comps[id].lock);
-
- return 0;
-}
-
-int connmgr_alloc(enum comp_id id,
- const char * dst,
- qosspec_t * qs,
- struct conn * conn)
-{
- 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;
- }
-
- 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);
-
- 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;
- }
-
- 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 (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 (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 (connmgr.comps[id].info.pref_syntax != conn->conn_info.pref_syntax) {
- log_dbg("Unknown protocol syntax.");
- flow_dealloc(conn->flow_info.fd);
- return -1;
- }
-
- switch (id) {
- case COMPID_DT:
- notifier_event(NOTIFY_DT_CONN_ADD, conn);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-int connmgr_dealloc(enum comp_id id,
- struct conn * conn)
-{
- switch (id) {
- case COMPID_DT:
- notifier_event(NOTIFY_DT_CONN_DEL, conn);
- break;
- default:
- break;
- }
-
- return flow_dealloc(conn->flow_info.fd);
-}
-
-
-int connmgr_wait(enum comp_id id,
- struct conn * conn)
-{
- struct conn_el * el;
- struct comp * comp;
-
- assert(id >= 0 && id < COMPID_MAX);
- assert(conn);
-
- comp = connmgr.comps + id;
-
- pthread_mutex_lock(&comp->lock);
-
- pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,
- (void *) &comp->lock);
-
- while (list_is_empty(&comp->pending))
- pthread_cond_wait(&comp->cond, &comp->lock);
-
- pthread_cleanup_pop(false);
-
- el = list_first_entry((&comp->pending), struct conn_el, next);
- if (el == NULL) {
- pthread_mutex_unlock(&comp->lock);
- return -1;
- }
-
- *conn = el->conn;
-
- list_del(&el->next);
- list_add(&el->next, &connmgr.comps[id].conns);
+#include <ouroboros/ipcp.h>
- pthread_mutex_unlock(&comp->lock);
+#define BUILD_IPCP_BROADCAST
- return 0;
-}
+#include "common/connmgr.c"
diff --git a/src/ipcpd/broadcast/connmgr.h b/src/ipcpd/broadcast/connmgr.h
deleted file mode 100644
index 019056f2..00000000
--- a/src/ipcpd/broadcast/connmgr.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2020
- *
- * Handles the different AP connections
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_IPCPD_BROADCAST_CONNMGR_H
-#define OUROBOROS_IPCPD_BROADCAST_CONNMGR_H
-
-#include <ouroboros/cacep.h>
-#include <ouroboros/qos.h>
-
-#include "comp.h"
-
-#define NOTIFY_DT_CONN_ADD 0x00D0
-#define NOTIFY_DT_CONN_DEL 0x00D1
-#define NOTIFY_DT_CONN_QOS 0x00D2
-#define NOTIFY_DT_CONN_UP 0x00D3
-#define NOTIFY_DT_CONN_DOWN 0x00D4
-#define NOTIFY_DT_FLOW_UP 0x00D5
-#define NOTIFY_DT_FLOW_DOWN 0x00D6
-#define NOTIFY_DT_FLOW_DEALLOC 0x00D7
-
-int connmgr_init(void);
-
-void connmgr_fini(void);
-
-int connmgr_start(void);
-
-void connmgr_stop(void);
-
-int connmgr_comp_init(enum comp_id id,
- const struct conn_info * info);
-
-void connmgr_comp_fini(enum comp_id id);
-
-int connmgr_ipcp_connect(const char * dst,
- const char * component,
- qosspec_t qs);
-
-int connmgr_ipcp_disconnect(const char * dst,
- const char * component);
-
-int connmgr_alloc(enum comp_id id,
- const char * dst,
- qosspec_t * qs,
- struct conn * conn);
-
-int connmgr_dealloc(enum comp_id id,
- struct conn * conn);
-
-int connmgr_wait(enum comp_id id,
- struct conn * conn);
-
-#endif /* OUROBOROS_IPCPD_BROADCAST_CONNMGR_H */
diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c
index 6e8bacf1..938c9085 100644
--- a/src/ipcpd/broadcast/dt.c
+++ b/src/ipcpd/broadcast/dt.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2020
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Forward loop for broadcast
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * 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
@@ -33,7 +33,6 @@
#define DT "dt"
#define OUROBOROS_PREFIX DT
-#include <ouroboros/endian.h>
#include <ouroboros/dev.h>
#include <ouroboros/errno.h>
#include <ouroboros/fqueue.h>
@@ -41,17 +40,16 @@
#include <ouroboros/logs.h>
#include <ouroboros/notifier.h>
#include <ouroboros/utils.h>
+#include <ouroboros/pthread.h>
-#include "comp.h"
-#include "connmgr.h"
+#include "common/comp.h"
+#include "common/connmgr.h"
#include "dt.h"
-#include "ipcp.h"
#include <assert.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
-#include <pthread.h>
struct nb {
struct list_head next;
@@ -80,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;
}
@@ -98,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;
}
@@ -126,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;
}
@@ -158,8 +159,7 @@ static void dt_packet(uint8_t * buf,
pthread_rwlock_rdlock(&fwd.nbs_lock);
- pthread_cleanup_push((void (*))(void *) pthread_rwlock_unlock,
- &fwd.nbs_lock);
+ pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.nbs_lock);
list_for_each(p, &fwd.nbs) {
struct nb * nb = list_entry(p, struct nb, next);
@@ -170,6 +170,11 @@ static void dt_packet(uint8_t * buf,
pthread_cleanup_pop(true);
}
+static void __cleanup_fqueue_destroy(void * fq)
+{
+ fqueue_destroy((fqueue_t *) fq);
+}
+
static void * dt_reader(void * o)
{
fqueue_t * fq;
@@ -184,13 +189,12 @@ static void * dt_reader(void * o)
if (fq == NULL)
return (void *) -1;
- pthread_cleanup_push((void (*) (void *)) fqueue_destroy,
- (void *) fq);
+ pthread_cleanup_push(__cleanup_fqueue_destroy, (void *) fq);
while (true) {
ret = fevent(fwd.set, fq, NULL);
if (ret < 0) {
- log_warn("Event error: %d.", ret);
+ log_warn("Event warning: %d.", ret);
continue;
}
@@ -225,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 e573511c..8d3b83f8 100644
--- a/src/ipcpd/broadcast/dt.h
+++ b/src/ipcpd/broadcast/dt.h
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2020
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Forward loop for broadcast
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * 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
diff --git a/src/ipcpd/broadcast/enroll.c b/src/ipcpd/broadcast/enroll.c
deleted file mode 100644
index 511892b7..00000000
--- a/src/ipcpd/broadcast/enroll.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2020
- *
- * Enrollment Task
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#if defined(__linux__) || defined(__CYGWIN__)
-#define _DEFAULT_SOURCE
-#else
-#define _POSIX_C_SOURCE 199309L
-#endif
-
-#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 "connmgr.h"
-#include "enroll.h"
-#include "ipcp.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#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
-#define ENROLL_BUF_LEN 1024
-
-enum enroll_state {
- ENROLL_NULL = 0,
- ENROLL_INIT,
- ENROLL_RUNNING
-};
-
-struct {
- struct ipcp_config conf;
- enum enroll_state state;
- pthread_t listener;
-} enroll;
-
-static int send_rcv_enroll_msg(int fd)
-{
- 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);
-
- 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;
- }
-
- if (reply->code != ENROLL_CODE__ENROLL_BOOT) {
- log_dbg("Failed to unpack enrollment response.");
- enroll_msg__free_unpacked(reply, NULL);
- return -1;
- }
-
- if (!(reply->has_t_sec && reply->has_t_nsec)) {
- log_dbg("No time in response message.");
- enroll_msg__free_unpacked(reply, NULL);
- return -1;
- }
-
- clock_gettime(CLOCK_REALTIME, &rtt);
-
- delta_t = ts_diff_ms(&t0, &rtt);
-
- rtt.tv_sec = reply->t_sec;
- rtt.tv_nsec = reply->t_nsec;
-
- 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.layer_info.dir_hash_algo
- = reply->conf->layer_info->dir_hash_algo;
-
- enroll_msg__free_unpacked(reply, NULL);
-
- return 0;
-}
-
-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;
-
- 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;
- config.layer_info = &layer_info;
-
- layer_info.layer_name = (char *) enroll.conf.layer_info.layer_name;
- layer_info.dir_hash_algo = enroll.conf.layer_info.dir_hash_algo;
-
- len = enroll_msg__get_packed_size(&msg);
-
- *buf = malloc(len);
- if (*buf == NULL)
- return -1;
-
- enroll_msg__pack(&msg, *buf);
-
- return 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;
-
- (void) o;
-
- while (true) {
- if (connmgr_wait(COMPID_ENROLL, &conn)) {
- log_err("Failed to get next connection.");
- continue;
- }
-
- 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;
- }
-
- msg = enroll_msg__unpack(NULL, len, buf);
- if (msg == NULL) {
- log_err("Failed to unpack message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
-
- if (msg->code != ENROLL_CODE__ENROLL_REQ) {
- log_err("Wrong message type.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- enroll_msg__free_unpacked(msg, NULL);
- continue;
- }
-
- 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;
- }
-
- log_dbg("Sending enrollment info (%zd bytes).", len);
-
- 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;
- }
-
- free(reply);
-
- 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;
- }
-
- msg = enroll_msg__unpack(NULL, len, buf);
- if (msg == NULL) {
- log_err("Failed to unpack message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
-
- 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;
- }
-
- if (msg->result == 0)
- log_dbg("Neighbor enrollment successful.");
- else
- log_dbg("Neigbor reported failed enrollment.");
-
- enroll_msg__free_unpacked(msg, NULL);
-
- connmgr_dealloc(COMPID_ENROLL, &conn);
- }
-
- return 0;
-}
-
-int enroll_boot(struct conn * conn)
-{
- log_dbg("Getting boot information.");
-
- if (send_rcv_enroll_msg(conn->flow_info.fd)) {
- log_err("Failed to enroll.");
- return -1;
- }
-
- return 0;
-}
-
-int enroll_done(struct conn * conn,
- int result)
-{
- enroll_msg_t msg = ENROLL_MSG__INIT;
- uint8_t buf[ENROLL_BUF_LEN];
- ssize_t len;
-
- msg.code = ENROLL_CODE__ENROLL_DONE;
- msg.has_result = true;
- msg.result = result;
-
- len = enroll_msg__get_packed_size(&msg);
- if (len < 0) {
- log_dbg("Failed pack request message.");
- return -1;
- }
-
- enroll_msg__pack(&msg, buf);
-
- if (flow_write(conn->flow_info.fd, buf, len) < 0) {
- log_dbg("Failed to send acknowledgment.");
- return -1;
- }
-
- return 0;
-}
-
-void enroll_bootstrap(const struct ipcp_config * conf)
-{
- assert(conf);
-
- memcpy(&enroll.conf, conf, sizeof(enroll.conf));
-}
-
-struct ipcp_config * enroll_get_conf(void)
-{
- return &enroll.conf;
-}
-
-int enroll_init(void)
-{
- struct conn_info info;
-
- memset(&info, 0, sizeof(info));
-
- strcpy(info.comp_name, ENROLL_COMP);
- strcpy(info.protocol, ENROLL_PROTO);
- info.pref_version = 1;
- info.pref_syntax = PROTO_GPB;
- info.addr = 0;
-
- if (connmgr_comp_init(COMPID_ENROLL, &info)) {
- log_err("Failed to register with connmgr.");
- return -1;
- }
-
- enroll.state = ENROLL_INIT;
-
- return 0;
-}
-
-void enroll_fini(void)
-{
- if (enroll.state == ENROLL_RUNNING)
- pthread_join(enroll.listener, NULL);
-
- connmgr_comp_fini(COMPID_ENROLL);
-}
-
-int enroll_start(void)
-{
- if (pthread_create(&enroll.listener, NULL, enroll_handle, NULL))
- return -1;
-
- enroll.state = ENROLL_RUNNING;
-
- return 0;
-}
-
-void enroll_stop(void)
-{
- if (enroll.state == ENROLL_RUNNING)
- pthread_cancel(enroll.listener);
-}
diff --git a/src/ipcpd/broadcast/enroll.h b/src/ipcpd/broadcast/enroll.h
deleted file mode 100644
index 837e0a28..00000000
--- a/src/ipcpd/broadcast/enroll.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2020
- *
- * Enrollment Task
- *
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_IPCPD_BROADCAST_ENROLL_H
-#define OUROBOROS_IPCPD_BROADCAST_ENROLL_H
-
-#include <ouroboros/ipcp.h>
-
-#include "comp.h"
-
-int enroll_init(void);
-
-void enroll_fini(void);
-
-int enroll_start(void);
-
-void enroll_stop(void);
-
-void enroll_bootstrap(const struct ipcp_config * conf);
-
-int enroll_boot(struct conn * conn);
-
-int enroll_done(struct conn * conn,
- int result);
-
-struct ipcp_config * enroll_get_conf(void);
-
-#endif /* OUROBOROS_IPCPD_BROADCAST_ENROLL_H */
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 120b2bf1..f51fc629 100644
--- a/src/ipcpd/broadcast/main.c
+++ b/src/ipcpd/broadcast/main.c
@@ -1,10 +1,10 @@
/*
- * Ouroboros - Copyright (C) 2016 - 2020
+ * Ouroboros - Copyright (C) 2016 - 2024
*
* Broadcast IPC Process
*
- * Dimitri Staessens <dimitri.staessens@ugent.be>
- * Sander Vrijders <sander.vrijders@ugent.be>
+ * 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
@@ -29,19 +29,20 @@
#include "config.h"
#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 "connmgr.h"
+#include "common/connmgr.h"
+#include "common/enroll.h"
#include "dt.h"
-#include "enroll.h"
#include "ipcp.h"
#include <stdbool.h>
@@ -51,54 +52,38 @@
#include <assert.h>
#include <inttypes.h>
-#define THIS_TYPE IPCP_BROADCAST
+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;
}
@@ -114,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;
@@ -167,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;
}
@@ -175,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);
@@ -188,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:
@@ -223,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;
@@ -230,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;
}
@@ -250,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,
@@ -273,17 +264,11 @@ static struct ipcp_ops broadcast_ops = {
int main(int argc,
char * argv[])
{
- if (ipcp_init(argc, argv, &broadcast_ops) < 0) {
- log_err("Failed to init IPCP.");
+ if (ipcp_init(argc, argv, &broadcast_ops, THIS_TYPE) < 0) {
+ log_err("Failed to initialize IPCP.");
goto fail_init;
}
- /* These components must be init at creation. */
- if (rib_init(ipcpi.name)) {
- log_err("Failed to initialize RIB.");
- goto fail_rib_init;
- }
-
if (notifier_init()) {
log_err("Failed to initialize notifier component.");
goto fail_notifier_init;
@@ -299,49 +284,38 @@ 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();
notifier_fini();
- rib_fini();
-
ipcp_fini();
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:
- rib_fini();
- fail_rib_init:
ipcp_fini();
fail_init:
- ipcp_create_r(-1);
exit(EXIT_FAILURE);
}