diff options
-rw-r--r-- | include/ouroboros/irm_config.h | 2 | ||||
-rw-r--r-- | src/irmd/main.c | 173 | ||||
-rw-r--r-- | src/irmd/registry.c | 512 | ||||
-rw-r--r-- | src/irmd/registry.h | 139 |
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 |