summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ouroboros/irm_config.h2
-rw-r--r--src/irmd/main.c173
-rw-r--r--src/irmd/registry.c512
-rw-r--r--src/irmd/registry.h139
4 files changed, 421 insertions, 405 deletions
diff --git a/include/ouroboros/irm_config.h b/include/ouroboros/irm_config.h
index d5f2b565..dd68e4ec 100644
--- a/include/ouroboros/irm_config.h
+++ b/include/ouroboros/irm_config.h
@@ -31,6 +31,8 @@
#define BIND_AP_AUTO 0x01
#define BIND_AP_UNIQUE 0x02
+#define UNBIND_AP_HARD 0x01
+
enum ipcp_type {
IPCP_NORMAL = 0,
IPCP_LOCAL,
diff --git a/src/irmd/main.c b/src/irmd/main.c
index c05a99f6..30ecbc59 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -233,7 +233,6 @@ static struct ipcp_entry * get_ipcp_entry_by_api(pid_t api)
list_for_each(pos, &instance->ipcps) {
struct ipcp_entry * tmp =
list_entry(pos, struct ipcp_entry, next);
-
if (api == tmp->api)
return tmp;
}
@@ -246,50 +245,16 @@ static struct ipcp_entry * get_ipcp_entry_by_api(pid_t api)
static pid_t get_ipcp_by_dst_name(char * dst_name)
{
struct list_head * pos = NULL;
- struct reg_entry * re =
- registry_get_entry_by_name(&instance->registry, dst_name);
-
- if (re != NULL) {
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
- if (e->dif_name == NULL)
- continue;
-
- if (e->type == IPCP_LOCAL)
- return e->api;
- }
- }
-
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
- if (e->dif_name != NULL && e->type == IPCP_NORMAL) {
- if (re != NULL &&
- !reg_entry_is_local_in_dif(re, e->dif_name))
- continue;
- return e->api;
- }
- }
-
- if (re == NULL) {
- list_for_each(pos, &instance->ipcps) {
- struct ipcp_entry * e =
- list_entry(pos, struct ipcp_entry, next);
- if (e->dif_name != NULL && e->type == IPCP_SHIM_ETH_LLC)
- return e->api;
- }
- }
+ char * dif_name =
+ registry_get_dif_for_dst(&instance->registry, dst_name);
+ if (dif_name == NULL)
+ return -1;
list_for_each(pos, &instance->ipcps) {
struct ipcp_entry * e =
list_entry(pos, struct ipcp_entry, next);
- if (e->dif_name != NULL && e->type == IPCP_SHIM_UDP) {
- if (re != NULL &&
- !reg_entry_is_local_in_dif(re, e->dif_name))
- continue;
+ if (strcmp(e->dif_name, dif_name) == 0)
return e->api;
- }
}
return -1;
@@ -520,10 +485,9 @@ static int bind_name(char * name,
int argc,
char ** argv)
{
- int i;
-
+ char * apn = path_strip(ap_name);
char ** argv_dup = NULL;
- char * apn = path_strip(ap_name);
+ int i = 0;
if (name == NULL || ap_name == NULL)
return -EINVAL;
@@ -537,14 +501,6 @@ static int bind_name(char * name,
pthread_rwlock_wrlock(&instance->reg_lock);
- if (registry_add_entry(&instance->registry,
- strdup(name), strdup(apn), opts) < 0) {
- pthread_rwlock_unlock(&instance->reg_lock);
- pthread_rwlock_unlock(&instance->state_lock);
- LOG_ERR("Failed to register %s.", name);
- return -1;
- }
-
if (opts & BIND_AP_AUTO) {
/* we need to duplicate argv */
if (argc != 0) {
@@ -554,9 +510,15 @@ static int bind_name(char * name,
argv_dup[i] = strdup(argv[i - 1]);
argv_dup[argc + 1] = NULL;
}
+ }
- registry_add_ap_auto(&instance->registry,
- name, strdup(apn), argv_dup);
+ if (registry_add_binding(&instance->registry,
+ strdup(name), strdup(apn),
+ opts, argv_dup) < 0) {
+ pthread_rwlock_unlock(&instance->reg_lock);
+ pthread_rwlock_unlock(&instance->state_lock);
+ LOG_ERR("Failed to register %s.", name);
+ return -1;
}
pthread_rwlock_unlock(&instance->reg_lock);
@@ -567,15 +529,16 @@ static int bind_name(char * name,
return 0;
}
-static int unbind_name(char * name,
- char * ap_name,
+static int unbind_name(char * name,
+ char * apn,
uint16_t opts)
{
- struct reg_entry * rne = NULL;
+ if (name == NULL)
+ return -EINVAL;
- if (name == NULL || ap_name == NULL)
- return -1;
+ if (!(opts & UNBIND_AP_HARD) && apn == NULL)
+ return -EINVAL;
pthread_rwlock_rdlock(&instance->state_lock);
@@ -586,25 +549,18 @@ static int unbind_name(char * name,
pthread_rwlock_wrlock(&instance->reg_lock);
- rne = registry_get_entry_by_name(&instance->registry, name);
- if (rne == NULL) {
+ if ((opts & UNBIND_AP_HARD) && apn == NULL) {
+ registry_deassign(&instance->registry, name);
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
- LOG_ERR("Tried to unbind a name that is not bound.");
- return -1;
+ LOG_INFO("Removed all bindings of %s.", name);
+ } else {
+ registry_del_binding(&instance->registry, name, apn);
+ pthread_rwlock_unlock(&instance->reg_lock);
+ pthread_rwlock_unlock(&instance->state_lock);
+ LOG_INFO("Removed binding from %s to %s.", apn, name);
}
- /*
- * FIXME: Remove the mapping of name to ap_name.
- * Remove the name only if it was the last mapping.
- */
- registry_del_name(&instance->registry, rne->name);
-
- pthread_rwlock_unlock(&instance->reg_lock);
- pthread_rwlock_unlock(&instance->state_lock);
-
- LOG_INFO("Removed binding from %s to %s.", ap_name, name);
-
return 0;
}
@@ -647,7 +603,6 @@ static int ap_reg(char * name,
{
int i;
int ret = 0;
- struct reg_entry * reg = NULL;
struct list_head * pos = NULL;
if (name == NULL || difs == NULL || len == 0 || difs[0] == NULL)
@@ -668,14 +623,6 @@ static int ap_reg(char * name,
return -1;
}
- reg = registry_get_entry_by_name(&instance->registry, name);
- if (reg == NULL) {
- pthread_rwlock_unlock(&instance->reg_lock);
- pthread_rwlock_unlock(&instance->state_lock);
- LOG_ERR("Tried to register a name that is not bound.");
- return -1;
- }
-
list_for_each(pos, &instance->ipcps) {
struct ipcp_entry * e =
list_entry(pos, struct ipcp_entry, next);
@@ -687,13 +634,19 @@ static int ap_reg(char * name,
if (wildcard_match(difs[i], e->dif_name))
continue;
- if (ipcp_name_reg(e->api, name) ||
- reg_entry_add_local_in_dif(reg, e->dif_name)) {
+ if (ipcp_name_reg(e->api, name)) {
LOG_ERR("Could not register %s in DIF %s.",
name, e->dif_name);
} else {
- LOG_INFO("Registered %s in %s",
- name, e->dif_name);
+ if(registry_add_name_to_dif(&instance->registry,
+ name,
+ e->dif_name,
+ e->type) < 0)
+ LOG_WARN("Registered unbound name %s. "
+ "Registry may be inconsistent",
+ name);
+ LOG_INFO("Registered %s in %s %d.",
+ name, e->dif_name, e->type);
++ret;
}
}
@@ -717,7 +670,6 @@ static int ap_unreg(char * name,
{
int i;
int ret = 0;
- struct reg_entry * re = NULL;
struct list_head * pos = NULL;
if (name == NULL || len == 0 || difs == NULL || difs[0] == NULL)
@@ -732,14 +684,6 @@ static int ap_unreg(char * name,
pthread_rwlock_wrlock(&instance->reg_lock);
- re = registry_get_entry_by_name(&instance->registry, name);
- if (re == NULL) {
- pthread_rwlock_unlock(&instance->reg_lock);
- pthread_rwlock_unlock(&instance->state_lock);
- LOG_ERR("Tried to unregister a name that is not bound.");
- return -1;
- }
-
list_for_each(pos, &instance->ipcps) {
struct ipcp_entry * e =
list_entry(pos, struct ipcp_entry, next);
@@ -751,14 +695,16 @@ static int ap_unreg(char * name,
if (wildcard_match(difs[i], e->dif_name))
continue;
- if (ipcp_name_unreg(e->api, re->name)) {
+ if (ipcp_name_unreg(e->api, name)) {
LOG_ERR("Could not unregister %s in DIF %s.",
- re->name, e->dif_name);
+ name, e->dif_name);
--ret;
} else {
- reg_entry_del_local_from_dif(re, e->dif_name);
+ registry_del_name_from_dif(&instance->registry,
+ name,
+ e->dif_name);
LOG_INFO("Unregistered %s from %s.",
- re->name, e->dif_name);
+ name, e->dif_name);
}
}
}
@@ -774,8 +720,8 @@ static struct port_map_entry * flow_accept(pid_t api,
char ** dst_ae_name)
{
struct port_map_entry * pme = NULL;
- struct reg_entry * rne = NULL;
- struct reg_instance * rgi = NULL;
+ struct reg_entry * rne = NULL;
+ struct reg_api * rgi = NULL;
pthread_rwlock_rdlock(&instance->state_lock);
@@ -786,7 +732,7 @@ static struct port_map_entry * flow_accept(pid_t api,
pthread_rwlock_wrlock(&instance->reg_lock);
- rne = registry_get_entry_by_ap_name(&instance->registry, srv_ap_name);
+ rne = registry_get_entry_by_apn(&instance->registry, srv_ap_name);
if (rne == NULL) {
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
@@ -794,7 +740,7 @@ static struct port_map_entry * flow_accept(pid_t api,
return NULL;
}
- if (!reg_entry_has_api(rne, api)) {
+ if (!reg_entry_get_reg_api(rne, api)) {
rgi = registry_add_api_name(&instance->registry,
api,
rne->name);
@@ -811,7 +757,7 @@ static struct port_map_entry * flow_accept(pid_t api,
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
- reg_instance_sleep(rgi);
+ reg_api_sleep(rgi);
pthread_rwlock_rdlock(&instance->state_lock);
pthread_rwlock_rdlock(&instance->reg_lock);
@@ -865,7 +811,7 @@ static int flow_alloc_resp(pid_t n_api,
pthread_rwlock_wrlock(&instance->reg_lock);
- rne = registry_get_entry_by_ap_id(&instance->registry, n_api);
+ rne = registry_get_entry_by_api(&instance->registry, n_api);
if (rne == NULL) {
pthread_rwlock_unlock(&instance->reg_lock);
pthread_rwlock_unlock(&instance->state_lock);
@@ -881,7 +827,7 @@ static int flow_alloc_resp(pid_t n_api,
pthread_mutex_lock(&rne->state_lock);
- registry_remove_api_name(&instance->registry, n_api, rne->name);
+ registry_del_api(&instance->registry, n_api);
pthread_mutex_unlock(&rne->state_lock);
@@ -1180,7 +1126,7 @@ static struct port_map_entry * flow_req_arr(pid_t api,
rne->state = REG_NAME_AUTO_EXEC;
pthread_mutex_unlock(&rne->state_lock);
- if ((c_api->api = auto_execute(reg_entry_resolve_auto(rne)))
+ if ((c_api->api = auto_execute(reg_entry_get_auto_info(rne)))
< 0) {
pthread_mutex_lock(&rne->state_lock);
rne->state = REG_NAME_AUTO_ACCEPT;
@@ -1241,7 +1187,7 @@ static struct port_map_entry * flow_req_arr(pid_t api,
rne->state = REG_NAME_FLOW_ARRIVED;
- reg_instance_wake(reg_entry_get_reg_instance(rne, pme->n_api));
+ reg_api_wake(reg_entry_get_reg_api(rne, pme->n_api));
pthread_mutex_unlock(&rne->state_lock);
@@ -1492,19 +1438,18 @@ void * irm_flow_cleaner()
struct reg_entry * e =
list_entry(pos, struct reg_entry, next);
- list_for_each_safe(pos2, n2, &e->ap_instances) {
- struct reg_instance * r =
+ list_for_each_safe(pos2, n2, &e->reg_apis) {
+ struct reg_api * r =
list_entry(pos2,
- struct reg_instance,
+ struct reg_api,
next);
if (kill(r->api, 0) < 0) {
LOG_INFO("Process %d gone, "
"registry binding removed.",
r->api);
- registry_remove_api_name(
+ registry_del_api(
&instance->registry,
- r->api,
- e->name);
+ r->api);
}
}
}
diff --git a/src/irmd/registry.c b/src/irmd/registry.c
index e9927b7e..f688e1cc 100644
--- a/src/irmd/registry.c
+++ b/src/irmd/registry.c
@@ -34,9 +34,27 @@
#include <stdbool.h>
#include <string.h>
-struct reg_instance * reg_instance_create(pid_t api)
+#define reg_entry_has_auto_binding(e) (reg_entry_get_auto_info(e) != NULL)
+#define reg_entry_has_api(e, api) (reg_entry_get_reg_api(e, api) != NULL)
+#define reg_entry_has_binding(e, name) (reg_entry_get_binding(e, name) != NULL)
+
+
+struct reg_binding {
+ struct list_head next;
+ char * apn;
+ uint32_t flags;
+ char ** argv;
+};
+
+struct reg_dif {
+ struct list_head next;
+ char * dif_name;
+ enum ipcp_type type;
+};
+
+struct reg_api * reg_api_create(pid_t api)
{
- struct reg_instance * i;
+ struct reg_api * i;
i = malloc(sizeof(*i));
if (i == NULL)
return NULL;
@@ -52,7 +70,7 @@ struct reg_instance * reg_instance_create(pid_t api)
return i;
}
-void reg_instance_destroy(struct reg_instance * i)
+void reg_api_destroy(struct reg_api * i)
{
bool wait = true;
pthread_mutex_lock(&i->mutex);
@@ -75,7 +93,7 @@ void reg_instance_destroy(struct reg_instance * i)
free(i);
}
-void reg_instance_sleep(struct reg_instance * i)
+void reg_api_sleep(struct reg_api * i)
{
pthread_mutex_lock(&i->mutex);
if (i->state != REG_I_WAKE) {
@@ -94,7 +112,7 @@ void reg_instance_sleep(struct reg_instance * i)
pthread_cleanup_pop(true);
}
-void reg_instance_wake(struct reg_instance * i)
+void reg_api_wake(struct reg_api * i)
{
pthread_mutex_lock(&i->mutex);
@@ -109,6 +127,39 @@ void reg_instance_wake(struct reg_instance * i)
pthread_mutex_unlock(&i->mutex);
}
+struct reg_binding * reg_binding_create(char * apn,
+ uint32_t flags,
+ char ** argv)
+{
+ struct reg_binding * b = malloc(sizeof(*b));
+ if (b == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&b->next);
+
+ b->apn = apn;
+ b->flags = flags;
+ b->argv = argv;
+
+ return b;
+}
+
+void reg_binding_destroy(struct reg_binding * b)
+{
+ if (b == NULL)
+ return;
+
+ if (b->argv != NULL) {
+ char ** t = b->argv;
+ while (*t != NULL)
+ free(*t++);
+ free(b->argv);
+ }
+
+ free(b->apn);
+ free(b);
+}
+
struct reg_entry * reg_entry_create()
{
struct reg_entry * e = malloc(sizeof(*e));
@@ -117,7 +168,6 @@ struct reg_entry * reg_entry_create()
e->name = NULL;
e->state = REG_NAME_NULL;
- e->flags = 0;
e->req_ae_name = NULL;
e->response = -1;
@@ -126,40 +176,23 @@ struct reg_entry * reg_entry_create()
}
struct reg_entry * reg_entry_init(struct reg_entry * e,
- char * name,
- char * ap_name,
- uint32_t flags)
+ char * name)
{
- struct reg_ap_name * n = NULL;
-
- if (e == NULL || name == NULL || ap_name == NULL)
- return NULL;
-
- n = malloc(sizeof(*n));
- if (n == NULL)
+ if (e == NULL || name == NULL)
return NULL;
INIT_LIST_HEAD(&e->next);
- INIT_LIST_HEAD(&e->ap_names);
- INIT_LIST_HEAD(&e->auto_ap_info);
- INIT_LIST_HEAD(&e->ap_instances);
INIT_LIST_HEAD(&e->difs);
+ INIT_LIST_HEAD(&e->bindings);
+ INIT_LIST_HEAD(&e->reg_apis);
- e->name = name;
- e->flags = flags;
- n->ap_name = ap_name;
-
- list_add(&n->next, &e->ap_names);
+ e->name = name;
- if (pthread_cond_init(&e->acc_signal, NULL)) {
- free(e);
+ if (pthread_cond_init(&e->acc_signal, NULL))
return NULL;
- }
- if (pthread_mutex_init(&e->state_lock, NULL)) {
- free(e);
+ if (pthread_mutex_init(&e->state_lock, NULL))
return NULL;
- }
e->state = REG_NAME_IDLE;
@@ -200,38 +233,20 @@ void reg_entry_destroy(struct reg_entry * e)
if (e->req_ae_name != NULL)
free(e->req_ae_name);
- list_for_each_safe(pos, n, &e->ap_instances) {
- struct reg_instance * i =
- list_entry(pos, struct reg_instance, next);
- reg_instance_destroy(i);
- }
-
- list_for_each_safe(pos, n, &e->auto_ap_info) {
- struct reg_auto * a =
- list_entry(pos, struct reg_auto, next);
-
- if (a->argv != NULL) {
- char ** t = a->argv;
- while (*a->argv != NULL)
- free(*(a->argv++));
- free(t);
- }
-
- free(a->ap_name);
- free(a);
+ list_for_each_safe(pos, n, &e->reg_apis) {
+ struct reg_api * i = list_entry(pos, struct reg_api, next);
+ reg_api_destroy(i);
}
- list_for_each_safe(pos, n, &e->ap_names) {
- struct reg_ap_name * n =
- list_entry(pos, struct reg_ap_name, next);
-
- free(n->ap_name);
- free(n);
+ list_for_each_safe(pos, n, &e->bindings) {
+ struct reg_binding * b =
+ list_entry(pos, struct reg_binding, next);
+ reg_binding_destroy(b);
}
list_for_each_safe(pos, n, &e->difs) {
- struct reg_dif_name * d =
- list_entry(pos, struct reg_dif_name, next);
+ struct reg_dif * d =
+ list_entry(pos, struct reg_dif, next);
free(d->dif_name);
free(d);
}
@@ -245,8 +260,8 @@ bool reg_entry_is_local_in_dif(struct reg_entry * e,
struct list_head * pos = NULL;
list_for_each(pos, &e->difs) {
- struct reg_dif_name * d =
- list_entry(pos, struct reg_dif_name, next);
+ struct reg_dif * d =
+ list_entry(pos, struct reg_dif, next);
if (!strcmp(dif_name, d->dif_name))
return true;
@@ -256,13 +271,15 @@ bool reg_entry_is_local_in_dif(struct reg_entry * e,
}
int reg_entry_add_local_in_dif(struct reg_entry * e,
- char * dif_name)
+ char * dif_name,
+ enum ipcp_type type)
{
if (!reg_entry_is_local_in_dif(e, dif_name)) {
- struct reg_dif_name * rdn = malloc(sizeof(*rdn));
+ struct reg_dif * rdn = malloc(sizeof(*rdn));
rdn->dif_name = strdup(dif_name);
if (rdn->dif_name == NULL)
return -1;
+ rdn->type = type;
list_add(&rdn->next, &e->difs);
return 0;
}
@@ -277,8 +294,8 @@ void reg_entry_del_local_from_dif(struct reg_entry * e,
struct list_head * n = NULL;
list_for_each_safe(pos, n, &e->difs) {
- struct reg_dif_name * d =
- list_entry(pos, struct reg_dif_name, next);
+ struct reg_dif * d =
+ list_entry(pos, struct reg_dif, next);
if (!strcmp(dif_name, d->dif_name)) {
list_del(&d->next);
@@ -287,81 +304,101 @@ void reg_entry_del_local_from_dif(struct reg_entry * e,
}
}
-
-struct reg_ap_name * reg_entry_get_ap_name(struct reg_entry * e,
- char * ap_name)
+struct reg_binding * reg_entry_get_binding(struct reg_entry * e,
+ char * apn)
{
struct list_head * pos = NULL;
- list_for_each(pos, &e->ap_names) {
- struct reg_ap_name * n =
- list_entry(pos, struct reg_ap_name, next);
+ list_for_each(pos, &e->bindings) {
+ struct reg_binding * n =
+ list_entry(pos, struct reg_binding, next);
- if (strcmp(ap_name, n->ap_name) == 0)
+ if (strcmp(apn, n->apn) == 0)
return n;
}
return NULL;
}
-struct reg_instance * reg_entry_get_reg_instance(struct reg_entry * e,
- pid_t api)
+void reg_entry_del_binding(struct reg_entry * e,
+ char * apn)
{
- struct list_head * pos = NULL;
+ struct reg_binding * b = reg_entry_get_binding(e, apn);
+ if (b == NULL)
+ return;
- list_for_each(pos, &e->ap_instances) {
- struct reg_instance * r =
- list_entry(pos, struct reg_instance, next);
+ list_del(&b->next);
+ free(b);
+}
- if (r->api == api)
- return r;
+struct reg_binding * reg_entry_add_binding(struct reg_entry * e,
+ char * apn,
+ uint32_t flags,
+ char ** argv)
+{
+ struct reg_binding * b;
+ if ((b = reg_entry_get_binding(e, apn)) != NULL) {
+ LOG_DBG("Updating AP name %s binding with %s.",
+ apn, e->name);
+ reg_entry_del_binding(e, b->apn);
}
- return NULL;
+ if (flags & BIND_AP_AUTO) {
+ b = reg_binding_create(apn, flags, argv);
+ if (e->state == REG_NAME_IDLE)
+ e->state = REG_NAME_AUTO_ACCEPT;
+ } else {
+ flags &= ~BIND_AP_AUTO;
+ b = reg_binding_create(apn, flags, NULL);
+ }
+
+ list_add(&b->next, &e->bindings);
+
+ return b;
}
-struct reg_auto * reg_entry_get_reg_auto(struct reg_entry * e,
- char * ap_name)
+char ** reg_entry_get_auto_info(struct reg_entry * e)
{
struct list_head * pos = NULL;
- list_for_each(pos, &e->auto_ap_info) {
- struct reg_auto * a =
- list_entry(pos, struct reg_auto, next);
-
- if (strcmp(ap_name, a->ap_name) == 0)
- return a;
+ list_for_each(pos, &e->bindings) {
+ struct reg_binding * b =
+ list_entry(pos, struct reg_binding, next);
+ if (b->flags & BIND_AP_AUTO)
+ return b->argv;
}
return NULL;
}
-pid_t reg_entry_resolve_api(struct reg_entry * e)
+struct reg_api * reg_entry_get_reg_api(struct reg_entry * e,
+ pid_t api)
{
struct list_head * pos = NULL;
- /* FIXME: now just returns the first accepting instance */
- list_for_each(pos, &e->ap_instances) {
- struct reg_instance * r =
- list_entry(pos, struct reg_instance, next);
- return r->api;
+ list_for_each(pos, &e->reg_apis) {
+ struct reg_api * r =
+ list_entry(pos, struct reg_api, next);
+
+ if (r->api == api)
+ return r;
}
- return -1;
+ return NULL;
}
-char ** reg_entry_resolve_auto(struct reg_entry * e)
+pid_t reg_entry_resolve_api(struct reg_entry * e)
{
struct list_head * pos = NULL;
/* FIXME: now just returns the first accepting instance */
- list_for_each(pos, &e->auto_ap_info) {
- struct reg_auto * r =
- list_entry(pos, struct reg_auto, next);
- return r->argv;
+ list_for_each(pos, &e->reg_apis) {
+ struct reg_api * r =
+ list_entry(pos, struct reg_api, next);
+ return r->api;
}
- return NULL;
+ return -1;
}
struct reg_entry * registry_get_entry_by_name(struct list_head * registry,
@@ -380,8 +417,8 @@ struct reg_entry * registry_get_entry_by_name(struct list_head * registry,
return NULL;
}
-struct reg_entry * registry_get_entry_by_ap_name(struct list_head * registry,
- char * ap_name)
+struct reg_entry * registry_get_entry_by_apn(struct list_head * registry,
+ char * apn)
{
struct list_head * pos = NULL;
@@ -390,11 +427,11 @@ struct reg_entry * registry_get_entry_by_ap_name(struct list_head * registry,
struct reg_entry * e =
list_entry(pos, struct reg_entry, next);
- list_for_each(p, &e->ap_names) {
- struct reg_ap_name * n =
- list_entry(p, struct reg_ap_name, next);
+ list_for_each(p, &e->bindings) {
+ struct reg_binding * b =
+ list_entry(p, struct reg_binding, next);
- if (strcmp(n->ap_name, ap_name) == 0)
+ if (strcmp(b->apn, apn) == 0)
return e;
}
}
@@ -402,8 +439,8 @@ struct reg_entry * registry_get_entry_by_ap_name(struct list_head * registry,
return NULL;
}
-struct reg_entry * registry_get_entry_by_ap_id(struct list_head * registry,
- pid_t api)
+struct reg_entry * registry_get_entry_by_api(struct list_head * registry,
+ pid_t api)
{
struct list_head * pos = NULL;
@@ -412,9 +449,9 @@ struct reg_entry * registry_get_entry_by_ap_id(struct list_head * registry,
struct reg_entry * e =
list_entry(pos, struct reg_entry, next);
- list_for_each(p, &e->ap_instances) {
- struct reg_instance * r =
- list_entry(p, struct reg_instance, next);
+ list_for_each(p, &e->reg_apis) {
+ struct reg_api * r =
+ list_entry(p, struct reg_api, next);
if (r->api == api)
return e;
@@ -424,136 +461,109 @@ struct reg_entry * registry_get_entry_by_ap_id(struct list_head * registry,
return NULL;
}
-int registry_add_entry(struct list_head * registry,
- char * name,
- char * ap_name,
- uint16_t flags)
+struct reg_entry * registry_assign(struct list_head * registry,
+ char * name)
{
struct reg_entry * e = NULL;
- if (name == NULL || ap_name == NULL)
- return -EINVAL;
+ if (name == NULL)
+ return NULL;
- e = registry_get_entry_by_name(registry, name);
- if (e != NULL) {
+ if (registry_has_name(registry, name)) {
LOG_DBG("Name %s already registered.", name);
- return -1;
+ return NULL;
}
e = reg_entry_create();
if (e == NULL) {
LOG_DBG("Could not create registry entry.");
- return -1;
+ return NULL;
}
- e = reg_entry_init(e, name, ap_name, flags);
+ e = reg_entry_init(e, name);
if (e == NULL) {
LOG_DBG("Could not initialize registry entry.");
reg_entry_destroy(e);
- return -1;
+ return NULL;
}
list_add(&e->next, registry);
- return 0;
+ return e;
+}
+
+void registry_deassign(struct list_head * registry,
+ char * name)
+{
+ struct reg_entry * e = registry_get_entry_by_name(registry, name);
+ if (e == NULL)
+ return;
+
+ list_del(&e->next);
+ reg_entry_destroy(e);
+
+ return;
}
-int registry_add_ap_auto(struct list_head * registry,
+int registry_add_binding(struct list_head * registry,
char * name,
- char * ap_name,
+ char * apn,
+ uint32_t flags,
char ** argv)
{
struct reg_entry * e;
- struct reg_auto * a;
- if (name == NULL || ap_name == NULL)
+ if (name == NULL || apn == NULL)
return -EINVAL;
e = registry_get_entry_by_name(registry, name);
if (e == NULL) {
- LOG_DBG("Name %s not found in registry.", name);
- return -1;
- }
-
- if (!(e->flags & BIND_AP_AUTO)) {
- LOG_DBG("%s does not allow auto-instantiation.", name);
- return -1;
- }
-
- if (!reg_entry_has_ap_name(e, ap_name)) {
- LOG_DBG("AP name %s not associated with %s.", ap_name, name);
- return -1;
+ LOG_DBG("Adding new name to registry: %s.", name);
+ e = registry_assign(registry, name);
}
if (e->state == REG_NAME_NULL) {
- LOG_DBG("Tried to add instantiation info in NULL state.");
+ LOG_DBG("Tried to add binding in NULL state.");
return -1;
}
- a = reg_entry_get_reg_auto(e, ap_name);
- if (a != NULL) {
- LOG_DBG("Updating auto-instantiation info for %s.", ap_name);
- list_del(&a->next);
- free(a->ap_name);
- if (a->argv != NULL) {
- while (*a->argv != NULL)
- free(*a->argv++);
- }
- } else {
- a = malloc(sizeof(*a));
- if (a == NULL)
- return -1;
- }
-
- a->ap_name = ap_name;
- a->argv = argv;
-
- if (e->state == REG_NAME_IDLE)
- e->state = REG_NAME_AUTO_ACCEPT;
-
- list_add(&a->next, &e->auto_ap_info);
+ if(reg_entry_add_binding(e, apn, flags, argv) == NULL)
+ return -1;
return 0;
}
-int registry_remove_ap_auto(struct list_head * registry,
- char * name,
- char * ap_name)
+void registry_del_binding(struct list_head * registry,
+ char * name,
+ char * apn)
{
- struct reg_entry * e;
- struct reg_auto * a;
+ struct reg_entry * e = NULL;
- if (name == NULL || ap_name == NULL)
- return -EINVAL;
+ if (name == NULL || apn == NULL)
+ return;
e = registry_get_entry_by_name(registry, name);
if (e == NULL) {
LOG_DBG("Name %s not found in registry.", name);
- return -1;
- }
-
- a = reg_entry_get_reg_auto(e, ap_name);
- if (a == NULL) {
- LOG_DBG("Auto-instantiation info for %s not found.", ap_name);
- return -1;
+ return;
}
- list_del(&a->next);
+ reg_entry_del_binding(e, apn);
- if (e->state == REG_NAME_AUTO_ACCEPT && list_empty(&e->auto_ap_info))
+ if (e->state == REG_NAME_AUTO_ACCEPT && !reg_entry_has_auto_binding(e))
e->state = REG_NAME_IDLE;
- return 0;
+ return;
}
-struct reg_instance * registry_add_api_name(struct list_head * registry,
- pid_t api,
- char * name)
+struct reg_api * registry_add_api_name(struct list_head * registry,
+ pid_t api,
+ char * name)
{
- struct reg_entry * e = NULL;
- struct reg_instance * i = NULL;
+ struct reg_entry * e = NULL;
+ struct reg_api * i = NULL;
if (name == NULL || api == -1)
return NULL;
@@ -564,17 +574,17 @@ struct reg_instance * registry_add_api_name(struct list_head * registry,
return NULL;
}
- if (reg_entry_has_api(e, api)) {
- LOG_DBG("Instance already registered with this name.");
+ if (e->state == REG_NAME_NULL) {
+ LOG_DBG("Tried to add instance in NULL state.");
return NULL;
}
- if (e->state == REG_NAME_NULL) {
- LOG_DBG("Tried to add instance in NULL state.");
+ if (reg_entry_has_api(e, api)) {
+ LOG_DBG("Instance already registered with this name.");
return NULL;
}
- i = reg_instance_create(api);
+ i = reg_api_create(api);
if (i == NULL) {
LOG_DBG("Failed to create reg_instance");
return NULL;
@@ -586,41 +596,39 @@ struct reg_instance * registry_add_api_name(struct list_head * registry,
pthread_cond_signal(&e->acc_signal);
}
- list_add(&i->next, &e->ap_instances);
+ list_add(&i->next, &e->reg_apis);
return i;
}
-int registry_remove_api_name(struct list_head * registry,
- pid_t api,
- char * name)
+void registry_del_api(struct list_head * registry,
+ pid_t api)
{
- struct reg_entry * e = NULL;
- struct reg_instance * i = NULL;
+ struct reg_entry * e = NULL;
+ struct reg_api * i = NULL;
- if (name == NULL || api == -1)
- return -EINVAL;
+ if ( api == -1)
+ return;
- e = registry_get_entry_by_name(registry, name);
+ e = registry_get_entry_by_api(registry, api);
if (e == NULL) {
- LOG_DBG("Name %s is not registered.", name);
- return -1;
+ LOG_DBG("Instance %d not found.", api);
+ return;
}
- i = reg_entry_get_reg_instance(e, api);
+ i = reg_entry_get_reg_api(e, api);
if (i == NULL) {
LOG_DBG("Instance %d is not accepting flows for %s.",
- api, name);
- return -1;
+ api, e->name);
+ return;
}
list_del(&i->next);
- reg_instance_destroy(i);
+ reg_api_destroy(i);
- if (list_empty(&e->ap_instances)) {
- if ((e->flags & BIND_AP_AUTO) &&
- !list_empty(&e->auto_ap_info))
+ if (list_empty(&e->reg_apis)) {
+ if (reg_entry_has_auto_binding(e))
e->state = REG_NAME_AUTO_ACCEPT;
else
e->state = REG_NAME_IDLE;
@@ -628,18 +636,88 @@ int registry_remove_api_name(struct list_head * registry,
e->state = REG_NAME_FLOW_ACCEPT;
}
- return 0;
+ return;
}
-void registry_del_name(struct list_head * registry,
- char * name)
+/* FIXME: optimize this */
+char * registry_get_dif_for_dst(struct list_head * registry,
+ char * dst_name)
{
- struct reg_entry * e = registry_get_entry_by_name(registry, name);
- if (e == NULL)
- return;
+ struct list_head * pos = NULL;
+ struct reg_entry * re =
+ registry_get_entry_by_name(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_del(&e->next);
- reg_entry_destroy(e);
+ 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;
+ }
- return;
+ 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_DBGF("No local ap %s found.", dst_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_ETH_LLC)
+ 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;
+ }
+
+ return NULL;
+ }
+}
+
+int registry_add_name_to_dif(struct list_head * registry,
+ char * name,
+ char * dif_name,
+ enum ipcp_type type)
+{
+ struct reg_entry * re = registry_get_entry_by_name(registry, name);
+ if (re == NULL)
+ return -1;
+
+ return reg_entry_add_local_in_dif(re, dif_name, type);
+}
+
+void registry_del_name_from_dif(struct list_head * registry,
+ char * name,
+ char * dif_name)
+{
+ struct reg_entry * re = registry_get_entry_by_name(registry, name);
+ if (re == NULL)
+ return;
+
+ reg_entry_del_local_from_dif(re, dif_name);
}
diff --git a/src/irmd/registry.h b/src/irmd/registry.h
index 927b2364..04ce7cf8 100644
--- a/src/irmd/registry.h
+++ b/src/irmd/registry.h
@@ -25,6 +25,7 @@
#include <ouroboros/config.h>
#include <ouroboros/list.h>
+#include <ouroboros/irm_config.h>
#include <stdint.h>
#include <stdbool.h>
@@ -32,9 +33,10 @@
#include <string.h>
#include <sys/types.h>
-#define reg_entry_has_api(e, id) (reg_entry_get_reg_instance(e, id) != NULL)
-#define reg_entry_has_ap_name(e, name) (reg_entry_get_ap_name(e, name) != NULL)
-#define reg_entry_has_ap_auto(e, name) (reg_entry_get_reg_auto(e, name) != NULL)
+#define registry_has_name(r, name) \
+ (registry_get_entry_by_name(r, name) != NULL)
+#define registry_name_has_api(r, name) \
+ (registry_get_api_by_name(r, name) != NULL)
enum reg_name_state {
REG_NAME_NULL = 0,
@@ -51,7 +53,7 @@ enum reg_i_state {
REG_I_WAKE
};
-struct reg_instance {
+struct reg_api {
struct list_head next;
pid_t api;
@@ -63,102 +65,91 @@ struct reg_instance {
/* an entry in the registry */
struct reg_entry {
- struct list_head next;
-
- /* generic name */
- char * name;
-
- /* names of the aps that can listen to this name */
- struct list_head ap_names;
-
- enum reg_name_state state;
-
- uint32_t flags;
+ struct list_head next;
+ char * name;
- /* auto execution info */
- struct list_head auto_ap_info;
+ /* DIFs in which this name is registered */
+ struct list_head difs;
+ /* names of the APs that can listen to this name */
+ struct list_head bindings;
/* known instances */
- struct list_head ap_instances;
+ struct list_head reg_apis;
- /* difs in which this name is registered */
- struct list_head difs;
-
- char * req_ae_name;
- int response;
-
- pthread_cond_t acc_signal;
- pthread_mutex_t state_lock;
+ /* flow handling information */
+ enum reg_name_state state;
+ char * req_ae_name;
+ int response;
+ pthread_cond_t acc_signal;
+ pthread_mutex_t state_lock;
};
-struct reg_auto {
- struct list_head next;
- char * ap_name;
- char ** argv;
-};
+struct reg_api * reg_api_create(pid_t api);
+void reg_api_destroy(struct reg_api * i);
+void reg_api_sleep(struct reg_api * i);
+void reg_api_wake(struct reg_api * i);
-struct reg_ap_name {
- struct list_head next;
- char * ap_name;
-};
-
-struct reg_dif_name {
- struct list_head next;
- char * dif_name;
-};
-struct reg_instance * reg_instance_create(pid_t api);
-void reg_instance_destroy(struct reg_instance * i);
-void reg_instance_sleep(struct reg_instance * i);
-void reg_instance_wake(struct reg_instance * i);
+struct reg_binding * reg_binding_create(char * apn,
+ uint32_t opts,
+ char ** argv);
+void reg_binding_destroy();
struct reg_entry * reg_entry_create();
struct reg_entry * reg_entry_init(struct reg_entry * e,
- char * name,
- char * ap_name,
- uint32_t flags);
+ char * name);
void reg_entry_destroy(struct reg_entry * e);
-struct reg_ap_name * reg_entry_get_ap_name(struct reg_entry * e,
- char * ap_name);
-struct reg_instance * reg_entry_get_reg_instance(struct reg_entry * e,
- pid_t api);
+struct reg_binding * reg_entry_get_binding(struct reg_entry * e,
+ char * apn);
+char ** reg_entry_get_auto_info(struct reg_entry * e);
+void reg_entry_del_binding(struct reg_entry * e,
+ char * apn);
+struct reg_api * reg_entry_get_reg_api(struct reg_entry * e,
+ pid_t api);
-struct reg_auto * reg_entry_get_reg_auto(struct reg_entry * e,
- char * ap_name);
pid_t reg_entry_resolve_api(struct reg_entry * e);
-char ** reg_entry_resolve_auto(struct reg_entry * e);
bool reg_entry_is_local_in_dif(struct reg_entry * e,
char * dif_name);
int reg_entry_add_local_in_dif(struct reg_entry * e,
- char * dif_name);
+ char * dif_name,
+ enum ipcp_type type);
void reg_entry_del_local_from_dif(struct reg_entry * e,
char * dif_name);
-int registry_add_entry(struct list_head * registry,
- char * name,
- char * ap_name,
- uint16_t flags);
-int registry_add_ap_auto(struct list_head * registry,
+
+struct reg_entry * registry_assign(struct list_head * registry,
+ char * name);
+void registry_deassign(struct list_head * registry,
+ char * name);
+int registry_add_binding(struct list_head * registry,
char * name,
- char * ap_name,
+ char * apn,
+ uint32_t flags,
char ** argv);
-int registry_remove_ap_auto(struct list_head * registry,
- char * name,
- char * ap_name);
-struct reg_instance * registry_add_api_name(struct list_head * registry,
+void registry_del_binding(struct list_head * registry,
+ char * name,
+ char * apn);
+struct reg_api * registry_add_api_name(struct list_head * registry,
pid_t api,
char * name);
-int registry_remove_api_name(struct list_head * registry,
- pid_t api,
+void registry_del_api(struct list_head * registry,
+ pid_t api);
+struct reg_api * registry_get_api_by_name(struct list_head * registry,
char * name);
struct reg_entry * registry_get_entry_by_name(struct list_head * registry,
char * name);
-struct reg_entry * registry_get_entry_by_ap_name(struct list_head * registry,
- char * ap_name);
-struct reg_entry * registry_get_entry_by_ap_id(struct list_head * registry,
- pid_t api);
-void registry_del_name(struct list_head * registry,
- char * name);
-
+struct reg_entry * registry_get_entry_by_apn(struct list_head * registry,
+ char * apn);
+struct reg_entry * registry_get_entry_by_api(struct list_head * registry,
+ pid_t api);
+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,
+ enum ipcp_type type);
+void registry_del_name_from_dif(struct list_head * registry,
+ char * name,
+ char * dif_name);
#endif