diff options
32 files changed, 1229 insertions, 809 deletions
diff --git a/doc/man/ouroboros.8 b/doc/man/ouroboros.8 index 063f5e8d..95d17a05 100644 --- a/doc/man/ouroboros.8 +++ b/doc/man/ouroboros.8 @@ -272,6 +272,11 @@ disconnects \fIcomponent\fR (\fBdt\fR or \fBmgmt\fR) of a normal IPCP  with name \fIname\fR from that component of the destination IPCP within the  same layer.  .RE + +\fBirm ipcp list\fR type \fItype\fR name \fIname\fR layer \fIlayer\fR +.RS 4 +lists IPCPs in the system. You can filter by type, by name or by layer. +.RE  .RE  .SH IRM COMMANDS @@ -329,15 +334,17 @@ not accept future flow allocation requests for \fIname\fR.  .RE  .PP -\fBirm reg\fR name \fIname\fR layer \fIlayer\fR [layer \fIlayer\fR ...] +\fBirm reg\fR name \fIname\fR \fIipcp\fR ipcp [\fIipcp\fR ...] +layer [layer \fIlayer\fR ...]  .RS 4 -Register name \fIname\fR in layers \fIlayer\fR. +Register name \fIname\fR in ipcps \fIipcp\fR ipcp and layers \fIlayer\fR.  .RE  .PP -\fBirm unreg\fR name \fIname\fR layer \fIlayer\fR [layer \fIlayer\fR ...] +\fBirm unreg\fR name \fIname\fR \fIipcp\fR ipcp [\fIipcp\fR ...] +layer [layer \fIlayer\fR ...]  .RS 4 -Unregister name \fIname\fR in layers \fIlayer\fR. +Unregister name \fIname\fR in ipcps \fIipcp\fR ipcp and layers \fIlayer\fR.  .RE  .SH TERMINOLOGY diff --git a/include/ouroboros/irm.h b/include/ouroboros/irm.h index ed0b2f71..fe6d2e9f 100644 --- a/include/ouroboros/irm.h +++ b/include/ouroboros/irm.h @@ -35,19 +35,27 @@  /* Name binding options. */  #define BIND_AUTO   0x01 +#define NAME_SIZE 256 +#define LAYER_SIZE LAYER_NAME_SIZE + +struct ipcp_info { +        pid_t          pid; +        enum ipcp_type type; +        char           name[NAME_SIZE]; +        char           layer[LAYER_SIZE];; +}; +  __BEGIN_DECLS  pid_t   irm_create_ipcp(const char *   name, -                        enum ipcp_type ipcp_type); +                        enum ipcp_type type);  int     irm_destroy_ipcp(pid_t pid); -/* pids is an out-parameter */ -ssize_t irm_list_ipcps(const char * name, -                       pid_t **     pids); +ssize_t irm_list_ipcps(struct ipcp_info ** ipcps);  int     irm_enroll_ipcp(pid_t        pid, -                        const char * layer_name); +                        const char * dst);  int     irm_bootstrap_ipcp(pid_t                      pid,                             const struct ipcp_config * conf); @@ -75,13 +83,11 @@ int     irm_bind_process(pid_t        pid,  int     irm_unbind_process(pid_t        pid,                             const char * name); -int     irm_reg(const char *  name, -                char **       layers, -                size_t        len); +int     irm_reg(pid_t        pid, +                const char * name); -int     irm_unreg(const char * name, -                  char **      layers, -                  size_t       len); +int     irm_unreg(pid_t        pid, +                  const char * name);  __END_DECLS diff --git a/include/ouroboros/sockets.h b/include/ouroboros/sockets.h index da3e36d0..36ea4da9 100644 --- a/include/ouroboros/sockets.h +++ b/include/ouroboros/sockets.h @@ -31,6 +31,7 @@ typedef LayerInfoMsg layer_info_msg_t;  #include "irmd_messages.pb-c.h"  typedef IrmMsg irm_msg_t; +typedef IpcpInfoMsg ipcp_info_msg_t;  #include "ipcpd_messages.pb-c.h"  typedef IpcpMsg ipcp_msg_t; @@ -39,7 +40,7 @@ typedef IpcpMsg ipcp_msg_t;  #define SOCK_PATH_SUFFIX ".sock"  #define IRM_SOCK_PATH SOCK_PATH "irm" SOCK_PATH_SUFFIX -#define IRM_MSG_BUF_SIZE 256 +#define IRM_MSG_BUF_SIZE 2048  #define IPCP_SOCK_PATH_PREFIX SOCK_PATH "ipcp"  #define IPCP_MSG_BUF_SIZE IRM_MSG_BUF_SIZE diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index b0ce87c5..d834997f 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -312,7 +312,7 @@ static void * mainloop(void * o)                                  break;                          } -                        ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst_name, +                        ret_msg.result = ipcpi.ops->ipcp_enroll(msg->dst,                                                                  &info);                          if (ret_msg.result == 0) {                                  ret_msg.layer_info       = &layer_info; @@ -329,9 +329,8 @@ static void * mainloop(void * o)                                  break;                          } -                        ret_msg.result = -                                ipcpi.ops->ipcp_connect(msg->dst_name, -                                                        msg->comp_name); +                        ret_msg.result = ipcpi.ops->ipcp_connect(msg->dst, +                                                                 msg->comp);                          break;                  case IPCP_MSG_CODE__IPCP_DISCONNECT:                          ret_msg.has_result = true; @@ -342,9 +341,8 @@ static void * mainloop(void * o)                                  break;                          } -                        ret_msg.result = -                                ipcpi.ops->ipcp_disconnect(msg->dst_name, -                                                           msg->comp_name); +                        ret_msg.result = ipcpi.ops->ipcp_disconnect(msg->dst, +                                                                    msg->comp);                          break;                  case IPCP_MSG_CODE__IPCP_REG:                          ret_msg.has_result = true; diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index efb5fbf3..49bf13c9 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -253,8 +253,8 @@ int ipcp_enroll(pid_t               pid,          if (dst == NULL)                  return -EINVAL; -        msg.code     = IPCP_MSG_CODE__IPCP_ENROLL; -        msg.dst_name = (char *) dst; +        msg.code = IPCP_MSG_CODE__IPCP_ENROLL; +        msg.dst  = (char *) dst;          recv_msg = send_recv_ipcp_msg(pid, &msg);          if (recv_msg == NULL) @@ -292,11 +292,11 @@ int ipcp_connect(pid_t        pid,          ipcp_msg_t * recv_msg = NULL;          int          ret      = -1; -        msg.code      = IPCP_MSG_CODE__IPCP_CONNECT; -        msg.dst_name  = (char *) dst; -        msg.comp_name = (char *) component; -        msg.has_pid   = true; -        msg.pid       = pid; +        msg.code    = IPCP_MSG_CODE__IPCP_CONNECT; +        msg.dst     = (char *) dst; +        msg.comp    = (char *) component; +        msg.has_pid = true; +        msg.pid     = pid;          recv_msg = send_recv_ipcp_msg(pid, &msg);          if (recv_msg == NULL) @@ -321,11 +321,11 @@ int ipcp_disconnect(pid_t        pid,          ipcp_msg_t * recv_msg = NULL;          int          ret      = -1; -        msg.code      = IPCP_MSG_CODE__IPCP_DISCONNECT; -        msg.dst_name  = (char *) dst; -        msg.comp_name = (char *) component; -        msg.has_pid   = true; -        msg.pid       = pid; +        msg.code    = IPCP_MSG_CODE__IPCP_DISCONNECT; +        msg.dst     = (char *) dst; +        msg.comp    = (char *) component; +        msg.has_pid = true; +        msg.pid     = pid;          recv_msg = send_recv_ipcp_msg(pid, &msg);          if (recv_msg == NULL) diff --git a/src/irmd/main.c b/src/irmd/main.c index 411df6dd..e90cbbc8 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -83,11 +83,11 @@ struct ipcp_entry {          pid_t            pid;          enum ipcp_type   type;          enum hash_algo   dir_hash_algo; -        char *           layer_name; +        char *           layer; -        enum init_state  init_state; -        pthread_cond_t   init_cond; -        pthread_mutex_t  init_lock; +        enum init_state  state; +        pthread_cond_t   cond; +        pthread_mutex_t  lock;  };  enum irm_state { @@ -107,6 +107,7 @@ struct {          struct list_head     registry;     /* registered names known     */          struct list_head     ipcps;        /* list of ipcps in system    */ +        size_t               n_ipcps;      /* number of ipcps            */          struct list_head     proc_table;   /* processes                  */          struct list_head     prog_table;   /* programs known             */ @@ -197,47 +198,116 @@ static struct irm_flow * get_irm_flow_n(pid_t n_pid)          return NULL;  } -static struct ipcp_entry * ipcp_entry_create(void) +static struct ipcp_entry * ipcp_entry_create(const char *   name, +                                             enum ipcp_type type)  { -        struct ipcp_entry * e = malloc(sizeof(*e)); +        struct ipcp_entry * e; +        pthread_condattr_t  cattr; + +        e = malloc(sizeof(*e));          if (e == NULL) -                return NULL; +                goto fail_malloc; + +        e->layer = NULL; +        e->type  = type; +        e->state = IPCP_BOOT; +        e->name  = strdup(name); +        if (e->name == NULL) +                goto fail_name; + +        if (pthread_condattr_init(&cattr)) +                goto fail_cattr; +#ifndef __APPLE__ +        pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); +#endif +        if (pthread_cond_init(&e->cond, &cattr)) +                goto fail_cond; + +        if (pthread_mutex_init(&e->lock, NULL)) +                goto fail_mutex; -        e->name       = NULL; -        e->layer_name = NULL;          list_head_init(&e->next); +        pthread_condattr_destroy(&cattr); +          return e; + + fail_mutex: +        pthread_cond_destroy(&e->cond); + fail_cond: +        pthread_condattr_destroy(&cattr); + fail_cattr: +        free(e->name); + fail_name: +        free(e); + fail_malloc: +        return NULL;  }  static void ipcp_entry_destroy(struct ipcp_entry * e)  {          assert(e); -        pthread_mutex_lock(&e->init_lock); +        pthread_mutex_lock(&e->lock); -        while (e->init_state == IPCP_BOOT) -                pthread_cond_wait(&e->init_cond, &e->init_lock); +        while (e->state == IPCP_BOOT) +                pthread_cond_wait(&e->cond, &e->lock); -        pthread_mutex_unlock(&e->init_lock); +        pthread_mutex_unlock(&e->lock); -        if (e->name != NULL) -                free(e->name); +        free(e->name); +        free(e->layer); +        free(e); +} -        if (e->layer_name != NULL) -                free(e->layer_name); +static void ipcp_entry_set_state(struct ipcp_entry * e, +                                 enum init_state     state) +{ +        pthread_mutex_lock(&e->lock); +        e->state = state; +        pthread_cond_broadcast(&e->cond); +        pthread_mutex_unlock(&e->lock); +} -        free(e); +static int ipcp_entry_wait_boot(struct ipcp_entry * e) +{ +        int             ret = 0; +        struct timespec dl; +        struct timespec to = {SOCKET_TIMEOUT / 1000, +                              (SOCKET_TIMEOUT % 1000) * MILLION}; + +        clock_gettime(PTHREAD_COND_CLOCK, &dl); +        ts_add(&dl, &to, &dl); + +        pthread_mutex_lock(&e->lock); + +        while (e->state == IPCP_BOOT && ret != ETIMEDOUT) +                ret = pthread_cond_timedwait(&e->cond, &e->lock, &dl); + +        if (ret == ETIMEDOUT) { +                kill(e->pid, SIGTERM); +                e->state = IPCP_NULL; +                pthread_cond_signal(&e->cond); +        } + +        if (e->state != IPCP_LIVE) { +                pthread_mutex_unlock(&e->lock); +                return -1; +        } + +        pthread_mutex_unlock(&e->lock); + +        return 0;  }  static struct ipcp_entry * get_ipcp_entry_by_pid(pid_t pid)  { -        struct list_head * p = NULL; +        struct list_head * p;          list_for_each(p, &irmd.ipcps) {                  struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); -                if (pid == e->pid) +                if (e->pid == pid)                          return e;          } @@ -246,7 +316,7 @@ static struct ipcp_entry * get_ipcp_entry_by_pid(pid_t pid)  static struct ipcp_entry * get_ipcp_entry_by_name(const char * name)  { -        struct list_head * p = NULL; +        struct list_head * p;          list_for_each(p, &irmd.ipcps) {                  struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); @@ -264,15 +334,18 @@ static struct ipcp_entry * get_ipcp_by_dst_name(const char * name,          struct list_head * h;          uint8_t *          hash;          pid_t              pid; +        size_t             len;          pthread_rwlock_rdlock(&irmd.reg_lock);          list_for_each_safe(p, h, &irmd.ipcps) {                  struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); -                if (e->layer_name == NULL || e->pid == src) +                if (e->layer == NULL || e->pid == src)                          continue; -                hash = malloc(IPCP_HASH_LEN(e)); +                len = IPCP_HASH_LEN(e); + +                hash = malloc(len);                  if  (hash == NULL)                          return NULL; @@ -282,7 +355,7 @@ static struct ipcp_entry * get_ipcp_by_dst_name(const char * name,                  pthread_rwlock_unlock(&irmd.reg_lock); -                if (ipcp_query(pid, hash, IPCP_HASH_LEN(e)) == 0) { +                if (ipcp_query(pid, hash, len) == 0) {                          free(hash);                          return e;                  } @@ -297,134 +370,89 @@ static struct ipcp_entry * get_ipcp_by_dst_name(const char * name,          return NULL;  } -static pid_t create_ipcp(char *         name, -                         enum ipcp_type ipcp_type) +static pid_t create_ipcp(const char *   name, +                         enum ipcp_type type)  { -        struct pid_el *     ppid  = NULL; -        struct ipcp_entry * tmp   = NULL; -        struct list_head *  p     = NULL; -        struct ipcp_entry * entry = NULL; -        int                 ret   = 0; -        pthread_condattr_t  cattr; -        struct timespec     dl; -        struct timespec     to = {SOCKET_TIMEOUT / 1000, -                                  (SOCKET_TIMEOUT % 1000) * MILLION}; -        pid_t               ipcp_pid; - -        ppid = malloc(sizeof(*ppid)); -        if (ppid == NULL) -                return -ENOMEM; +        struct pid_el *     ppid; +        struct ipcp_entry * entry; +        struct list_head *  p; +        pid_t               pid; -        pthread_rwlock_wrlock(&irmd.reg_lock); +        pthread_rwlock_rdlock(&irmd.reg_lock);          entry = get_ipcp_entry_by_name(name);          if (entry != NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock); -                free(ppid);                  log_err("IPCP by that name already exists."); -                return -1; -        } - -        ppid->pid = ipcp_create(name, ipcp_type); -        if (ppid->pid == -1) { -                pthread_rwlock_unlock(&irmd.reg_lock); -                free(ppid); -                log_err("Failed to create IPCP."); -                return -1; +                return -EPERM;          } -        tmp = ipcp_entry_create(); -        if (tmp == NULL) { -                pthread_rwlock_unlock(&irmd.reg_lock); -                free(ppid); -                return -1; -        } +        pthread_rwlock_unlock(&irmd.reg_lock); -        list_head_init(&tmp->next); +        ppid = malloc(sizeof(*ppid)); +        if (ppid == NULL) +                goto fail_ppid; -        tmp->name = strdup(name); -        if (tmp->name == NULL) { -                ipcp_entry_destroy(tmp); -                pthread_rwlock_unlock(&irmd.reg_lock); -                free(ppid); -                return -1; +        entry = ipcp_entry_create(name, type); +        if (entry == NULL) { +                log_err("Failed to create IPCP entry."); +                goto fail_ipcp_entry;          } -        pthread_condattr_init(&cattr); -#ifndef __APPLE__ -        pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); -#endif - -        pthread_cond_init(&tmp->init_cond, &cattr); - -        pthread_condattr_destroy(&cattr); +        pid = ipcp_create(name, type); +        if (pid == -1) { +                log_err("Failed to create IPCP."); +                goto fail_ipcp; +        } -        pthread_mutex_init(&tmp->init_lock, NULL); +        entry->pid = pid; -        tmp->pid           = ppid->pid; -        tmp->layer_name    = NULL; -        tmp->type          = ipcp_type; -        tmp->init_state    = IPCP_BOOT; -        tmp->dir_hash_algo = -1; -        ipcp_pid           = tmp->pid; +        pthread_rwlock_wrlock(&irmd.reg_lock);          list_for_each(p, &irmd.ipcps) { -                struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); -                if (e->type > ipcp_type) +                if (list_entry(p, struct ipcp_entry, next)->type > type)                          break;          } -        list_add_tail(&tmp->next, p); +        list_add_tail(&entry->next, p); +        ++irmd.n_ipcps; +        ppid->pid = entry->pid;          list_add(&ppid->next, &irmd.spawned_pids);          pthread_rwlock_unlock(&irmd.reg_lock); -        pthread_mutex_lock(&tmp->init_lock); - -        clock_gettime(PTHREAD_COND_CLOCK, &dl); -        ts_add(&dl, &to, &dl); - -        while (tmp->init_state == IPCP_BOOT && ret != -ETIMEDOUT) -                ret = -pthread_cond_timedwait(&tmp->init_cond, -                                              &tmp->init_lock, -                                              &dl); - -        if (ret == -ETIMEDOUT) { -                kill(tmp->pid, SIGKILL); -                tmp->init_state = IPCP_NULL; -                pthread_cond_signal(&tmp->init_cond); -                pthread_mutex_unlock(&tmp->init_lock); -                log_err("IPCP %d failed to respond.", ipcp_pid); +        /* IRMd maintenance will clean up if booting fails. */ +        if (ipcp_entry_wait_boot(entry)) { +                log_err("IPCP %d failed to boot.", pid);                  return -1;          } -        pthread_mutex_unlock(&tmp->init_lock); +        log_info("Created IPCP %d.", pid); -        log_info("Created IPCP %d.", ipcp_pid); +        return pid; -        return ipcp_pid; +        ipcp_destroy(pid); + fail_ipcp: +        ipcp_entry_destroy(entry); + fail_ipcp_entry: +        free(ppid); + fail_ppid: +        return -1;  }  static int create_ipcp_r(pid_t pid,                           int   result)  { -        struct list_head * pos = NULL; - -        if (result != 0) -                return result; +        struct list_head * p;          pthread_rwlock_rdlock(&irmd.reg_lock); -        list_for_each(pos, &irmd.ipcps) { -                struct ipcp_entry * e = -                        list_entry(pos, struct ipcp_entry, next); - +        list_for_each(p, &irmd.ipcps) { +                struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next);                  if (e->pid == pid) { -                        pthread_mutex_lock(&e->init_lock); -                        e->init_state = IPCP_LIVE; -                        pthread_cond_broadcast(&e->init_cond); -                        pthread_mutex_unlock(&e->init_lock); +                        ipcp_entry_set_state(e, result ? IPCP_NULL : IPCP_LIVE); +                        break;                  }          } @@ -435,12 +463,12 @@ static int create_ipcp_r(pid_t pid,  static void clear_spawned_process(pid_t pid)  { -        struct list_head * pos = NULL; -        struct list_head * n   = NULL; +        struct list_head * p; +        struct list_head * h; -        list_for_each_safe(pos, n, &(irmd.spawned_pids)) { -                struct pid_el * a = list_entry(pos, struct pid_el, next); -                if (pid == a->pid) { +        list_for_each_safe(p, h, &(irmd.spawned_pids)) { +                struct pid_el * a = list_entry(p, struct pid_el, next); +                if (a->pid == pid) {                          list_del(&a->next);                          free(a);                  } @@ -449,22 +477,20 @@ static void clear_spawned_process(pid_t pid)  static int destroy_ipcp(pid_t pid)  { -        struct list_head * pos = NULL; -        struct list_head * n   = NULL; +        struct list_head * p; +        struct list_head * h;          pthread_rwlock_wrlock(&irmd.reg_lock); -        list_for_each_safe(pos, n, &(irmd.ipcps)) { -                struct ipcp_entry * tmp = -                        list_entry(pos, struct ipcp_entry, next); - -                if (pid == tmp->pid) { +        list_for_each_safe(p, h, &irmd.ipcps) { +                struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); +                if (e->pid == pid) {                          clear_spawned_process(pid);                          if (ipcp_destroy(pid))                                  log_err("Could not destroy IPCP."); -                        list_del(&tmp->next); -                        ipcp_entry_destroy(tmp); - +                        list_del(&e->next); +                        ipcp_entry_destroy(e); +                        --irmd.n_ipcps;                          log_info("Destroyed IPCP %d.", pid);                  }          } @@ -477,7 +503,7 @@ static int destroy_ipcp(pid_t pid)  static int bootstrap_ipcp(pid_t               pid,                            ipcp_config_msg_t * conf)  { -        struct ipcp_entry * entry = NULL; +        struct ipcp_entry * entry;          struct layer_info   info;          pthread_rwlock_wrlock(&irmd.reg_lock); @@ -501,8 +527,8 @@ static int bootstrap_ipcp(pid_t               pid,                  return -1;          } -        entry->layer_name = strdup(info.layer_name); -        if (entry->layer_name == NULL) { +        entry->layer = strdup(info.layer_name); +        if (entry->layer == NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock);                  log_warn("Failed to set name of layer.");                  return -ENOMEM; @@ -519,7 +545,7 @@ static int bootstrap_ipcp(pid_t               pid,  }  static int enroll_ipcp(pid_t  pid, -                       char * dst_name) +                       char * dst)  {          struct ipcp_entry * entry = NULL;          struct layer_info   info; @@ -533,7 +559,7 @@ static int enroll_ipcp(pid_t  pid,                  return -1;          } -        if (entry->layer_name != NULL) { +        if (entry->layer != NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock);                  log_err("IPCP in wrong state");                  return -1; @@ -541,7 +567,7 @@ static int enroll_ipcp(pid_t  pid,          pthread_rwlock_unlock(&irmd.reg_lock); -        if (ipcp_enroll(pid, dst_name, &info) < 0) { +        if (ipcp_enroll(pid, dst, &info) < 0) {                  log_err("Could not enroll IPCP %d.", pid);                  return -1;          } @@ -555,8 +581,8 @@ static int enroll_ipcp(pid_t  pid,                  return -1;          } -        entry->layer_name = strdup(info.layer_name); -        if (entry->layer_name == NULL) { +        entry->layer = strdup(info.layer_name); +        if (entry->layer == NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock);                  log_err("Failed to strdup layer_name.");                  return -ENOMEM; @@ -648,13 +674,13 @@ static int bind_program(char *   prog,                          int      argc,                          char **  argv)  { -        char * progs; -        char * progn; -        char ** argv_dup = NULL; -        int i; -        char * name_dup = NULL; -        struct prog_entry * e = NULL; -        struct reg_entry * re = NULL; +        char *              progs; +        char *              progn; +        char **             argv_dup = NULL; +        int                 i; +        char *              name_dup = NULL; +        struct prog_entry * e        = NULL; +        struct reg_entry *  re       = NULL;          if (prog == NULL || name == NULL)                  return -EINVAL; @@ -662,7 +688,6 @@ static int bind_program(char *   prog,          pthread_rwlock_wrlock(&irmd.reg_lock);          e = prog_table_get(&irmd.prog_table, path_strip(prog)); -          if (e == NULL) {                  progs = strdup(path_strip(prog));                  if (progs == NULL) { @@ -704,9 +729,7 @@ static int bind_program(char *   prog,                          argvfree(argv_dup);                          return -ENOMEM;                  } -                  prog_table_add(&irmd.prog_table, e); -          }          name_dup = strdup(name); @@ -835,68 +858,78 @@ static int unbind_process(pid_t        pid,          return 0;  } -static ssize_t list_ipcps(char *   name, -                          pid_t ** pids) +static ssize_t list_ipcps(ipcp_info_msg_t *** ipcps, +                          size_t *            n_ipcps)  { -        struct list_head * pos = NULL; -        size_t count = 0; -        int i = 0; +        struct list_head * p; +        int                i = 0;          pthread_rwlock_rdlock(&irmd.reg_lock); -        list_for_each(pos, &irmd.ipcps) { -                struct ipcp_entry * tmp = -                        list_entry(pos, struct ipcp_entry, next); -                if (wildcard_match(name, tmp->name) == 0) -                        count++; -        } +        *n_ipcps = irmd.n_ipcps; -        if (count == 0) { +        if (*n_ipcps == 0) {                  pthread_rwlock_unlock(&irmd.reg_lock);                  return 0;          } -        *pids = malloc(count * sizeof(**pids)); -        if (*pids == NULL) { +        *ipcps = malloc(irmd.n_ipcps * sizeof(**ipcps)); +        if (*ipcps == NULL) {                  pthread_rwlock_unlock(&irmd.reg_lock); +                *n_ipcps = 0;                  return -1;          } -        list_for_each(pos, &irmd.ipcps) { -                struct ipcp_entry * tmp = -                        list_entry(pos, struct ipcp_entry, next); -                if (wildcard_match(name, tmp->name) == 0) -                        (*pids)[i++] = tmp->pid; -        } +        list_for_each(p, &irmd.ipcps) { +                struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); +                (*ipcps)[i] = malloc(sizeof(***ipcps)); +                if ((*ipcps)[i] == NULL) +                        goto fail_malloc; + +                ipcp_info_msg__init((*ipcps)[i]); +                (*ipcps)[i]->name = strdup(e->name); +                if ((*ipcps)[i]->name == NULL) +                        goto fail_mem; + +                (*ipcps)[i]->layer = strdup( +                        e->layer != NULL ? e->layer : "Not enrolled"); +                if ((*ipcps)[i]->layer == NULL) +                        goto fail_mem; + +                (*ipcps)[i]->pid    = e->pid; +                (*ipcps)[i++]->type = e->type; +       }          pthread_rwlock_unlock(&irmd.reg_lock); -        return count; +        return 0; + + fail_mem: +        while (i > 0) { +                free((*ipcps)[i]->layer); +                free((*ipcps)[i]->name); +                free(*ipcps[--i]); +        } +        free(*ipcps); +        *n_ipcps = 0; +        return -ENOMEM; + + fail_malloc: +        while (i > 0) +                free(*ipcps[--i]); +        free(*ipcps); +        *n_ipcps = 0; +        return -ENOMEM;  } -static int name_reg(const char *  name, -                    char **       layers, -                    size_t        len) +static int irm_update_name(const char * name)  { -        size_t i; -        int ret = 0; -        struct list_head * p = NULL; - -        assert(name); -        assert(len); -        assert(layers); -        assert(layers[0]); +        struct list_head * p;          pthread_rwlock_wrlock(&irmd.reg_lock); -        if (list_is_empty(&irmd.ipcps)) { -                pthread_rwlock_unlock(&irmd.reg_lock); -                return -1; -        } -          if (!registry_has_name(&irmd.registry, name)) { -                struct reg_entry * re = -                        registry_add_name(&irmd.registry, name); +                struct reg_entry * re = registry_add_name(&irmd.registry, name);                  if (re == NULL) {                          log_err("Failed creating registry entry for %s.", name);                          pthread_rwlock_unlock(&irmd.reg_lock); @@ -906,11 +939,11 @@ static int name_reg(const char *  name,                  /* check the tables for client programs */                  list_for_each(p, &irmd.proc_table) {                          struct list_head * q; -                        struct proc_entry * e = -                                list_entry(p, struct proc_entry, next); +                        struct proc_entry * e; +                        e = list_entry(p, struct proc_entry, next);                          list_for_each(q, &e->names) { -                                struct str_el * s = -                                        list_entry(q, struct str_el, next); +                                struct str_el * s; +                                s = list_entry(q, struct str_el, next);                                  if (!strcmp(s->str, name))                                          reg_entry_add_pid(re, e->pid);                          } @@ -918,145 +951,145 @@ static int name_reg(const char *  name,                  list_for_each(p, &irmd.prog_table) {                          struct list_head * q; -                        struct prog_entry * e = -                                list_entry(p, struct prog_entry, next); +                        struct prog_entry * e; +                        e = list_entry(p, struct prog_entry, next);                          list_for_each(q, &e->names) { -                                struct str_el * s = -                                        list_entry(q, struct str_el, next); +                                struct str_el * s; +                                s = list_entry(q, struct str_el, next);                                  if (!strcmp(s->str, name))                                          reg_entry_add_prog(re, e);                          }                  }          } -        list_for_each(p, &irmd.ipcps) { -                struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next); -                if (e->layer_name == NULL) -                        continue; +        pthread_rwlock_unlock(&irmd.reg_lock); -                for (i = 0; i < len; ++i) { -                        uint8_t * hash; -                        pid_t     pid; -                        size_t    len; +        return 0; +} -                        if (wildcard_match(layers[i], e->layer_name)) -                                continue; +static int name_reg(pid_t         pid, +                    const char *  name) +{ +        size_t              len; +        struct ipcp_entry * ipcp; +        uint8_t *           hash; +        int                 err; -                        hash = malloc(IPCP_HASH_LEN(e)); -                        if (hash == NULL) -                                break; +        assert(name); -                        str_hash(e->dir_hash_algo, hash, name); +        pthread_rwlock_wrlock(&irmd.reg_lock); -                        pid = e->pid; -                        len = IPCP_HASH_LEN(e); +        ipcp = get_ipcp_entry_by_pid(pid); +        if (ipcp == NULL) { +                err = -EIPCP; +                goto fail; +        } -                        pthread_rwlock_unlock(&irmd.reg_lock); +        if (ipcp->layer == NULL) { +                err = -EPERM; +                goto fail; +        } -                        if (ipcp_reg(pid, hash, len)) { -                                log_err("Could not register " HASH_FMT -                                        " with IPCP %d.", -                                        HASH_VAL(hash), pid); -                                pthread_rwlock_wrlock(&irmd.reg_lock); -                                free(hash); -                                break; -                        } +        len = IPCP_HASH_LEN(ipcp); -                        pthread_rwlock_wrlock(&irmd.reg_lock); +        hash = malloc(len); +        if (hash == NULL) { +                err = -ENOMEM; +                goto fail; +        } -                        log_info("Registered %s in %s as " HASH_FMT ".", -                                 name, e->layer_name, HASH_VAL(hash)); -                        ++ret; +        str_hash(ipcp->dir_hash_algo, hash, name); +        pthread_rwlock_unlock(&irmd.reg_lock); -                        free(hash); -                } +        if (ipcp_reg(pid, hash, len)) { +                log_err("Could not register " HASH_FMT " with IPCP %d.", +                        HASH_VAL(hash), pid); +                free(hash); +                return -1;          } -        pthread_rwlock_unlock(&irmd.reg_lock); +        irm_update_name(name); -        return (ret > 0 ? 0 : -1); +        log_info("Registered %s with IPCP %d as " HASH_FMT ".", +                 name, pid, HASH_VAL(hash)); + +        free(hash); + +        return 0; + +fail: +        pthread_rwlock_unlock(&irmd.reg_lock); +        return err;  } -static int name_unreg(const char *  name, -                      char **       layers, -                      size_t        len) +static int name_unreg(pid_t         pid, +                      const char *  name)  { -        size_t i; -        int ret = 0; -        struct list_head * pos = NULL; +        struct ipcp_entry * ipcp; +        int                 err; +        uint8_t *           hash; +        size_t              len;          assert(name); -        assert(len); -        assert(layers); -        assert(layers[0]);          pthread_rwlock_wrlock(&irmd.reg_lock); -        list_for_each(pos, &irmd.ipcps) { -                struct ipcp_entry * e = -                        list_entry(pos, struct ipcp_entry, next); - -                if (e->layer_name == NULL) -                        continue; - -                for (i = 0; i < len; ++i) { -                        uint8_t * hash; -                        pid_t     pid; -                        size_t    len; +        ipcp = get_ipcp_entry_by_pid(pid); +        if (ipcp == NULL) { +                err = -EIPCP; +                goto fail; +        } -                        if (wildcard_match(layers[i], e->layer_name)) -                                continue; +        if (ipcp->layer == NULL) { +                err = -EPERM; +                goto fail; +        } -                        hash = malloc(IPCP_HASH_LEN(e)); -                        if  (hash == NULL) -                                break; +        len = IPCP_HASH_LEN(ipcp); -                        str_hash(e->dir_hash_algo, hash, name); +        hash = malloc(len); +        if  (hash == NULL) { +                err = -ENOMEM; +                goto fail; +        } -                        pid = e->pid; -                        len = IPCP_HASH_LEN(e); +        str_hash(ipcp->dir_hash_algo, hash, name); -                        pthread_rwlock_unlock(&irmd.reg_lock); +        pthread_rwlock_unlock(&irmd.reg_lock); -                        if (ipcp_unreg(pid, hash, len)) { -                                log_err("Could not unregister %s with IPCP %d.", -                                        name, pid); -                                pthread_rwlock_wrlock(&irmd.reg_lock); -                                free(hash); -                                break; -                        } +        if (ipcp_unreg(pid, hash, len)) { +                log_err("Could not unregister %s with IPCP %d.", name, pid); +                free(hash); +                return -1; +        } -                        pthread_rwlock_wrlock(&irmd.reg_lock); +        log_info("Unregistered %s from %d.", name, pid); -                        log_info("Unregistered %s from %s.", -                                 name, e->layer_name); -                        ++ret; +        free(hash); -                        free(hash); -                } -        } +        return 0; + fail:          pthread_rwlock_unlock(&irmd.reg_lock); - -        return (ret > 0 ? 0 : -1); +        return err;  }  static int proc_announce(pid_t  pid,                           char * prog)  { -        struct proc_entry * e = NULL; -        struct prog_entry * a = NULL; -        char * prog_dup; -        if (prog == NULL) -                return -EINVAL; +        struct proc_entry * e; +        struct prog_entry * a; +        char *              prog_dup; + +        assert(prog);          prog_dup = strdup(prog); -        if (prog_dup == NULL) { +        if (prog_dup == NULL)                  return -ENOMEM; -        }          e = proc_entry_create(pid, prog_dup);          if (e == NULL) { +                free(prog_dup);                  return -ENOMEM;          } @@ -1065,7 +1098,6 @@ static int proc_announce(pid_t  pid,          proc_table_add(&irmd.proc_table, e);          /* Copy listen names from program if it exists. */ -          a = prog_table_get(&irmd.prog_table, e->prog);          if (a != NULL) {                  struct list_head * p; @@ -1876,17 +1908,24 @@ static void * mainloop(void * o)          (void) o;          while (true) { -                irm_msg_t         ret_msg = IRM_MSG__INIT; +                irm_msg_t       * ret_msg;                  struct irm_flow * e       = NULL; -                pid_t *           pids    = NULL;                  struct timespec * timeo   = NULL;                  struct timespec   ts      = {0, 0};                  struct cmd *      cmd; -                ret_msg.code = IRM_MSG_CODE__IRM_REPLY; +                ret_msg = malloc(sizeof(*ret_msg)); +                if (ret_msg == NULL) +                        return (void *) -1; + +                irm_msg__init(ret_msg); + +                ret_msg->code = IRM_MSG_CODE__IRM_REPLY; +                  pthread_mutex_lock(&irmd.cmd_lock); +                pthread_cleanup_push(free_msg, ret_msg);                  pthread_cleanup_push((void *)(void *) pthread_mutex_unlock,                                       &irmd.cmd_lock); @@ -1897,6 +1936,7 @@ static void * mainloop(void * o)                  list_del(&cmd->next);                  pthread_cleanup_pop(true); +                pthread_cleanup_pop(false);                  msg = irm_msg__unpack(NULL, cmd->len, cmd->cbuf);                  sfd = cmd->fd; @@ -1905,6 +1945,7 @@ static void * mainloop(void * o)                  if (msg == NULL) {                          close(sfd); +                        irm_msg__free_unpacked(ret_msg, NULL);                          continue;                  } @@ -1920,151 +1961,145 @@ static void * mainloop(void * o)                  pthread_cleanup_push(close_ptr, &sfd);                  pthread_cleanup_push(free_msg, msg); +                pthread_cleanup_push(free_msg, ret_msg);                  switch (msg->code) {                  case IRM_MSG_CODE__IRM_CREATE_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = create_ipcp(msg->dst_name, -                                                     msg->ipcp_type); +                        ret_msg->has_result = true; +                        ret_msg->result = create_ipcp(msg->name, +                                                      msg->ipcp_type);                          break;                  case IRM_MSG_CODE__IPCP_CREATE_R: -                        ret_msg.has_result = true; -                        ret_msg.result = create_ipcp_r(msg->pid, msg->result); +                        ret_msg->has_result = true; +                        ret_msg->result = create_ipcp_r(msg->pid, msg->result);                          break;                  case IRM_MSG_CODE__IRM_DESTROY_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = destroy_ipcp(msg->pid); +                        ret_msg->has_result = true; +                        ret_msg->result = destroy_ipcp(msg->pid);                          break;                  case IRM_MSG_CODE__IRM_BOOTSTRAP_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = bootstrap_ipcp(msg->pid, msg->conf); +                        ret_msg->has_result = true; +                        ret_msg->result = bootstrap_ipcp(msg->pid, msg->conf);                          break;                  case IRM_MSG_CODE__IRM_ENROLL_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = enroll_ipcp(msg->pid, -                                                     msg->layer_name[0]); +                        ret_msg->has_result = true; +                        ret_msg->result = enroll_ipcp(msg->pid, msg->dst);                          break;                  case IRM_MSG_CODE__IRM_CONNECT_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = connect_ipcp(msg->pid, -                                                      msg->dst_name, -                                                      msg->comp_name); +                        ret_msg->has_result = true; +                        ret_msg->result = connect_ipcp(msg->pid, +                                                       msg->dst, +                                                       msg->comp);                          break;                  case IRM_MSG_CODE__IRM_DISCONNECT_IPCP: -                        ret_msg.has_result = true; -                        ret_msg.result = disconnect_ipcp(msg->pid, -                                                         msg->dst_name, -                                                         msg->comp_name); +                        ret_msg->has_result = true; +                        ret_msg->result = disconnect_ipcp(msg->pid, +                                                          msg->dst, +                                                          msg->comp);                          break;                  case IRM_MSG_CODE__IRM_BIND_PROGRAM: -                        ret_msg.has_result = true; -                        ret_msg.result = bind_program(msg->prog_name, -                                                      msg->dst_name, -                                                      msg->opts, -                                                      msg->n_args, -                                                      msg->args); +                        ret_msg->has_result = true; +                        ret_msg->result = bind_program(msg->prog, +                                                       msg->name, +                                                       msg->opts, +                                                       msg->n_args, +                                                       msg->args);                          break;                  case IRM_MSG_CODE__IRM_UNBIND_PROGRAM: -                        ret_msg.has_result = true; -                        ret_msg.result = unbind_program(msg->prog_name, -                                                        msg->dst_name); +                        ret_msg->has_result = true; +                        ret_msg->result = unbind_program(msg->prog, msg->name);                          break;                  case IRM_MSG_CODE__IRM_PROC_ANNOUNCE: -                        ret_msg.has_result = true; -                        ret_msg.result = proc_announce(msg->pid, -                                                       msg->prog_name); +                        ret_msg->has_result = true; +                        ret_msg->result = proc_announce(msg->pid, msg->prog);                          break;                  case IRM_MSG_CODE__IRM_BIND_PROCESS: -                        ret_msg.has_result = true; -                        ret_msg.result = bind_process(msg->pid, msg->dst_name); +                        ret_msg->has_result = true; +                        ret_msg->result = bind_process(msg->pid, msg->name);                          break;                  case IRM_MSG_CODE__IRM_UNBIND_PROCESS: -                        ret_msg.has_result = true; -                        ret_msg.result = unbind_process(msg->pid, -                                                        msg->dst_name); +                        ret_msg->has_result = true; +                        ret_msg->result = unbind_process(msg->pid, msg->name);                          break;                  case IRM_MSG_CODE__IRM_LIST_IPCPS: -                        ret_msg.has_result = true; -                        ret_msg.n_pids = list_ipcps(msg->dst_name, &pids); -                        ret_msg.pids = pids; +                        ret_msg->has_result = true; +                        ret_msg->result = list_ipcps(&ret_msg->ipcps, +                                                     &ret_msg->n_ipcps);                          break;                  case IRM_MSG_CODE__IRM_REG: -                        ret_msg.has_result = true; -                        ret_msg.result = name_reg(msg->dst_name, -                                                  msg->layer_name, -                                                  msg->n_layer_name); +                        ret_msg->has_result = true; +                        ret_msg->result = name_reg(msg->pid, msg->name);                          break;                  case IRM_MSG_CODE__IRM_UNREG: -                        ret_msg.has_result = true; -                        ret_msg.result = name_unreg(msg->dst_name, -                                                    msg->layer_name, -                                                    msg->n_layer_name); +                        ret_msg->has_result = true; +                        ret_msg->result = name_unreg(msg->pid, msg->name);                          break;                  case IRM_MSG_CODE__IRM_FLOW_ACCEPT: -                        ret_msg.has_result = true; -                        ret_msg.result = flow_accept(msg->pid, timeo, &e); -                        if (ret_msg.result == 0) { -                                ret_msg.has_port_id = true; -                                ret_msg.port_id     = e->port_id; -                                ret_msg.has_pid     = true; -                                ret_msg.pid         = e->n_1_pid; -                                ret_msg.has_qoscube = true; -                                ret_msg.qoscube     = e->qc; +                        ret_msg->has_result = true; +                        ret_msg->result = flow_accept(msg->pid, timeo, &e); +                        if (ret_msg->result == 0) { +                                ret_msg->has_port_id = true; +                                ret_msg->port_id     = e->port_id; +                                ret_msg->has_pid     = true; +                                ret_msg->pid         = e->n_1_pid; +                                ret_msg->has_qoscube = true; +                                ret_msg->qoscube     = e->qc;                          }                          break;                  case IRM_MSG_CODE__IRM_FLOW_ALLOC: -                        ret_msg.has_result = true; -                        ret_msg.result = flow_alloc(msg->pid, msg->dst_name, -                                                    msg->qoscube, timeo, &e); -                        if (ret_msg.result == 0) { -                                ret_msg.has_port_id = true; -                                ret_msg.port_id     = e->port_id; -                                ret_msg.has_pid     = true; -                                ret_msg.pid         = e->n_1_pid; +                        ret_msg->has_result = true; +                        ret_msg->result = flow_alloc(msg->pid, msg->dst, +                                                     msg->qoscube, timeo, &e); +                        if (ret_msg->result == 0) { +                                ret_msg->has_port_id = true; +                                ret_msg->port_id     = e->port_id; +                                ret_msg->has_pid     = true; +                                ret_msg->pid         = e->n_1_pid;                          }                          break;                  case IRM_MSG_CODE__IRM_FLOW_DEALLOC: -                        ret_msg.has_result = true; -                        ret_msg.result = flow_dealloc(msg->pid, msg->port_id); +                        ret_msg->has_result = true; +                        ret_msg->result = flow_dealloc(msg->pid, msg->port_id);                          break;                  case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR:                          e = flow_req_arr(msg->pid,                                           msg->hash.data,                                           msg->qoscube); -                        ret_msg.has_result = true; +                        ret_msg->has_result = true;                          if (e == NULL) { -                                ret_msg.result = -1; +                                ret_msg->result = -1;                                  break;                          } -                        ret_msg.has_port_id = true; -                        ret_msg.port_id     = e->port_id; -                        ret_msg.has_pid     = true; -                        ret_msg.pid         = e->n_pid; +                        ret_msg->has_port_id = true; +                        ret_msg->port_id     = e->port_id; +                        ret_msg->has_pid     = true; +                        ret_msg->pid         = e->n_pid;                          break;                  case IRM_MSG_CODE__IPCP_FLOW_ALLOC_REPLY: -                        ret_msg.has_result = true; -                        ret_msg.result = flow_alloc_reply(msg->port_id, -                                                          msg->response); +                        ret_msg->has_result = true; +                        ret_msg->result = flow_alloc_reply(msg->port_id, +                                                           msg->response);                          break;                  default:                          log_err("Don't know that message code.");                          break;                  } +                pthread_cleanup_pop(false);                  pthread_cleanup_pop(true);                  pthread_cleanup_pop(false); -                if (ret_msg.result == -EPIPE || !ret_msg.has_result) { +                if (ret_msg->result == -EPIPE || !ret_msg->has_result) { +                        irm_msg__free_unpacked(ret_msg, NULL);                          close(sfd);                          tpm_inc(irmd.tpm);                          continue;                  } -                buffer.len = irm_msg__get_packed_size(&ret_msg); +                buffer.len = irm_msg__get_packed_size(ret_msg);                  if (buffer.len == 0) {                          log_err("Failed to calculate length of reply message."); -                        if (pids != NULL) -                                free(pids); +                        irm_msg__free_unpacked(ret_msg, NULL);                          close(sfd);                          tpm_inc(irmd.tpm);                          continue; @@ -2072,22 +2107,20 @@ static void * mainloop(void * o)                  buffer.data = malloc(buffer.len);                  if (buffer.data == NULL) { -                        if (pids != NULL) -                                free(pids); +                        irm_msg__free_unpacked(ret_msg, NULL);                          close(sfd);                          tpm_inc(irmd.tpm);                          continue;                  } -                irm_msg__pack(&ret_msg, buffer.data); +                irm_msg__pack(ret_msg, buffer.data); -                if (pids != NULL) -                        free(pids); +                irm_msg__free_unpacked(ret_msg, NULL);                  pthread_cleanup_push(close_ptr, &sfd);                  if (write(sfd, buffer.data, buffer.len) == -1) -                        if (ret_msg.result != -EIRMD) +                        if (ret_msg->result != -EIRMD)                                  log_warn("Failed to send reply message.");                  free(buffer.data); diff --git a/src/irmd/proc_table.c b/src/irmd/proc_table.c index beda2f62..e8d08447 100644 --- a/src/irmd/proc_table.c +++ b/src/irmd/proc_table.c @@ -166,7 +166,7 @@ void proc_entry_del_name(struct proc_entry * e,          list_for_each_safe(p, h, &e->names) {                  struct str_el * s = list_entry(p, struct str_el, next); -                if (!wildcard_match(name, s->str)) { +                if (!strcmp(name, s->str)) {                          list_del(&s->next);                          if (s->str != NULL)                                  free(s->str); diff --git a/src/irmd/prog_table.c b/src/irmd/prog_table.c index 563e7e10..bd69e156 100644 --- a/src/irmd/prog_table.c +++ b/src/irmd/prog_table.c @@ -115,7 +115,7 @@ void prog_entry_del_name(struct prog_entry * e,          list_for_each_safe(p, h, &e->names) {                  struct str_el * s = list_entry(p, struct str_el, next); -                if (!wildcard_match(name, s->str)) { +                if (!strcmp(name, s->str)) {                          list_del(&s->next);                          if (s->str != NULL)                                  free(s->str); @@ -146,7 +146,7 @@ void prog_table_del(struct list_head * prog_table,          list_for_each_safe(p, h, prog_table) {                  struct prog_entry * e = list_entry(p, struct prog_entry, next); -                if (!wildcard_match(prog, e->prog)) { +                if (!strcmp(prog, e->prog)) {                          list_del(&e->next);                          prog_entry_destroy(e);                  } diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 6da36055..145a7452 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -44,7 +44,9 @@  static struct reg_entry * reg_entry_create(void)  { -        struct reg_entry * e = malloc(sizeof(*e)); +        struct reg_entry * e; + +        e = malloc(sizeof(*e));          if (e == NULL)                  return NULL; @@ -59,8 +61,8 @@ static int reg_entry_init(struct reg_entry * e,  {          pthread_condattr_t cattr; -        if (e == NULL || name == NULL) -                return -1; +        assert(e); +        assert(name);          list_head_init(&e->next);          list_head_init(&e->reg_progs); @@ -69,20 +71,29 @@ static int reg_entry_init(struct reg_entry * e,          e->name = name;          if (pthread_condattr_init(&cattr)) -                return -1; +                goto fail_cattr;  #ifndef __APPLE__          pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK);  #endif          if (pthread_cond_init(&e->state_cond, &cattr)) -                return -1; +                goto fail_cond;          if (pthread_mutex_init(&e->state_lock, NULL)) -                return -1; +                goto fail_mutex; + +        pthread_condattr_destroy(&cattr);          e->state = REG_NAME_IDLE;          return 0; + + fail_mutex: +        pthread_cond_destroy(&e->state_cond); + fail_cond: +        pthread_condattr_destroy(&cattr); + fail_cattr: +        return -1;  }  static void cancel_reg_entry_destroy(void * o) @@ -199,12 +210,12 @@ int reg_entry_add_prog(struct reg_entry *  e,  void reg_entry_del_prog(struct reg_entry * e,                          const char *       prog)  { -        struct list_head * p = NULL; -        struct list_head * h = NULL; +        struct list_head * p; +        struct list_head * h;          list_for_each_safe(p, h, &e->reg_progs) {                  struct str_el * e = list_entry(p, struct str_el, next); -                if (!wildcard_match(prog, e->str)) { +                if (!strcmp(prog, e->str)) {                          list_del(&e->next);                          free(e->str);                          free(e); @@ -470,7 +481,7 @@ struct reg_entry * registry_get_entry(struct list_head * registry,          list_for_each(p, registry) {                  struct reg_entry * e = list_entry(p, struct reg_entry, next); -                if (!wildcard_match(name, e->name)) +                if (!strcmp(name, e->name))                          return e;          } diff --git a/src/irmd/registry.h b/src/irmd/registry.h index c570be32..62d90c39 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -55,8 +55,6 @@ struct reg_entry {          struct list_head    next;          char *              name; -        /* layers in which this name is registered */ -        struct list_head    layers;          /* Programs that can be instantiated by the irmd */          struct list_head    reg_progs;          /* Processes that are listening for this name */ diff --git a/src/irmd/utils.c b/src/irmd/utils.c index a13fa485..c2bda581 100644 --- a/src/irmd/utils.c +++ b/src/irmd/utils.c @@ -62,74 +62,3 @@ char ** argvdup(char ** argv)          argv_dup[argc] = NULL;          return argv_dup;  } - -/* - * Copyright (c) 1989, 1993, 1994 - *      The Regents of the University of California.  All rights reserved. - * - * Wildcard Match code below is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * wildcard_match is based on the fnmatch function from POSIX.2. - * Implementation based on that one from FreeBSD. - */ - -int wildcard_match(const char * pattern, const char * string) -{ -        char c; - -        /* For loop? Why not Zoidberg? */ -        for (;;) { -                switch (c = *pattern++) { -                case '\0': -                        return (*string == '\0' ? 0 : -1); -                case '*': -                        c = *pattern; - -                        if (c == '\0') -                                return 0; - -                        /* General case, use recursion. */ -                        while ((c = *string) != '\0') { -                                if (!wildcard_match(pattern, string)) -                                        return 0; -                                ++string; -                        } -                        return -1; -                default: -                        if (c != *string) -                                return -1; -                        string++; -                        break; -                } -        } -} diff --git a/src/irmd/utils.h b/src/irmd/utils.h index 01a58e38..763e654a 100644 --- a/src/irmd/utils.h +++ b/src/irmd/utils.h @@ -20,11 +20,6 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -/* - * Checks whether the string argument matches the pattern argument, - * which is a wildcard pattern. - */ -  #ifndef OUROBOROS_IRMD_UTILS_H  #define OUROBOROS_IRMD_UTILS_H @@ -40,9 +35,6 @@ struct pid_el {          pid_t            pid;  }; -int     wildcard_match(const char * pattern, -                       const char * string); -  /* functions for copying and destroying arguments list */  char ** argvdup(char ** argv); diff --git a/src/lib/dev.c b/src/lib/dev.c index d0766783..d9589b08 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -209,9 +209,8 @@ static int proc_announce(char * prog)          msg.code    = IRM_MSG_CODE__IRM_PROC_ANNOUNCE;          msg.has_pid = true; - -        msg.pid       = ai.pid; -        msg.prog_name = prog; +        msg.pid     = ai.pid; +        msg.prog    = prog;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) { @@ -550,7 +549,7 @@ int flow_accept(qosspec_t *             qs,          return fd;  } -int flow_alloc(const char *            dst_name, +int flow_alloc(const char *            dst,                 qosspec_t *             qs,                 const struct timespec * timeo)  { @@ -560,7 +559,7 @@ int flow_alloc(const char *            dst_name,          int         fd;          msg.code        = IRM_MSG_CODE__IRM_FLOW_ALLOC; -        msg.dst_name    = (char *) dst_name; +        msg.dst         = (char *) dst;          msg.has_pid     = true;          msg.has_qoscube = true;          msg.pid         = ai.pid; diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index 2d3bad7f..de78d809 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -40,15 +40,14 @@ enum ipcp_msg_code {  message ipcp_msg {          required ipcp_msg_code code        =  1; -        optional string name               =  2;          optional bytes hash                =  3;          optional int32 port_id             =  4; -        optional string dst_name           =  5; +        optional string dst                =  5;          optional uint32 qoscube            =  6;          optional ipcp_config_msg conf      =  7;          optional int32 pid                 =  8;          optional layer_info_msg layer_info =  9;          optional int32 response            = 10; -        optional string comp_name          = 11; +        optional string comp               = 11;          optional int32 result              = 12;  }; diff --git a/src/lib/irm.c b/src/lib/irm.c index c12ab893..6a9f837e 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -34,7 +34,7 @@  #include <sys/stat.h>  pid_t irm_create_ipcp(const char *   name, -                      enum ipcp_type ipcp_type) +                      enum ipcp_type type)  {          irm_msg_t   msg      = IRM_MSG__INIT;          irm_msg_t * recv_msg = NULL; @@ -44,9 +44,9 @@ pid_t irm_create_ipcp(const char *   name,                  return -EINVAL;          msg.code          = IRM_MSG_CODE__IRM_CREATE_IPCP; -        msg.dst_name      = (char *) name; +        msg.name          = (char *) name;          msg.has_ipcp_type = true; -        msg.ipcp_type     = ipcp_type; +        msg.ipcp_type     = type;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -54,7 +54,7 @@ pid_t irm_create_ipcp(const char *   name,          if (!recv_msg->has_result) {                  irm_msg__free_unpacked(recv_msg, NULL); -                return -1; +                return -EIRMD;          }          ret = recv_msg->result; @@ -174,8 +174,8 @@ int irm_connect_ipcp(pid_t        pid,          int         ret;          msg.code      = IRM_MSG_CODE__IRM_CONNECT_IPCP; -        msg.dst_name  = (char *) dst; -        msg.comp_name = (char *) component; +        msg.dst       = (char *) dst; +        msg.comp      = (char *) component;          msg.has_pid   = true;          msg.pid       = pid; @@ -202,11 +202,11 @@ int irm_disconnect_ipcp(pid_t        pid,          irm_msg_t * recv_msg = NULL;          int         ret; -        msg.code      = IRM_MSG_CODE__IRM_DISCONNECT_IPCP; -        msg.dst_name  = (char *) dst; -        msg.comp_name = (char *) component; -        msg.has_pid   = true; -        msg.pid       = pid; +        msg.code    = IRM_MSG_CODE__IRM_DISCONNECT_IPCP; +        msg.dst     = (char *) dst; +        msg.comp    = (char *) component; +        msg.has_pid = true; +        msg.pid     = pid;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -223,38 +223,47 @@ int irm_disconnect_ipcp(pid_t        pid,          return ret;  } -ssize_t irm_list_ipcps(const char * name, -                       pid_t **     pids) +ssize_t irm_list_ipcps(struct ipcp_info ** ipcps)  {          irm_msg_t msg        = IRM_MSG__INIT; -        irm_msg_t * recv_msg = NULL; -        size_t nr            = 0; +        irm_msg_t * recv_msg; +        size_t nr;          size_t i; -        if (pids == NULL) +        if (ipcps == NULL)                  return -EINVAL; +        *ipcps = NULL; +          msg.code     = IRM_MSG_CODE__IRM_LIST_IPCPS; -        msg.dst_name = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL)                  return -EIRMD; -        if (recv_msg->pids == NULL) { +        if (recv_msg->ipcps == NULL) {                  irm_msg__free_unpacked(recv_msg, NULL); -                return -1; +                return 0; +        } + +        nr = recv_msg->n_ipcps; +        if (nr == 0) { +                irm_msg__free_unpacked(recv_msg, NULL); +                return 0;          } -        nr = recv_msg->n_pids; -        *pids = malloc(nr * sizeof(pid_t)); -        if (*pids == NULL) { +        *ipcps = malloc(nr * sizeof(**ipcps)); +        if (*ipcps == NULL) {                  irm_msg__free_unpacked(recv_msg, NULL);                  return -ENOMEM;          } -        for (i = 0; i < nr; i++) -                (*pids)[i] = recv_msg->pids[i]; +        for (i = 0; i < nr; i++) { +                (*ipcps)[i].pid   = recv_msg->ipcps[i]->pid; +                (*ipcps)[i].type  = recv_msg->ipcps[i]->type; +                strcpy((*ipcps)[i].name, recv_msg->ipcps[i]->name); +                strcpy((*ipcps)[i].layer, recv_msg->ipcps[i]->layer); +        }          irm_msg__free_unpacked(recv_msg, NULL); @@ -262,30 +271,23 @@ ssize_t irm_list_ipcps(const char * name,  }  int irm_enroll_ipcp(pid_t        pid, -                    const char * layer_name) +                    const char * dst)  {          irm_msg_t   msg      = IRM_MSG__INIT;          irm_msg_t * recv_msg = NULL;          int         ret      = -1; -        if (pid == -1 || layer_name == NULL) +        if (pid == -1 || dst == NULL)                  return -EINVAL;          msg.code         = IRM_MSG_CODE__IRM_ENROLL_IPCP;          msg.has_pid      = true;          msg.pid          = pid; -        msg.n_layer_name = 1; -        msg.layer_name   = malloc(sizeof(*(msg.layer_name))); -        if (msg.layer_name == NULL) -                return -ENOMEM; - -        msg.layer_name[0] = (char *) layer_name; +        msg.dst          = (char *) dst;          recv_msg = send_recv_irm_msg(&msg); -        if (recv_msg == NULL) { -                free(msg.layer_name); +        if (recv_msg == NULL)                  return -EIRMD; -        }          if (!recv_msg->has_result) {                  irm_msg__free_unpacked(recv_msg, NULL); @@ -295,7 +297,6 @@ int irm_enroll_ipcp(pid_t        pid,          ret = recv_msg->result;          irm_msg__free_unpacked(recv_msg, NULL); -        free(msg.layer_name);          return ret;  } @@ -403,9 +404,9 @@ int irm_bind_program(const char * prog,                  return ret;          } -        msg.code      = IRM_MSG_CODE__IRM_BIND_PROGRAM; -        msg.dst_name  = (char *) name; -        msg.prog_name = full_name; +        msg.code = IRM_MSG_CODE__IRM_BIND_PROGRAM; +        msg.name = (char *) name; +        msg.prog = full_name;          if (argv != NULL) {                  msg.n_args = argc; @@ -443,10 +444,10 @@ int irm_bind_process(pid_t        pid,          if (name == NULL)                  return -EINVAL; -        msg.code     = IRM_MSG_CODE__IRM_BIND_PROCESS; -        msg.has_pid  = true; -        msg.pid      = pid; -        msg.dst_name = (char *) name; +        msg.code    = IRM_MSG_CODE__IRM_BIND_PROCESS; +        msg.has_pid = true; +        msg.pid     = pid; +        msg.name    = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -473,9 +474,9 @@ int irm_unbind_program(const char * prog,          if (name == NULL)                  return -EINVAL; -        msg.code      = IRM_MSG_CODE__IRM_UNBIND_PROGRAM; -        msg.prog_name = (char *) prog; -        msg.dst_name  = (char *) name; +        msg.code = IRM_MSG_CODE__IRM_UNBIND_PROGRAM; +        msg.prog = (char *) prog; +        msg.name = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -502,10 +503,10 @@ int irm_unbind_process(pid_t        pid,          if (name == NULL)                  return -EINVAL; -        msg.code = IRM_MSG_CODE__IRM_UNBIND_PROCESS; -        msg.has_pid  = true; -        msg.pid      = pid; -        msg.dst_name = (char *) name; +        msg.code    = IRM_MSG_CODE__IRM_UNBIND_PROCESS; +        msg.has_pid = true; +        msg.pid     = pid; +        msg.name    = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -522,23 +523,20 @@ int irm_unbind_process(pid_t        pid,          return ret;  } -int irm_reg(const char * name, -            char **      layers, -            size_t       len) +int irm_reg(pid_t        pid, +            const char * name)  {          irm_msg_t   msg      = IRM_MSG__INIT;          irm_msg_t * recv_msg = NULL;          int         ret      = -1; -        if (name == NULL || layers == NULL || len == 0) +        if (name == NULL)                  return -EINVAL; -        msg.code = IRM_MSG_CODE__IRM_REG; - -        msg.dst_name = (char *) name; - -        msg.layer_name   = layers; -        msg.n_layer_name = len; +        msg.code    = IRM_MSG_CODE__IRM_REG; +        msg.has_pid = true; +        msg.pid     = pid; +        msg.name    = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) @@ -556,23 +554,20 @@ int irm_reg(const char * name,  } -int irm_unreg(const char * name, -              char **      layers, -              size_t       len) +int irm_unreg(pid_t        pid, +              const char * name)  {          irm_msg_t   msg      = IRM_MSG__INIT;          irm_msg_t * recv_msg = NULL;          int         ret      = -1; -        if (name == NULL || layers == NULL || len == 0) +        if (name == NULL)                  return -EINVAL; -        msg.code = IRM_MSG_CODE__IRM_UNREG; - -        msg.dst_name = (char *) name; - -        msg.layer_name   = (char **) layers; -        msg.n_layer_name = len; +        msg.code    = IRM_MSG_CODE__IRM_UNREG; +        msg.has_pid = true; +        msg.pid     = pid; +        msg.name    = (char *) name;          recv_msg = send_recv_irm_msg(&msg);          if (recv_msg == NULL) diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index 51b15023..16dfe828 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -48,23 +48,31 @@ enum irm_msg_code {          IRM_REPLY             = 21;  }; +message ipcp_info_msg { +        required uint32 pid   = 1; +        required uint32 type  = 2; +        required string name  = 3; +        required string layer = 4; +}; +  message irm_msg {          required irm_msg_code code    =  1; -        optional string prog_name     =  2; +        optional string prog          =  2;          optional sint32 pid           =  3; -        optional uint32 ipcp_type     =  4; -        repeated string layer_name    =  5; -        repeated string args          =  6; -        optional sint32 response      =  7; -        optional string dst_name      =  8; -        optional bytes  hash          =  9; -        optional sint32 port_id       = 10; -        optional sint32 qoscube       = 11; -        optional ipcp_config_msg conf = 12; -        optional uint32 opts          = 13; -        repeated sint32 pids          = 14; -        optional uint32 timeo_sec     = 15; -        optional uint32 timeo_nsec    = 16; -        optional string comp_name     = 17; -        optional sint32 result        = 18; +        optional string name          =  4; +        optional uint32 ipcp_type     =  5; +        optional string layer         =  6; +        repeated string args          =  7; +        optional sint32 response      =  8; +        optional string dst           =  9; +        optional bytes  hash          = 10; +        optional sint32 port_id       = 11; +        optional sint32 qoscube       = 12; +        optional ipcp_config_msg conf = 13; +        optional uint32 opts          = 14; +        repeated ipcp_info_msg ipcps  = 15; +        optional uint32 timeo_sec     = 16; +        optional uint32 timeo_nsec    = 17; +        optional string comp          = 18; +        optional sint32 result        = 19;  }; diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt index e87bd0a5..ca32e9c7 100644 --- a/src/tools/irm/CMakeLists.txt +++ b/src/tools/irm/CMakeLists.txt @@ -14,6 +14,7 @@ set(SOURCE_FILES    irm_ipcp_destroy.c    irm_ipcp_bootstrap.c    irm_ipcp_enroll.c +  irm_ipcp_list.c    irm_ipcp_connect.c    irm_ipcp_disconnect.c    irm_unbind_program.c diff --git a/src/tools/irm/irm_bind_ipcp.c b/src/tools/irm/irm_bind_ipcp.c index 2fcacec7..a30b4192 100644 --- a/src/tools/irm/irm_bind_ipcp.c +++ b/src/tools/irm/irm_bind_ipcp.c @@ -45,6 +45,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm bind ipcp <name> name <name>\n"); @@ -53,13 +55,11 @@ static void usage(void)  int do_bind_ipcp(int     argc,                   char ** argv)  { -        char * ipcp = NULL; -        char * name = NULL; - -        pid_t * pids = NULL; -        ssize_t len  = 0; - -        int i; +        char *             ipcp = NULL; +        char *             name = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -85,12 +85,17 @@ int do_bind_ipcp(int     argc,                  return -1;          } -        len = irm_list_ipcps(ipcp, &pids); - +        len = irm_list_ipcps(&ipcps);          for (i = 0; i < len; ++i) -                irm_bind_process(pids[i], name); +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_bind_process(ipcps[i].pid, name)) { +                                free(ipcps); +                                return -1; +                        } +                        break; +                } -        free(pids); +        free(ipcps);          return 0;  } diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c index a791f6a4..89aa4145 100644 --- a/src/tools/irm/irm_ipcp.c +++ b/src/tools/irm/irm_ipcp.c @@ -68,6 +68,7 @@ static const struct cmd {          { "enroll",     do_enroll_ipcp },          { "connect",    do_connect_ipcp },          { "disconnect", do_disconnect_ipcp }, +        { "list",       do_list_ipcp},          { "help",       do_help },          { NULL,         NULL }  }; diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 4eeedbd3..07dcea0f 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -36,6 +36,12 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +#include <ouroboros/irm.h> + +#include "irm_ops.h" +#include "irm_utils.h" + +#include <assert.h>  #include <stdio.h>  #include <stdlib.h>  #include <string.h> @@ -43,10 +49,6 @@  #ifdef __FreeBSD__  #include <sys/socket.h>  #endif -#include <ouroboros/irm.h> - -#include "irm_ops.h" -#include "irm_utils.h"  #define NORMAL                 "normal"  #define UDP                    "udp" @@ -83,7 +85,7 @@ static void usage(void)          printf("Usage: irm ipcp bootstrap\n"                 "                name <ipcp name>\n"                 "                layer <layer name>\n" -               "                type [TYPE]\n" +               "                [type [TYPE]]\n"                 "where TYPE = {" NORMAL " " LOCAL " "                 UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "},\n\n"                 "if TYPE == " NORMAL "\n" @@ -132,8 +134,8 @@ static void usage(void)  int do_bootstrap_ipcp(int     argc,                        char ** argv)  { -        char *             name           = NULL; -        pid_t              pid; +        char *             ipcp           = NULL; +        pid_t              pid            = -1;          struct ipcp_config conf;          uint8_t            addr_size      = DEFAULT_ADDR_SIZE;          uint8_t            eid_size       = DEFAULT_EID_SIZE; @@ -145,10 +147,11 @@ int do_bootstrap_ipcp(int     argc,          uint32_t           ip_addr        = 0;          uint32_t           dns_addr       = DEFAULT_DDNS;          char *             ipcp_type      = NULL; -        char *             layer_name     = NULL; +        enum ipcp_type     type; +        char *             layer          = NULL;          char *             dev            = NULL;          uint16_t           ethertype      = DEFAULT_ETHERTYPE; -        pid_t *            pids           = NULL; +        struct ipcp_info * ipcps;          ssize_t            len            = 0;          int                i              = 0;          bool               autobind       = false; @@ -159,9 +162,9 @@ int do_bootstrap_ipcp(int     argc,                  if (matches(*argv, "type") == 0) {                          ipcp_type = *(argv + 1);                  } else if (matches(*argv, "layer") == 0) { -                        layer_name = *(argv + 1); +                        layer = *(argv + 1);                  } else if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "hash") == 0) {                          if (strcmp(*(argv + 1), SHA3_224) == 0)                                  hash_algo = DIR_HASH_SHA3_224; @@ -231,98 +234,133 @@ int do_bootstrap_ipcp(int     argc,                  argv += cargs;          } -        if (name == NULL || layer_name == NULL || ipcp_type == NULL) { +        if (ipcp == NULL || layer == NULL) {                  usage();                  return -1;          } -        strcpy(conf.layer_info.layer_name, layer_name); -        if (strcmp(ipcp_type, UDP) != 0) -                conf.layer_info.dir_hash_algo = hash_algo; - -        if (strcmp(ipcp_type, NORMAL) == 0) { -                conf.type           = IPCP_NORMAL; -                conf.addr_size      = addr_size; -                conf.eid_size       = eid_size; -                conf.max_ttl        = max_ttl; -                conf.addr_auth_type = addr_auth_type; -                conf.routing_type   = routing_type; -                conf.pff_type       = pff_type; -        } else if (strcmp(ipcp_type, UDP) == 0) { -                conf.type = IPCP_UDP; -                if (ip_addr == 0) { -                        usage(); -                        return -1; -                } -                conf.ip_addr = ip_addr; -                conf.dns_addr = dns_addr; -        } else if (strcmp(ipcp_type, LOCAL) == 0) { -                conf.type = IPCP_LOCAL; -        } else if (strcmp(ipcp_type, RAPTOR) == 0) { -                conf.type = IPCP_RAPTOR; -        } else if (strcmp(ipcp_type, ETH_LLC) == 0) { -                conf.type = IPCP_ETH_LLC; -                if (dev == NULL) { -                        usage(); -                        return -1; -                } -                conf.dev = dev; -        } else if (strcmp(ipcp_type, ETH_DIX) == 0) { -                conf.type = IPCP_ETH_DIX; -                if (dev == NULL) { -                        usage(); -                        return -1; +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) { +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        break;                  } -                conf.dev = dev; -                conf.ethertype = ethertype; -        } else { -                usage(); -                return -1;          } -        if (autobind && conf.type != IPCP_NORMAL) { -                printf("Can only bind normal IPCPs, autobind disabled.\n"); -                autobind = false; -        } +        if (pid == -1) { +                if (ipcp_type == NULL) { +                        printf("No IPCPs matching %s found.\n\n", ipcp); +                        goto fail; +                } else { +                        if (strcmp(ipcp_type, NORMAL) == 0) +                                type = IPCP_NORMAL; +                        else if (strcmp(ipcp_type, UDP) == 0) +                                type = IPCP_UDP; +                        else if (strcmp(ipcp_type, ETH_LLC) == 0) +                                type = IPCP_ETH_LLC; +                        else if (strcmp(ipcp_type, ETH_DIX) == 0) +                                type = IPCP_ETH_DIX; +                        else if (strcmp(ipcp_type, LOCAL) == 0) +                                type = IPCP_LOCAL; +                        else if (strcmp(ipcp_type, RAPTOR) == 0) +                                type = IPCP_RAPTOR; +                        else goto fail_usage; +                } -        len = irm_list_ipcps(name, &pids); -        if (len <= 0) { -                pid = irm_create_ipcp(name, conf.type); -                if (pid <= 0) -                        return -1; -                len = irm_list_ipcps(name, &pids); +                pid = irm_create_ipcp(ipcp, type); +                if (pid < 0) +                        goto fail; +                free(ipcps); +                len = irm_list_ipcps(&ipcps);          }          for (i = 0; i < len; i++) { -                if (autobind && irm_bind_process(pids[i], name)) { -                        printf("Failed to bind %d to %s.\n", pids[i], name); -                        free(pids); -                        return -1; -                } +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        if (ipcp_type != NULL && type != ipcps[i].type) { +                                printf("Types do not match.\n\n"); +                                goto fail; +                        } +                        conf.type = ipcps[i].type; -                if (autobind && irm_bind_process(pids[i], layer_name)) { -                        printf("Failed to bind %d to %s.\n", -                               pids[i], layer_name); -                        irm_unbind_process(pids[i], name); -                        free(pids); -                        return -1; -                } +                        if (autobind && conf.type != IPCP_NORMAL) { +                                printf("Can only bind normal IPCPs, " +                                       "autobind disabled.\n"); +                                autobind = false; +                        } + +                        strcpy(conf.layer_info.layer_name, layer); +                        if (conf.type == IPCP_UDP) +                                conf.layer_info.dir_hash_algo = hash_algo; -                if (irm_bootstrap_ipcp(pids[i], &conf)) { -                        if (autobind) { -                                irm_unbind_process(pids[i], name); -                                irm_unbind_process(pids[i], layer_name); +                        switch (conf.type) { +                        case IPCP_NORMAL: +                                conf.addr_size      = addr_size; +                                conf.eid_size       = eid_size; +                                conf.max_ttl        = max_ttl; +                                conf.addr_auth_type = addr_auth_type; +                                conf.routing_type   = routing_type; +                                conf.pff_type       = pff_type; +                                break; +                        case IPCP_UDP: +                                if (ip_addr == 0) +                                        goto fail_usage; +                                conf.ip_addr = ip_addr; +                                conf.dns_addr = dns_addr; +                                break; +                        case IPCP_ETH_LLC: +                                if (dev == NULL) +                                        goto fail_usage; +                                conf.dev = dev; +                                break; +                        case IPCP_ETH_DIX: +                                if (dev == NULL) +                                        goto fail_usage; +                                conf.dev = dev; +                                conf.ethertype = ethertype; +                                break; +                        case IPCP_LOCAL: +                                /* FALLTHRU */ +                        case IPCP_RAPTOR: +                                break; +                        default: +                                assert(false); +                                break; +                        } + +                        if (autobind && irm_bind_process(pid, ipcp)) { +                                printf("Failed to bind %d to %s.\n", pid, ipcp); +                                goto fail; +                        } + +                        if (autobind && irm_bind_process(pid, layer)) { +                                printf("Failed to bind %d to %s.\n", +                                       pid, layer); +                                irm_unbind_process(pid, ipcp); +                                goto fail; +                        } + +                        if (irm_bootstrap_ipcp(pid, &conf)) { +                                if (autobind) { +                                        irm_unbind_process(pid, ipcp); +                                        irm_unbind_process(pid, layer); +                                } +                                goto fail;                          } -                        free(pids); -                        return -1;                  }          } -        free(pids); +        free(ipcps);          return 0;   unknown_param:          printf("Unknown parameter for %s: \"%s\".\n", *argv, *(argv + 1));          return -1; + + fail_usage: +        usage(); + fail: +        free(ipcps); +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_connect.c b/src/tools/irm/irm_ipcp_connect.c index b9cad57d..42c07354 100644 --- a/src/tools/irm/irm_ipcp_connect.c +++ b/src/tools/irm/irm_ipcp_connect.c @@ -60,19 +60,21 @@ static void usage(void)  int do_connect_ipcp(int     argc,                      char ** argv)  { -        char *  name      = NULL; -        char *  dst_name  = NULL; -        char *  comp_name = NULL; -        pid_t * pids      = NULL; -        ssize_t len       = 0; +        char *             ipcp = NULL; +        char *             dst  = NULL; +        char *             comp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len  = 0; +        pid_t              pid  = -1; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "dst") == 0) { -                        dst_name = *(argv + 1); +                        dst = *(argv + 1);                  } else if (matches(*argv, "component") == 0) { -                        comp_name = *(argv + 1); +                        comp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcpi connect\".\n", *argv); @@ -83,28 +85,29 @@ int do_connect_ipcp(int     argc,                  argv += 2;          } -        if (name == NULL || dst_name == NULL || comp_name == NULL) { +        if (ipcp == NULL || dst == NULL || comp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len != 1) +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (strcmp(ipcps[i].name, ipcp) == 0) +                        pid = ipcps[i].pid; + +        free(ipcps); + +        if (pid == -1)                  return -1; -        if (!strcmp(comp_name, DT)) -                comp_name = DT_COMP; +        if (!strcmp(comp, DT)) +                comp = DT_COMP; -        if (!strcmp(comp_name , MGMT)) -                comp_name = MGMT_COMP; +        if (!strcmp(comp , MGMT)) +                comp = MGMT_COMP; -        if (irm_connect_ipcp(pids[0], dst_name, comp_name)) { -                free(pids); +        if (irm_connect_ipcp(pid, dst, comp))                  return -1; -        } - -        if (pids != NULL) -                free(pids);          return 0;  } diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c index 6da853ba..c8866962 100644 --- a/src/tools/irm/irm_ipcp_create.c +++ b/src/tools/irm/irm_ipcp_create.c @@ -47,6 +47,7 @@  #define NORMAL  "normal"  #define UDP     "udp"  #define ETH_LLC "eth-llc" +#define ETH_DIX "eth-dix"  #define LOCAL   "local"  #define RAPTOR  "raptor" @@ -59,7 +60,8 @@ static void usage(void)                 UDP " " ETH_LLC " " RAPTOR "}\n");  } -int do_create_ipcp(int argc, char ** argv) +int do_create_ipcp(int     argc, +                   char ** argv)  {          char * ipcp_type = NULL;          char * ipcp_name = NULL; @@ -94,6 +96,8 @@ int do_create_ipcp(int argc, char ** argv)                  type = IPCP_LOCAL;          else if (strcmp(ipcp_type, ETH_LLC) == 0)                  type = IPCP_ETH_LLC; +        else if (strcmp(ipcp_type, ETH_DIX) == 0) +                type = IPCP_ETH_DIX;          else if (strcmp(ipcp_type, RAPTOR) == 0)                  type = IPCP_RAPTOR;          else { @@ -102,7 +106,7 @@ int do_create_ipcp(int argc, char ** argv)          }          pid = irm_create_ipcp(ipcp_name, type); -        if (pid == 0) +        if (pid <= 0)                  return -1;          return 0; diff --git a/src/tools/irm/irm_ipcp_destroy.c b/src/tools/irm/irm_ipcp_destroy.c index 4c37f52b..cb86b167 100644 --- a/src/tools/irm/irm_ipcp_destroy.c +++ b/src/tools/irm/irm_ipcp_destroy.c @@ -44,22 +44,25 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm ipcp destroy\n"                 "                name <ipcp name>\n");  } -int do_destroy_ipcp(int argc, char ** argv) +int do_destroy_ipcp(int     argc, +                    char ** argv)  { -        char *  name = NULL; -        pid_t * pids; -        ssize_t len = 0; -        int     i = 0; +        char *             ipcp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        int                i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcp destroy\".\n", *argv); @@ -70,20 +73,26 @@ int do_destroy_ipcp(int argc, char ** argv)                  argv += 2;          } -        if (name == NULL) { +        if (ipcp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); +        len = irm_list_ipcps(&ipcps);          if (len <= 0) -                return -1; +                goto fail;          for (i = 0; i < len; i++) -                if (irm_destroy_ipcp(pids[i])) -                        return -1; +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_destroy_ipcp(ipcps[i].pid)) +                                goto fail_destroy; +                        break; +                } -        free(pids);          return 0; + fail_destroy: +        free(ipcps); + fail: +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_disconnect.c b/src/tools/irm/irm_ipcp_disconnect.c index 8b5eb596..73f1588d 100644 --- a/src/tools/irm/irm_ipcp_disconnect.c +++ b/src/tools/irm/irm_ipcp_disconnect.c @@ -60,19 +60,21 @@ static void usage(void)  int do_disconnect_ipcp(int     argc,                         char ** argv)  { -        char *  name      = NULL; -        char *  dst_name  = NULL; -        char *  comp_name = NULL; -        pid_t * pids      = NULL; -        ssize_t len       = 0; +        char *             ipcp = NULL; +        char *             dst  = NULL; +        char *             comp = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len  = 0; +        pid_t              pid  = -1; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "dst") == 0) { -                        dst_name = *(argv + 1); +                        dst = *(argv + 1);                  } else if (matches(*argv, "component") == 0) { -                        comp_name = *(argv + 1); +                        comp = *(argv + 1);                  } else {                          printf("\"%s\" is unknown, try \"irm "                                 "ipcpi connect\".\n", *argv); @@ -83,28 +85,29 @@ int do_disconnect_ipcp(int     argc,                  argv += 2;          } -        if (name == NULL || dst_name == NULL || comp_name == NULL) { +        if (ipcp == NULL || dst == NULL || comp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len != 1) +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (strcmp(ipcps[i].name, ipcp) == 0) +                        pid = ipcps[i].pid; + +        free(ipcps); + +        if (pid == -1)                  return -1; -        if (!strcmp(comp_name, DT)) -                comp_name = DT_COMP; +        if (!strcmp(comp, DT)) +                comp = DT_COMP; -        if (!strcmp(comp_name , MGMT)) -                comp_name = MGMT_COMP; +        if (!strcmp(comp , MGMT)) +                comp = MGMT_COMP; -        if (irm_disconnect_ipcp(pids[0], dst_name, comp_name)) { -                free(pids); +        if (irm_disconnect_ipcp(pid, dst, comp))                  return -1; -        } - -        if (pids != NULL) -                free(pids);          return 0;  } diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c index 8b897096..c1628af6 100644 --- a/src/tools/irm/irm_ipcp_enroll.c +++ b/src/tools/irm/irm_ipcp_enroll.c @@ -44,6 +44,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm ipcp enroll\n" @@ -52,23 +54,24 @@ static void usage(void)                 "                [autobind]\n");  } -int do_enroll_ipcp(int argc, char ** argv) +int do_enroll_ipcp(int     argc, +                   char ** argv)  { -        char *  name       = NULL; -        char *  layer_name = NULL; -        pid_t * pids       = NULL; -        pid_t   pid; -        ssize_t len        = 0; -        int     i          = 0; -        bool    autobind   = false; -        int     cargs; +        char *             ipcp     = NULL; +        char *             layer    = NULL; +        struct ipcp_info * ipcps; +        pid_t              pid      = -1; +        ssize_t            len      = 0; +        int                i        = 0; +        bool               autobind = false; +        int                cargs;          while (argc > 0) {                  cargs = 2;                  if (matches(*argv, "name") == 0) { -                        name = *(argv + 1); +                        ipcp = *(argv + 1);                  } else if (matches(*argv, "layer") == 0) { -                        layer_name = *(argv + 1); +                        layer = *(argv + 1);                  } else if (matches(*argv, "autobind") == 0) {                          autobind = true;                          cargs = 1; @@ -82,42 +85,53 @@ int do_enroll_ipcp(int argc, char ** argv)                  argv += cargs;          } -        if (layer_name == NULL || name == NULL) { +        if (layer == NULL || ipcp == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(name, &pids); -        if (len <= 0) { -                pid = irm_create_ipcp(name, IPCP_NORMAL); -                if (pid == 0) -                        return -1; -                len = irm_list_ipcps(name, &pids); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; i++) +                if (wildcard_match(ipcps[i].name, ipcp) == 0 && +                    ipcps[i].type == IPCP_NORMAL) +                        pid = ipcps[i].pid; + +        if (pid < 0) { +                pid = irm_create_ipcp(ipcp, IPCP_NORMAL); +                if (pid < 0) +                        goto fail; +                free(ipcps); +                len = irm_list_ipcps(&ipcps);          }          for (i = 0; i < len; i++) { -                if (autobind && irm_bind_process(pids[i], name)) { -                        free(pids); -                        return -1; -                } +                if (ipcps[i].type != IPCP_NORMAL) +                        continue; +                if (wildcard_match(ipcps[i].name, ipcp) == 0) { +                        pid = ipcps[i].pid; +                        if (autobind && irm_bind_process(pid, ipcp)) { +                                printf("Failed to bind %d to %s.\n", pid, ipcp); +                                goto fail; +                        } -                if (irm_enroll_ipcp(pids[i], layer_name)) { -                        if (autobind) -                                irm_unbind_process(pids[i], name); -                        free(pids); -                        return -1; -                } +                        if (irm_enroll_ipcp(pid, layer)) { +                                if (autobind) +                                        irm_unbind_process(pid, ipcp); +                                goto fail; +                        } -                if (autobind && irm_bind_process(pids[i], layer_name)) { -                        printf("Failed to bind %d to %s.\n", -                               pids[i], layer_name); -                        free(pids); -                        return -1; +                        if (autobind && irm_bind_process(pid, layer)) { +                                printf("Failed to bind %d to %s.\n", pid, layer); +                                goto fail; +                        }                  }          } -        if (pids != NULL) -                free(pids); +        free(ipcps);          return 0; + + fail: +        free(ipcps); +        return -1;  } diff --git a/src/tools/irm/irm_ipcp_list.c b/src/tools/irm/irm_ipcp_list.c new file mode 100644 index 00000000..e16ca523 --- /dev/null +++ b/src/tools/irm/irm_ipcp_list.c @@ -0,0 +1,158 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2018 + * + * Create IPC Processes + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <ouroboros/irm.h> + +#include "irm_ops.h" +#include "irm_utils.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NORMAL  "normal" +#define UDP     "udp" +#define ETH_LLC "eth-llc" +#define ETH_DIX "eth-dix" +#define LOCAL   "local" +#define RAPTOR  "raptor" + +static void usage(void) +{ +        printf("Usage: irm ipcp list\n" +               "                [name  <ipcp name>]\n" +               "                [layer <layer_name>]\n\n" +               "                [type [TYPE]]\n\n" +               "where TYPE = {" NORMAL " " LOCAL " " +               UDP " " ETH_LLC " " ETH_DIX " " RAPTOR "}\n"); +} + +static char * str_type(enum ipcp_type type) +{ +        switch(type) { +        case IPCP_NORMAL: +                return NORMAL; +        case IPCP_ETH_LLC: +                return ETH_LLC; +        case IPCP_ETH_DIX: +                return ETH_DIX; +        case IPCP_UDP: +                return UDP; +        case IPCP_RAPTOR: +                return RAPTOR; +        case IPCP_LOCAL: +                return LOCAL; +        default: +                return "UNKNOWN"; +        } +}; + +int do_list_ipcp(int     argc, +                 char ** argv) +{ +        char *             ipcp_type = NULL; +        char *             ipcp_name = NULL; +        enum ipcp_type     type      = -1; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i; + +        while (argc > 0) { +                if (matches(*argv, "type") == 0) { +                        ipcp_type = *(argv + 1); +                } else if (matches(*argv, "name") == 0) { +                        ipcp_name = *(argv + 1); +                } else { +                        printf("\"%s\" is unknown, try \"irm " +                               "ipcp list\".\n", *argv); +                        return -1; +                } + +                argc -= 2; +                argv += 2; +        } + +        if (ipcp_type != NULL) { +                if (strcmp(ipcp_type, NORMAL) == 0) +                        type = IPCP_NORMAL; +                else if (strcmp(ipcp_type, UDP) == 0) +                        type = IPCP_UDP; +                else if (strcmp(ipcp_type, LOCAL) == 0) +                        type = IPCP_LOCAL; +                else if (strcmp(ipcp_type, ETH_LLC) == 0) +                        type = IPCP_ETH_LLC; +                else if (strcmp(ipcp_type, ETH_DIX) == 0) +                        type = IPCP_ETH_DIX; +                else if (strcmp(ipcp_type, RAPTOR) == 0) +                        type = IPCP_RAPTOR; +                else { +                        usage(); +                        return -1; +                } +        } + +        len = irm_list_ipcps(&ipcps); +        if (len == 0) { +                printf("No IPCPs in system.\n\n"); +                return 0; +        } + +        /* FIXME: Implement filtering based on type and name. */ +        (void) type; +        (void) ipcp_name; + +        printf("+---------+----------------------+------------+" +               "----------------------+\n"); +        printf("| %7s | %20s | %10s | %20s |\n", "pid", "name", "type", "layer"); +        printf("+---------+----------------------+------------+" +               "----------------------+\n"); + +        for (i = 0; i < len; i++) +                printf("| %7d | %20s | %10s | %20s |\n", +                       ipcps[i].pid, +                       ipcps[i].name, +                       str_type(ipcps[i].type), +                       ipcps[i].layer); + +        printf("+---------+----------------------+------------+" +               "----------------------+\n\n"); + +        free(ipcps); + +        return 0; +} diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h index a2cb5399..74035434 100644 --- a/src/tools/irm/irm_ops.h +++ b/src/tools/irm/irm_ops.h @@ -57,6 +57,9 @@ int do_connect_ipcp(int     argc,  int do_disconnect_ipcp(int     argc,                         char ** argv); +int do_list_ipcp(int     argc, +                 char ** argv); +  int bind_cmd(int     argc,               char ** argv); diff --git a/src/tools/irm/irm_register.c b/src/tools/irm/irm_register.c index 574c2224..59d65a69 100644 --- a/src/tools/irm/irm_register.c +++ b/src/tools/irm/irm_register.c @@ -38,29 +38,42 @@  #include <ouroboros/irm.h> -#include <stdio.h>  #include "irm_ops.h"  #include "irm_utils.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define MAX_IPCPS  128  #define MAX_LAYERS 128  static void usage(void)  {          printf("Usage: irm register\n"                 "           name <name>\n" +               "           ipcp <ipcp to register with>\n" +               "           [ipcp <ipcp to register with>]\n" +               "           [... (maximum %d ipcps)]\n"                 "           layer <layer to register with>\n"                 "           [layer <layer to register with>]\n"                 "           [... (maximum %d layers)]\n" -               , MAX_LAYERS); +               , MAX_IPCPS, MAX_LAYERS);  } -int do_register(int argc, char ** argv) +int do_register(int     argc, +                char ** argv)  { -        char * name = NULL; -        char * layers[MAX_LAYERS]; -        size_t layers_len = 0; +        char *             name       = NULL; +        char *             layers[MAX_LAYERS]; +        size_t             layers_len = 0; +        char *             ipcp[MAX_IPCPS]; +        size_t             ipcp_len   = 0; +        struct ipcp_info * ipcps; +        size_t             len; +        size_t             i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -68,7 +81,13 @@ int do_register(int argc, char ** argv)                  } else if (matches(*argv, "layer") == 0) {                          layers[layers_len++] = *(argv + 1);                          if (layers_len > MAX_LAYERS) { -                                printf("Too many layers specified\n"); +                                printf("Too many layers specified.\n"); +                                return -1; +                        } +                } else if (matches(*argv, "ipcp") == 0) { +                        ipcp[ipcp_len++] = *(argv + 1); +                        if (ipcp_len > MAX_IPCPS) { +                                printf("Too many IPCPs specified.\n");                                  return -1;                          }                  } else { @@ -81,10 +100,35 @@ int do_register(int argc, char ** argv)                  argv += 2;          } -        if (layers_len < 1 || name == NULL) { +        if ((layers_len < 1 && ipcp_len < 1) || name == NULL) {                  usage();                  return -1;          } -        return irm_reg(name, layers, layers_len); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; ++i) { +                size_t j; +                for (j = 0; j < layers_len; j++) { +                        if (wildcard_match(ipcps[i].layer, layers[j]) == 0) { +                                if (irm_reg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +                for (j = 0; j < ipcp_len; j++) { +                        if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) { +                                if (irm_reg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +        } + +        free(ipcps); + +        return 0;  } diff --git a/src/tools/irm/irm_unbind_ipcp.c b/src/tools/irm/irm_unbind_ipcp.c index f804da90..9b2a930a 100644 --- a/src/tools/irm/irm_unbind_ipcp.c +++ b/src/tools/irm/irm_unbind_ipcp.c @@ -45,6 +45,8 @@  #include "irm_ops.h"  #include "irm_utils.h" +#include <string.h> +  static void usage(void)  {          printf("Usage: irm unbind ipcp <name>\n" @@ -52,15 +54,14 @@ static void usage(void)                 "\n");  } -int do_unbind_ipcp(int argc, char ** argv) +int do_unbind_ipcp(int     argc, +                   char ** argv)  { -        char * ipcp = NULL; -        char * name = NULL; - -        pid_t * pids = NULL; -        ssize_t len  = 0; - -        int i; +        char *             ipcp = NULL; +        char *             name = NULL; +        struct ipcp_info * ipcps; +        ssize_t            len; +        ssize_t            i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -81,17 +82,22 @@ int do_unbind_ipcp(int argc, char ** argv)                  --argc;          } -        if (ipcp == NULL) { +        if (ipcp == NULL || name  == NULL) {                  usage();                  return -1;          } -        len = irm_list_ipcps(ipcp, &pids); - +        len = irm_list_ipcps(&ipcps);          for (i = 0; i < len; ++i) -                irm_unbind_process(pids[i], name); +                if (strcmp(ipcps[i].name, ipcp) == 0) { +                        if (irm_unbind_process(ipcps[i].pid, name)) { +                                free(ipcps); +                                return -1; +                        } +                        break; +                } -        free(pids); +        free(ipcps);          return 0;  } diff --git a/src/tools/irm/irm_unregister.c b/src/tools/irm/irm_unregister.c index 3b161169..52491b42 100644 --- a/src/tools/irm/irm_unregister.c +++ b/src/tools/irm/irm_unregister.c @@ -36,31 +36,41 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ -#include <stdio.h> -#include <string.h> -  #include <ouroboros/irm.h>  #include "irm_ops.h"  #include "irm_utils.h" +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#define MAX_IPCPS  128  #define MAX_LAYERS 128  static void usage(void)  {          printf("Usage: irm unregister\n"                 "           name <name>\n" +               "           ipcp <ipcp to register with>\n" +               "           [ipcp <ipcp to register with>]\n" +               "           [... (maximum %d ipcps)]\n"                 "           layer <layer to unregister from>\n"                 "           [layer <layer to unregister from>]\n"                 "           [... (maximum %d layers)]\n" -               , MAX_LAYERS); +               , MAX_IPCPS, MAX_LAYERS);  }  int do_unregister(int argc, char ** argv)  { -        char * layers[MAX_LAYERS]; -        size_t layers_len = 0; -        char * name = NULL; +        char *             name       = NULL; +        char *             layers[MAX_LAYERS]; +        size_t             layers_len = 0; +        char *             ipcp[MAX_IPCPS]; +        size_t             ipcp_len   = 0; +        struct ipcp_info * ipcps; +        size_t             len; +        size_t             i;          while (argc > 0) {                  if (matches(*argv, "name") == 0) { @@ -68,7 +78,13 @@ int do_unregister(int argc, char ** argv)                  } else if (matches(*argv, "layer") == 0) {                          layers[layers_len++] = *(argv + 1);                          if (layers_len > MAX_LAYERS) { -                                printf("Too many layers specified\n"); +                                printf("Too many layers specified.\n"); +                                return -1; +                        } +                } else if (matches(*argv, "ipcp") == 0) { +                        ipcp[ipcp_len++] = *(argv + 1); +                        if (ipcp_len > MAX_IPCPS) { +                                printf("Too many IPCPs specified.\n");                                  return -1;                          }                  } else { @@ -81,10 +97,35 @@ int do_unregister(int argc, char ** argv)                  argv += 2;          } -        if (layers_len == 0 || name == NULL) { +        if ((layers_len < 1 && ipcp_len < 1) || name == NULL) {                  usage();                  return -1;          } -        return irm_unreg(name, layers, layers_len); +        len = irm_list_ipcps(&ipcps); +        for (i = 0; i < len; ++i) { +                size_t j; +                for (j = 0; j < layers_len; j++) { +                        if (wildcard_match(ipcps[i].layer, layers[j]) == 0) { +                                if (irm_unreg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +                for (j = 0; j < ipcp_len; j++) { +                        if (wildcard_match(ipcps[i].name, ipcp[j]) == 0) { +                                if (irm_unreg(ipcps[i].pid, name)) { +                                        free(ipcps); +                                        return -1; +                                } +                                break; +                        } +                } +        } + +        free(ipcps); + +        return 0;  } diff --git a/src/tools/irm/irm_utils.c b/src/tools/irm/irm_utils.c index 573eab70..c5ea9246 100644 --- a/src/tools/irm/irm_utils.c +++ b/src/tools/irm/irm_utils.c @@ -36,9 +36,48 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +/* + * Copyright (c) 1989, 1993, 1994 + *      The Regents of the University of California.  All rights reserved. + * + * Wildcard Match code below is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * wildcard_match is based on the fnmatch function from POSIX.2. + * Implementation based on that one from FreeBSD. + */ + +  #include <string.h> -#include <stdbool.h> -#include <stdlib.h>  #include "irm_utils.h" @@ -52,3 +91,35 @@ int matches(const char * cmd,          return memcmp(pattern, cmd, len);  } + +int wildcard_match(const char * pattern, +                   const char * string) +{ +        char c; + +        /* For loop? Why not Zoidberg? */ +        for (;;) { +                switch (c = *pattern++) { +                case '\0': +                        return (*string == '\0' ? 0 : -1); +                case '*': +                        c = *pattern; + +                        if (c == '\0') +                                return 0; + +                        /* General case, use recursion. */ +                        while ((c = *string) != '\0') { +                                if (!wildcard_match(pattern, string)) +                                        return 0; +                                ++string; +                        } +                        return -1; +                default: +                        if (c != *string) +                                return -1; +                        string++; +                        break; +                } +        } +} diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h index 9f24c4b7..03113f12 100644 --- a/src/tools/irm/irm_utils.h +++ b/src/tools/irm/irm_utils.h @@ -36,10 +36,53 @@   * OF THE POSSIBILITY OF SUCH DAMAGE.   */ +/* + * Copyright (c) 1989, 1993, 1994 + *      The Regents of the University of California.  All rights reserved. + * + * Wildcard Match code below is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + *    may be used to endorse or promote products derived from this software + *    without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * wildcard_match is based on the fnmatch function from POSIX.2. + * Implementation based on that one from FreeBSD. + */ +  #ifndef OUROBOROS_TOOLS_IRM_UTILS_H  #define OUROBOROS_TOOLS_IRM_UTILS_H  int matches(const char * cmd,              const char * pattern); +int wildcard_match(const char * pattern, +                   const char * string); +  #endif /* OUROBOROS_TOOLS_IRM_UTILS_H */  | 
