From f4f67651db3891652f4dd08dec990aa0560bb35c Mon Sep 17 00:00:00 2001 From: dimitri staessens Date: Fri, 22 Apr 2016 17:39:30 +0200 Subject: irmd: reg/unreg whatevercast names Unregistering ap's now works. An AP now registers/unregisters its AP-I by sending its AP name and its pid to the IRMd. The IPCPs register whatevercast names. An AP name is currently mapped on a whatevercast name represented by the same string literal. The IRMd allows registration of only one AP-I per AP. A Name Space Management system is needed in the processing system so we can resolve this completely. Changing the stack to register whatevercast names required some changes all over the ipcpd implemented and in the library. --- src/irmd/main.c | 284 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 254 insertions(+), 30 deletions(-) (limited to 'src/irmd') diff --git a/src/irmd/main.c b/src/irmd/main.c index 374bfb6c..fcd93bd5 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -41,6 +41,10 @@ #include #include #include +#include + +/* FIXME: this smells like part of namespace management */ +#define ALL_DIFS "*" struct ipcp_entry { struct list_head next; @@ -49,12 +53,27 @@ struct ipcp_entry { char * dif_name; }; +/* currently supports only registering whatevercast groups of a single AP */ +struct reg_name_entry { + struct list_head next; + + /* generic whatevercast name */ + char * name; + + /* FIXME: resolve name instead */ + instance_name_t * api; + uint32_t reg_ap_id; +}; + struct irm { + /* FIXME: list of ipcps can be merged with registered names */ struct list_head ipcps; + struct list_head reg_names; + + struct shm_du_map * dum; }; struct irm * instance = NULL; -struct shm_du_map * dum; static pid_t find_pid_by_ipcp_name(instance_name_t * api) { @@ -105,6 +124,101 @@ static pid_t find_pid_by_dif_name(char * dif_name) return 0; } +static struct reg_name_entry * reg_name_entry_create() +{ + struct reg_name_entry * e = malloc(sizeof(*e)); + if (e == NULL) + return NULL; + + e->reg_ap_id = rand() % INT_MAX; + e->name = NULL; + + INIT_LIST_HEAD(&e->next); + + return e; +} + +static struct reg_name_entry * reg_name_entry_init(struct reg_name_entry * e, + char * name, + instance_name_t * api) +{ + if (e == NULL || name == NULL || api == NULL) + return NULL; + + e->name = name; + e->api = api; + + return e; +} + +static int reg_name_entry_destroy(struct reg_name_entry * e) +{ + if (e == NULL) + return 0; + + free(e->name); + instance_name_destroy(e->api); + return 0; +} + +static struct reg_name_entry * find_reg_name_entry_by_name(char * name) +{ + struct list_head * pos = NULL; + + list_for_each(pos, &instance->reg_names) { + struct reg_name_entry * e = + list_entry(pos, struct reg_name_entry, next); + + if (strcmp(name, e->name) == 0) + return e; + } + + return NULL; +} + +static struct reg_name_entry * find_reg_name_entry_by_id(uint32_t reg_ap_id) +{ + struct list_head * pos = NULL; + + list_for_each(pos, &instance->reg_names) { + struct reg_name_entry * e = + list_entry(pos, struct reg_name_entry, next); + + if (reg_ap_id == e->reg_ap_id) + return e; + } + + return NULL; +} + +/* FIXME: add only name when we have NSM solved */ +static int reg_name_entry_add_name_instance(char * name, instance_name_t * api) +{ + struct reg_name_entry * e = find_reg_name_entry_by_name(name); + if (e == NULL) { + e = reg_name_entry_create(); + e = reg_name_entry_init(e, name, api); + list_add(&e->next, &instance->reg_names); + return 0; + } + + /* already exists, we don't have NSM yet */ + return -1; +} + +static int reg_name_entry_del_name(char * name) +{ + struct reg_name_entry * e = find_reg_name_entry_by_name(name); + if (e == NULL) + return 0; + + list_del(&e->next); + + reg_name_entry_destroy(e); + + return 0; +} + static int create_ipcp(instance_name_t * api, enum ipcp_type ipcp_type) { @@ -280,54 +394,161 @@ static int unreg_ipcp(instance_name_t * api, return 0; } -static int ap_reg(char * ap_name, +static int ap_unreg_id(uint32_t reg_ap_id, + pid_t pid, + char ** difs, + size_t len) +{ + int i; + int ret = 0; + struct reg_name_entry * rne = NULL; + struct list_head * pos = NULL; + + rne = find_reg_name_entry_by_id (reg_ap_id); + if (rne == NULL) + return 0; /* no such id */ + + if (instance->ipcps.next == NULL) { + LOG_ERR("No IPCPs in this system."); + return 0; + } + + if (strcmp(difs[0], ALL_DIFS) == 0) { + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + + if (ipcp_name_unreg(e->pid, rne->name)) { + LOG_ERR("Could not unregister %s in DIF %s.", + rne->name, e->dif_name); + --ret; + } + } + } else { + for (i = 0; i < len; ++i) { + pid = find_pid_by_dif_name(difs[i]); + if (pid == 0) { + LOG_ERR("%s: No such DIF.", difs[i]); + continue; + } + + if (ipcp_name_unreg(pid, rne->name)) { + LOG_ERR("Could not unregister %s in DIF %s.", + rne->name, difs[i]); + --ret; + } + } + } + + reg_name_entry_del_name(rne->name); + + return ret; +} + +static int ap_reg(char * ap_name, + pid_t ap_id, char ** difs, - size_t difs_size) + size_t len) { pid_t pid = 0; int i; int ret = 0; + int reg_ap_id = 0; + struct list_head * pos = NULL; + struct reg_name_entry * rne = NULL; + instance_name_t * api = NULL; + if (instance->ipcps.next == NULL) LOG_ERR("No IPCPs in this system."); + /* check if this ap_name is already registered */ + rne = find_reg_name_entry_by_name(ap_name); + if (rne != NULL) + return -1; /* can only register one instance for now */ + + rne = reg_name_entry_create(); + if (rne == NULL) + return -1; + + api = instance_name_create(); + if (instance_name_init_from(api, ap_name, ap_id) == NULL) { + instance_name_destroy(api); + return -1; + } + /* - * FIXME: this should be resolved by NSM - * Now it just takes the first DIF + * for now, the whatevercast name is the same as the ap_name and + * contains a single instance only */ - if (strcmp(difs[0], "*") == 0) { - difs[0] = list_entry(instance->ipcps.next, - struct ipcp_entry, - next)->dif_name; - difs_size = 1; + if (reg_name_entry_init(rne, strdup(ap_name), api) == NULL) { + reg_name_entry_destroy(rne); + instance_name_destroy(api); + return -1; } - for (i = 0; i < difs_size; ++i) { - pid = find_pid_by_dif_name(difs[i]); - if (pid == 0) { - LOG_ERR("%s: No such DIF.", difs[i]); - continue; + if (strcmp(difs[0], ALL_DIFS) == 0) { + list_for_each(pos, &instance->ipcps) { + struct ipcp_entry * e = + list_entry(pos, struct ipcp_entry, next); + + if (ipcp_name_reg(e->pid, api->name)) { + LOG_ERR("Could not register %s in DIF %s.", + api->name, e->dif_name); + } else { + ++ret; + } } - - /* FIXME: get proper reg_ap_id */ - if (ipcp_ap_reg(pid, rand(),ap_name)) { - LOG_ERR("Could not register %s in DIF %s.", - ap_name, difs[i]); - ret = -1; + } else { + for (i = 0; i < len; ++i) { + pid = find_pid_by_dif_name(difs[i]); + if (pid == 0) { + LOG_ERR("%s: No such DIF.", difs[i]); + continue; + } + + if (ipcp_name_reg(pid, api->name)) { + LOG_ERR("Could not register %s in DIF %s.", + api->name, difs[i]); + } else { + ++ret; + } } } - return ret; + if (ret == 0) { + instance_name_destroy(api); + return -1; + } + /* for now, we register single instances */ + reg_name_entry_add_name_instance(strdup(ap_name), instance_name_dup(api)); + + return reg_ap_id; } -static int ap_unreg(char * ap_name, +static int ap_unreg(char * ap_name, + pid_t ap_id, char ** difs, - size_t difs_size) + size_t len) { - return -1; + struct reg_name_entry * tmp = NULL; + + instance_name_t * api = instance_name_create(); + if (instance_name_init_from(api, ap_name, ap_id) == NULL) { + instance_name_destroy(api); + return -1; + } + + /* check if ap_name is registered */ + tmp = find_reg_name_entry_by_name(api->name); + if (tmp == NULL) + return 0; + else + return ap_unreg_id(tmp->reg_ap_id, api->id, difs, len); } + static int flow_accept(int fd, char * ap_name, char * ae_name) @@ -392,7 +613,7 @@ void irmd_sig_handler(int sig, siginfo_t * info, void * c) case SIGINT: case SIGTERM: case SIGHUP: - shm_du_map_close(dum); + shm_du_map_close(instance->dum); free(instance); exit(0); default: @@ -421,14 +642,15 @@ int main() if (access("/dev/shm/" SHM_DU_MAP_FILENAME, F_OK) != -1) unlink("/dev/shm/" SHM_DU_MAP_FILENAME); - if ((dum = shm_du_map_create()) == NULL) - return -1; - instance = malloc(sizeof(*instance)); if (instance == NULL) return -1; + if ((instance->dum = shm_du_map_create()) == NULL) + return -1; + INIT_LIST_HEAD(&instance->ipcps); + INIT_LIST_HEAD(&instance->reg_names); sockfd = server_socket_open(IRM_SOCK_PATH); if (sockfd < 0) { @@ -502,12 +724,14 @@ int main() case IRM_MSG_CODE__IRM_AP_REG: ret_msg.has_fd = true; ret_msg.fd = ap_reg(msg->ap_name, + msg->pid, msg->dif_name, msg->n_dif_name); break; case IRM_MSG_CODE__IRM_AP_UNREG: ret_msg.has_result = true; ret_msg.result = ap_unreg(msg->ap_name, + msg->pid, msg->dif_name, msg->n_dif_name); break; @@ -524,7 +748,7 @@ int main() break; case IRM_MSG_CODE__IRM_FLOW_ALLOC: ret_msg.has_fd = true; - ret_msg.fd = flow_alloc(msg->dst_ap_name, + ret_msg.fd = flow_alloc(msg->dst_name, msg->ap_name, msg->ae_name, NULL, -- cgit v1.2.3