summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander Vrijders <[email protected]>2016-10-25 13:22:51 +0200
committerSander Vrijders <[email protected]>2016-10-26 11:52:53 +0200
commitf0646875d0bc941e339d305d0c68b13543cd6f2a (patch)
tree0a3dde0e4f6284ece935d6eff99f26234126f1ab
parent1c06b9ff80a2bf7ee6042534fee6098f7e452b59 (diff)
downloadouroboros-f0646875d0bc941e339d305d0c68b13543cd6f2a.tar.gz
ouroboros-f0646875d0bc941e339d305d0c68b13543cd6f2a.zip
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.
-rw-r--r--src/ipcpd/ipcp-data.c308
-rw-r--r--src/ipcpd/ipcp-data.h56
-rw-r--r--src/ipcpd/ipcp-ops.h2
-rw-r--r--src/ipcpd/ipcp.c17
-rw-r--r--src/ipcpd/local/main.c25
-rw-r--r--src/ipcpd/normal/main.c30
-rw-r--r--src/ipcpd/shim-eth-llc/main.c114
-rw-r--r--src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto10
-rw-r--r--src/ipcpd/shim-udp/main.c130
-rw-r--r--src/irmd/ipcp.c32
-rw-r--r--src/irmd/ipcp.h2
-rw-r--r--src/irmd/main.c91
-rw-r--r--src/irmd/registry.c45
-rw-r--r--src/irmd/registry.h9
-rw-r--r--src/lib/ipcpd_messages.proto9
15 files changed, 604 insertions, 276 deletions
diff --git a/src/ipcpd/ipcp-data.c b/src/ipcpd/ipcp-data.c
index ed7e578d..b3078054 100644
--- a/src/ipcpd/ipcp-data.c
+++ b/src/ipcpd/ipcp-data.c
@@ -21,14 +21,16 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <ouroboros/config.h>
-#include <ouroboros/list.h>
-
#define OUROBOROS_PREFIX "ipcp-utils"
+#include <ouroboros/config.h>
+#include <ouroboros/list.h>
+#include <ouroboros/time_utils.h>
#include <ouroboros/logs.h>
+#include <ouroboros/errno.h>
#include "ipcp-data.h"
+#include "ipcp.h"
#include <string.h>
#include <stdlib.h>
@@ -41,8 +43,8 @@ struct reg_entry {
struct dir_entry {
struct list_head list;
- char * ap_name;
- uint64_t addr;
+ char * name;
+ uint64_t addr;
};
static struct reg_entry * reg_entry_create(char * name)
@@ -70,18 +72,18 @@ static void reg_entry_destroy(struct reg_entry * entry)
free(entry);
}
-static struct dir_entry * dir_entry_create(char * ap_name,
+static struct dir_entry * dir_entry_create(char * name,
uint64_t addr)
{
struct dir_entry * entry = malloc(sizeof(*entry));
if (entry == NULL)
return NULL;
- assert(ap_name);
+ assert(name);
entry->addr = addr;
- entry->ap_name = ap_name;
- if (entry->ap_name == NULL)
+ entry->name = name;
+ if (entry->name == NULL)
return NULL;
return entry;
@@ -91,8 +93,8 @@ static void dir_entry_destroy(struct dir_entry * entry)
{
assert(entry);
- if (entry->ap_name != NULL)
- free(entry->ap_name);
+ if (entry->name != NULL)
+ free(entry->name);
free(entry);
}
@@ -120,10 +122,12 @@ struct ipcp_data * ipcp_data_init(struct ipcp_data * dst,
/* init the lists */
INIT_LIST_HEAD(&dst->registry);
INIT_LIST_HEAD(&dst->directory);
+ INIT_LIST_HEAD(&dst->dir_queries);
/* init the locks */
pthread_rwlock_init(&dst->reg_lock, NULL);
pthread_rwlock_init(&dst->dir_lock, NULL);
+ pthread_mutex_init(&dst->dir_queries_lock, NULL);
return dst;
}
@@ -156,6 +160,20 @@ static void clear_directory(struct ipcp_data * data)
}
}
+static void clear_dir_queries(struct ipcp_data * data)
+{
+ struct list_head * h;
+ struct list_head * t;
+
+ assert(data);
+
+ list_for_each_safe(h, t, &data->dir_queries) {
+ struct dir_query * e = list_entry(h, struct dir_query, next);
+ list_del(&e->next);
+ ipcp_data_dir_query_destroy(e);
+ }
+}
+
void ipcp_data_destroy(struct ipcp_data * data)
{
if (data == NULL)
@@ -163,27 +181,27 @@ void ipcp_data_destroy(struct ipcp_data * data)
/* clear the lists */
pthread_rwlock_wrlock(&data->reg_lock);
-
clear_registry(data);
-
pthread_rwlock_unlock(&data->reg_lock);
- pthread_rwlock_wrlock(&data->dir_lock);
+ pthread_rwlock_wrlock(&data->dir_lock);
clear_directory(data);
-
pthread_rwlock_unlock(&data->dir_lock);
+ pthread_mutex_lock(&data->dir_queries_lock);
+ clear_dir_queries(data);
+ pthread_mutex_unlock(&data->dir_queries_lock);
+
if (data->dif_name != NULL)
free(data->dif_name);
pthread_rwlock_destroy(&data->dir_lock);
pthread_rwlock_destroy(&data->reg_lock);
+ pthread_mutex_destroy(&data->dir_queries_lock);
free(data);
}
-
-
static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data,
const char * name)
{
@@ -202,13 +220,13 @@ static struct reg_entry * find_reg_entry_by_name(struct ipcp_data * data,
}
static struct dir_entry * find_dir_entry(struct ipcp_data * data,
- const char * ap_name,
+ const char * name,
uint64_t addr)
{
struct list_head * h;
list_for_each(h, &data->directory) {
struct dir_entry * e = list_entry(h, struct dir_entry, list);
- if (e->addr == addr && !strcmp(e->ap_name, ap_name))
+ if (e->addr == addr && !strcmp(e->name, name))
return e;
}
@@ -216,33 +234,47 @@ static struct dir_entry * find_dir_entry(struct ipcp_data * data,
}
static struct dir_entry * find_dir_entry_any(struct ipcp_data * data,
- const char * ap_name)
+ const char * name)
{
struct list_head * h;
list_for_each(h, &data->directory) {
struct dir_entry * e = list_entry(h, struct dir_entry, list);
- if (!strcmp(e->ap_name, ap_name))
+ if (!strcmp(e->name, name))
return e;
}
return NULL;
}
-bool ipcp_data_is_in_directory(struct ipcp_data * data,
- const char * ap_name)
+int ipcp_data_reg_add_entry(struct ipcp_data * data,
+ char * name)
{
- bool ret = false;
+ struct reg_entry * entry;
- pthread_rwlock_rdlock(&data->dir_lock);
+ if (data == NULL || name == NULL)
+ return -1;
- ret = (find_dir_entry_any(data, ap_name) != NULL);
+ pthread_rwlock_wrlock(&data->reg_lock);
- pthread_rwlock_unlock(&data->dir_lock);
+ if (find_reg_entry_by_name(data, name)) {
+ pthread_rwlock_unlock(&data->reg_lock);
+ return -1;
+ }
- return ret;
+ entry = reg_entry_create(name);
+ if (entry == NULL) {
+ pthread_rwlock_unlock(&data->reg_lock);
+ return -1;
+ }
+
+ list_add(&entry->list, &data->registry);
+
+ pthread_rwlock_unlock(&data->reg_lock);
+
+ return 0;
}
-int ipcp_data_del_reg_entry(struct ipcp_data * data,
+int ipcp_data_reg_del_entry(struct ipcp_data * data,
const char * name)
{
struct reg_entry * e;
@@ -266,114 +298,109 @@ int ipcp_data_del_reg_entry(struct ipcp_data * data,
return 0;
}
-int ipcp_data_del_dir_entry(struct ipcp_data * data,
- const char * ap_name,
- uint64_t addr)
+bool ipcp_data_reg_has(struct ipcp_data * data,
+ const char * name)
{
- struct dir_entry * e;
- if (data == NULL)
- return -1;
-
- pthread_rwlock_wrlock(&data->dir_lock);
+ bool ret = false;
- e = find_dir_entry(data, ap_name, addr);
- if (e == NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return 0; /* nothing to do */
- }
+ if (data == NULL || name == NULL)
+ return false;
- list_del(&e->list);
+ pthread_rwlock_rdlock(&data->reg_lock);
- pthread_rwlock_unlock(&data->dir_lock);
+ ret = (find_reg_entry_by_name(data, name) != NULL);
- dir_entry_destroy(e);
+ pthread_rwlock_unlock(&data->reg_lock);
- return 0;
+ return ret;
}
-int ipcp_data_add_reg_entry(struct ipcp_data * data,
- char * name)
+int ipcp_data_dir_add_entry(struct ipcp_data * data,
+ char * name,
+ uint64_t addr)
{
- struct reg_entry * entry;
+ struct dir_entry * entry;
+ char * entry_name;
if (data == NULL || name == NULL)
return -1;
- pthread_rwlock_wrlock(&data->reg_lock);
+ pthread_rwlock_wrlock(&data->dir_lock);
- if (find_reg_entry_by_name(data, name)) {
- pthread_rwlock_unlock(&data->reg_lock);
+ if (find_dir_entry(data, name, addr) != NULL) {
+ pthread_rwlock_unlock(&data->dir_lock);
return -1;
}
- entry = reg_entry_create(name);
+ entry_name = strdup(name);
+ if (entry_name == NULL) {
+ pthread_rwlock_unlock(&data->dir_lock);
+ return -1;
+ }
+
+ entry = dir_entry_create(entry_name, addr);
if (entry == NULL) {
- pthread_rwlock_unlock(&data->reg_lock);
+ pthread_rwlock_unlock(&data->dir_lock);
return -1;
}
- list_add(&entry->list, &data->registry);
+ list_add(&entry->list,&data->directory);
- pthread_rwlock_unlock(&data->reg_lock);
+ pthread_rwlock_unlock(&data->dir_lock);
+
+ LOG_DBG("Added directory entry for %s.", entry_name);
return 0;
}
-int ipcp_data_add_dir_entry(struct ipcp_data * data,
- char * ap_name,
+int ipcp_data_dir_del_entry(struct ipcp_data * data,
+ const char * name,
uint64_t addr)
{
- struct dir_entry * entry;
-
- if (data == NULL || ap_name == NULL)
+ struct dir_entry * e;
+ if (data == NULL)
return -1;
pthread_rwlock_wrlock(&data->dir_lock);
- if (find_dir_entry(data, ap_name, addr) != NULL) {
- pthread_rwlock_unlock(&data->dir_lock);
- return -1;
- }
-
- entry = dir_entry_create(ap_name, addr);
- if (entry == NULL) {
+ e = find_dir_entry(data, name, addr);
+ if (e == NULL) {
pthread_rwlock_unlock(&data->dir_lock);
- return -1;
+ return 0; /* nothing to do */
}
- list_add(&entry->list,&data->directory);
+ list_del(&e->list);
pthread_rwlock_unlock(&data->dir_lock);
+ dir_entry_destroy(e);
+
return 0;
}
-bool ipcp_data_is_in_registry(struct ipcp_data * data,
- const char * ap_name)
+bool ipcp_data_dir_has(struct ipcp_data * data,
+ const char * name)
{
bool ret = false;
- if (data == NULL || ap_name == NULL)
- return false;
-
- pthread_rwlock_rdlock(&data->reg_lock);
+ pthread_rwlock_rdlock(&data->dir_lock);
- ret = (find_reg_entry_by_name(data, ap_name) != NULL);
+ ret = (find_dir_entry_any(data, name) != NULL);
- pthread_rwlock_unlock(&data->reg_lock);
+ pthread_rwlock_unlock(&data->dir_lock);
return ret;
}
-uint64_t ipcp_data_get_addr(struct ipcp_data * data,
- const char * ap_name)
+uint64_t ipcp_data_dir_get_addr(struct ipcp_data * data,
+ const char * name)
{
struct dir_entry * entry;
uint64_t addr;
pthread_rwlock_rdlock(&data->dir_lock);
- entry = find_dir_entry_any(data, ap_name);
+ entry = find_dir_entry_any(data, name);
if (entry == NULL) {
pthread_rwlock_unlock(&data->dir_lock);
@@ -386,3 +413,122 @@ uint64_t ipcp_data_get_addr(struct ipcp_data * data,
return addr;
}
+
+struct dir_query * ipcp_data_dir_query_create(char * name)
+{
+ struct dir_query * query;
+ pthread_condattr_t cattr;
+
+ query = malloc(sizeof(*query));
+ if (query == NULL)
+ return NULL;
+
+ query->name = strdup(name);
+ if (query->name == NULL) {
+ free(query);
+ return NULL;
+ }
+
+ query->state = QUERY_INIT;
+
+ pthread_condattr_init(&cattr);
+#ifndef __APPLE__
+ pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);
+#endif
+ pthread_cond_init(&query->cond, &cattr);
+ pthread_mutex_init(&query->lock, NULL);
+
+ INIT_LIST_HEAD(&query->next);
+
+ return query;
+}
+
+void ipcp_data_dir_query_respond(struct dir_query * query)
+{
+ assert(query);
+
+ pthread_mutex_lock(&query->lock);
+
+ if (query->state != QUERY_PENDING) {
+ pthread_mutex_unlock(&query->lock);
+ return;
+ }
+
+ query->state = QUERY_RESPONSE;
+ pthread_cond_broadcast(&query->cond);
+
+ while (query->state == QUERY_RESPONSE)
+ pthread_cond_wait(&query->cond, &query->lock);
+
+ pthread_mutex_unlock(&query->lock);
+}
+
+void ipcp_data_dir_query_destroy(struct dir_query * query)
+{
+ assert(query);
+
+ pthread_mutex_lock(&query->lock);
+
+ if (query->state == QUERY_DESTROY) {
+ pthread_mutex_unlock(&query->lock);
+ return;
+ }
+
+ if (query->state == QUERY_INIT)
+ query->state = QUERY_DONE;
+
+ if (query->state == QUERY_PENDING) {
+ query->state = QUERY_DESTROY;
+ pthread_cond_broadcast(&query->cond);
+ }
+
+ while (query->state != QUERY_DONE)
+ pthread_cond_wait(&query->cond, &query->lock);
+
+ pthread_mutex_unlock(&query->lock);
+
+ pthread_cond_destroy(&query->cond);
+ pthread_mutex_destroy(&query->lock);
+
+ free(query->name);
+ free(query);
+}
+
+int ipcp_data_dir_query_wait(struct dir_query * query,
+ const struct timespec * timeout)
+{
+ struct timespec abstime;
+ int ret = 0;
+
+ assert(query);
+ assert(timeout);
+
+ clock_gettime(PTHREAD_COND_CLOCK, &abstime);
+ ts_add(&abstime, timeout, &abstime);
+
+ pthread_mutex_lock(&query->lock);
+
+ if (query->state != QUERY_INIT) {
+ pthread_mutex_unlock(&query->lock);
+ return -EINVAL;
+ }
+
+ query->state = QUERY_PENDING;
+
+ while (query->state == QUERY_PENDING) {
+ if ((ret = -pthread_cond_timedwait(&query->cond,
+ &query->lock,
+ &abstime)) == -ETIMEDOUT)
+ break;
+ }
+
+ if (query->state == QUERY_DESTROY)
+ ret = -1;
+
+ query->state = QUERY_DONE;
+ pthread_cond_broadcast(&query->cond);
+
+ pthread_mutex_unlock(&query->lock);
+
+ return ret;
+}
diff --git a/src/ipcpd/ipcp-data.h b/src/ipcpd/ipcp-data.h
index 4472a1d7..5263b156 100644
--- a/src/ipcpd/ipcp-data.h
+++ b/src/ipcpd/ipcp-data.h
@@ -26,10 +26,28 @@
#include <ouroboros/shared.h>
#include <ouroboros/list.h>
+
+#include "ipcp-ops.h"
+
#include <sys/types.h>
#include <pthread.h>
-#include "ipcp-ops.h"
+enum dir_query_state {
+ QUERY_INIT = 0,
+ QUERY_PENDING,
+ QUERY_RESPONSE,
+ QUERY_DONE,
+ QUERY_DESTROY
+};
+
+struct dir_query {
+ struct list_head next;
+ char * name;
+ enum dir_query_state state;
+
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+};
struct ipcp_data {
enum ipcp_type type;
@@ -40,6 +58,9 @@ struct ipcp_data {
struct list_head directory;
pthread_rwlock_t dir_lock;
+
+ struct list_head dir_queries;
+ pthread_mutex_t dir_queries_lock;
};
struct ipcp_data * ipcp_data_create(void);
@@ -49,26 +70,35 @@ struct ipcp_data * ipcp_data_init(struct ipcp_data * dst,
void ipcp_data_destroy(struct ipcp_data * data);
-int ipcp_data_add_reg_entry(struct ipcp_data * data,
+int ipcp_data_reg_add_entry(struct ipcp_data * data,
char * name);
-int ipcp_data_del_reg_entry(struct ipcp_data * data,
+int ipcp_data_reg_del_entry(struct ipcp_data * data,
const char * name);
-int ipcp_data_add_dir_entry(struct ipcp_data * data,
- char * ap_name,
+bool ipcp_data_reg_has(struct ipcp_data * data,
+ const char * name);
+
+int ipcp_data_dir_add_entry(struct ipcp_data * data,
+ char * name,
uint64_t addr);
-int ipcp_data_del_dir_entry(struct ipcp_data * data,
- const char * ap_name,
+int ipcp_data_dir_del_entry(struct ipcp_data * data,
+ const char * name,
uint64_t addr);
-bool ipcp_data_is_in_registry(struct ipcp_data * data,
- const char * name);
+bool ipcp_data_dir_has(struct ipcp_data * data,
+ const char * name);
+
+uint64_t ipcp_data_dir_get_addr(struct ipcp_data * data,
+ const char * name);
+
+struct dir_query * ipcp_data_dir_query_create(char * name);
+
+void ipcp_data_dir_query_respond(struct dir_query * query);
-bool ipcp_data_is_in_directory(struct ipcp_data * data,
- const char * ap_name);
+void ipcp_data_dir_query_destroy(struct dir_query * query);
-uint64_t ipcp_data_get_addr(struct ipcp_data * data,
- const char * ap_name);
+int ipcp_data_dir_query_wait(struct dir_query * query,
+ const struct timespec * timeout);
#endif /* IPCPD_IPCP_DATA_H */
diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/ipcp-ops.h
index 815cda09..0b79a328 100644
--- a/src/ipcpd/ipcp-ops.h
+++ b/src/ipcpd/ipcp-ops.h
@@ -36,6 +36,8 @@ struct ipcp_ops {
int (* ipcp_name_unreg)(char * name);
+ int (* ipcp_name_query)(char * name);
+
int (* ipcp_flow_alloc)(int fd,
char * dst_ap_name,
char * src_ae_name,
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c
index c2d343f8..90fb94ef 100644
--- a/src/ipcpd/ipcp.c
+++ b/src/ipcpd/ipcp.c
@@ -20,7 +20,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
+#define OUROBOROS_PREFIX "ipcpd/ipcp"
+
#include <ouroboros/config.h>
+#include <ouroboros/logs.h>
#include <ouroboros/time_utils.h>
#include <ouroboros/utils.h>
#include <ouroboros/sockets.h>
@@ -28,13 +32,11 @@
#include <ouroboros/dev.h>
#include <ouroboros/np1_flow.h>
-#define OUROBOROS_PREFIX "ipcpd/ipcp"
-#include <ouroboros/logs.h>
+#include "ipcp.h"
#include <string.h>
#include <sys/socket.h>
#include <stdlib.h>
-#include "ipcp.h"
int ipcp_init(enum ipcp_type type, struct ipcp_ops * ops)
{
@@ -307,6 +309,15 @@ void * ipcp_main_loop(void * o)
ret_msg.result =
ipcpi.ops->ipcp_name_unreg(msg->name);
break;
+ case IPCP_MSG_CODE__IPCP_NAME_QUERY:
+ if (ipcpi.ops->ipcp_name_query == NULL) {
+ LOG_ERR("Ap_query unsupported.");
+ break;
+ }
+ ret_msg.has_result = true;
+ ret_msg.result =
+ ipcpi.ops->ipcp_name_query(msg->name);
+ break;
case IPCP_MSG_CODE__IPCP_FLOW_ALLOC:
if (ipcpi.ops->ipcp_flow_alloc == NULL) {
LOG_ERR("Flow_alloc unsupported.");
diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c
index 192607c1..b8783d9d 100644
--- a/src/ipcpd/local/main.c
+++ b/src/ipcpd/local/main.c
@@ -20,17 +20,18 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define OUROBOROS_PREFIX "ipcpd/local"
+
#include <ouroboros/config.h>
-#include "ipcp.h"
+#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/dev.h>
#include <ouroboros/fcntl.h>
#include <ouroboros/fqueue.h>
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/local-dev.h>
-#define OUROBOROS_PREFIX "ipcpd/local"
-#include <ouroboros/logs.h>
+#include "ipcp.h"
#include <string.h>
#include <signal.h>
@@ -176,7 +177,7 @@ static int ipcp_local_name_reg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- if (ipcp_data_add_reg_entry(ipcpi.data, name)) {
+ if (ipcp_data_reg_add_entry(ipcpi.data, name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
LOG_DBG("Failed to add %s to local registry.", name);
return -1;
@@ -193,7 +194,7 @@ static int ipcp_local_name_unreg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- ipcp_data_del_reg_entry(ipcpi.data, name);
+ ipcp_data_reg_del_entry(ipcpi.data, name);
pthread_rwlock_unlock(&ipcpi.state_lock);
@@ -202,6 +203,19 @@ static int ipcp_local_name_unreg(char * name)
return 0;
}
+static int ipcp_local_name_query(char * name)
+{
+ int ret;
+
+ pthread_rwlock_rdlock(&ipcpi.state_lock);
+
+ ret = (ipcp_data_reg_has(ipcpi.data, name) ? 0 : -1);
+
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+
+ return ret;
+}
+
static int ipcp_local_flow_alloc(int fd,
char * dst_name,
char * src_ae_name,
@@ -302,6 +316,7 @@ static struct ipcp_ops local_ops = {
.ipcp_enroll = NULL, /* shim */
.ipcp_name_reg = ipcp_local_name_reg,
.ipcp_name_unreg = ipcp_local_name_unreg,
+ .ipcp_name_query = ipcp_local_name_query,
.ipcp_flow_alloc = ipcp_local_flow_alloc,
.ipcp_flow_alloc_resp = ipcp_local_flow_alloc_resp,
.ipcp_flow_dealloc = ipcp_local_flow_dealloc
diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c
index 32aabdf2..2402972f 100644
--- a/src/ipcpd/normal/main.c
+++ b/src/ipcpd/normal/main.c
@@ -28,6 +28,11 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/time_utils.h>
+#include "fmgr.h"
+#include "ribmgr.h"
+#include "ipcp.h"
+#include "frct.h"
+
#include <stdbool.h>
#include <signal.h>
#include <stdlib.h>
@@ -35,11 +40,6 @@
#include <string.h>
#include <errno.h>
-#include "fmgr.h"
-#include "ribmgr.h"
-#include "ipcp.h"
-#include "frct.h"
-
#define THIS_TYPE IPCP_NORMAL
/* global for trapping signal */
@@ -72,7 +72,7 @@ static int normal_ipcp_name_reg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- if (ipcp_data_add_reg_entry(ipcpi.data, name)) {
+ if (ipcp_data_reg_add_entry(ipcpi.data, name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
LOG_ERR("Failed to add %s to local registry.", name);
return -1;
@@ -89,13 +89,28 @@ static int normal_ipcp_name_unreg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- ipcp_data_del_reg_entry(ipcpi.data, name);
+ ipcp_data_reg_del_entry(ipcpi.data, name);
pthread_rwlock_unlock(&ipcpi.state_lock);
return 0;
}
+static int normal_ipcp_name_query(char * name)
+{
+ LOG_MISSING;
+
+ (void) name;
+
+ /*
+ * NOTE: For the moment we just return -1,
+ * for testing purposes we may return zero here
+ * for certain names.
+ */
+
+ return -1;
+}
+
static int normal_ipcp_enroll(char * dif_name)
{
struct timespec timeout = {(ENROLL_TIMEOUT / 1000),
@@ -165,6 +180,7 @@ static struct ipcp_ops normal_ops = {
.ipcp_enroll = normal_ipcp_enroll,
.ipcp_name_reg = normal_ipcp_name_reg,
.ipcp_name_unreg = normal_ipcp_name_unreg,
+ .ipcp_name_query = normal_ipcp_name_query,
.ipcp_flow_alloc = fmgr_np1_alloc,
.ipcp_flow_alloc_resp = fmgr_np1_alloc_resp,
.ipcp_flow_dealloc = fmgr_np1_dealloc
diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c
index 6046d939..d4ea8eba 100644
--- a/src/ipcpd/shim-eth-llc/main.c
+++ b/src/ipcpd/shim-eth-llc/main.c
@@ -20,10 +20,11 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <ouroboros/config.h>
-
#define _DEFAULT_SOURCE
+#define OUROBOROS_PREFIX "ipcpd/shim-eth-llc"
+
+#include <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
@@ -32,12 +33,10 @@
#include <ouroboros/ipcp-dev.h>
#include <ouroboros/fcntl.h>
#include <ouroboros/fqueue.h>
-
-#define OUROBOROS_PREFIX "ipcpd/shim-eth-llc"
-
#include <ouroboros/logs.h>
#include "ipcp.h"
+#include "shim_eth_llc_messages.pb-c.h"
#include <net/if.h>
#include <signal.h>
@@ -65,8 +64,6 @@
#include <poll.h>
#include <sys/mman.h>
-#include "shim_eth_llc_messages.pb-c.h"
-
typedef ShimEthLlcMsg shim_eth_llc_msg_t;
#define THIS_TYPE IPCP_SHIM_ETH_LLC
@@ -80,6 +77,7 @@ typedef ShimEthLlcMsg shim_eth_llc_msg_t;
+ SHIM_ETH_LLC_MAX_SDU_SIZE)
#define EVENT_WAIT_TIMEOUT 100 /* us */
+#define NAME_QUERY_TIMEOUT 100000000 /* ns */
/* global for trapping signal */
int irmd_api;
@@ -313,6 +311,7 @@ static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr,
shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
msg.code = SHIM_ETH_LLC_MSG_CODE__FLOW_REQ;
+ msg.has_ssap = true;
msg.ssap = ssap;
msg.dst_name = dst_name;
msg.src_ae_name = src_ae_name;
@@ -328,6 +327,7 @@ static int eth_llc_ipcp_sap_alloc_resp(uint8_t * dst_addr,
shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
msg.code = SHIM_ETH_LLC_MSG_CODE__FLOW_REPLY;
+ msg.has_ssap = true;
msg.ssap = ssap;
msg.has_dsap = true;
msg.dsap = dsap;
@@ -341,8 +341,9 @@ static int eth_llc_ipcp_sap_dealloc(uint8_t * dst_addr, uint8_t ssap)
{
shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
- msg.code = SHIM_ETH_LLC_MSG_CODE__FLOW_DEALLOC;
- msg.ssap = ssap;
+ msg.code = SHIM_ETH_LLC_MSG_CODE__FLOW_DEALLOC;
+ msg.has_ssap = true;
+ msg.ssap = ssap;
return eth_llc_ipcp_send_mgmt_frame(&msg, dst_addr);
}
@@ -438,6 +439,42 @@ static int eth_llc_ipcp_flow_dealloc_req(uint8_t ssap)
return 0;
}
+static int eth_llc_ipcp_name_query_req(char * name, uint8_t * r_addr)
+{
+ shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
+
+ if (ipcp_data_reg_has(ipcpi.data, name)) {
+ msg.code = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REPLY;
+ msg.dst_name = name;
+
+ eth_llc_ipcp_send_mgmt_frame(&msg, r_addr);
+ }
+
+ return 0;
+}
+
+static int eth_llc_ipcp_name_query_reply(char * name, uint8_t * r_addr)
+{
+ uint64_t address = 0;
+ struct list_head * pos;
+
+ memcpy(&address, r_addr, MAC_SIZE);
+
+ ipcp_data_dir_add_entry(ipcpi.data, name, address);
+
+ pthread_mutex_lock(&ipcpi.data->dir_queries_lock);
+ list_for_each(pos, &ipcpi.data->dir_queries) {
+ struct dir_query * e =
+ list_entry(pos, struct dir_query, next);
+ if (strcmp(e->name, name) == 0) {
+ ipcp_data_dir_query_respond(e);
+ }
+ }
+ pthread_mutex_unlock(&ipcpi.data->dir_queries_lock);
+
+ return 0;
+}
+
static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, size_t len, uint8_t * r_addr)
{
shim_eth_llc_msg_t * msg = shim_eth_llc_msg__unpack(NULL, len, buf);
@@ -448,7 +485,7 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, size_t len, uint8_t * r_addr)
switch (msg->code) {
case SHIM_ETH_LLC_MSG_CODE__FLOW_REQ:
- if (ipcp_data_is_in_registry(ipcpi.data, msg->dst_name)) {
+ if (ipcp_data_reg_has(ipcpi.data, msg->dst_name)) {
eth_llc_ipcp_sap_req(msg->ssap,
r_addr,
msg->dst_name,
@@ -464,6 +501,12 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, size_t len, uint8_t * r_addr)
case SHIM_ETH_LLC_MSG_CODE__FLOW_DEALLOC:
eth_llc_ipcp_flow_dealloc_req(msg->ssap);
break;
+ case SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REQ:
+ eth_llc_ipcp_name_query_req(msg->dst_name, r_addr);
+ break;
+ case SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REPLY:
+ eth_llc_ipcp_name_query_reply(msg->dst_name, r_addr);
+ break;
default:
LOG_ERR("Unknown message received %d.", msg->code);
shim_eth_llc_msg__free_unpacked(msg, NULL);
@@ -854,7 +897,7 @@ static int eth_llc_ipcp_name_reg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- if (ipcp_data_add_reg_entry(ipcpi.data, name)) {
+ if (ipcp_data_reg_add_entry(ipcpi.data, name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
LOG_ERR("Failed to add %s to local registry.", name);
return -1;
@@ -871,13 +914,49 @@ static int eth_llc_ipcp_name_unreg(char * name)
{
pthread_rwlock_rdlock(&ipcpi.state_lock);
- ipcp_data_del_reg_entry(ipcpi.data, name);
+ ipcp_data_reg_del_entry(ipcpi.data, name);
pthread_rwlock_unlock(&ipcpi.state_lock);
return 0;
}
+static int eth_llc_ipcp_name_query(char * name)
+{
+ uint8_t r_addr[MAC_SIZE];
+ struct timespec timeout = {0, NAME_QUERY_TIMEOUT};
+ shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT;
+ struct dir_query * query;
+ int ret;
+
+ if (ipcp_data_dir_has(ipcpi.data, name))
+ return 0;
+
+ msg.code = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REQ;
+ msg.dst_name = name;
+
+ memset(r_addr, 0xff, MAC_SIZE);
+
+ query = ipcp_data_dir_query_create(name);
+ if (query == NULL)
+ return -1;
+
+ pthread_mutex_lock(&ipcpi.data->dir_queries_lock);
+ list_add(&query->next, &ipcpi.data->dir_queries);
+ pthread_mutex_unlock(&ipcpi.data->dir_queries_lock);
+
+ eth_llc_ipcp_send_mgmt_frame(&msg, r_addr);
+
+ ret = ipcp_data_dir_query_wait(query, &timeout);
+
+ pthread_mutex_lock(&ipcpi.data->dir_queries_lock);
+ list_del(&query->next);
+ ipcp_data_dir_query_destroy(query);
+ pthread_mutex_unlock(&ipcpi.data->dir_queries_lock);
+
+ return ret;
+}
+
static int eth_llc_ipcp_flow_alloc(int fd,
char * dst_name,
char * src_ae_name,
@@ -885,6 +964,7 @@ static int eth_llc_ipcp_flow_alloc(int fd,
{
uint8_t ssap = 0;
uint8_t r_addr[MAC_SIZE];
+ uint64_t addr = 0;
LOG_DBG("Allocating flow to %s.", dst_name);
@@ -902,6 +982,13 @@ static int eth_llc_ipcp_flow_alloc(int fd,
return -1; /* -ENOTENROLLED */
}
+ if (!ipcp_data_dir_has(ipcpi.data, dst_name)) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_ERR("Destination unreachable.");
+ return -1;
+ }
+ addr = ipcp_data_dir_get_addr(ipcpi.data, dst_name);
+
pthread_rwlock_wrlock(&eth_llc_data.flows_lock);
ssap = bmp_allocate(eth_llc_data.saps);
@@ -917,7 +1004,7 @@ static int eth_llc_ipcp_flow_alloc(int fd,
pthread_rwlock_unlock(&eth_llc_data.flows_lock);
pthread_rwlock_unlock(&ipcpi.state_lock);
- memset(r_addr, 0xff, MAC_SIZE);
+ memcpy(r_addr, &addr, MAC_SIZE);
if (eth_llc_ipcp_sap_alloc(r_addr,
ssap,
@@ -1025,6 +1112,7 @@ static struct ipcp_ops eth_llc_ops = {
.ipcp_enroll = NULL,
.ipcp_name_reg = eth_llc_ipcp_name_reg,
.ipcp_name_unreg = eth_llc_ipcp_name_unreg,
+ .ipcp_name_query = eth_llc_ipcp_name_query,
.ipcp_flow_alloc = eth_llc_ipcp_flow_alloc,
.ipcp_flow_alloc_resp = eth_llc_ipcp_flow_alloc_resp,
.ipcp_flow_dealloc = eth_llc_ipcp_flow_dealloc
diff --git a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto
index 0e8a1ce2..4d027d98 100644
--- a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto
+++ b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto
@@ -1,14 +1,16 @@
enum shim_eth_llc_msg_code {
- FLOW_REQ = 1;
- FLOW_REPLY = 2;
- FLOW_DEALLOC = 3;
+ FLOW_REQ = 1;
+ FLOW_REPLY = 2;
+ FLOW_DEALLOC = 3;
+ NAME_QUERY_REQ = 4;
+ NAME_QUERY_REPLY = 5;
};
message shim_eth_llc_msg {
required shim_eth_llc_msg_code code = 1;
optional string dst_name = 2;
optional string src_ae_name = 3;
- required uint32 ssap = 4;
+ optional uint32 ssap = 4;
optional uint32 dsap = 5;
optional sint32 response = 6;
};
diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c
index 62e1b2d0..f779713c 100644
--- a/src/ipcpd/shim-udp/main.c
+++ b/src/ipcpd/shim-udp/main.c
@@ -20,9 +20,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#define OUROBOROS_PREFIX "ipcpd/shim-udp"
+
#include <ouroboros/config.h>
-#include "ipcp.h"
-#include "shim_udp_config.h"
#include <ouroboros/list.h>
#include <ouroboros/utils.h>
#include <ouroboros/dev.h>
@@ -30,11 +30,12 @@
#include <ouroboros/fqueue.h>
#include <ouroboros/fcntl.h>
#include <ouroboros/errno.h>
-
-#define OUROBOROS_PREFIX "ipcpd/shim-udp"
-
#include <ouroboros/logs.h>
+#include "shim_udp_messages.pb-c.h"
+#include "ipcp.h"
+#include "shim_udp_config.h"
+
#include <string.h>
#include <sys/socket.h>
#include <sys/select.h>
@@ -47,8 +48,6 @@
#include <sys/wait.h>
#include <fcntl.h>
-#include "shim_udp_messages.pb-c.h"
-
typedef ShimUdpMsg shim_udp_msg_t;
#define THIS_TYPE IPCP_SHIM_UDP
@@ -833,7 +832,7 @@ static int ipcp_udp_name_reg(char * name)
pthread_rwlock_rdlock(&ipcpi.state_lock);
- if (ipcp_data_add_reg_entry(ipcpi.data, name)) {
+ if (ipcp_data_reg_add_entry(ipcpi.data, name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
LOG_ERR("Failed to add %s to local registry.", name);
return -1;
@@ -864,7 +863,7 @@ static int ipcp_udp_name_reg(char * name)
if (ddns_send(cmd)) {
pthread_rwlock_rdlock(&ipcpi.state_lock);
- ipcp_data_del_reg_entry(ipcpi.data, name);
+ ipcp_data_reg_del_entry(ipcpi.data, name);
pthread_rwlock_unlock(&ipcpi.state_lock);
return -1;
}
@@ -885,7 +884,6 @@ static int ipcp_udp_name_unreg(char * name)
char cmd[100];
uint32_t dns_addr;
#endif
-
if (strlen(name) > 24) {
LOG_ERR("DNS names cannot be longer than 24 chars.");
return -1;
@@ -914,7 +912,74 @@ static int ipcp_udp_name_unreg(char * name)
pthread_rwlock_rdlock(&ipcpi.state_lock);
- ipcp_data_del_reg_entry(ipcpi.data, name);
+ ipcp_data_reg_del_entry(ipcpi.data, name);
+
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+
+ return 0;
+}
+
+static int ipcp_udp_name_query(char * name)
+{
+ uint32_t ip_addr = 0;
+ struct hostent * h;
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ uint32_t dns_addr = 0;
+#endif
+
+ assert(name);
+
+ if (strlen(name) > 24) {
+ LOG_ERR("DNS names cannot be longer than 24 chars.");
+ return -1;
+ }
+
+ pthread_rwlock_rdlock(&ipcpi.state_lock);
+
+ if (ipcp_get_state() != IPCP_ENROLLED) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_DBG("Won't query a name on a non-enrolled IPCP.");
+ return -1; /* -ENOTENROLLED */
+ }
+
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ dns_addr = udp_data.dns_addr;
+
+ if (dns_addr != 0) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+
+ ip_addr = ddns_resolve(name, dns_addr);
+ if (ip_addr == 0) {
+ LOG_DBG("Could not resolve %s.", name);
+ return -1;
+ }
+
+ pthread_rwlock_rdlock(&ipcpi.state_lock);
+
+ if (ipcp_get_state() != IPCP_ENROLLED) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_DBG("Won't add name to the directory.");
+ return -1; /* -ENOTENROLLED */
+ }
+ } else {
+#endif
+ h = gethostbyname(name);
+ if (h == NULL) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_DBG("Could not resolve %s.", name);
+ return -1;
+ }
+
+ ip_addr = *((uint32_t *) (h->h_addr_list[0]));
+#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ }
+#endif
+
+ if (ipcp_data_dir_add_entry(ipcpi.data, name, ip_addr)) {
+ pthread_rwlock_unlock(&ipcpi.state_lock);
+ LOG_ERR("Failed to add directory entry.");
+ return -1;
+ }
pthread_rwlock_unlock(&ipcpi.state_lock);
@@ -930,15 +995,13 @@ static int ipcp_udp_flow_alloc(int fd,
struct sockaddr_in f_saddr; /* flow */
socklen_t f_saddr_len = sizeof(f_saddr);
int skfd;
- struct hostent * h;
uint32_t ip_addr = 0;
-#ifdef CONFIG_OUROBOROS_ENABLE_DNS
- uint32_t dns_addr = 0;
-#endif
+
LOG_DBG("Allocating flow to %s.", dst_name);
if (dst_name == NULL || src_ae_name == NULL)
return -1;
+
if (strlen(dst_name) > 255
|| strlen(src_ae_name) > 255) {
LOG_ERR("Name too long for this shim.");
@@ -976,39 +1039,13 @@ static int ipcp_udp_flow_alloc(int fd,
return -1; /* -ENOTENROLLED */
}
-#ifdef CONFIG_OUROBOROS_ENABLE_DNS
- dns_addr = udp_data.dns_addr;
-
- if (dns_addr != 0) {
+ if (!ipcp_data_dir_has(ipcpi.data, dst_name)) {
pthread_rwlock_unlock(&ipcpi.state_lock);
-
- ip_addr = ddns_resolve(dst_name, dns_addr);
- if (ip_addr == 0) {
- LOG_DBG("Could not resolve %s.", dst_name);
- close(fd);
- return -1;
- }
-
- pthread_rwlock_rdlock(&ipcpi.state_lock);
- if (ipcp_get_state() != IPCP_ENROLLED) {
- pthread_rwlock_unlock(&ipcpi.state_lock);
- LOG_DBG("Won't allocate flow with non-enrolled IPCP.");
- close(skfd);
- return -1; /* -ENOTENROLLED */
- }
- } else {
-#endif
- h = gethostbyname(dst_name);
- if (h == NULL) {
- LOG_DBG("Could not resolve %s.", dst_name);
- close(skfd);
- return -1;
- }
-
- ip_addr = *((uint32_t *) (h->h_addr_list[0]));
-#ifdef CONFIG_OUROBOROS_ENABLE_DNS
+ LOG_DBG("Could not resolve destination.");
+ close(skfd);
+ return -1;
}
-#endif
+ ip_addr = (uint32_t) ipcp_data_dir_get_addr(ipcpi.data, dst_name);
/* connect to server (store the remote IP address in the fd) */
memset((char *) &r_saddr, 0, sizeof(r_saddr));
@@ -1171,6 +1208,7 @@ static struct ipcp_ops udp_ops = {
.ipcp_enroll = NULL, /* shim */
.ipcp_name_reg = ipcp_udp_name_reg,
.ipcp_name_unreg = ipcp_udp_name_unreg,
+ .ipcp_name_query = ipcp_udp_name_query,
.ipcp_flow_alloc = ipcp_udp_flow_alloc,
.ipcp_flow_alloc_resp = ipcp_udp_flow_alloc_resp,
.ipcp_flow_dealloc = ipcp_udp_flow_dealloc
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 <ouroboros/config.h>
+#include <ouroboros/logs.h>
#include <ouroboros/errno.h>
#include <ouroboros/utils.h>
#include <ouroboros/sockets.h>
-#define OUROBOROS_PREFIX "irmd/ipcp"
-
-#include <ouroboros/logs.h>
-
#include "ipcp.h"
#include <stdlib.h>
@@ -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 <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/sockets.h>
@@ -33,9 +35,6 @@
#include <ouroboros/bitmap.h>
#include <ouroboros/qos.h>
#include <ouroboros/time_utils.h>
-
-#define OUROBOROS_PREFIX "irmd"
-
#include <ouroboros/logs.h>
#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 <ouroboros/config.h>
#include <ouroboros/errno.h>
#include <ouroboros/logs.h>
#include <ouroboros/irm_config.h>
+#include "registry.h"
+#include "utils.h"
+
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -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 <ouroboros/list.h>
#include <ouroboros/irm_config.h>
+#include "api_table.h"
+#include "apn_table.h"
+
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
-#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,
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index f64b6882..147d40c6 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -5,10 +5,11 @@ enum ipcp_msg_code {
IPCP_ENROLL = 2;
IPCP_NAME_REG = 3;
IPCP_NAME_UNREG = 4;
- IPCP_FLOW_ALLOC = 5;
- IPCP_FLOW_ALLOC_RESP = 6;
- IPCP_FLOW_DEALLOC = 7;
- IPCP_REPLY = 8;
+ IPCP_NAME_QUERY = 5;
+ IPCP_FLOW_ALLOC = 6;
+ IPCP_FLOW_ALLOC_RESP = 7;
+ IPCP_FLOW_DEALLOC = 8;
+ IPCP_REPLY = 9;
};
message ipcp_msg {