diff options
author | Dimitri Staessens <[email protected]> | 2018-12-27 15:42:00 +0100 |
---|---|---|
committer | Sander Vrijders <[email protected]> | 2018-12-27 16:08:56 +0100 |
commit | 9dab3985812e75071271ce69000561156d0d9374 (patch) | |
tree | 8569e3186cdcf37c205c7bae0d2d9b595b607602 /src/irmd/main.c | |
parent | 8eed1b3fc3d4e3261a68855ccc54c35102738a79 (diff) | |
download | ouroboros-9dab3985812e75071271ce69000561156d0d9374.tar.gz ouroboros-9dab3985812e75071271ce69000561156d0d9374.zip |
include: Add a flow_join operation for broadcast
This adds a new flow_join operaiton for broadcast, which is a much
safer solution than overloading destination name semantics. The
internal API now also has a different IPCP_FLOW_JOIN operation. The
IRMd doesn't need to query broadcasts IPCPs for the name, it can just
check if an IPCP with the layer name exists. The broadcast IPCP
doesn't need to implement the query proxy call anymore.
Signed-off-by: Dimitri Staessens <[email protected]>
Signed-off-by: Sander Vrijders <[email protected]>
Diffstat (limited to 'src/irmd/main.c')
-rw-r--r-- | src/irmd/main.c | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c index 67e16de0..802b01f0 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -330,6 +330,19 @@ static struct ipcp_entry * get_ipcp_entry_by_name(const char * name) return NULL; } +static struct ipcp_entry * get_ipcp_entry_by_layer(const char * layer) +{ + struct list_head * p; + + list_for_each(p, &irmd.ipcps) { + struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); + if (strcmp(layer, e->layer) == 0) + return e; + } + + return NULL; +} + static struct ipcp_entry * get_ipcp_by_dst_name(const char * name, pid_t src) { @@ -1267,7 +1280,8 @@ static int flow_alloc(pid_t pid, const char * dst, qosspec_t qs, struct timespec * timeo, - struct irm_flow ** e) + struct irm_flow ** e, + bool join) { struct irm_flow * f; struct ipcp_entry * ipcp; @@ -1275,7 +1289,10 @@ static int flow_alloc(pid_t pid, int state; uint8_t * hash; - ipcp = get_ipcp_by_dst_name(dst, pid); + if (join) + ipcp = get_ipcp_entry_by_layer(dst); + else + ipcp = get_ipcp_by_dst_name(dst, pid); if (ipcp == NULL) { log_info("Destination %s unreachable.", dst); return -1; @@ -1310,12 +1327,22 @@ static int flow_alloc(pid_t pid, str_hash(ipcp->dir_hash_algo, hash, dst); - if (ipcp_flow_alloc(ipcp->pid, flow_id, pid, hash, - IPCP_HASH_LEN(ipcp), qs)) { - /* sanitizer cleans this */ - log_info("Flow_allocation failed."); - free(hash); - return -EAGAIN; + if (join) { + if (ipcp_flow_join(ipcp->pid, flow_id, pid, hash, + IPCP_HASH_LEN(ipcp), qs)) { + /* sanitizer cleans this */ + log_info("Flow_join failed."); + free(hash); + return -EAGAIN; + } + } else { + if (ipcp_flow_alloc(ipcp->pid, flow_id, pid, hash, + IPCP_HASH_LEN(ipcp), qs)) { + /* sanitizer cleans this */ + log_info("Flow_allocation failed."); + free(hash); + return -EAGAIN; + } } free(hash); @@ -1978,7 +2005,18 @@ static void * mainloop(void * o) case IRM_MSG_CODE__IRM_FLOW_ALLOC: result = flow_alloc(msg->pid, msg->dst, msg_to_spec(msg->qosspec), - timeo, &e); + timeo, &e, false); + if (result == 0) { + ret_msg->has_flow_id = true; + ret_msg->flow_id = e->flow_id; + ret_msg->has_pid = true; + ret_msg->pid = e->n_1_pid; + } + break; + case IRM_MSG_CODE__IRM_FLOW_JOIN: + result = flow_alloc(msg->pid, msg->dst, + msg_to_spec(msg->qosspec), + timeo, &e, true); if (result == 0) { ret_msg->has_flow_id = true; ret_msg->flow_id = e->flow_id; |