summaryrefslogtreecommitdiff
path: root/src/ipcpd/ipcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ipcpd/ipcp.c')
-rw-r--r--src/ipcpd/ipcp.c239
1 files changed, 151 insertions, 88 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index bc16e2f0..ab38f5d0 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -68,6 +68,34 @@
#define CLOCK_REALTIME_COARSE CLOCK_REALTIME
#endif
+static char * ipcp_type_str[] = {
+ "local",
+ "unicast",
+ "broadcast",
+ "eth-llc",
+ "eth-dix",
+ "udp"
+};
+
+static char * dir_hash_str[] = {
+ "SHA3-224",
+ "SHA3-256",
+ "SHA3-384",
+ "SHA3-512",
+ "CRC32",
+ "MD5"
+};
+
+static char * ipcp_state_str[] = {
+ "null",
+ "init",
+ "boot",
+ "bootstrapped",
+ "enrolled",
+ "operational",
+ "shutdown"
+};
+
struct {
pid_t irmd_pid;
char * name;
@@ -102,13 +130,6 @@ struct {
pthread_t acceptor;
} ipcpd;
-char * info[LAYER_NAME_SIZE + 1] = {
- "_state",
- "_type",
- "_layer",
- NULL
-};
-
struct cmd {
struct list_head next;
@@ -127,6 +148,11 @@ const char * ipcp_get_name(void)
return ipcpd.name;
}
+void ipcp_set_dir_hash_algo(enum hash_algo algo)
+{
+ ipcpd.dir_hash_algo = algo;
+}
+
size_t ipcp_dir_hash_len(void)
{
return hash_len(ipcpd.dir_hash_algo);
@@ -158,6 +184,13 @@ void ipcp_hash_str(char * buf,
buf[2 * i] = '\0';
}
+static const char * info[] = {
+ "_state",
+ "_type",
+ "_layer",
+ NULL
+};
+
static int ipcp_rib_read(const char * path,
char * buf,
size_t len)
@@ -223,7 +256,7 @@ static int ipcp_rib_readdir(char *** buf)
*buf = malloc(sizeof(**buf) * i);
if (*buf == NULL)
- goto fail;
+ goto fail_entries;
i = 0;
@@ -236,12 +269,12 @@ static int ipcp_rib_readdir(char *** buf)
return i;
fail_dup:
- while (i > 0)
- free((*buf)[--i]);
- fail:
+ while (i-- > 0)
+ free((*buf)[i]);
+ fail_entries:
free(*buf);
- return -1;
+ return -ENOMEM;
}
static int ipcp_rib_getattr(const char * path,
@@ -402,20 +435,24 @@ static void free_msg(void * o)
static void do_bootstrap(ipcp_config_msg_t * conf_msg,
ipcp_msg_t * ret_msg)
{
- struct ipcp_config conf;
+ struct ipcp_config conf;
+ struct layer_info * info;
log_info("Bootstrapping...");
if (ipcpd.ops->ipcp_bootstrap == NULL) {
- log_err("Bootstrap unsupported.");
+ log_err("Failed to Bootstrap: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
+
+ log_err("Failed to bootstrap: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_INIT]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ return;
}
conf = ipcp_config_msg_to_s(conf_msg);
@@ -431,15 +468,24 @@ static void do_bootstrap(ipcp_config_msg_t * conf_msg,
}
ret_msg->result = ipcpd.ops->ipcp_bootstrap(&conf);
- if (ret_msg->result == 0) {
- enum pol_dir_hash algo = conf.layer_info.dir_hash_algo;
- strcpy(ipcpd.layer_name, conf.layer_info.name);
- ipcpd.dir_hash_algo = (enum hash_algo) algo;
- ret_msg->layer_info = layer_info_s_to_msg(&conf.layer_info);
- ipcp_set_state(IPCP_OPERATIONAL);
+ if (ret_msg->result < 0) {
+ log_err("Failed to bootstrap IPCP.");
+ return;
}
- finish:
- log_info("Finished bootstrapping: %d.", ret_msg->result);
+
+ info = &conf.layer_info;
+
+ strcpy(ipcpd.layer_name, info->name);
+ ipcpd.dir_hash_algo = (enum hash_algo) info->dir_hash_algo;
+ ret_msg->layer_info = layer_info_s_to_msg(info);
+
+ log_info("Finished bootstrapping in %s.", info->name);
+ log_info(" type: %s", ipcp_type_str[ipcpd.type]);
+ log_info(" hash: %s [%zd bytes]",
+ dir_hash_str[ipcpd.dir_hash_algo],
+ ipcp_dir_hash_len());
+
+ ipcp_set_state(IPCP_OPERATIONAL);
}
static void do_enroll(const char * dst,
@@ -450,26 +496,35 @@ static void do_enroll(const char * dst,
log_info("Enrolling with %s...", dst);
if (ipcpd.ops->ipcp_enroll == NULL) {
- log_err("Enroll unsupported.");
+ log_err("Failed to enroll: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_INIT) {
- log_err("IPCP in wrong state.");
+ log_err("Failed to enroll: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_INIT]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_enroll(dst, &info);
- if (ret_msg->result == 0) {
- strcpy(ipcpd.layer_name, info.name);
- ipcpd.dir_hash_algo = (enum hash_algo) info.dir_hash_algo;
- ret_msg->layer_info = layer_info_s_to_msg(&info);
- ipcp_set_state(IPCP_OPERATIONAL);
+ if (ret_msg->result < 0) {
+ log_err("Failed to bootstrap IPCP.");
+ return;
}
- finish:
- log_info("Finished enrolling with %s: %d.", dst, ret_msg->result);
+
+ strcpy(ipcpd.layer_name, info.name);
+ ipcpd.dir_hash_algo = (enum hash_algo) info.dir_hash_algo;
+ ret_msg->layer_info = layer_info_s_to_msg(&info);
+ ipcp_set_state(IPCP_OPERATIONAL);
+
+ log_info("Finished enrolling with %s in layer %s.", dst, info.name);
+ log_info(" type: %s", ipcp_type_str[ipcpd.type]);
+ log_info(" hash: %s [%zd bytes]",
+ dir_hash_str[ipcpd.dir_hash_algo],
+ ipcp_dir_hash_len());
}
static void do_connect(const char * dst,
@@ -480,14 +535,14 @@ static void do_connect(const char * dst,
log_info("Connecting %s to %s...", comp, dst);
if (ipcpd.ops->ipcp_connect == NULL) {
- log_err("Connect unsupported.");
+ log_err("Failed to connect: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_connect(dst, comp, qs);
- finish:
- log_info("Finished connecting: %d.", ret_msg->result);
+
+ log_info("Finished connecting.");
}
static void do_disconnect(const char * dst,
@@ -497,16 +552,14 @@ static void do_disconnect(const char * dst,
log_info("Disconnecting %s from %s...", comp, dst);
if (ipcpd.ops->ipcp_disconnect == NULL) {
- log_err("Disconnect unsupported.");
+ log_err("Failed to disconnect: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_disconnect(dst, comp);
- finish:
- log_info("Finished disconnecting %s from %s: %d.",
- comp, dst, ret_msg->result);
+ log_info("Finished disconnecting %s from %s.", comp, dst);
}
static void do_reg(const uint8_t * hash,
@@ -516,15 +569,14 @@ static void do_reg(const uint8_t * hash,
log_info("Registering " HASH_FMT32 "...", HASH_VAL32(hash));
if (ipcpd.ops->ipcp_reg == NULL) {
- log_err("Registration unsupported.");
+ log_err("Failed to register: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_reg(hash);
- finish:
- log_info("Finished registering " HASH_FMT32 " : %d.",
- HASH_VAL32(hash), ret_msg->result);
+
+ log_info("Finished registering " HASH_FMT32 ".", HASH_VAL32(hash));
}
static void do_unreg(const uint8_t * hash,
@@ -533,15 +585,14 @@ static void do_unreg(const uint8_t * hash,
log_info("Unregistering " HASH_FMT32 "...", HASH_VAL32(hash));
if (ipcpd.ops->ipcp_unreg == NULL) {
- log_err("Unregistration unsupported.");
+ log_err("Failed to unregister: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_unreg(hash);
- finish:
- log_info("Finished unregistering " HASH_FMT32 ": %d.",
- HASH_VAL32(hash), ret_msg->result);
+
+ log_info("Finished unregistering " HASH_FMT32 ".", HASH_VAL32(hash));
}
static void do_query(const uint8_t * hash,
@@ -550,13 +601,15 @@ static void do_query(const uint8_t * hash,
/* TODO: Log this operation when IRMd has internal caches. */
if (ipcpd.ops->ipcp_query == NULL) {
- log_err("Directory query unsupported.");
+ log_err("Failed to query: operation unsupported.");
ret_msg->result = -ENOTSUP;
return;
}
if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
+ log_dbg("Failed to query: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_OPERATIONAL]);
ret_msg->result = -EIPCPSTATE;
return;
}
@@ -577,15 +630,17 @@ static void do_flow_alloc(pid_t pid,
flow_id, pid, HASH_VAL32(dst));
if (ipcpd.ops->ipcp_flow_alloc == NULL) {
- log_err("Flow allocation unsupported.");
+ log_err("Flow allocation failed: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
+ log_err("Failed to enroll: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_OPERATIONAL]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ return;
}
fd = np1_flow_alloc(pid, flow_id);
@@ -593,13 +648,13 @@ static void do_flow_alloc(pid_t pid,
log_err("Failed allocating n + 1 fd on flow_id %d: %d",
flow_id, fd);
ret_msg->result = -EFLOWDOWN;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_flow_alloc(fd, dst, qs, data);
- finish:
- log_info("Finished allocating flow %d to " HASH_FMT32 ": %d.",
- flow_id, HASH_VAL32(dst), ret_msg->result);
+
+ log_info("Finished allocating flow %d to " HASH_FMT32 ".",
+ flow_id, HASH_VAL32(dst));
}
@@ -614,26 +669,28 @@ static void do_flow_join(pid_t pid,
log_info("Joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
if (ipcpd.ops->ipcp_flow_join == NULL) {
- log_err("Broadcast unsupported.");
+ log_err("Failed to join: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
+ log_err("Failed to join: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_OPERATIONAL]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ return;
}
fd = np1_flow_alloc(pid, flow_id);
if (fd < 0) {
log_err("Failed allocating n + 1 fd on flow_id %d.", flow_id);
ret_msg->result = -1;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_flow_join(fd, dst, qs);
- finish:
+
log_info("Finished joining layer " HASH_FMT32 ".", HASH_VAL32(dst));
}
@@ -647,15 +704,20 @@ static void do_flow_alloc_resp(int resp,
log_info("Responding %d to alloc on flow_id %d.", resp, flow_id);
if (ipcpd.ops->ipcp_flow_alloc_resp == NULL) {
- log_err("Flow_alloc_resp unsupported.");
+ log_err("Failed to respond on flow %d: operation unsupported.",
+ flow_id);
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
+ log_err("Failed to respond to flow %d:"
+ "IPCP in state <%s>, need <%s>.",
+ flow_id,
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_OPERATIONAL]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ return;
}
if (resp == 0) {
@@ -663,13 +725,13 @@ static void do_flow_alloc_resp(int resp,
if (fd < 0) {
log_warn("Flow_id %d is not known.", flow_id);
ret_msg->result = -1;
- goto finish;
+ return;
}
}
ret_msg->result = ipcpd.ops->ipcp_flow_alloc_resp(fd, resp, data);
- finish:
- log_info("Finished responding to allocation request: %d",
+
+ log_info("Finished responding %d to allocation request.",
ret_msg->result);
}
@@ -682,28 +744,29 @@ static void do_flow_dealloc(int flow_id,
log_info("Deallocating flow %d.", flow_id);
if (ipcpd.ops->ipcp_flow_dealloc == NULL) {
- log_err("Flow deallocation unsupported.");
+ log_err("Failed to dealloc: operation unsupported.");
ret_msg->result = -ENOTSUP;
- goto finish;
+ return;
}
if (ipcp_get_state() != IPCP_OPERATIONAL) {
- log_err("IPCP in wrong state.");
+ log_err("Failed to enroll: IPCP in state <%s>, need <%s>.",
+ ipcp_state_str[ipcp_get_state()],
+ ipcp_state_str[IPCP_OPERATIONAL]);
ret_msg->result = -EIPCPSTATE;
- goto finish;
+ 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;
- goto finish;
+ return;
}
ret_msg->result = ipcpd.ops->ipcp_flow_dealloc(fd);
- finish:
- log_info("Finished deallocating flow %d: %d.",
- flow_id, ret_msg->result);
+
+ log_info("Finished deallocating flow %d.", flow_id);
}
static void * mainloop(void * o)
@@ -888,8 +951,8 @@ int ipcp_init(int argc,
log_init(log);
- ipcpd.state = IPCP_NULL;
- ipcpd.type = type;
+ ipcpd.state = IPCP_NULL;
+ ipcpd.type = type;
#if defined (__linux__)
prctl(PR_SET_TIMERSLACK, IPCP_LINUX_SLACK_NS, 0, 0, 0);