summaryrefslogtreecommitdiff
path: root/src/irmd/registry.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/irmd/registry.c')
-rw-r--r--src/irmd/registry.c512
1 files changed, 295 insertions, 217 deletions
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);
}