summaryrefslogtreecommitdiff
path: root/src/ipcpd
diff options
context:
space:
mode:
authorDimitri Staessens <[email protected]>2023-02-12 21:05:40 +0100
committerSander Vrijders <[email protected]>2023-02-13 21:10:11 +0100
commit269f25d3bac5ab871d8044935eacc15cfeadeec6 (patch)
treed68cba31a7a4b941658836d0c0d616fc7ec6400b /src/ipcpd
parentc3814fa77eb7afbe6e798ded0fdff2df74ad8642 (diff)
downloadouroboros-269f25d3bac5ab871d8044935eacc15cfeadeec6.tar.gz
ouroboros-269f25d3bac5ab871d8044935eacc15cfeadeec6.zip
ipcpd: refactor IPCP configuration
The ipcp configuration struct now has internal structures for the different IPCPs and for IPCP components of the unicast IPCP. Split the very long IPCP main loop into individual handler functions. Signed-off-by: Dimitri Staessens <[email protected]> Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src/ipcpd')
-rw-r--r--src/ipcpd/broadcast/main.c16
-rw-r--r--src/ipcpd/common/enroll.c50
-rw-r--r--src/ipcpd/eth/eth.c31
-rw-r--r--src/ipcpd/ipcp.c631
-rw-r--r--src/ipcpd/ipcp.h2
-rw-r--r--src/ipcpd/local/main.c6
-rw-r--r--src/ipcpd/udp/main.c48
-rw-r--r--src/ipcpd/unicast/dt.c17
-rw-r--r--src/ipcpd/unicast/dt.h6
-rw-r--r--src/ipcpd/unicast/main.c22
10 files changed, 423 insertions, 406 deletions
diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c
index 2b8b90a5..d0becc63 100644
--- a/src/ipcpd/broadcast/main.c
+++ b/src/ipcpd/broadcast/main.c
@@ -56,36 +56,24 @@ 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;
- }
-
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo;
assert(ipcp_dir_hash_len() != 0);
if (dt_init()) {
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)
diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c
index c71dc4cc..745829e7 100644
--- a/src/ipcpd/common/enroll.c
+++ b/src/ipcpd/common/enroll.c
@@ -74,7 +74,9 @@ static int send_rcv_enroll_msg(int fd)
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);
@@ -132,12 +134,14 @@ static int send_rcv_enroll_msg(int fd)
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;
+ 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;
@@ -151,6 +155,10 @@ 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;
@@ -161,28 +169,24 @@ static ssize_t enroll_pack(uint8_t ** buf)
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.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;
+ 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
- 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;
+ config.layer_info = &layer_info;
+ msg.conf = &config;
+
len = enroll_msg__get_packed_size(&msg);
*buf = malloc(len);
diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c
index 582351f8..6e0cb179 100644
--- a/src/ipcpd/eth/eth.c
+++ b/src/ipcpd/eth/eth.c
@@ -1281,31 +1281,27 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
- if (conf->dev == NULL) {
+ if (conf->eth.dev == NULL) {
log_err("Device name is NULL.");
return -1;
}
- 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) {
+ if (conf->eth.ethertype < 0x0600 || conf->eth.ethertype == 0xFFFF) {
log_err("Invalid Ethertype.");
return -1;
}
- eth_data.ethertype = htons(conf->ethertype);
+ eth_data.ethertype = htons(conf->eth.ethertype);
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
@@ -1315,9 +1311,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,
@@ -1352,7 +1348,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;
@@ -1376,7 +1373,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;
@@ -1386,7 +1383,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) {
@@ -1526,7 +1523,7 @@ static int eth_ipcp_bootstrap(const struct ipcp_config * conf)
#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());
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index de68f2f2..1e777637 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -261,23 +261,329 @@ static void free_msg(void * o)
ipcp_msg__free_unpacked((ipcp_msg_t *) o, NULL);
}
+
+static void handle_bootstrap(ipcp_config_msg_t * conf_msg,
+ layer_info_msg_t * layer_info_msg,
+ ipcp_msg_t * ret_msg)
+{
+ struct ipcp_config conf;
+ enum ipcp_type ipcp_type;
+ uni_config_msg_t * uni_cfg_msg;
+
+ if (ipcpi.ops->ipcp_bootstrap == NULL) {
+ log_err("Bootstrap unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ conf.type = conf_msg->ipcp_type;
+
+ strcpy(conf.layer_info.layer_name, conf_msg->layer_info->layer_name);
+
+ ipcp_type = conf_msg->ipcp_type;
+
+ switch(ipcp_type) {
+ case IPCP_LOCAL:
+ break;
+ case IPCP_UNICAST:
+ uni_cfg_msg = conf_msg->unicast;
+
+ conf.unicast.dt.addr_size = uni_cfg_msg->dt->addr_size;
+ conf.unicast.dt.eid_size = uni_cfg_msg->dt->eid_size;
+ conf.unicast.dt.max_ttl = uni_cfg_msg->dt->max_ttl;
+ conf.unicast.dt.routing_type = uni_cfg_msg->dt->routing_type;
+ conf.unicast.addr_auth_type = uni_cfg_msg->addr_auth_type;
+ conf.unicast.cong_avoid = uni_cfg_msg->cong_avoid;
+ break;
+ case IPCP_ETH_DIX:
+ conf.eth.ethertype = conf_msg->eth->ethertype;
+ /* FALLTHRU */
+ case IPCP_ETH_LLC:
+ conf.eth.dev = conf_msg->eth->dev;
+ break;
+ case IPCP_UDP:
+ conf.udp.ip_addr = conf_msg->udp->ip_addr;
+ conf.udp.dns_addr = conf_msg->udp->dns_addr;
+ conf.udp.port = conf_msg->udp->port;
+ conf.layer_info.dir_hash_algo = HASH_MD5;
+ break;
+ case IPCP_BROADCAST:
+ conf.layer_info.dir_hash_algo = HASH_SHA3_256;
+ break;
+ default:
+ log_err("Unknown IPCP type: %d.", conf_msg->ipcp_type);
+ ret_msg->result = -EIPCP;
+ return;
+ }
+
+ /* UDP and broadcast use fixed hash algorithm. */
+ if (ipcp_type != IPCP_UDP && 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);
+ }
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_bootstrap(&conf);
+ if (ret_msg->result == 0) {
+ layer_info_msg->layer_name = strdup(conf.layer_info.layer_name);
+ layer_info_msg->dir_hash_algo = conf.layer_info.dir_hash_algo;
+ ret_msg->layer_info = layer_info_msg;
+ }
+}
+
+static void handle_enroll(const char * dst,
+ layer_info_msg_t * layer_info_msg,
+ ipcp_msg_t * ret_msg)
+{
+ struct layer_info info;
+
+ if (ipcpi.ops->ipcp_enroll == NULL) {
+ log_err("Enroll unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_INIT) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_enroll(dst, &info);
+ if (ret_msg->result == 0) {
+ layer_info_msg->layer_name = strdup(info.layer_name);
+ layer_info_msg->dir_hash_algo = info.dir_hash_algo;
+ ret_msg->layer_info = layer_info_msg;
+
+ }
+}
+
+static void handle_connect(const char * dst,
+ const char * comp,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_connect == NULL) {
+ log_err("Connect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_connect(dst, comp, qs);
+}
+
+static void handle_disconnect(const char * dst,
+ const char * comp,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_disconnect == NULL) {
+ log_err("Disconnect unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_disconnect(dst, comp);
+}
+
+static void handle_reg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+
+ if (ipcpi.ops->ipcp_reg == NULL) {
+ log_err("Registration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_reg(hash);
+}
+
+static void handle_unreg(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ if (ipcpi.ops->ipcp_unreg == NULL) {
+ log_err("Unregistration unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_unreg(hash);
+}
+
+static void handle_query(const uint8_t * hash,
+ ipcp_msg_t * ret_msg)
+{
+ 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 handle_flow_alloc(pid_t pid,
+ int flow_id,
+ uint8_t * dst,
+ qosspec_t qs,
+ void * data,
+ size_t len,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_alloc == NULL) {
+ log_err("Flow allocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating fd on flow_id %d.", flow_id);
+ ret_msg->result = -EFLOWDOWN;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc(fd, dst, qs, data, len);
+}
+
+
+static void handle_flow_join(pid_t pid,
+ int flow_id,
+ const uint8_t * dst,
+ qosspec_t qs,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_join == NULL) {
+ log_err("Broadcast unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ fd = np1_flow_alloc(pid, flow_id);
+ if (fd < 0) {
+ log_err("Failed allocating fd on flow_id %d.", flow_id);
+ ret_msg->result = -1;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_join(fd, dst, qs);
+}
+
+static void handle_flow_alloc_resp(int resp,
+ int flow_id,
+ const void * data,
+ size_t len,
+ ipcp_msg_t * ret_msg)
+{
+ int fd = -1;
+
+ if (ipcpi.ops->ipcp_flow_alloc_resp == NULL) {
+ log_err("Flow_alloc_resp unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ 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;
+ return;
+ }
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_alloc_resp(fd, resp, data, len);
+}
+
+static void handle_flow_dealloc(int flow_id,
+ int timeo_sec,
+ ipcp_msg_t * ret_msg)
+{
+ int fd;
+
+ if (ipcpi.ops->ipcp_flow_dealloc == NULL) {
+ log_err("Flow deallocation unsupported.");
+ ret_msg->result = -ENOTSUP;
+ return;
+ }
+
+ if (ipcp_get_state() != IPCP_OPERATIONAL) {
+ log_err("IPCP in wrong state.");
+ ret_msg->result = -EIPCPSTATE;
+ return;
+ }
+
+ 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;
+ return;
+ }
+
+ ret_msg->result = ipcpi.ops->ipcp_flow_dealloc(fd);
+}
+
+
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;
+ layer_info_msg_t layer_info_msg = LAYER_INFO_MSG__INIT;
+ qosspec_t qs;
+ struct cmd * cmd;
ret_msg.code = IPCP_MSG_CODE__IPCP_REPLY;
@@ -308,327 +614,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;
- }
+ handle_bootstrap(msg->conf, &layer_info_msg, &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;
- }
+ handle_enroll(msg->dst, &layer_info_msg, &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);
+ handle_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);
+ handle_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);
+ handle_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);
+ handle_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);
+ handle_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;
- }
-
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
qs = msg_to_spec(msg->qosspec);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc(fd,
- msg->hash.data,
- qs,
- msg->pk.data,
- msg->pk.len);
+ handle_flow_alloc(msg->pid, msg->flow_id,
+ msg->hash.data, qs,
+ msg->pk.data, msg->pk.len,
+ &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;
- }
-
- fd = np1_flow_alloc(msg->pid,
- msg->flow_id);
- if (fd < 0) {
- log_err("Failed allocating fd on flow_id %d.",
- msg->flow_id);
- ret_msg.result = -1;
- break;
- }
-
qs = msg_to_spec(msg->qosspec);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_join(fd,
- msg->hash.data,
- qs);
+ handle_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);
+ : msg->pk.data == NULL);
- ret_msg.result =
- ipcpi.ops->ipcp_flow_alloc_resp(fd,
- msg->response,
- msg->pk.data,
- msg->pk.len);
+ handle_flow_alloc_resp(msg->response, msg->flow_id,
+ msg->pk.data, msg->pk.len,
+ &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, msg->timeo_sec);
- 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);
+ handle_flow_dealloc(msg->flow_id, msg->timeo_sec,
+ &ret_msg);
break;
default:
- ret_msg.has_result = true;
ret_msg.result = -1;
log_err("Unknown message code: %d.", msg->code);
break;
}
- exit:
+
pthread_cleanup_pop(true);
pthread_cleanup_pop(false);
@@ -650,12 +697,16 @@ static void * mainloop(void * o)
ipcp_msg__pack(&ret_msg, buffer.data);
+ if (ret_msg.layer_info != NULL)
+ free(ret_msg.layer_info->layer_name);
+
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);
diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h
index 37d5b972..9e7a7223 100644
--- a/src/ipcpd/ipcp.h
+++ b/src/ipcpd/ipcp.h
@@ -85,7 +85,7 @@ extern struct ipcp {
char * name;
enum ipcp_type type;
- char * layer_name;
+ char layer_name[LAYER_NAME_SIZE + 1];
uint64_t dt_addr;
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index c1e95d23..f43d4713 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -145,11 +145,7 @@ static int ipcp_local_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name,conf->layer_info.layer_name);
ipcp_set_state(IPCP_OPERATIONAL);
diff --git a/src/ipcpd/udp/main.c b/src/ipcpd/udp/main.c
index fe25e17e..1a7725c1 100644
--- a/src/ipcpd/udp/main.c
+++ b/src/ipcpd/udp/main.c
@@ -591,6 +591,12 @@ static void * ipcp_udp_packet_writer(void * o)
return (void *) 1;
}
+static const char * inet4_ntop(const void * addr,
+ char * buf)
+{
+ return inet_ntop(AF_INET, &addr, buf, INET_ADDRSTRLEN);
+}
+
static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
{
char ipstr[INET_ADDRSTRLEN];
@@ -602,21 +608,15 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * 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;
- }
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
- if (inet_ntop(AF_INET, &conf->ip_addr, ipstr, INET_ADDRSTRLEN)
- == NULL) {
+ 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) {
+ if (conf->udp.dns_addr != 0) {
+ if (inet4_ntop(&conf->udp.dns_addr, dnsstr) == NULL) {
log_err("Failed to convert DNS address");
return -1;
}
@@ -636,15 +636,15 @@ 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);
goto fail_bind;
}
- udp_data.dns_addr = conf->dns_addr;
+ udp_data.dns_addr = conf->udp.dns_addr;
ipcp_set_state(IPCP_OPERATIONAL);
@@ -670,11 +670,11 @@ static int ipcp_udp_bootstrap(const struct ipcp_config * conf)
}
}
- sprintf(portstr, "%d", conf->port);
+ sprintf(portstr, "%d", conf->udp.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("Using port %u.", conf->udp.port);
log_dbg("DNS server address is %s.", dnsstr);
return 0;
@@ -759,7 +759,7 @@ 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)) {
@@ -855,14 +855,12 @@ 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) {
free(hashstr);
return -1;
}
- if (inet_ntop(AF_INET, &dns_addr,
- dnsstr, INET_ADDRSTRLEN) == NULL) {
+ if (inet4_ntop(&dns_addr, dnsstr) == NULL) {
free(hashstr);
return -1;
}
@@ -908,8 +906,7 @@ 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) {
free(hashstr);
return -1;
}
@@ -1002,13 +999,16 @@ static int ipcp_udp_flow_alloc(int fd,
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);
+ if (inet4_ntop(&ip_addr, ipstr) == NULL) {
+ log_err("Could not convert IP address.");
+ return -1;
+ }
log_dbg("Destination UDP ipcp resolved at %s.", ipstr);
memset((char *) &r_saddr, 0, sizeof(r_saddr));
diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c
index 48940a2b..60975aed 100644
--- a/src/ipcpd/unicast/dt.c
+++ b/src/ipcpd/unicast/dt.c
@@ -563,10 +563,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 +579,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;
@@ -607,7 +604,7 @@ int dt_init(enum pol_routing pr,
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;
diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h
index 5ad8cceb..478c79ea 100644
--- a/src/ipcpd/unicast/dt.h
+++ b/src/ipcpd/unicast/dt.h
@@ -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/main.c b/src/ipcpd/unicast/main.c
index 4d2ef1f2..1318ec2f 100644
--- a/src/ipcpd/unicast/main.c
+++ b/src/ipcpd/unicast/main.c
@@ -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;
- }
-
+ strcpy(ipcpi.layer_name, conf->layer_info.layer_name);
ipcpi.dir_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;
}
@@ -83,15 +78,12 @@ static int initialize_components(const struct ipcp_config * conf)
log_dbg("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,8 +125,6 @@ static void finalize_components(void)
ca_fini();
addr_auth_fini();
-
- free(ipcpi.layer_name);
}
static int start_components(void)