diff options
| author | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-04-27 15:40:50 +0200 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@intec.ugent.be> | 2016-04-27 15:40:50 +0200 | 
| commit | 34c40b7ba465382cfc3ef83af00793dfbb8fa943 (patch) | |
| tree | 9f64215f326c3847699ae8856ae9cd0d609cbfac /src/irmd | |
| parent | b6dc5ba9576d61d42db82c3da8cb0c039fac7179 (diff) | |
| parent | 6809a2beea07a661a9c651cae1e100537c401bb7 (diff) | |
| download | ouroboros-34c40b7ba465382cfc3ef83af00793dfbb8fa943.tar.gz ouroboros-34c40b7ba465382cfc3ef83af00793dfbb8fa943.zip  | |
Merge remote-tracking branch 'upstream/be' into be
Diffstat (limited to 'src/irmd')
| -rw-r--r-- | src/irmd/main.c | 410 | 
1 files changed, 344 insertions, 66 deletions
diff --git a/src/irmd/main.c b/src/irmd/main.c index 13076cd1..31dabebb 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -41,23 +41,42 @@  #include <stdlib.h>  #include <errno.h>  #include <string.h> +#include <limits.h> + +/* FIXME: this smells like part of namespace management */ +#define ALL_DIFS "*"  struct ipcp_entry {          struct list_head  next; -        pid_t             pid;          instance_name_t * api;          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) +static struct ipcp_entry * find_ipcp_entry_by_name(instance_name_t * api)  { +        struct ipcp_entry * tmp = NULL;          struct list_head * pos = NULL;          list_for_each(pos, &instance->ipcps) { @@ -65,35 +84,147 @@ static pid_t find_pid_by_ipcp_name(instance_name_t * api)                          list_entry(pos, struct ipcp_entry, next);                  if (instance_name_cmp(api, tmp->api) == 0) -                        return tmp->pid; +                        return tmp;          } -        return 0; +        return tmp;  } -static struct ipcp_entry * find_ipcp_by_name(instance_name_t * api) +static instance_name_t * get_ipcp_by_name(char * ap_name)  { -        struct ipcp_entry * tmp = NULL;          struct list_head * pos = NULL;          list_for_each(pos, &instance->ipcps) { -                struct ipcp_entry * tmp = +                struct ipcp_entry * e =                          list_entry(pos, struct ipcp_entry, next); -                if (instance_name_cmp(api, tmp->api) == 0) -                        return tmp; +                if (strcmp(e->api->name, ap_name) == 0) +                        return e->api;          } -        return tmp; +        return NULL; +} + +static instance_name_t * get_ipcp_by_dif_name(char * dif_name) +{ +        struct list_head * pos = 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 (strcmp(dif_name, e->dif_name) == 0) +                        return e->api; +        } + +        return NULL; +} + +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) +static pid_t create_ipcp(char *         ap_name, +                         enum ipcp_type ipcp_type)  {          pid_t pid;          struct ipcp_entry * tmp = NULL; -        pid = ipcp_create(api, ipcp_type); +        pid = ipcp_create(ap_name, ipcp_type);          if (pid == -1) {                  LOG_ERR("Failed to create IPCP");                  return -1; @@ -106,36 +237,42 @@ static int create_ipcp(instance_name_t * api,          INIT_LIST_HEAD(&tmp->next); -        tmp->pid = pid; -        tmp->api = instance_name_dup(api); +        tmp->api = instance_name_create();          if (tmp->api == NULL) {                  free(tmp);                  return -1;          } +        if(instance_name_init_from(tmp->api, ap_name, pid) == NULL) { +                instance_name_destroy(tmp->api); +                free(tmp); +                return -1; +        } +          tmp->dif_name = NULL;          LOG_DBG("Created IPC process with pid %d", pid);          list_add(&tmp->next, &instance->ipcps); -        return 0; +        return pid;  }  static int destroy_ipcp(instance_name_t * api)  { -        pid_t pid = 0;          struct list_head * pos = NULL;          struct list_head * n = NULL; -        pid = find_pid_by_ipcp_name(api); -        if (pid == 0) { -                LOG_ERR("No such IPCP"); +        if (api->id == 0) +                api = get_ipcp_by_name(api->name); + +        if (api == NULL) { +                LOG_ERR("No such IPCP in the system.");                  return -1;          } -        LOG_DBG("Destroying ipcp with pid %d", pid); +        LOG_DBG("Destroying ipcp %s-%d", api->name, api->id); -        if (ipcp_destroy(pid)) +        if (ipcp_destroy(api->id))                  LOG_ERR("Could not destroy IPCP");          list_for_each_safe(pos, n, &(instance->ipcps)) { @@ -154,7 +291,15 @@ static int bootstrap_ipcp(instance_name_t *  api,  {          struct ipcp_entry * entry = NULL; -        entry = find_ipcp_by_name(api); +        if (api->id == 0) +                api = get_ipcp_by_name(api->name); + +        if (api == NULL) { +                LOG_ERR("No such IPCP in the system."); +                return -1; +        } + +        entry = find_ipcp_entry_by_name(api);          if (entry == NULL) {                  LOG_ERR("No such IPCP");                  return -1; @@ -166,7 +311,7 @@ static int bootstrap_ipcp(instance_name_t *  api,                  return -1;          } -        if (ipcp_bootstrap(entry->pid, conf)) { +        if (ipcp_bootstrap(entry->api->id, conf)) {                  LOG_ERR("Could not bootstrap IPCP");                  free(entry->dif_name);                  entry->dif_name = NULL; @@ -184,7 +329,7 @@ static int enroll_ipcp(instance_name_t  * api,          ssize_t n_1_difs_size = 0;          struct ipcp_entry * entry = NULL; -        entry = find_ipcp_by_name(api); +        entry = find_ipcp_entry_by_name(api);          if (entry == NULL) {                  LOG_ERR("No such IPCP");                  return -1; @@ -212,7 +357,7 @@ static int enroll_ipcp(instance_name_t  * api,                  return -1;          } -        if (ipcp_enroll(entry->pid, member, n_1_difs[0])) { +        if (ipcp_enroll(entry->api->id, member, n_1_difs[0])) {                  LOG_ERR("Could not enroll IPCP");                  free(entry->dif_name);                  entry->dif_name = NULL; @@ -226,15 +371,7 @@ static int reg_ipcp(instance_name_t * api,                      char **           difs,                      size_t            difs_size)  { -        pid_t pid = 0; - -        pid = find_pid_by_ipcp_name(api); -        if (pid == 0) { -                LOG_ERR("No such IPCP"); -                return -1; -        } - -        if (ipcp_reg(pid, difs, difs_size)) { +        if (ipcp_reg(api->id, difs, difs_size)) {                  LOG_ERR("Could not register IPCP to N-1 DIF(s)");                  return -1;          } @@ -246,15 +383,8 @@ static int unreg_ipcp(instance_name_t  * api,                        char **            difs,                        size_t             difs_size)  { -        pid_t pid = 0; - -        pid = find_pid_by_ipcp_name(api); -        if (pid == 0) { -                LOG_ERR("No such IPCP"); -                return -1; -        } -        if (ipcp_unreg(pid, difs, difs_size)) { +        if (ipcp_unreg(api->id, difs, difs_size)) {                  LOG_ERR("Could not unregister IPCP from N-1 DIF(s)");                  return -1;          } @@ -262,20 +392,162 @@ 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->api->id, rne->name)) { +                                LOG_ERR("Could not unregister %s in DIF %s.", +                                        rne->name, e->dif_name); +                                --ret; +                        } +                } +        } else { +                for (i = 0; i < len; ++i) { +                        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)  { -        return -1; +        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; +        instance_name_t * ipcpi = 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; +        } + +        /* +         * for now, the whatevercast name is the same as the ap_name and +         * contains a single instance only +         */ + +        if (reg_name_entry_init(rne, strdup(ap_name), api) == NULL) { +                reg_name_entry_destroy(rne); +                instance_name_destroy(api); +                return -1; +        } + +        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->api->id, ap_name)) { +                                LOG_ERR("Could not register %s in DIF %s.", +                                        api->name, e->dif_name); +                        } else { +                                ++ret; +                        } +                } +        } else { +                for (i = 0; i < len; ++i) { +                        ipcpi = get_ipcp_by_dif_name(difs[i]); +                        if (ipcpi == NULL) { +                                LOG_ERR("%s: No such DIF.", difs[i]); +                                continue; +                        } + +                        if (ipcp_name_reg(ipcpi->id, api->name)) { +                                LOG_ERR("Could not register %s in DIF %s.", +                                        api->name, difs[i]); +                        } else { +                                ++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)); +        instance_name_destroy(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 (api == NULL) +                return -1; + +        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) { +                instance_name_destroy(api); +                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) @@ -340,7 +612,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: @@ -356,7 +628,7 @@ int main()          struct sigaction sig_act;          /* init sig_act */ -        memset (&sig_act, 0, sizeof sig_act); +        memset(&sig_act, 0, sizeof sig_act);          /* install signal traps */          sig_act.sa_sigaction = &irmd_sig_handler; @@ -366,21 +638,24 @@ int main()          sigaction(SIGTERM, &sig_act, NULL);          sigaction(SIGHUP,  &sig_act, NULL); -          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) { +                free(instance); +                return -1; +        } +          INIT_LIST_HEAD(&instance->ipcps); +        INIT_LIST_HEAD(&instance->reg_names);          sockfd = server_socket_open(IRM_SOCK_PATH);          if (sockfd < 0) { +                shm_du_map_close(instance->dum);                  free(instance);                  return -1;          } @@ -415,12 +690,13 @@ int main()                  }                  api.name = msg->ap_name; -                api.id   = msg->api_id; +                if (msg->has_api_id == true) +                        api.id = msg->api_id;                  switch (msg->code) {                  case IRM_MSG_CODE__IRM_CREATE_IPCP:                          ret_msg.has_result = true; -                        ret_msg.result = create_ipcp(&api, +                        ret_msg.result = create_ipcp(msg->ap_name,                                                       msg->ipcp_type);                          break;                  case IRM_MSG_CODE__IRM_DESTROY_IPCP: @@ -451,12 +727,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; @@ -473,15 +751,15 @@ 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,                                                  msg->oflags);                          break;                  case IRM_MSG_CODE__IRM_FLOW_ALLOC_RES: -                        ret_msg.has_result = true; -                        ret_msg.result = flow_alloc_res(msg->fd); +                        ret_msg.has_response = true; +                        ret_msg.response = flow_alloc_res(msg->fd);                          break;                  case IRM_MSG_CODE__IRM_FLOW_DEALLOC:                          ret_msg.has_result = true; @@ -493,15 +771,15 @@ int main()                                                     msg->oflags);                          break;                  case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR: -                        ret_msg.has_fd = true; -                        ret_msg.fd = flow_req_arr(msg->port_id, -                                                  msg->ap_name, -                                                  msg->ae_name); +                        ret_msg.has_port_id = true; +                        ret_msg.port_id = flow_req_arr(msg->port_id, +                                                       msg->ap_name, +                                                       msg->ae_name);                          break;                  case IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY:                          ret_msg.has_result = true;                          ret_msg.result = flow_alloc_reply(msg->port_id, -                                                          msg->result); +                                                          msg->response);                          break;                  case IRM_MSG_CODE__IPCP_FLOW_DEALLOC:                          ret_msg.has_result = true;  | 
