summaryrefslogtreecommitdiff
path: root/src/irmd/main.c
diff options
context:
space:
mode:
authordimitri staessens <[email protected]>2017-04-12 16:57:48 +0200
committerdimitri staessens <[email protected]>2017-04-13 11:30:20 +0200
commitfc10a7587b1a642748ae0fd69f08d92b4a902248 (patch)
treee0b570cf30753a564855242c94d242f597b5c499 /src/irmd/main.c
parenta3d550ff972121641562d375f75bcf188fc7fe59 (diff)
downloadouroboros-fc10a7587b1a642748ae0fd69f08d92b4a902248.tar.gz
ouroboros-fc10a7587b1a642748ae0fd69f08d92b4a902248.zip
lib, ipcpd, irmd: Register hash instead of name
All information passed over the IRMd/IPCP boundary for using IPC services (flow allocation, registration) is now hashed. This effectively fixes the shared namespace between DIFs and the IRMDs. This PR also fixes some API issues (adding const identifiers), shuffles the include headers a bit and some small bugs.
Diffstat (limited to 'src/irmd/main.c')
-rw-r--r--src/irmd/main.c188
1 files changed, 114 insertions, 74 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c
index 5e5039b1..125061fb 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -27,7 +27,8 @@
#include <ouroboros/sockets.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
-#include <ouroboros/irm_config.h>
+#include <ouroboros/hash.h>
+#include <ouroboros/irm.h>
#include <ouroboros/lockfile.h>
#include <ouroboros/shm_flow_set.h>
#include <ouroboros/shm_rbuff.h>
@@ -36,6 +37,7 @@
#include <ouroboros/qos.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/logs.h>
+#include <ouroboros/sha3.h>
#include "utils.h"
#include "registry.h"
@@ -62,6 +64,8 @@ struct ipcp_entry {
char * name;
pid_t api;
enum ipcp_type type;
+ uint16_t dir_hash_len;
+ /* FIXME: add an enum to specify hash algo */
char * dif_name;
pthread_cond_t init_cond;
@@ -223,48 +227,33 @@ static struct ipcp_entry * get_ipcp_entry_by_name(const char * name)
return NULL;
}
-/* Check if the name exists anywhere in a DIF. */
-static pid_t get_ipcp_by_dst_name(char * dst_name)
+/*
+ * Check if the hash is reachable anywhere in a DIF.
+ * FIXME: specify algorithm used
+ */
+static struct ipcp_entry * get_ipcp_by_dst_name(const char * name)
{
struct list_head * p = NULL;
+ uint8_t * hash;
list_for_each(p, &irmd.ipcps) {
struct ipcp_entry * e =
list_entry(p, struct ipcp_entry, next);
- if (e->type == IPCP_LOCAL) {
- if (ipcp_name_query(e->api, dst_name) == 0)
- return e->api;
- }
- }
+ hash = malloc(e->dir_hash_len);
+ if (hash == NULL)
+ return NULL;
- list_for_each(p, &irmd.ipcps) {
- struct ipcp_entry * e =
- list_entry(p, struct ipcp_entry, next);
- if (e->type == IPCP_NORMAL) {
- if (ipcp_name_query(e->api, dst_name) == 0)
- return e->api;
- }
- }
+ get_hash(hash, name);
- list_for_each(p, &irmd.ipcps) {
- struct ipcp_entry * e =
- list_entry(p, struct ipcp_entry, next);
- if (e->type == IPCP_SHIM_ETH_LLC) {
- if (ipcp_name_query(e->api, dst_name) == 0)
- return e->api;
+ if (ipcp_query(e->api, hash, e->dir_hash_len) == 0) {
+ free(hash);
+ return e;
}
- }
- list_for_each(p, &irmd.ipcps) {
- struct ipcp_entry * e =
- list_entry(p, struct ipcp_entry, next);
- if (e->type == IPCP_SHIM_UDP) {
- if (ipcp_name_query(e->api, dst_name) == 0)
- return e->api;
- }
+ free(hash);
}
- return -1;
+ return NULL;
}
static pid_t create_ipcp(char * name,
@@ -317,14 +306,16 @@ static pid_t create_ipcp(char * name,
tmp->dif_name = NULL;
tmp->type = ipcp_type;
tmp->init = false;
+ /* FIXME: ipcp dir_hash_len should be configurable */
+ tmp->dir_hash_len = SHA3_256_HASH_LEN;
list_for_each(p, &irmd.ipcps) {
struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next);
- if (e->type < ipcp_type)
+ if (e->type > ipcp_type)
break;
}
- list_add(&tmp->next, &irmd.ipcps);
+ list_add_tail(&tmp->next, &irmd.ipcps);
list_add(&api->next, &irmd.spawned_apis);
@@ -411,7 +402,7 @@ static int destroy_ipcp(pid_t api)
}
static int bootstrap_ipcp(pid_t api,
- dif_config_msg_t * conf)
+ ipcp_config_msg_t * conf)
{
struct ipcp_entry * entry = NULL;
@@ -709,16 +700,18 @@ static ssize_t list_ipcps(char * name,
return count;
}
-static int name_reg(char * name,
- char ** difs,
- size_t len)
+static int name_reg(const char * name,
+ char ** difs,
+ size_t len)
{
size_t i;
int ret = 0;
struct list_head * p = NULL;
- if (name == NULL || difs == NULL || len == 0 || difs[0] == NULL)
- return -EINVAL;
+ assert(name);
+ assert(len);
+ assert(difs);
+ assert(difs[0]);
pthread_rwlock_wrlock(&irmd.reg_lock);
@@ -729,7 +722,7 @@ static int name_reg(char * name,
if (!registry_has_name(&irmd.registry, name)) {
struct reg_entry * re =
- registry_add_name(&irmd.registry, strdup(name));
+ registry_add_name(&irmd.registry, name);
if (re == NULL) {
log_err("Failed creating registry entry for %s.", name);
pthread_rwlock_unlock(&irmd.reg_lock);
@@ -768,12 +761,21 @@ static int name_reg(char * name,
continue;
for (i = 0; i < len; ++i) {
+ uint8_t * hash;
+
if (wildcard_match(difs[i], e->dif_name))
continue;
- if (ipcp_name_reg(e->api, name)) {
- log_err("Could not register %s in DIF %s.",
- name, e->dif_name);
+ hash = malloc(e->dir_hash_len);
+ if (hash == NULL)
+ break;
+
+ get_hash(hash, name);
+
+ if (ipcp_reg(e->api, hash, e->dir_hash_len)) {
+ log_err("Could not register " HASH_FMT
+ " in DIF %s.",
+ HASH_VAL(hash), e->dif_name);
} else {
if (registry_add_name_to_dif(&irmd.registry,
name,
@@ -782,10 +784,12 @@ static int name_reg(char * name,
log_warn("Registered unbound name %s. "
"Registry may be corrupt.",
name);
- log_info("Registered %s in %s as %s.",
- name, e->dif_name, name);
+ log_info("Registered %s in %s as " HASH_FMT ".",
+ name, e->dif_name, HASH_VAL(hash));
++ret;
}
+
+ free(hash);
}
}
@@ -794,16 +798,18 @@ static int name_reg(char * name,
return (ret > 0 ? 0 : -1);
}
-static int name_unreg(char * name,
- char ** difs,
- size_t len)
+static int name_unreg(const char * name,
+ char ** difs,
+ size_t len)
{
size_t i;
int ret = 0;
struct list_head * pos = NULL;
- if (name == NULL || len == 0 || difs == NULL || difs[0] == NULL)
- return -1;
+ assert(name);
+ assert(len);
+ assert(difs);
+ assert(difs[0]);
pthread_rwlock_wrlock(&irmd.reg_lock);
@@ -815,10 +821,18 @@ static int name_unreg(char * name,
continue;
for (i = 0; i < len; ++i) {
+ uint8_t * hash;
+
if (wildcard_match(difs[i], e->dif_name))
continue;
- if (ipcp_name_unreg(e->api, name)) {
+ hash = malloc(e->dir_hash_len);
+ if (hash == NULL)
+ break;
+
+ get_hash(hash, name);
+
+ if (ipcp_unreg(e->api, hash, e->dir_hash_len)) {
log_err("Could not unregister %s in DIF %s.",
name, e->dif_name);
} else {
@@ -829,6 +843,8 @@ static int name_unreg(char * name,
name, e->dif_name);
++ret;
}
+
+ free(hash);
}
}
@@ -1038,22 +1054,23 @@ static int flow_accept(pid_t api,
}
static int flow_alloc(pid_t api,
- char * dst_name,
+ const char * dst,
qoscube_t cube,
struct timespec * timeo,
struct irm_flow ** e)
{
- struct irm_flow * f;
- pid_t ipcp;
- int port_id;
- int state;
+ struct irm_flow * f;
+ struct ipcp_entry * ipcp;
+ int port_id;
+ int state;
+ uint8_t * hash;
pthread_rwlock_rdlock(&irmd.reg_lock);
- ipcp = get_ipcp_by_dst_name(dst_name);
- if (ipcp == -1) {
+ ipcp = get_ipcp_by_dst_name(dst);
+ if (ipcp == NULL) {
pthread_rwlock_unlock(&irmd.reg_lock);
- log_info("Destination unreachable.");
+ log_info("Destination %s unreachable.", dst);
return -1;
}
@@ -1066,7 +1083,7 @@ static int flow_alloc(pid_t api,
return -EBADF;
}
- f = irm_flow_create(api, ipcp, port_id, cube);
+ f = irm_flow_create(api, ipcp->api, port_id, cube);
if (f == NULL) {
bmp_release(irmd.port_ids, port_id);
pthread_rwlock_unlock(&irmd.flows_lock);
@@ -1080,12 +1097,24 @@ static int flow_alloc(pid_t api,
assert(irm_flow_get_state(f) == FLOW_ALLOC_PENDING);
- if (ipcp_flow_alloc(ipcp, port_id, api, dst_name, cube)) {
+ hash = malloc(ipcp->dir_hash_len);
+ if (hash == NULL) {
+ /* sanitizer cleans this */
+ return -ENOMEM;
+ }
+
+ get_hash(hash, dst);
+
+ if (ipcp_flow_alloc(ipcp->api, port_id, api, hash,
+ ipcp->dir_hash_len, cube)) {
/* sanitizer cleans this */
log_info("Flow_allocation failed.");
+ free(hash);
return -EAGAIN;
}
+ free(hash);
+
state = irm_flow_wait_state(f, FLOW_ALLOCATED, timeo);
if (state != FLOW_ALLOCATED) {
if (state == -ETIMEDOUT) {
@@ -1093,7 +1122,7 @@ static int flow_alloc(pid_t api,
return -ETIMEDOUT;
}
- log_info("Pending flow to %s torn down.", dst_name);
+ log_info("Pending flow to %s torn down.", dst);
return -EPIPE;
}
@@ -1191,38 +1220,49 @@ static pid_t auto_execute(char ** argv)
exit(EXIT_FAILURE);
}
-static struct irm_flow * flow_req_arr(pid_t api,
- char * dst_name,
- qoscube_t cube)
+static struct irm_flow * flow_req_arr(pid_t api,
+ const uint8_t * hash,
+ qoscube_t cube)
{
struct reg_entry * re = NULL;
struct apn_entry * a = NULL;
struct api_entry * e = NULL;
struct irm_flow * f = NULL;
- struct pid_el * c_api;
- pid_t h_api = -1;
- int port_id = -1;
+ struct pid_el * c_api;
+ struct ipcp_entry * ipcp;
+ pid_t h_api = -1;
+ int port_id = -1;
struct timespec wt = {IRMD_REQ_ARR_TIMEOUT / 1000,
(IRMD_REQ_ARR_TIMEOUT % 1000) * MILLION};
- log_dbg("Flow req arrived from IPCP %d for %s.", api, dst_name);
+ log_dbg("Flow req arrived from IPCP %d for " HASH_FMT ".",
+ api, HASH_VAL(hash));
pthread_rwlock_rdlock(&irmd.reg_lock);
- re = registry_get_entry(&irmd.registry, dst_name);
+ ipcp = get_ipcp_entry_by_api(api);
+ if (ipcp == NULL) {
+ log_err("IPCP died.");
+ return NULL;
+ }
+
+ re = registry_get_entry_by_hash(&irmd.registry, hash,
+ ipcp->dir_hash_len);
if (re == NULL) {
pthread_rwlock_unlock(&irmd.reg_lock);
- log_err("Unknown name: %s.", dst_name);
+ log_err("Unknown hash: " HASH_FMT ".", HASH_VAL(hash));
return NULL;
}
+ log_info("Flow request arrived for %s.", re->name);
+
pthread_rwlock_unlock(&irmd.reg_lock);
/* Give the AP a bit of slop time to call accept */
if (reg_entry_leave_state(re, REG_NAME_IDLE, &wt) == -1) {
- log_err("No APs for %s.", dst_name);
+ log_err("No APs for " HASH_FMT ".", HASH_VAL(hash));
return NULL;
}
@@ -1231,7 +1271,7 @@ static struct irm_flow * flow_req_arr(pid_t api,
switch (reg_entry_get_state(re)) {
case REG_NAME_IDLE:
pthread_rwlock_unlock(&irmd.reg_lock);
- log_err("No APs for %s.", dst_name);
+ log_err("No APs for " HASH_FMT ".", HASH_VAL(hash));
return NULL;
case REG_NAME_AUTO_ACCEPT:
c_api = malloc(sizeof(*c_api));
@@ -1830,7 +1870,7 @@ void * mainloop(void * o)
break;
case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:
e = flow_req_arr(msg->api,
- msg->dst_name,
+ msg->hash.data,
msg->qoscube);
ret_msg.has_result = true;
if (e == NULL) {