summaryrefslogtreecommitdiff
path: root/src/irmd
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2023-10-05 11:28:46 +0200
committerSander Vrijders <sander@ouroboros.rocks>2023-10-25 09:53:27 +0200
commit0d35f3772706200f5cff670ad33e7837db7d6a2e (patch)
treefaf6bcfc6af3597c241b59327fafdb242ca1c686 /src/irmd
parentfd3381002564c87b85feb2d1947a588e8ca6fdf9 (diff)
downloadouroboros-0d35f3772706200f5cff670ad33e7837db7d6a2e.tar.gz
ouroboros-0d35f3772706200f5cff670ad33e7837db7d6a2e.zip
irmd: Simplify mainloop
This moves the command parsing function out of the mainloop implementation to make it a bit less unwieldy. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/irmd')
-rw-r--r--src/irmd/main.c425
1 files changed, 213 insertions, 212 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 6073db46..823be5dc 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -266,8 +266,8 @@ static struct reg_ipcp * registry_get_ipcp_by_layer(const char * layer)
return NULL;
}
-static struct reg_ipcp *registry_get_ipcp_by_dst_name(const char * name,
- pid_t src)
+static struct reg_ipcp * registry_get_ipcp_by_dst_name(const char * name,
+ pid_t src)
{
struct list_head * p;
struct list_head * h;
@@ -1551,11 +1551,11 @@ static int flow_alloc(pid_t pid,
struct reg_flow * f_out,
buffer_t * data)
{
- struct reg_flow * f;
+ struct reg_flow * f;
struct reg_ipcp * ipcp;
- int flow_id;
- int state;
- uint8_t * hash;
+ int flow_id;
+ int state;
+ uint8_t * hash;
log_info("Allocating flow for %d to %s.", pid, dst);
@@ -1609,11 +1609,11 @@ static int flow_alloc(pid_t pid,
state = reg_flow_wait_state(f, FLOW_ALLOCATED, dl);
if (state != FLOW_ALLOCATED) {
if (state == -ETIMEDOUT) {
- log_dbg("Flow allocation timed out");
+ log_err("Flow allocation timed out");
return -ETIMEDOUT;
}
- log_info("Pending flow to %s torn down.", dst);
+ log_warn("Pending flow to %s torn down.", dst);
return -EPIPE;
}
@@ -2072,6 +2072,198 @@ static void free_msg(void * o)
irm_msg__free_unpacked((irm_msg_t *) o, NULL);
}
+static irm_msg_t * do_command_msg(irm_msg_t * msg)
+{
+ struct ipcp_config conf;
+ irm_msg_t * ret_msg;
+ buffer_t data;
+ struct reg_flow f;
+ struct qos_spec qs;
+ struct timespec * dl = NULL;
+ struct timespec ts = {0, 0};
+ int res;
+
+ memset(&f, 0, sizeof(f));
+
+ ret_msg = malloc(sizeof(*ret_msg));
+ if (ret_msg == NULL) {
+ log_err("Failed to malloc return msg.");
+ return NULL;
+ }
+
+ irm_msg__init(ret_msg);
+
+ ret_msg->code = IRM_MSG_CODE__IRM_REPLY;
+
+ if (msg->has_timeo_sec) {
+ struct timespec now;
+ clock_gettime(PTHREAD_COND_CLOCK, &now);
+ assert(msg->has_timeo_nsec);
+
+ ts.tv_sec = msg->timeo_sec;
+ ts.tv_nsec = msg->timeo_nsec;
+
+ ts_add(&ts, &now, &ts);
+
+ dl = &ts;
+ }
+
+ pthread_cleanup_push(free_msg, ret_msg);
+
+ switch (msg->code) {
+ case IRM_MSG_CODE__IRM_CREATE_IPCP:
+ res = create_ipcp(msg->name, msg->ipcp_type);
+ break;
+ case IRM_MSG_CODE__IPCP_CREATE_R:
+ res = create_ipcp_r(msg->pid, msg->result);
+ break;
+ case IRM_MSG_CODE__IRM_DESTROY_IPCP:
+ res = destroy_ipcp(msg->pid);
+ break;
+ case IRM_MSG_CODE__IRM_BOOTSTRAP_IPCP:
+ conf = ipcp_config_msg_to_s(msg->conf);
+ res = bootstrap_ipcp(msg->pid, &conf);
+ break;
+ case IRM_MSG_CODE__IRM_ENROLL_IPCP:
+ res = enroll_ipcp(msg->pid, msg->dst);
+ break;
+ case IRM_MSG_CODE__IRM_CONNECT_IPCP:
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ res = connect_ipcp(msg->pid, msg->dst, msg->comp, qs);
+ break;
+ case IRM_MSG_CODE__IRM_DISCONNECT_IPCP:
+ res = disconnect_ipcp(msg->pid, msg->dst, msg->comp);
+ break;
+ case IRM_MSG_CODE__IRM_BIND_PROGRAM:
+ res = bind_program(msg->prog, msg->name, msg->opts,
+ msg->n_args, msg->args);
+ break;
+ case IRM_MSG_CODE__IRM_UNBIND_PROGRAM:
+ res = unbind_program(msg->prog, msg->name);
+ break;
+ case IRM_MSG_CODE__IRM_PROC_ANNOUNCE:
+ res = proc_announce(msg->pid, msg->prog);
+ break;
+ case IRM_MSG_CODE__IRM_BIND_PROCESS:
+ res = bind_process(msg->pid, msg->name);
+ break;
+ case IRM_MSG_CODE__IRM_UNBIND_PROCESS:
+ res = unbind_process(msg->pid, msg->name);
+ break;
+ case IRM_MSG_CODE__IRM_LIST_IPCPS:
+ res = list_ipcps(&ret_msg->ipcps, &ret_msg->n_ipcps);
+ break;
+ case IRM_MSG_CODE__IRM_CREATE_NAME:
+ res = name_create(msg->names[0]->name,
+ msg->names[0]->pol_lb);
+ break;
+ case IRM_MSG_CODE__IRM_DESTROY_NAME:
+ res = name_destroy(msg->name);
+ break;
+ case IRM_MSG_CODE__IRM_LIST_NAMES:
+ res = list_names(&ret_msg->names, &ret_msg->n_names);
+ break;
+ case IRM_MSG_CODE__IRM_REG_NAME:
+ res = name_reg(msg->name, msg->pid);
+ break;
+ case IRM_MSG_CODE__IRM_UNREG_NAME:
+ res = name_unreg(msg->name, msg->pid);
+ break;
+ case IRM_MSG_CODE__IRM_FLOW_ACCEPT:
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ assert(data.len > 0 ? data.data != NULL : data.data == NULL);
+ res = flow_accept(msg->pid, dl, &f, &data);
+ if (res == 0) {
+ qosspec_msg_t * qs_msg;
+ qs_msg = qos_spec_s_to_msg(&f.qs);
+ ret_msg->has_flow_id = true;
+ ret_msg->flow_id = f.flow_id;
+ ret_msg->has_pid = true;
+ ret_msg->pid = f.n_1_pid;
+ ret_msg->qosspec = qs_msg;
+ ret_msg->has_mpl = true;
+ ret_msg->mpl = f.mpl;
+ ret_msg->has_pk = true;
+ ret_msg->pk.data = data.data;
+ ret_msg->pk.len = data.len;
+ }
+ break;
+ case IRM_MSG_CODE__IRM_FLOW_ALLOC:
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ assert(data.len > 0 ? data.data != NULL : data.data == NULL);
+ res = flow_alloc(msg->pid, msg->dst, qs, dl, &f, &data);
+ if (res == 0) {
+ ret_msg->has_flow_id = true;
+ ret_msg->flow_id = f.flow_id;
+ ret_msg->has_pid = true;
+ ret_msg->pid = f.n_1_pid;
+ ret_msg->has_mpl = true;
+ ret_msg->mpl = f.mpl;
+ ret_msg->has_pk = true;
+ ret_msg->pk.data = data.data;
+ ret_msg->pk.len = data.len;
+ }
+ break;
+ case IRM_MSG_CODE__IRM_FLOW_JOIN:
+ assert(msg->pk.len == 0 && msg->pk.data == NULL);
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ res = flow_join(msg->pid, msg->dst, qs, dl, &f);
+ if (res == 0) {
+ ret_msg->has_flow_id = true;
+ ret_msg->flow_id = f.flow_id;
+ ret_msg->has_pid = true;
+ ret_msg->pid = f.n_1_pid;
+ ret_msg->has_mpl = true;
+ ret_msg->mpl = f.mpl;
+ }
+ break;
+ case IRM_MSG_CODE__IRM_FLOW_DEALLOC:
+ res = flow_dealloc(msg->pid, msg->flow_id, msg->timeo_sec);
+ break;
+ case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ msg->has_pk = false; /* pass data */
+ msg->pk.data = NULL;
+ msg->pk.len = 0;
+ assert(data.len > 0 ? data.data != NULL : data.data == NULL);
+ qs = qos_spec_msg_to_s(msg->qosspec);
+ res = flow_req_arr(msg->pid, &f, msg->hash.data,
+ msg->mpl, qs, data);
+ if (res == 0) {
+ ret_msg->has_flow_id = true;
+ ret_msg->flow_id = f.flow_id;
+ ret_msg->has_pid = true;
+ ret_msg->pid = f.n_pid;
+ }
+ break;
+ case IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY:
+ data.len = msg->pk.len;
+ data.data = msg->pk.data;
+ msg->has_pk = false; /* pass data */
+ msg->pk.data = NULL;
+ msg->pk.len = 0;
+ assert(data.len > 0 ? data.data != NULL : data.data == NULL);
+ res = flow_alloc_reply(msg->flow_id, msg->response,
+ msg->mpl, data);
+ break;
+ default:
+ log_err("Don't know that message code.");
+ res = -1;
+ break;
+ }
+
+ pthread_cleanup_pop(false);
+
+ ret_msg->has_result = true;
+ ret_msg->result = res;
+
+ return ret_msg;
+}
+
static void * mainloop(void * o)
{
int sfd;
@@ -2081,28 +2273,11 @@ static void * mainloop(void * o)
(void) o;
while (true) {
- irm_msg_t * ret_msg;
- struct reg_flow f;
- struct ipcp_config conf;
- struct timespec * dl = NULL;
- struct timespec ts = {0, 0};
- struct cmd * cmd;
- int result;
- buffer_t data;
-
- memset(&f, 0, sizeof(f));
-
- ret_msg = malloc(sizeof(*ret_msg));
- if (ret_msg == NULL)
- return (void *) -1;
-
- irm_msg__init(ret_msg);
-
- ret_msg->code = IRM_MSG_CODE__IRM_REPLY;
+ irm_msg_t * ret_msg;
+ struct cmd * cmd;
pthread_mutex_lock(&irmd.cmd_lock);
- pthread_cleanup_push(free_msg, ret_msg);
pthread_cleanup_push(__cleanup_mutex_unlock, &irmd.cmd_lock);
while (list_is_empty(&irmd.cmds))
@@ -2112,7 +2287,6 @@ static void * mainloop(void * o)
list_del(&cmd->next);
pthread_cleanup_pop(true);
- pthread_cleanup_pop(false);
msg = irm_msg__unpack(NULL, cmd->len, cmd->cbuf);
sfd = cmd->fd;
@@ -2121,201 +2295,28 @@ static void * mainloop(void * o)
if (msg == NULL) {
close(sfd);
- irm_msg__free_unpacked(msg, NULL);
- free(ret_msg);
continue;
}
tpm_dec(irmd.tpm);
- if (msg->has_timeo_sec) {
- struct timespec now;
- clock_gettime(PTHREAD_COND_CLOCK, &now);
- assert(msg->has_timeo_nsec);
-
- ts.tv_sec = msg->timeo_sec;
- ts.tv_nsec = msg->timeo_nsec;
-
- ts_add(&ts, &now, &ts);
-
- dl = &ts;
- }
-
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
pthread_cleanup_push(free_msg, msg);
- pthread_cleanup_push(free_msg, ret_msg);
- switch (msg->code) {
- case IRM_MSG_CODE__IRM_CREATE_IPCP:
- result = create_ipcp(msg->name, msg->ipcp_type);
- break;
- case IRM_MSG_CODE__IPCP_CREATE_R:
- result = create_ipcp_r(msg->pid, msg->result);
- break;
- case IRM_MSG_CODE__IRM_DESTROY_IPCP:
- result = destroy_ipcp(msg->pid);
- break;
- case IRM_MSG_CODE__IRM_BOOTSTRAP_IPCP:
- conf = ipcp_config_msg_to_s(msg->conf);
- result = bootstrap_ipcp(msg->pid, &conf);
- break;
- case IRM_MSG_CODE__IRM_ENROLL_IPCP:
- result = enroll_ipcp(msg->pid, msg->dst);
- break;
- case IRM_MSG_CODE__IRM_CONNECT_IPCP:
- result = connect_ipcp(msg->pid, msg->dst, msg->comp,
- qos_spec_msg_to_s(msg->qosspec));
- break;
- case IRM_MSG_CODE__IRM_DISCONNECT_IPCP:
- result = disconnect_ipcp(msg->pid, msg->dst, msg->comp);
- break;
- case IRM_MSG_CODE__IRM_BIND_PROGRAM:
- result = bind_program(msg->prog,
- msg->name,
- msg->opts,
- msg->n_args,
- msg->args);
- break;
- case IRM_MSG_CODE__IRM_UNBIND_PROGRAM:
- result = unbind_program(msg->prog, msg->name);
- break;
- case IRM_MSG_CODE__IRM_PROC_ANNOUNCE:
- result = proc_announce(msg->pid, msg->prog);
- break;
- case IRM_MSG_CODE__IRM_BIND_PROCESS:
- result = bind_process(msg->pid, msg->name);
- break;
- case IRM_MSG_CODE__IRM_UNBIND_PROCESS:
- result = unbind_process(msg->pid, msg->name);
- break;
- case IRM_MSG_CODE__IRM_LIST_IPCPS:
- result = list_ipcps(&ret_msg->ipcps, &ret_msg->n_ipcps);
- break;
- case IRM_MSG_CODE__IRM_CREATE_NAME:
- result = name_create(msg->names[0]->name,
- msg->names[0]->pol_lb);
- break;
- case IRM_MSG_CODE__IRM_DESTROY_NAME:
- result = name_destroy(msg->name);
- break;
- case IRM_MSG_CODE__IRM_LIST_NAMES:
- result = list_names(&ret_msg->names, &ret_msg->n_names);
- break;
- case IRM_MSG_CODE__IRM_REG_NAME:
- result = name_reg(msg->name, msg->pid);
- break;
- case IRM_MSG_CODE__IRM_UNREG_NAME:
- result = name_unreg(msg->name, msg->pid);
- break;
- case IRM_MSG_CODE__IRM_FLOW_ACCEPT:
- data.len = msg->pk.len;
- data.data = msg->pk.data;
- assert(data.len > 0 ? data.data != NULL
- : data.data == NULL);
- result = flow_accept(msg->pid, dl, &f, &data);
- if (result == 0) {
- qosspec_msg_t * qs_msg;
- qs_msg = qos_spec_s_to_msg(&f.qs);
- ret_msg->has_flow_id = true;
- ret_msg->flow_id = f.flow_id;
- ret_msg->has_pid = true;
- ret_msg->pid = f.n_1_pid;
- ret_msg->qosspec = qs_msg;
- ret_msg->has_mpl = true;
- ret_msg->mpl = f.mpl;
- ret_msg->has_pk = true;
- ret_msg->pk.data = data.data;
- ret_msg->pk.len = data.len;
- }
- break;
- case IRM_MSG_CODE__IRM_FLOW_ALLOC:
- data.len = msg->pk.len;
- data.data = msg->pk.data;
- assert(data.len > 0 ? data.data != NULL
- : data.data == NULL);
- result = flow_alloc(msg->pid, msg->dst,
- qos_spec_msg_to_s(msg->qosspec),
- dl, &f, &data);
- if (result == 0) {
- ret_msg->has_flow_id = true;
- ret_msg->flow_id = f.flow_id;
- ret_msg->has_pid = true;
- ret_msg->pid = f.n_1_pid;
- ret_msg->has_mpl = true;
- ret_msg->mpl = f.mpl;
- ret_msg->has_pk = true;
- ret_msg->pk.data = data.data;
- ret_msg->pk.len = data.len;
- }
- break;
- case IRM_MSG_CODE__IRM_FLOW_JOIN:
- assert(msg->pk.len == 0 && msg->pk.data == NULL);
- result = flow_join(msg->pid, msg->dst,
- qos_spec_msg_to_s(msg->qosspec),
- dl, &f);
- if (result == 0) {
- ret_msg->has_flow_id = true;
- ret_msg->flow_id = f.flow_id;
- ret_msg->has_pid = true;
- ret_msg->pid = f.n_1_pid;
- ret_msg->has_mpl = true;
- ret_msg->mpl = f.mpl;
- }
- break;
- case IRM_MSG_CODE__IRM_FLOW_DEALLOC:
- result = flow_dealloc(msg->pid,
- msg->flow_id,
- msg->timeo_sec);
- break;
- case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:
- data.len = msg->pk.len;
- data.data = msg->pk.data;
- msg->has_pk = false; /* pass data */
- msg->pk.data = NULL;
- msg->pk.len = 0;
- assert(data.len > 0 ? data.data != NULL
- : data.data == NULL);
- result = flow_req_arr(msg->pid,
- &f,
- msg->hash.data,
- msg->mpl,
- qos_spec_msg_to_s(msg->qosspec),
- data);
- if (result == 0) {
- ret_msg->has_flow_id = true;
- ret_msg->flow_id = f.flow_id;
- ret_msg->has_pid = true;
- ret_msg->pid = f.n_pid;
- }
- break;
- case IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY:
- data.len = msg->pk.len;
- data.data = msg->pk.data;
- msg->has_pk = false; /* pass data */
- msg->pk.data = NULL;
- msg->pk.len = 0;
- assert(data.len > 0 ? data.data != NULL
- : data.data == NULL);
- result = flow_alloc_reply(msg->flow_id,
- msg->response,
- msg->mpl,
- data);
- break;
- default:
- log_err("Don't know that message code.");
- result = -1;
- break;
- }
+ ret_msg = do_command_msg(msg);
- pthread_cleanup_pop(false);
pthread_cleanup_pop(true);
pthread_cleanup_pop(false);
- if (result == -EPIPE)
- goto fail;
+ if (ret_msg == NULL) {
+ log_err("Failed to create return message.");
+ goto fail_msg;
+ }
- ret_msg->has_result = true;
- ret_msg->result = result;
+ if (ret_msg->result == -EPIPE || ret_msg->result == -EIRMD) {
+ log_err("Failed to execute command: %d.", ret_msg->result);
+ goto fail;
+ }
buffer.len = irm_msg__get_packed_size(ret_msg);
if (buffer.len == 0) {
@@ -2336,8 +2337,7 @@ static void * mainloop(void * o)
pthread_cleanup_push(__cleanup_close_ptr, &sfd);
if (write(sfd, buffer.data, buffer.len) == -1)
- if (result != -EIRMD)
- log_warn("Failed to send reply message.");
+ log_warn("Failed to send reply message.");
free(buffer.data);
@@ -2348,6 +2348,7 @@ static void * mainloop(void * o)
continue;
fail:
irm_msg__free_unpacked(ret_msg, NULL);
+ fail_msg:
close(sfd);
tpm_inc(irmd.tpm);
continue;