From f0646875d0bc941e339d305d0c68b13543cd6f2a Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 25 Oct 2016 13:22:51 +0200 Subject: lib, irmd, ipcpd: Add name querying to IPCPs This adds the ability to query IPCPs if a name can be reached through them, e.g. if a name is available in a DIF. This means that in the shim-udp a DNS query is performed, in the shim-eth-llc an ARP-like query has been added, in the local a check is done to see if the name is registered, and in the normal currently no application is reachable through it. --- src/irmd/ipcp.c | 32 ++++++++++++++++--- src/irmd/ipcp.h | 2 ++ src/irmd/main.c | 91 +++++++++++++++++++++++++---------------------------- src/irmd/registry.c | 45 +++----------------------- src/irmd/registry.h | 9 ++---- 5 files changed, 79 insertions(+), 100 deletions(-) (limited to 'src/irmd') diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index 33f7650a..29327df4 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -20,15 +20,14 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define OUROBOROS_PREFIX "irmd/ipcp" + #include +#include #include #include #include -#define OUROBOROS_PREFIX "irmd/ipcp" - -#include - #include "ipcp.h" #include @@ -302,6 +301,31 @@ int ipcp_name_unreg(pid_t api, return ret; } +int ipcp_name_query(pid_t api, + char * name) +{ + ipcp_msg_t msg = IPCP_MSG__INIT; + ipcp_msg_t * recv_msg = NULL; + int ret = -1; + + msg.code = IPCP_MSG_CODE__IPCP_NAME_QUERY; + msg.name = name; + + recv_msg = send_recv_ipcp_msg(api, &msg); + if (recv_msg == NULL) + return -1; + + if (recv_msg->has_result == false) { + ipcp_msg__free_unpacked(recv_msg, NULL); + return -1; + } + + ret = recv_msg->result; + ipcp_msg__free_unpacked(recv_msg, NULL); + + return ret; +} + int ipcp_flow_alloc(pid_t api, int port_id, pid_t n_api, diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index 930695fa..67b14ece 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -44,6 +44,8 @@ int ipcp_name_reg(pid_t api, char * name); int ipcp_name_unreg(pid_t api, char * name); +int ipcp_name_query(pid_t api, + char * name); int ipcp_flow_alloc(pid_t api, int port_id, diff --git a/src/irmd/main.c b/src/irmd/main.c index 3884a9a7..aac47adb 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -21,6 +21,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define OUROBOROS_PREFIX "irmd" + #include #include #include @@ -33,9 +35,6 @@ #include #include #include - -#define OUROBOROS_PREFIX "irmd" - #include #include "utils.h" @@ -170,52 +169,45 @@ static struct ipcp_entry * get_ipcp_entry_by_api(pid_t api) return NULL; } -/* FIXME: Check if the name exists anywhere in a DIF. */ +/* Check if the name exists anywhere in a DIF. */ static pid_t get_ipcp_by_dst_name(char * dst_name) { struct list_head * p = NULL; - char * dif_name = - registry_get_dif_for_dst(&irmd->registry, dst_name); - if (dif_name == NULL) { - list_for_each(p, &irmd->ipcps) { - struct ipcp_entry * e = - list_entry(p, struct ipcp_entry, next); - if (e->type == IPCP_NORMAL) { - dif_name = e->dif_name; - break; - } - } - list_for_each(p, &irmd->ipcps) { - struct ipcp_entry * e = - list_entry(p, struct ipcp_entry, next); - if (e->type == IPCP_SHIM_ETH_LLC) { - dif_name = e->dif_name; - break; - } + 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; } + } - - list_for_each(p, &irmd->ipcps) { - struct ipcp_entry * e = - list_entry(p, struct ipcp_entry, next); - if (e->type == IPCP_SHIM_UDP) { - dif_name = e->dif_name; - break; - } + 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; } } - if (dif_name == NULL) - return -1; - list_for_each(p, &irmd->ipcps) { - struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); - if (e->dif_name == NULL) - continue; + 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 (strcmp(e->dif_name, dif_name) == 0) - return e->api; + 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; + } } return -1; @@ -1136,6 +1128,18 @@ static struct irm_flow * flow_alloc(pid_t api, return NULL; } + pthread_rwlock_rdlock(&irmd->reg_lock); + + ipcp = get_ipcp_by_dst_name(dst_name); + if (ipcp == -1) { + pthread_rwlock_unlock(&irmd->reg_lock); + pthread_rwlock_unlock(&irmd->state_lock); + LOG_INFO("Destination unreachable."); + return NULL; + } + + pthread_rwlock_unlock(&irmd->reg_lock); + f = irm_flow_create(); if (f == NULL) { pthread_rwlock_unlock(&irmd->state_lock); @@ -1149,17 +1153,6 @@ static struct irm_flow * flow_alloc(pid_t api, if (clock_gettime(CLOCK_MONOTONIC, &f->t0) < 0) LOG_WARN("Failed to set timestamp."); - pthread_rwlock_rdlock(&irmd->reg_lock); - - ipcp = get_ipcp_by_dst_name(dst_name); - if (ipcp == -1) { - pthread_rwlock_unlock(&irmd->reg_lock); - pthread_rwlock_unlock(&irmd->state_lock); - LOG_INFO("Destination unreachable."); - return NULL; - } - - pthread_rwlock_unlock(&irmd->reg_lock); pthread_rwlock_wrlock(&irmd->flows_lock); port_id = f->port_id = bmp_allocate(irmd->port_ids); diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 9442f3db..07ec370c 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -20,15 +20,16 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "registry.h" -#include "utils.h" - #define OUROBOROS_PREFIX "registry" +#include #include #include #include +#include "registry.h" +#include "utils.h" + #include #include #include @@ -405,44 +406,6 @@ void registry_del_api(struct list_head * registry, return; } -char * registry_get_dif_for_dst(struct list_head * registry, - char * dst_name) -{ - struct list_head * pos = NULL; - struct reg_entry * re = - registry_get_entry(registry, dst_name); - - if (re != NULL) { /* local AP */ - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_LOCAL) - return rd->dif_name; - } - - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_NORMAL) - return rd->dif_name; - } - - list_for_each(pos, &re->difs) { - struct reg_dif * rd = - list_entry(pos, struct reg_dif, next); - if (rd->type == IPCP_SHIM_UDP) - return rd->dif_name; - } - - LOG_DBG("Could not find DIF for %s.", dst_name); - - return NULL; - } else { - LOG_DBG("No local ap %s found.", dst_name); - return NULL; - } -} - int registry_add_name_to_dif(struct list_head * registry, char * name, char * dif_name, diff --git a/src/irmd/registry.h b/src/irmd/registry.h index 35c4c10b..10cb12e8 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -27,15 +27,15 @@ #include #include +#include "api_table.h" +#include "apn_table.h" + #include #include #include #include #include -#include "api_table.h" -#include "apn_table.h" - #define registry_has_name(r, name) \ (registry_get_entry(r, name) != NULL) @@ -99,9 +99,6 @@ void registry_sanitize_apis(struct list_head * registry); struct reg_entry * registry_get_entry(struct list_head * registry, char * name); -char * registry_get_dif_for_dst(struct list_head * registry, - char * dst_name); - int registry_add_name_to_dif(struct list_head * registry, char * name, char * dif_name, -- cgit v1.2.3