From b398dbe5cfd12b928e00f9a22cd6826bbdfb18d7 Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Wed, 26 Apr 2017 20:31:39 +0200 Subject: ipcpd: Add capability reporting The IPCP will now report the DIF name and the hash value to the IRMd as a dif_info struct. This can later be extended to add further capability reporting. Some bugfixes in normal. Fixes #24 --- include/ouroboros/ipcp.h | 8 ++++++ src/ipcpd/ipcp.c | 12 +++++++-- src/ipcpd/ipcp.h | 3 ++- src/ipcpd/normal/main.c | 29 +++++++++++--------- src/irmd/ipcp.c | 26 +++++++++++++----- src/irmd/ipcp.h | 7 ++--- src/irmd/main.c | 64 +++++++++++++++++++++++++------------------- src/lib/ipcpd_messages.proto | 6 +++-- 8 files changed, 102 insertions(+), 53 deletions(-) diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h index b9c5b740..f418d640 100644 --- a/include/ouroboros/ipcp.h +++ b/include/ouroboros/ipcp.h @@ -86,4 +86,12 @@ struct ipcp_config { char * if_name; }; +#define DIF_NAME_SIZE 256 + +/* capability report of a DIF */ +struct dif_info { + enum hash_algo algo; + char dif_name[DIF_NAME_SIZE]; +}; + #endif /* OUROBOROS_IPCP_H */ diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index d682309d..7f3ebc73 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -143,9 +143,10 @@ static void * ipcp_main_loop(void * o) ipcp_config_msg_t * conf_msg; struct ipcp_config conf; + struct dif_info info; struct timeval ltv = {(SOCKET_TIMEOUT / 1000), - (SOCKET_TIMEOUT % 1000) * 1000}; + (SOCKET_TIMEOUT % 1000) * 1000}; ssize_t id = (ssize_t) o; @@ -259,7 +260,14 @@ static void * ipcp_main_loop(void * o) break; } - ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name); + ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name, + &info); + + if (ret_msg.result == 0) { + ret_msg.has_dir_hash_algo = true; + ret_msg.dir_hash_algo = info.algo; + ret_msg.dif_name = info.dif_name; + } break; case IPCP_MSG_CODE__IPCP_REG: ret_msg.has_result = true; diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index c78aa5a6..3f5e1bd6 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -43,7 +43,8 @@ enum ipcp_state { struct ipcp_ops { int (* ipcp_bootstrap)(const struct ipcp_config * conf); - int (* ipcp_enroll)(const char * dst); + int (* ipcp_enroll)(const char * dst, + struct dif_info * info); int (* ipcp_reg)(const uint8_t * hash); diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index ab8cf387..9228f36b 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -116,21 +116,21 @@ static int boot_components(void) log_dbg("Starting ribmgr."); - if (ribmgr_init()) { - log_err("Failed to initialize RIB manager."); + if (dir_init()) { + log_err("Failed to initialize directory."); goto fail_addr_auth; } - if (dir_init()) { - log_err("Failed to initialize directory."); - goto fail_ribmgr; + if (ribmgr_init()) { + log_err("Failed to initialize RIB manager."); + goto fail_dir; } log_dbg("Ribmgr started."); if (frct_init()) { log_err("Failed to initialize FRCT."); - goto fail_dir; + goto fail_ribmgr; } if (fa_init()) { @@ -180,10 +180,10 @@ static int boot_components(void) fa_fini(); fail_frct: frct_fini(); - fail_dir: - dir_fini(); fail_ribmgr: ribmgr_fini(); + fail_dir: + dir_fini(); fail_addr_auth: addr_auth_fini(); fail_name: @@ -208,16 +208,17 @@ void shutdown_components(void) frct_fini(); - dir_fini(); - ribmgr_fini(); + dir_fini(); + addr_auth_fini(); free(ipcpi.dif_name); } -static int normal_ipcp_enroll(const char * dst) +static int normal_ipcp_enroll(const char * dst, + struct dif_info * info) { if (rib_add(RIB_ROOT, MEMBERS_NAME)) { log_err("Failed to create members."); @@ -237,7 +238,11 @@ static int normal_ipcp_enroll(const char * dst) log_dbg("Enrolled with " HASH_FMT, HASH_VAL(dst)); - return ipcpi.dir_hash_algo; + info->algo = ipcpi.dir_hash_algo; + + strcpy(info->dif_name, ipcpi.dif_name); + + return 0; } const struct ros { diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index 7a32dd88..182970b1 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -212,13 +212,13 @@ int ipcp_bootstrap(pid_t api, return ret; } -/* return the hash algorithm */ -int ipcp_enroll(pid_t api, - const char * dst) +int ipcp_enroll(pid_t api, + const char * dst, + struct dif_info * info) { - ipcp_msg_t msg = IPCP_MSG__INIT; + ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; - int ret = -1; + int ret = -1; if (dst == NULL) return -EINVAL; @@ -236,9 +236,23 @@ int ipcp_enroll(pid_t api, } ret = recv_msg->result; + if (ret != 0) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return ret; + } + + if (!recv_msg->has_dir_hash_algo || recv_msg->dif_name == NULL) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return -EIPCP; + } + + info->algo = recv_msg->dir_hash_algo; + + strcpy(info->dif_name, recv_msg->dif_name); + ipcp_msg__free_unpacked(recv_msg, NULL); - return ret; + return 0; } int ipcp_reg(pid_t api, diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index 11adad7d..74175f97 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -34,10 +34,11 @@ pid_t ipcp_create(const char * name, int ipcp_destroy(pid_t api); -int ipcp_enroll(pid_t api, - const char * dst); +int ipcp_enroll(pid_t api, + const char * dst, + struct dif_info * info); -int ipcp_bootstrap(pid_t api, +int ipcp_bootstrap(pid_t api, ipcp_config_msg_t * conf); int ipcp_reg(pid_t api, diff --git a/src/irmd/main.c b/src/irmd/main.c index 45a348ae..67c2ad60 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -56,7 +56,7 @@ #define IRMD_CLEANUP_TIMER ((IRMD_FLOW_TIMEOUT / 20) * MILLION) /* ns */ #define SHM_SAN_HOLDOFF 1000 /* ms */ -#define IPCP_HASH_LEN(e) (hash_len(e->dir_hash_algo)) +#define IPCP_HASH_LEN(e) hash_len(e->dir_hash_algo) struct ipcp_entry { struct list_head next; @@ -226,27 +226,26 @@ static struct ipcp_entry * get_ipcp_entry_by_name(const char * name) return NULL; } -/* - * 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->dir_hash_algo < 0) + struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); + if (e->dif_name == NULL) continue; + + log_dbg("IPCP %s found for name %s with hash enum %d.", + e->dif_name, name, e->dir_hash_algo); + hash = malloc(IPCP_HASH_LEN(e)); if (hash == NULL) return NULL; str_hash(e->dir_hash_algo, hash, name); - if (ipcp_query(e->api, hash, hash_len(e->dir_hash_algo)) == 0) { + if (ipcp_query(e->api, hash, IPCP_HASH_LEN(e)) == 0) { free(hash); return e; } @@ -319,10 +318,10 @@ static pid_t create_ipcp(char * name, list_add(&api->next, &irmd.spawned_apis); - pthread_mutex_lock(&tmp->init_lock); - pthread_rwlock_unlock(&irmd.reg_lock); + pthread_mutex_lock(&tmp->init_lock); + while (tmp->init == false) pthread_cond_wait(&tmp->init_cond, &tmp->init_lock); @@ -401,7 +400,7 @@ static int destroy_ipcp(pid_t api) return 0; } -static int bootstrap_ipcp(pid_t api, +static int bootstrap_ipcp(pid_t api, ipcp_config_msg_t * conf) { struct ipcp_entry * entry = NULL; @@ -445,9 +444,10 @@ static int bootstrap_ipcp(pid_t api, } static int enroll_ipcp(pid_t api, - char * dif_name) + char * dst_name) { struct ipcp_entry * entry = NULL; + struct dif_info info; pthread_rwlock_wrlock(&irmd.reg_lock); @@ -464,27 +464,35 @@ static int enroll_ipcp(pid_t api, return -1; } - entry->dif_name = strdup(dif_name); - if (entry->dif_name == NULL) { - pthread_rwlock_unlock(&irmd.reg_lock); - log_err("Failed to strdup."); + pthread_rwlock_unlock(&irmd.reg_lock); + + if (ipcp_enroll(api, dst_name, &info) < 0) { + log_err("Could not enroll IPCP."); return -1; } - pthread_rwlock_unlock(&irmd.reg_lock); + pthread_rwlock_wrlock(&irmd.reg_lock); - entry->dir_hash_algo = ipcp_enroll(api, dif_name); - if (entry->dir_hash_algo < 0) { - pthread_rwlock_wrlock(&irmd.reg_lock); - free(entry->dif_name); - entry->dif_name = NULL; + entry = get_ipcp_entry_by_api(api); + if (entry == NULL) { pthread_rwlock_unlock(&irmd.reg_lock); - log_err("Could not enroll IPCP."); + log_err("No such IPCP."); return -1; } + entry->dif_name = strdup(info.dif_name); + if (entry->dif_name == NULL) { + pthread_rwlock_unlock(&irmd.reg_lock); + log_err("Failed to strdup dif_name."); + return -ENOMEM; + } + + entry->dir_hash_algo = info.algo; + + pthread_rwlock_unlock(&irmd.reg_lock); + log_info("Enrolled IPCP %d in DIF %s.", - api, dif_name); + api, info.dif_name); return 0; } @@ -769,6 +777,9 @@ static int name_reg(const char * name, if (wildcard_match(difs[i], e->dif_name)) continue; + log_dbg("gonna register %s in dif %s.", + name, e->dif_name); + hash = malloc(IPCP_HASH_LEN(e)); if (hash == NULL) break; @@ -1101,10 +1112,9 @@ static int flow_alloc(pid_t api, assert(irm_flow_get_state(f) == FLOW_ALLOC_PENDING); hash = malloc(IPCP_HASH_LEN(ipcp)); - if (hash == NULL) { + if (hash == NULL) /* sanitizer cleans this */ return -ENOMEM; - } str_hash(ipcp->dir_hash_algo, hash, dst); diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index bd71d3f3..9299afcd 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -46,6 +46,8 @@ message ipcp_msg { optional uint32 qoscube = 6; optional ipcp_config_msg conf = 7; optional int32 api = 8; - optional int32 response = 9; - optional int32 result = 10; + optional int32 dir_hash_algo = 9; + optional string dif_name = 10; + optional int32 response = 11; + optional int32 result = 12; }; -- cgit v1.2.3