summaryrefslogtreecommitdiff
path: root/src/ipcpd/common
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2023-03-04 03:48:48 +0100
committerSander Vrijders <sander@ouroboros.rocks>2023-03-08 15:59:37 +0100
commit89b58eaa2706c54aeb0a48252d1cfbd2b5ae01b7 (patch)
tree891c4a2de37e06fdb8879741911a6b7ff2f1b4b8 /src/ipcpd/common
parentf16b4a1954ab4fbca0ec403f6a04c80375328921 (diff)
downloadouroboros-89b58eaa2706c54aeb0a48252d1cfbd2b5ae01b7.tar.gz
ouroboros-89b58eaa2706c54aeb0a48252d1cfbd2b5ae01b7.zip
irmd: Add configuration file support
This adds initial support for configuration files using the C99 TOML parser (to be installed separately from https://github.com/cktan/tomlc99). The default location for the IRMd configuration file is /etc/ouroboros/irmd.conf. This is configurable at build time. An example file will be installed in the configuration directory with the name irmd.conf.example. Config file support can be disabled using the DISABLE_CONFIGFILE build option. There were some refactors and changes to the configuration messages and protobuf files. This works towards consolidation of protobuf C as an option for more generic handling of serialization/deserialization of various messages. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/ipcpd/common')
-rw-r--r--src/ipcpd/common/enroll.c241
-rw-r--r--src/ipcpd/common/enroll.h4
2 files changed, 92 insertions, 153 deletions
diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c
index 745829e7..32a5ed93 100644
--- a/src/ipcpd/common/enroll.c
+++ b/src/ipcpd/common/enroll.c
@@ -34,7 +34,7 @@
#include <ouroboros/dev.h>
#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
-#include <ouroboros/sockets.h>
+#include <ouroboros/serdes-oep.h>
#include "common/connmgr.h"
#include "common/enroll.h"
@@ -45,9 +45,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
@@ -67,56 +64,60 @@ struct {
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;
-#ifdef BUILD_IPCP_UNICAST
- uni_config_msg_t * uni_cfg_msg;
-#endif
- req.code = ENROLL_CODE__ENROLL_REQ;
-
- len = enroll_msg__get_packed_size(&req);
+ 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 ret;
+ struct enroll_resp resp;
+
+ buf.data = __buf;
+ buf.len = sizeof(__buf);
+
+ len = enroll_req_ser(buf);
if (len < 0) {
- log_dbg("Failed pack request message.");
+ log_dbg("Failed to pack request message.");
return -1;
}
- enroll_msg__pack(&req, buf);
-
clock_gettime(CLOCK_REALTIME, &t0);
- if (flow_write(fd, buf, len) < 0) {
+ log_dbg("Sending request message.");
+
+ if (flow_write(fd, buf.data, len) < 0) {
log_dbg("Failed to send request message.");
return -1;
}
- len = flow_read(fd, buf, ENROLL_BUF_LEN);
+ log_dbg("Waiting for reply message.");
+
+ len = flow_read(fd, buf.data, buf.len);
if (len < 0) {
- log_dbg("No enrollment reply received.");
+ log_dbg("No reply received.");
return -1;
}
- log_dbg("Received enrollment info (%zd bytes).", len);
+ log_dbg("Received configuration info (%zd bytes).", len);
+
+ msg.data = buf.data;
+ msg.len = len;
- reply = enroll_msg__unpack(NULL, len, buf);
- if (reply == NULL) {
- log_dbg("No enrollment response.");
+ ret = enroll_resp_des(&resp, msg);
+ if (ret < 0) {
+ log_dbg("Failed to unpack response message.");
return -1;
}
- if (reply->code != ENROLL_CODE__ENROLL_BOOT) {
- log_dbg("Failed to unpack enrollment response.");
- enroll_msg__free_unpacked(reply, NULL);
+ if (resp.response < 0) {
+ log_dbg("Remote denied request: %d.", resp.response);
return -1;
}
- if (!(reply->has_t_sec && reply->has_t_nsec)) {
- log_dbg("No time in response message.");
- enroll_msg__free_unpacked(reply, NULL);
+ if (resp.conf.type != ipcpi.type) {
+ log_dbg("Wrong type in enrollment response %d (%d).", resp.conf.type, ipcpi.type);
return -1;
}
@@ -124,168 +125,107 @@ static int send_rcv_enroll_msg(int fd)
delta_t = ts_diff_ms(&t0, &rtt);
- rtt.tv_sec = reply->t_sec;
- rtt.tv_nsec = reply->t_nsec;
+ 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("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
- uni_cfg_msg = reply->conf->unicast;
-
- enroll.conf.unicast.dt.addr_size = uni_cfg_msg->dt->addr_size;
- enroll.conf.unicast.dt.eid_size = uni_cfg_msg->dt->eid_size;
- enroll.conf.unicast.dt.max_ttl = uni_cfg_msg->dt->max_ttl;
- enroll.conf.unicast.dt.routing_type = uni_cfg_msg->dt->routing_type;
- enroll.conf.unicast.addr_auth_type = uni_cfg_msg->addr_auth_type;
- enroll.conf.unicast.cong_avoid = uni_cfg_msg->cong_avoid;
-#endif
- enroll.conf.layer_info.dir_hash_algo
- = reply->conf->layer_info->dir_hash_algo;
- enroll_msg__free_unpacked(reply, NULL);
+ enroll.conf = resp.conf;
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;
-#ifdef BUILD_IPCP_UNICAST
- dt_config_msg_t dt_cfg_msg = DT_CONFIG_MSG__INIT;
- uni_config_msg_t uni_cfg_msg = UNI_CONFIG_MSG__INIT;
-#endif
- 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;
-
- config.ipcp_type = enroll.conf.type;
-#ifdef BUILD_IPCP_UNICAST
- dt_cfg_msg.addr_size = enroll.conf.unicast.dt.addr_size;
- dt_cfg_msg.eid_size = enroll.conf.unicast.dt.eid_size;
- dt_cfg_msg.max_ttl = enroll.conf.unicast.dt.max_ttl;
- dt_cfg_msg.routing_type = enroll.conf.unicast.dt.routing_type;
- uni_cfg_msg.dt = &dt_cfg_msg;
- uni_cfg_msg.addr_auth_type = enroll.conf.unicast.addr_auth_type;
- uni_cfg_msg.cong_avoid = enroll.conf.unicast.cong_avoid;
- config.unicast = &uni_cfg_msg;
-#endif
- layer_info.layer_name = (char *) enroll.conf.layer_info.layer_name;
- layer_info.dir_hash_algo = enroll.conf.layer_info.dir_hash_algo;
-
- config.layer_info = &layer_info;
- msg.conf = &config;
-
- len = enroll_msg__get_packed_size(&msg);
-
- *buf = malloc(len);
- if (*buf == NULL)
- return -ENOMEM;
-
- 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;
+ struct enroll_resp resp;
+ struct conn conn;
+ uint8_t __buf[ENROLL_BUF_LEN];
+ buffer_t buf;
+ ssize_t len;
+ int response;
(void) o;
+ buf.data = __buf;
+ buf.len = sizeof(__buf);
+
+ resp.conf = enroll.conf;
+
while (true) {
+ buffer_t msg;
+
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);
+ log_info("New enrollment connection.");
+
+ 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;
}
- msg = enroll_msg__unpack(NULL, len, buf);
- if (msg == NULL) {
- log_err("Failed to unpack message.");
- connmgr_dealloc(COMPID_ENROLL, &conn);
- continue;
- }
+ log_dbg("Read request from flow (%zd bytes).", len);
+ msg.data = buf.data;
+ msg.len = (size_t) len;
- if (msg->code != ENROLL_CODE__ENROLL_REQ) {
- log_err("Wrong message type.");
+ if (enroll_req_des(msg) < 0) {
+ log_err("Failed to unpack request message.");
connmgr_dealloc(COMPID_ENROLL, &conn);
- enroll_msg__free_unpacked(msg, NULL);
continue;
}
+ /* TODO: authentication */
+
log_dbg("Enrolling a new neighbor.");
- enroll_msg__free_unpacked(msg, NULL);
+ clock_gettime(CLOCK_REALTIME, &resp.t);
- len = enroll_pack(&reply);
+ resp.response = 0;
+
+ len = enroll_resp_ser(&resp, buf);
if (len < 0) {
- log_err("Failed to pack enrollment message.");
+ log_err("Failed to pack reply.");
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.");
+ if (flow_write(conn.flow_info.fd, buf.data, len) < 0) {
+ log_err("Failed respond to request.");
connmgr_dealloc(COMPID_ENROLL, &conn);
- free(reply);
continue;
}
- free(reply);
-
- 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;
}
- 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_DONE || !msg->has_result) {
- log_err("Wrong message type.");
- enroll_msg__free_unpacked(msg, NULL);
+ if (enroll_ack_des(&response, msg) < 0) {
+ log_err("Failed to unpack acknowledgment.");
connmgr_dealloc(COMPID_ENROLL, &conn);
continue;
}
-
- if (msg->result == 0)
- log_dbg("Neighbor enrollment successful.");
+ if (response == 0)
+ log_info("Neighbor enrollment successful.");
else
- log_dbg("Neigbor reported failed enrollment.");
-
- enroll_msg__free_unpacked(msg, NULL);
+ log_info("Neigbor enrolment failed at remote.");
connmgr_dealloc(COMPID_ENROLL, &conn);
+
+ log_info("Enrollment connection closed.");
}
return 0;
@@ -293,36 +233,35 @@ static void * enroll_handle(void * o)
int enroll_boot(struct conn * conn)
{
- log_dbg("Getting boot information.");
+ log_dbg("Starting enrollment.");
if (send_rcv_enroll_msg(conn->flow_info.fd)) {
log_err("Failed to enroll.");
return -1;
}
+ log_dbg("Enrollment complete.");
+
return 0;
}
-int enroll_done(struct conn * conn,
- int result)
+int enroll_ack(struct conn * conn,
+ int result)
{
- enroll_msg_t msg = ENROLL_MSG__INIT;
- uint8_t buf[ENROLL_BUF_LEN];
- ssize_t len;
+ 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);
+ len = enroll_ack_ser(result, buf);
if (len < 0) {
- log_dbg("Failed pack request message.");
+ log_err("Failed to pack acknowledgement.");
return -1;
}
- enroll_msg__pack(&msg, buf);
-
- if (flow_write(conn->flow_info.fd, buf, len) < 0) {
+ if (flow_write(conn->flow_info.fd, buf.data, len) < 0) {
log_dbg("Failed to send acknowledgment.");
return -1;
}
diff --git a/src/ipcpd/common/enroll.h b/src/ipcpd/common/enroll.h
index bbb84561..fa22923f 100644
--- a/src/ipcpd/common/enroll.h
+++ b/src/ipcpd/common/enroll.h
@@ -39,8 +39,8 @@ void enroll_bootstrap(const struct ipcp_config * conf);
int enroll_boot(struct conn * conn);
-int enroll_done(struct conn * conn,
- int result);
+int enroll_ack(struct conn * conn,
+ int result);
struct ipcp_config * enroll_get_conf(void);