diff options
| author | dimitri staessens <dimitri.staessens@ugent.be> | 2017-08-28 20:10:22 +0000 | 
|---|---|---|
| committer | Sander Vrijders <sander.vrijders@ugent.be> | 2017-08-28 20:10:22 +0000 | 
| commit | e8875c08ac04a1d9aca342d94d4f788239334f72 (patch) | |
| tree | 4a96be10ea1b9f3d03bb2fd10f3f2e403c1dd934 /src/ipcpd | |
| parent | c3185b9a6e471b534a370b2d913425962af88654 (diff) | |
| parent | 999b5dec615ce4cfb30ee909bdd16e79a5e2a1ce (diff) | |
| download | ouroboros-e8875c08ac04a1d9aca342d94d4f788239334f72.tar.gz ouroboros-e8875c08ac04a1d9aca342d94d4f788239334f72.zip | |
Merged in dstaesse/ouroboros/be-deprecate-gam (pull request #572)
Be deprecate gam
Diffstat (limited to 'src/ipcpd')
37 files changed, 998 insertions, 1275 deletions
| diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index ff45407b..41ea4784 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -227,8 +227,6 @@ static void * mainloop(void * o)                                  conf.fd_size        = conf_msg->fd_size;                                  conf.has_ttl        = conf_msg->has_ttl;                                  conf.addr_auth_type = conf_msg->addr_auth_type; -                                conf.dt_gam_type    = conf_msg->dt_gam_type; -                                conf.rm_gam_type    = conf_msg->rm_gam_type;                                  conf.routing_type   = conf_msg->routing_type;                                  switch(conf_msg->dif_info->dir_hash_algo) { @@ -303,6 +301,32 @@ static void * mainloop(void * o)                                  dif_info.dif_name      = info.dif_name;                          }                          break; +                case IPCP_MSG_CODE__IPCP_CONNECT: +                        ret_msg.has_result = true; + +                        if (ipcpi.ops->ipcp_connect == NULL) { +                                log_err("Connect unsupported."); +                                ret_msg.result = -ENOTSUP; +                                break; +                        } + +                        ret_msg.result = +                                ipcpi.ops->ipcp_connect(msg->dst_name, +                                                        msg->comp_name); +                        break; +                case IPCP_MSG_CODE__IPCP_DISCONNECT: +                        ret_msg.has_result = true; + +                        if (ipcpi.ops->ipcp_disconnect == NULL) { +                                log_err("Disconnect unsupported."); +                                ret_msg.result = -ENOTSUP; +                                break; +                        } + +                        ret_msg.result = +                                ipcpi.ops->ipcp_disconnect(msg->dst_name, +                                                           msg->comp_name); +                        break;                  case IPCP_MSG_CODE__IPCP_REG:                          ret_msg.has_result = true; @@ -437,6 +461,8 @@ static void * mainloop(void * o)                                  ipcpi.ops->ipcp_flow_dealloc(fd);                          break;                  default: +                        ret_msg.has_result = true; +                        ret_msg.result     = -1;                          log_err("Don't know that message code");                          break;                  } diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index cd18d198..1b2a0334 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -45,6 +45,12 @@ struct ipcp_ops {          int   (* ipcp_enroll)(const char *      dst,                                struct dif_info * info); +        int   (* ipcp_connect)(const char * dst, +                               const char * component); + +        int   (* ipcp_disconnect)(const char * dst, +                                  const char * component); +          int   (* ipcp_reg)(const uint8_t * hash);          int   (* ipcp_unreg)(const uint8_t * hash); diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 37d23fc3..c6f88d78 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -323,7 +323,9 @@ static int ipcp_local_flow_dealloc(int fd)  static struct ipcp_ops local_ops = {          .ipcp_bootstrap       = ipcp_local_bootstrap, -        .ipcp_enroll          = NULL,                       /* shim */ +        .ipcp_enroll          = NULL, +        .ipcp_connect         = NULL, +        .ipcp_disconnect      = NULL,          .ipcp_reg             = ipcp_local_reg,          .ipcp_unreg           = ipcp_local_unreg,          .ipcp_query           = ipcp_local_query, diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 7a40e94c..aebc6c35 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -15,6 +15,8 @@ include_directories(${CMAKE_BINARY_DIR}/include)  set(IPCP_NORMAL_TARGET ipcpd-normal CACHE INTERNAL "")  protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto) +protobuf_generate_c(ENROLL_PROTO_SRCS ENROLL_PROTO_HDRS enroll.proto +  ${CMAKE_SOURCE_DIR}/src/lib/ipcp_config.proto)  protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)  # Add GPB sources of policies last @@ -34,7 +36,6 @@ set(SOURCE_FILES    dt_pci.c    enroll.c    fa.c -  gam.c    main.c    neighbors.c    pff.c @@ -42,14 +43,13 @@ set(SOURCE_FILES    routing.c    sdu_sched.c    # Add policies last -  pol/complete.c    pol/flat.c    pol/link_state.c    pol/graph.c    )  add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} -  ${FLOW_ALLOC_SRCS} ${FSO_SRCS} ${KAD_PROTO_SRCS}) +  ${FLOW_ALLOC_SRCS} ${FSO_SRCS} ${KAD_PROTO_SRCS} ${ENROLL_PROTO_SRCS})  target_link_libraries(ipcpd-normal LINK_PUBLIC ouroboros)  include(AddCompileFlags) diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index e327e2fa..e4aacccd 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -35,7 +35,8 @@ struct addr_auth {          struct pol_addr_auth_ops * ops;  } addr_auth; -int addr_auth_init(enum pol_addr_auth type) +int addr_auth_init(enum pol_addr_auth type, +                   const void *       info)  {          switch (type) {          case FLAT_RANDOM: @@ -46,7 +47,7 @@ int addr_auth_init(enum pol_addr_auth type)                  return -1;          } -        return addr_auth.ops->init(); +        return addr_auth.ops->init(info);  }  uint64_t addr_auth_address(void) diff --git a/src/ipcpd/normal/addr_auth.h b/src/ipcpd/normal/addr_auth.h index 5a6dec05..14754660 100644 --- a/src/ipcpd/normal/addr_auth.h +++ b/src/ipcpd/normal/addr_auth.h @@ -27,7 +27,8 @@  #include <stdint.h> -int      addr_auth_init(enum pol_addr_auth type); +int      addr_auth_init(enum pol_addr_auth type, +                        const void *       info);  int      addr_auth_fini(void); diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h index 6285ba6a..3d3bdc27 100644 --- a/src/ipcpd/normal/ae.h +++ b/src/ipcpd/normal/ae.h @@ -23,8 +23,26 @@  #ifndef OUROBOROS_IPCPD_NORMAL_AE_H  #define OUROBOROS_IPCPD_NORMAL_AE_H -#define MGMT_AE   "Management" -#define DT_AE     "Data transfer" -#define ENROLL_AE "Enrollment" +#include <ouroboros/cacep.h> + +#include "dt.h" + +#define DST_MAX_STRLEN 64 + +enum ae_id { +        AEID_DT = 0, +        AEID_ENROLL, +        AEID_MGMT, +        AEID_MAX +}; + +struct conn { +        struct conn_info conn_info; +        struct { +                char      dst[DST_MAX_STRLEN + 1]; +                int       fd; +                qosspec_t qs; +        } flow_info; +};  #endif /* OUROBOROS_IPCPD_NORMAL_AE_H */ diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c index a83d71c3..fa43b97a 100644 --- a/src/ipcpd/normal/connmgr.c +++ b/src/ipcpd/normal/connmgr.c @@ -22,7 +22,7 @@  #define _POSIX_C_SOURCE 200112L -#define OUROBOROS_PREFIX "normal-ipcp" +#define OUROBOROS_PREFIX "Connection manager"  #include <ouroboros/dev.h>  #include <ouroboros/cacep.h> @@ -42,92 +42,69 @@  #include <stdlib.h>  #include <assert.h> -struct ae_conn { +enum connmgr_state { +        CONNMGR_NULL = 0, +        CONNMGR_INIT, +        CONNMGR_RUNNING +}; + +struct conn_el {          struct list_head next;          struct conn      conn;  };  struct ae { -        struct list_head next; +        struct nbs *     nbs;          struct conn_info info; -        struct list_head conn_list; -        pthread_cond_t   conn_cond; -        pthread_mutex_t  conn_lock; +        struct list_head conns; +        struct list_head pending; + +        pthread_cond_t   cond; +        pthread_mutex_t  lock;  };  struct { -        pthread_t        acceptor; +        struct ae          aes[AEID_MAX]; +        enum connmgr_state state; -        struct list_head aes; -        pthread_rwlock_t aes_lock; +        pthread_t          acceptor;  } connmgr; - -static int get_info_by_name(const char *       name, -                            struct conn_info * info) +static int get_id_by_name(const char * name)  { -        struct list_head * p; +        enum ae_id i; -        pthread_rwlock_rdlock(&connmgr.aes_lock); - -        list_for_each(p, &connmgr.aes) { -                struct ae * ae = list_entry(p, struct ae, next); -                if (strcmp(ae->info.ae_name, name) == 0) { -                        memcpy(info, &ae->info, sizeof(*info)); -                        pthread_rwlock_unlock(&connmgr.aes_lock); -                        return 0; -                } -        } - -        pthread_rwlock_unlock(&connmgr.aes_lock); +        for (i = 0; i < AEID_MAX; ++i) +                if (strcmp(name, connmgr.aes[i].info.ae_name) == 0) +                        return i;          return -1;  } -static int add_ae_conn(const char *       name, +static int add_ae_conn(enum ae_id         id,                         int                fd,                         qosspec_t          qs,                         struct conn_info * rcv_info)  { -        struct ae_conn *   ae_conn; -        struct list_head * p; -        struct ae *        ae = NULL; +        struct conn_el * el; -        ae_conn = malloc(sizeof(*ae_conn)); -        if (ae_conn == NULL) { +        el = malloc(sizeof(*el)); +        if (el == NULL) {                  log_err("Not enough memory.");                  return -1;          } -        ae_conn->conn.conn_info    = *rcv_info; -        ae_conn->conn.flow_info.fd = fd; -        ae_conn->conn.flow_info.qs = qs; +        el->conn.conn_info    = *rcv_info; +        el->conn.flow_info.fd = fd; +        el->conn.flow_info.qs = qs; -        list_head_init(&ae_conn->next); +        pthread_mutex_lock(&connmgr.aes[id].lock); -        pthread_rwlock_wrlock(&connmgr.aes_lock); +        list_add(&el->next, &connmgr.aes[id].pending); +        pthread_cond_signal(&connmgr.aes[id].cond); -        list_for_each(p, &connmgr.aes) { -                ae = list_entry(p, struct ae, next); -                if (strcmp(ae->info.ae_name, name) == 0) -                        break; -        } - -        /* Check if entry was removed during allocation. */ -        if (ae == NULL || strcmp(ae->info.ae_name, name) != 0) { -                pthread_rwlock_unlock(&connmgr.aes_lock); -                return -1; -        } - -        pthread_mutex_lock(&ae->conn_lock); - -        list_add(&ae_conn->next, &ae->conn_list); -        pthread_cond_signal(&ae->conn_cond); - -        pthread_mutex_unlock(&ae->conn_lock); - -        pthread_rwlock_unlock(&connmgr.aes_lock); +        pthread_mutex_unlock(&connmgr.aes[id].lock);          return 0;  } @@ -136,7 +113,6 @@ static void * flow_acceptor(void * o)  {          int               fd;          qosspec_t         qs; -        struct conn_info  snd_info;          struct conn_info  rcv_info;          struct conn_info  fail_info; @@ -145,10 +121,7 @@ static void * flow_acceptor(void * o)          memset(&fail_info, 0, sizeof(fail_info));          while (true) { -                if (ipcp_get_state() != IPCP_OPERATIONAL) { -                        log_info("Shutting down flow acceptor."); -                        return 0; -                } +                int id;                  fd = flow_accept(&qs, NULL);                  if (fd < 0) { @@ -158,26 +131,30 @@ static void * flow_acceptor(void * o)                  }                  if (cacep_rcv(fd, &rcv_info)) { -                        log_err("Error establishing application connection."); +                        log_dbg("Error establishing application connection.");                          flow_dealloc(fd);                          continue;                  } -                if (get_info_by_name(rcv_info.ae_name, &snd_info)) { -                        log_err("Failed to get info for %s.", rcv_info.ae_name); +                id = get_id_by_name(rcv_info.ae_name); +                if (id < 0) { +                        log_dbg("Connection request for unknown AE %s.", +                                rcv_info.ae_name);                          cacep_snd(fd, &fail_info);                          flow_dealloc(fd);                          continue;                  } -                if (cacep_snd(fd, &snd_info)) { -                        log_err("Failed to respond to request."); +                assert(id < AEID_MAX); + +                if (cacep_snd(fd, &connmgr.aes[id].info)) { +                        log_dbg("Failed to respond to request.");                          flow_dealloc(fd);                          continue;                  } -                if (add_ae_conn(rcv_info.ae_name, fd, qs, &rcv_info)) { -                        log_err("Failed to add new connection."); +                if (add_ae_conn(id, fd, qs, &rcv_info)) { +                        log_dbg("Failed to add new connection.");                          flow_dealloc(fd);                          continue;                  } @@ -188,130 +165,192 @@ static void * flow_acceptor(void * o)  int connmgr_init(void)  { -        if (pthread_rwlock_init(&connmgr.aes_lock, NULL)) -                return -1; - -        list_head_init(&connmgr.aes); +        connmgr.state = CONNMGR_INIT;          return 0;  } +void connmgr_fini(void) +{ +        int i; + +        if (connmgr.state == CONNMGR_RUNNING) +                pthread_join(connmgr.acceptor, NULL); + +        for (i = 0; i < AEID_MAX; ++i) +                connmgr_ae_fini(i); +} +  int connmgr_start(void)  {          if (pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL))                  return -1; +        connmgr.state = CONNMGR_RUNNING; +          return 0;  }  void connmgr_stop(void)  { -        pthread_cancel(connmgr.acceptor); +        if (connmgr.state == CONNMGR_RUNNING) +                pthread_cancel(connmgr.acceptor);  } -static void destroy_ae(struct ae * ae) +int connmgr_ae_init(enum ae_id               id, +                    const struct conn_info * info, +                    struct nbs *             nbs)  { -        struct list_head * p; -        struct list_head * h; +        struct ae * ae; -        pthread_mutex_lock(&ae->conn_lock); +        assert(id >= 0 && id < AEID_MAX); -        list_for_each_safe(p, h, &ae->conn_list) { -                struct ae_conn * e = list_entry(p, struct ae_conn, next); -                list_del(&e->next); -                free(e); +        ae = connmgr.aes + id; + +        if (pthread_mutex_init(&ae->lock, NULL)) +                return -1; + +        if (pthread_cond_init(&ae->cond, NULL)) { +                pthread_mutex_destroy(&ae->lock); +                return -1;          } -        pthread_mutex_unlock(&ae->conn_lock); +        list_head_init(&ae->conns); +        list_head_init(&ae->pending); + +        memcpy(&connmgr.aes[id].info, info, sizeof(connmgr.aes[id].info)); -        pthread_cond_destroy(&ae->conn_cond); -        pthread_mutex_destroy(&ae->conn_lock); +        connmgr.aes[id].nbs = nbs; -        free(ae); +        return 0;  } -void connmgr_fini(void) +void connmgr_ae_fini(enum ae_id id)  {          struct list_head * p;          struct list_head * h; +        struct ae *        ae; + +        assert(id >= 0 && id < AEID_MAX); -        pthread_join(connmgr.acceptor, NULL); +        if (strlen(connmgr.aes[id].info.ae_name) == 0) +                return; -        pthread_rwlock_wrlock(&connmgr.aes_lock); +        ae = connmgr.aes + id; -        list_for_each_safe(p, h, &connmgr.aes) { -                struct ae * e = list_entry(p, struct ae, next); +        pthread_mutex_lock(&ae->lock); + +        list_for_each_safe(p, h, &ae->conns) { +                struct conn_el * e = list_entry(p, struct conn_el, next); +                list_del(&e->next); +                free(e); +        } + +        list_for_each_safe(p, h, &ae->pending) { +                struct conn_el * e = list_entry(p, struct conn_el, next);                  list_del(&e->next); -                destroy_ae(e); +                free(e);          } -        pthread_rwlock_unlock(&connmgr.aes_lock); +        pthread_mutex_unlock(&ae->lock); -        pthread_rwlock_destroy(&connmgr.aes_lock); +        pthread_cond_destroy(&ae->cond); +        pthread_mutex_destroy(&ae->lock); + +        memset(&connmgr.aes[id].info, 0, sizeof(connmgr.aes[id].info)); + +        connmgr.aes[id].nbs = NULL;  } -struct ae * connmgr_ae_create(struct conn_info info) +int connmgr_ipcp_connect(const char * dst, +                         const char * component)  { -        struct ae * ae; +        struct conn_el * ce; +        int              id; -        ae = malloc(sizeof(*ae)); -        if (ae == NULL) -                goto fail_malloc; +        assert(dst); +        assert(component); -        list_head_init(&ae->next); -        list_head_init(&ae->conn_list); - -        ae->info = info; +        ce = malloc(sizeof(*ce)); +        if (ce == NULL) { +                log_dbg("Out of memory."); +                return -1; +        } -        if (pthread_mutex_init(&ae->conn_lock, NULL)) -                goto fail_mutex_init; +        id = get_id_by_name(component); +        if (id < 0) { +                log_dbg("No such component: %s", component); +                free(ce); +                return -1; +        } -        if (pthread_cond_init(&ae->conn_cond, NULL)) -                goto fail_cond_init; +        /* FIXME: get the correct qos for the component. */ +        if (connmgr_alloc(id, dst, NULL, &ce->conn)) { +                free(ce); +                return -1; +        } -        pthread_rwlock_wrlock(&connmgr.aes_lock); +        if (strlen(dst) > DST_MAX_STRLEN) { +                log_warn("Truncating dst length for connection."); +                memcpy(ce->conn.flow_info.dst, dst, DST_MAX_STRLEN); +                ce->conn.flow_info.dst[DST_MAX_STRLEN] = '\0'; +        } else { +                strcpy(ce->conn.flow_info.dst, dst); +        } -        list_add(&ae->next, &connmgr.aes); +        pthread_mutex_lock(&connmgr.aes[id].lock); -        pthread_rwlock_unlock(&connmgr.aes_lock); +        list_add(&ce->next, &connmgr.aes[id].conns); -        return ae; +        pthread_mutex_unlock(&connmgr.aes[id].lock); - fail_cond_init: -        pthread_mutex_destroy(&ae->conn_lock); - fail_mutex_init: -        free(ae); - fail_malloc: -        return NULL; +        return 0;  } -void connmgr_ae_destroy(struct ae * ae) +int connmgr_ipcp_disconnect(const char * dst, +                            const char * component)  { -        assert(ae); +        struct list_head * p; +        struct list_head * h; +        int                id; -        pthread_rwlock_wrlock(&connmgr.aes_lock); +        assert(dst); +        assert(component); -        list_del(&ae->next); +        id = get_id_by_name(component); +        if (id < 0) +                return -1; -        pthread_rwlock_unlock(&connmgr.aes_lock); +        pthread_mutex_lock(&connmgr.aes[id].lock); + +        list_for_each_safe(p,h, &connmgr.aes[id].conns) { +                struct conn_el * el = list_entry(p, struct conn_el, next); +                if (strcmp(el->conn.flow_info.dst, dst) == 0) { +                        int ret; +                        pthread_mutex_unlock(&connmgr.aes[id].lock); +                        list_del(&el->next); +                        ret = connmgr_dealloc(id, &el->conn); +                        free(el); +                        return ret; +                } +        } + +        pthread_mutex_unlock(&connmgr.aes[id].lock); -        destroy_ae(ae); +        return 0;  } -int connmgr_alloc(struct ae *   ae, -                  const char *  dst_name, +int connmgr_alloc(enum ae_id    id, +                  const char *  dst,                    qosspec_t *   qs,                    struct conn * conn)  { -        assert(ae); -        assert(dst_name); -        assert(conn); - -        memset(&conn->conn_info, 0, sizeof(conn->conn_info)); +        assert(id >= 0 && id < AEID_MAX); +        assert(dst); -        conn->flow_info.fd = flow_alloc(dst_name, qs, NULL); +        conn->flow_info.fd = flow_alloc(dst, qs, NULL);          if (conn->flow_info.fd < 0) { -                log_err("Failed to allocate flow to %s.", dst_name); +                log_dbg("Failed to allocate flow to %s.", dst);                  return -1;          } @@ -320,58 +359,90 @@ int connmgr_alloc(struct ae *   ae,          else                  memset(&conn->flow_info.qs, 0, sizeof(conn->flow_info.qs)); -        if (cacep_snd(conn->flow_info.fd, &ae->info)) { -                log_err("Failed to create application connection."); +        log_dbg("Sending cacep info for protocol %s to fd %d.", +                connmgr.aes[id].info.protocol, conn->flow_info.fd); + +        if (cacep_snd(conn->flow_info.fd, &connmgr.aes[id].info)) { +                log_dbg("Failed to create application connection.");                  flow_dealloc(conn->flow_info.fd);                  return -1;          }          if (cacep_rcv(conn->flow_info.fd, &conn->conn_info)) { -                log_err("Failed to connect to application."); +                log_dbg("Failed to connect to application.");                  flow_dealloc(conn->flow_info.fd);                  return -1;          } -        if (strcmp(ae->info.protocol, conn->conn_info.protocol) || -            ae->info.pref_version != conn->conn_info.pref_version || -            ae->info.pref_syntax != conn->conn_info.pref_syntax) { +        if (strcmp(connmgr.aes[id].info.protocol, conn->conn_info.protocol)) { +                log_dbg("Unknown protocol (requested %s, got %s).", +                        connmgr.aes[id].info.protocol, +                        conn->conn_info.protocol);                  flow_dealloc(conn->flow_info.fd);                  return -1;          } +        if (connmgr.aes[id].info.pref_version != conn->conn_info.pref_version) { +                log_dbg("Unknown protocol version."); +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        if (connmgr.aes[id].info.pref_syntax != conn->conn_info.pref_syntax) { +                log_dbg("Unknown protocol syntax."); +                flow_dealloc(conn->flow_info.fd); +                return -1; +        } + +        if (connmgr.aes[id].nbs != NULL) +                nbs_add(connmgr.aes[id].nbs, *conn); +          return 0;  } -int connmgr_wait(struct ae *   ae, +int connmgr_dealloc(enum ae_id    id, +                    struct conn * conn) +{ +        if (connmgr.aes[id].nbs != NULL) +                nbs_del(connmgr.aes[id].nbs, conn->flow_info.fd); + +        return flow_dealloc(conn->flow_info.fd); +} + + +int connmgr_wait(enum ae_id    id,                   struct conn * conn)  { -        struct ae_conn * ae_conn; +        struct conn_el * el; +        struct ae *      ae; -        assert(ae); +        assert(id >= 0 && id < AEID_MAX);          assert(conn); -        pthread_mutex_lock(&ae->conn_lock); +        ae = connmgr.aes + id; + +        pthread_mutex_lock(&ae->lock);          pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, -                             (void *) &ae->conn_lock); +                             (void *) &ae->lock); -        while (list_is_empty(&ae->conn_list)) -                pthread_cond_wait(&ae->conn_cond, &ae->conn_lock); +        while (list_is_empty(&ae->pending)) +                pthread_cond_wait(&ae->cond, &ae->lock);          pthread_cleanup_pop(false); -        ae_conn = list_first_entry((&ae->conn_list), struct ae_conn, next); -        if (ae_conn == NULL) { -                pthread_mutex_unlock(&ae->conn_lock); +        el = list_first_entry((&ae->pending), struct conn_el, next); +        if (el == NULL) { +                pthread_mutex_unlock(&ae->lock);                  return -1;          } -        *conn = ae_conn->conn; +        *conn = el->conn; -        list_del(&ae_conn->next); -        free(ae_conn); +        list_del(&el->next); +        free(el); -        pthread_mutex_unlock(&ae->conn_lock); +        pthread_mutex_unlock(&ae->lock);          return 0;  } diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h index 40d74348..379877e6 100644 --- a/src/ipcpd/normal/connmgr.h +++ b/src/ipcpd/normal/connmgr.h @@ -26,13 +26,8 @@  #include <ouroboros/cacep.h>  #include <ouroboros/qos.h> -struct conn { -        struct conn_info conn_info; -        struct flow_info { -                int              fd; -                qosspec_t        qs; -        } flow_info; -}; +#include "ae.h" +#include "neighbors.h"  int         connmgr_init(void); @@ -42,16 +37,27 @@ int         connmgr_start(void);  void        connmgr_stop(void); -struct ae * connmgr_ae_create(struct conn_info info); +int         connmgr_ae_init(enum ae_id               id, +                            const struct conn_info * info, +                            struct nbs *             nbs); -void        connmgr_ae_destroy(struct ae * ae); +void        connmgr_ae_fini(enum ae_id id); -int         connmgr_alloc(struct ae *   ae, +int         connmgr_ipcp_connect(const char * dst, +                                 const char * component); + +int         connmgr_ipcp_disconnect(const char * dst, +                                    const char * component); + +int         connmgr_alloc(enum ae_id    id,                            const char *  dst,                            qosspec_t *   qs,                            struct conn * conn); -int         connmgr_wait(struct ae *   ae, +int         connmgr_dealloc(enum ae_id    id, +                            struct conn * conn); + +int         connmgr_wait(enum ae_id    id,                           struct conn * conn);  #endif /* OUROBOROS_IPCPD_NORMAL_CONNMGR_H */ diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index feae7013..2e2c113a 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -46,80 +46,21 @@  struct dht * dht; -static uint64_t find_peer_addr(void) +int dir_init(void)  { -        ssize_t  i; -        char ** members; -        ssize_t n_members; -        size_t  reset; -        char    path[RIB_MAX_PATH_LEN + 1]; - -        strcpy(path, MEMBERS_PATH); - -        reset = strlen(path); - -        n_members = rib_children(path, &members); -        if (n_members == 1) { -                freepp(ssize_t, members, n_members); -                return 0; -        } - -        for (i = 0; i < n_members; ++i) { -                uint64_t addr; -                rib_path_append(path, members[i]); -                if (rib_read(path, &addr, sizeof(addr)) != sizeof(addr)) { -                        log_err("Failed to read address from RIB."); -                        freepp(ssize_t, members, n_members); -                        return ipcpi.dt_addr; -                } - -                if (addr != ipcpi.dt_addr) { -                        freepp(ssize_t, members, n_members); -                        return addr; -                } - -                path[reset] = '\0'; -        } - -        freepp(ssize_t, members, n_members); - -        return 0; -} - -int dir_init() -{ -        uint64_t addr; -          dht = dht_create(ipcpi.dt_addr);          if (dht == NULL)                  return -ENOMEM; -        addr = find_peer_addr(); -        if (addr == ipcpi.dt_addr) { -                log_err("Failed to get peer address."); -                dht_destroy(dht); -                return -EPERM; -        } - -        if (addr != 0) { -                size_t retr = 0; -                log_dbg("Enrolling directory with peer %" PRIu64 ".", addr); -                /* NOTE: we could try other members if dht_enroll times out. */ -                while (dht_enroll(dht, addr)) { -                        if (retr++ == ENROL_RETR) { -                                dht_destroy(dht); -                                return -EPERM; -                        } - -                        log_dbg("Directory enrollment failed, retrying..."); -                        sleep(ENROL_INTV); -                } - -                log_dbg("Directory enrolled."); +        return 0; +} -                return 0; -        } +void dir_fini(void) +{ +        dht_destroy(dht); +} +int dir_bootstrap(void) {          log_dbg("Bootstrapping directory.");          /* TODO: get parameters for bootstrap from IRM tool. */ @@ -133,9 +74,20 @@ int dir_init()          return 0;  } -void dir_fini(void) -{ -        dht_destroy(dht); +int dir_enroll(uint64_t addr) { +        size_t retr = 0; +        log_dbg("Enrolling directory with peer %" PRIu64 ".", addr); +        while (dht_enroll(dht, addr)) { +                if (retr++ == ENROL_RETR) +                        return -EPERM; + +                log_dbg("Directory enrollment failed, retrying..."); +                sleep(ENROL_INTV); +        } + +        log_dbg("Directory enrolled."); + +        return 0;  }  int dir_reg(const uint8_t * hash) diff --git a/src/ipcpd/normal/dir.h b/src/ipcpd/normal/dir.h index 5f3f738e..13571b68 100644 --- a/src/ipcpd/normal/dir.h +++ b/src/ipcpd/normal/dir.h @@ -27,6 +27,10 @@ int      dir_init(void);  void     dir_fini(void); +int      dir_bootstrap(void); + +int      dir_enroll(uint64_t peer); +  int      dir_reg(const uint8_t * hash);  int      dir_unreg(const uint8_t * hash); diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c index f4ab2440..282f6bee 100644 --- a/src/ipcpd/normal/dt.c +++ b/src/ipcpd/normal/dt.c @@ -38,7 +38,6 @@  #include "dt_pci.h"  #include "pff.h"  #include "neighbors.h" -#include "gam.h"  #include "routing.h"  #include "sdu_sched.h"  #include "ae.h" @@ -67,11 +66,11 @@ struct {          struct ae_info     aes[AP_RES_FDS];          pthread_rwlock_t   lock; -        struct gam *       gam;          struct nbs *       nbs; -        struct ae *        ae;          struct nb_notifier nb_notifier; + +        pthread_t          listener;  } dt;  static int dt_neighbor_event(enum nb_event event, @@ -149,36 +148,48 @@ static int sdu_handler(int                  fd,          return 0;  } -int dt_init(void) +static void * dt_conn_handle(void * o)  { -        int              i; -        int              j; -        struct conn_info info; -        enum pol_routing pr; +        struct conn conn; -        if (rib_read(BOOT_PATH "/dt/routing/type", &pr, sizeof(pr)) -            != sizeof(pr)) { -                log_err("Failed to read policy for routing."); -                return -1; -        } +        (void) o; -        if (dt_pci_init()) { -                log_err("Failed to init shm dt_pci."); -                return -1; +        while (true) { +                if (connmgr_wait(AEID_DT, &conn)) { +                        log_err("Failed to get next DT connection."); +                        continue; +                } + +                log_dbg("Got new connection."); + +                /* NOTE: connection acceptance policy could be here. */ + +                nbs_add(dt.nbs, conn);          } +        return 0; +} + +int dt_init(enum pol_routing pr, +            uint8_t          addr_size, +            uint8_t          fd_size, +            bool             has_ttl) +{ +        int              i; +        int              j; +        struct conn_info info; +          memset(&info, 0, sizeof(info));          strcpy(info.ae_name, DT_AE);          strcpy(info.protocol, DT_PROTO);          info.pref_version = 1; -        info.pref_syntax = PROTO_FIXED; -        info.addr = ipcpi.dt_addr; +        info.pref_syntax  = PROTO_FIXED; +        info.addr         = ipcpi.dt_addr; -        dt.ae = connmgr_ae_create(info); -        if (dt.ae == NULL) { -                log_err("Failed to create AE struct."); -                goto fail_connmgr; +        if (dt_pci_init(addr_size, fd_size, has_ttl)) { +                log_err("Failed to init shm dt_pci."); +                goto fail_pci_init;          }          dt.nbs = nbs_create(); @@ -193,6 +204,11 @@ int dt_init(void)                  goto fail_nbs_notifier;          } +        if (connmgr_ae_init(AEID_DT, &info, dt.nbs)) { +                log_err("Failed to register with connmgr."); +                goto fail_connmgr_ae_init; +        } +          if (routing_init(pr, dt.nbs)) {                  log_err("Failed to init routing.");                  goto fail_routing; @@ -233,6 +249,8 @@ int dt_init(void)          for (j = 0; j < QOS_CUBE_MAX; ++j)                  routing_i_destroy(dt.routing[j]);   fail_routing_i: +        connmgr_ae_fini(AEID_DT); + fail_connmgr_ae_init:          for (i = 0; i < QOS_CUBE_MAX; ++i)                  pff_destroy(dt.pff[i]);   fail_pff: @@ -242,9 +260,9 @@ int dt_init(void)   fail_nbs_notifier:          nbs_destroy(dt.nbs);   fail_nbs: -        connmgr_ae_destroy(dt.ae); - fail_connmgr:          dt_pci_fini(); + fail_pci_init: +        connmgr_ae_fini(AEID_DT);          return -1;  } @@ -268,28 +286,19 @@ void dt_fini(void)          nbs_destroy(dt.nbs); -        connmgr_ae_destroy(dt.ae); +        connmgr_ae_fini(AEID_DT);  }  int dt_start(void)  { -        enum pol_gam pg; - -        if (rib_read(BOOT_PATH "/dt/gam/type", &pg, sizeof(pg)) -            != sizeof(pg)) { -                log_err("Failed to read policy for ribmgr gam."); -                return -1; -        } -          dt.sdu_sched = sdu_sched_create(sdu_handler);          if (dt.sdu_sched == NULL) {                  log_err("Failed to create N-1 SDU scheduler.");                  return -1;          } -        dt.gam = gam_create(pg, dt.nbs, dt.ae); -        if (dt.gam == NULL) { -                log_err("Failed to init dt graph adjacency manager."); +        if (pthread_create(&dt.listener, NULL, dt_conn_handle, NULL)) { +                log_err("Failed to create listener thread.");                  sdu_sched_destroy(dt.sdu_sched);                  return -1;          } @@ -299,8 +308,8 @@ int dt_start(void)  void dt_stop(void)  { -        gam_destroy(dt.gam); - +        pthread_cancel(dt.listener); +        pthread_join(dt.listener, NULL);          sdu_sched_destroy(dt.sdu_sched);  } diff --git a/src/ipcpd/normal/dt.h b/src/ipcpd/normal/dt.h index 99918ea5..09716153 100644 --- a/src/ipcpd/normal/dt.h +++ b/src/ipcpd/normal/dt.h @@ -23,13 +23,20 @@  #ifndef OUROBOROS_IPCPD_NORMAL_DT_H  #define OUROBOROS_IPCPD_NORMAL_DT_H +#include <ouroboros/ipcp.h>  #include <ouroboros/shm_rdrbuff.h>  #include "dt_pci.h" +#define DT_AE        "Data Transfer" +#define DT_PROTO     "dtp"  #define INVALID_ADDR 0 -int  dt_init(void); +int  dt_init(enum pol_routing pr, +             uint8_t          addr_size, +             uint8_t          fd_size, +             bool             has_ttl +);  void dt_fini(void); diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c index 9e6dfa89..5704a09a 100644 --- a/src/ipcpd/normal/dt_pci.c +++ b/src/ipcpd/normal/dt_pci.c @@ -44,19 +44,13 @@ struct {          size_t          fd_o;  } dt_pci_info; -int dt_pci_init() +int dt_pci_init(uint8_t addr_size, +                uint8_t fd_size, +                bool    has_ttl)  { -        /* read dt constants from the RIB */ -        if (rib_read(BOOT_PATH "/dt/const/addr_size", -                     &dt_pci_info.addr_size, -                     sizeof(dt_pci_info.addr_size)) < 0 || -            rib_read(BOOT_PATH "/dt/const/fd_size", -                     &dt_pci_info.fd_size, -                     sizeof(dt_pci_info.fd_size)) < 0 || -            rib_read(BOOT_PATH "/dt/const/has_ttl", -                     &dt_pci_info.has_ttl, -                     sizeof(dt_pci_info.has_ttl)) < 0) -                return -1; +        dt_pci_info.addr_size = addr_size; +        dt_pci_info.fd_size   = fd_size; +        dt_pci_info.has_ttl   = has_ttl;          dt_pci_info.qc_o = dt_pci_info.addr_size;          dt_pci_info.ttl_o = dt_pci_info.qc_o + QOS_LEN; diff --git a/src/ipcpd/normal/dt_pci.h b/src/ipcpd/normal/dt_pci.h index 5f14527c..efb4d0c0 100644 --- a/src/ipcpd/normal/dt_pci.h +++ b/src/ipcpd/normal/dt_pci.h @@ -30,8 +30,6 @@  #include <stdint.h>  #include <stdbool.h> -#define DT_PROTO "dt" -  /* Abstract syntax */  enum dtp_fields {          DTP_DST = 0,   /* DST ADDRESS */ @@ -54,7 +52,9 @@ struct dt_pci {          uint32_t  fd;  }; -int   dt_pci_init(void); +int   dt_pci_init(uint8_t addr_size, +                  uint8_t fd_size, +                  bool    has_ttl);  void  dt_pci_fini(void); diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index a33239a0..7f93ed3a 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -22,19 +22,19 @@  #define _POSIX_C_SOURCE 199309L -#define OUROBOROS_PREFIX "enrollment" +#define OUROBOROS_PREFIX "Enrollment"  #include <ouroboros/endian.h>  #include <ouroboros/errno.h> -#include <ouroboros/cdap.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/dev.h>  #include <ouroboros/logs.h>  #include <ouroboros/rib.h>  #include <ouroboros/errno.h> -#include "ae.h"  #include "connmgr.h" +#include "enroll.h" +#include "ipcp.h"  #include "ribconfig.h"  #include <assert.h> @@ -42,302 +42,337 @@  #include <string.h>  #include <pthread.h> -/* Symbolic, will return current time */ -#define TIME_NAME               "localtime" -#define TIME_PATH               DLR TIME_NAME +#include "enroll.pb-c.h" +typedef EnrollMsg enroll_msg_t; +typedef IpcpConfigMsg ipcp_config_msg_t; +typedef DifInfoMsg dif_info_msg_t; + +#define ENROLL_AE               "Enrollment" +#define ENROLL_PROTO            "OEP" /* Ouroboros enrollment protocol */  #define ENROLL_WARN_TIME_OFFSET 20 +#define ENROLL_BUF_LEN          1024 + +enum enroll_state { +        ENROLL_NULL = 0, +        ENROLL_INIT, +        ENROLL_RUNNING +};  struct { -        struct ae *   ae; -        struct cdap * cdap; -        pthread_t     listener; +        struct ipcp_config conf; +        enum enroll_state  state; +        pthread_t          listener;  } enroll; -static void * enroll_handle(void * o) +static int  send_rcv_enroll_msg(int fd)  { -        struct cdap *    cdap; -        struct conn      conn; -        cdap_key_t       key; -        enum cdap_opcode oc; -        char *           name; -        uint8_t *        buf; -        uint8_t *        data; -        ssize_t          len; -        uint32_t         flags; +        enroll_msg_t    req = ENROLL_MSG__INIT; +        enroll_msg_t *  reply; +        uint8_t         buf[ENROLL_BUF_LEN]; +        ssize_t         len; +        ssize_t         delta_t; +        struct timespec t0; +        struct timespec rtt; -        bool boot_r     = false; -        bool members_r  = false; +        req.code = ENROLL_CODE__ENROLL_REQ; -        char * boot_ro    = BOOT_PATH; -        char * members_ro = MEMBERS_PATH; +        len = enroll_msg__get_packed_size(&req); +        if (len < 0) { +                log_dbg("Failed pack request message."); +                return -1; +        } -        cdap = (struct cdap *) o; +        enroll_msg__pack(&req, buf); -        assert(cdap); +        clock_gettime(CLOCK_REALTIME, &t0); -        while (true) { -                if (connmgr_wait(enroll.ae, &conn)) { -                        log_err("Failed to get next connection."); -                        continue; -                } +        if (flow_write(fd, buf, len)) { +                log_dbg("Failed to send request message."); +                return -1; +        } -                if (cdap_add_flow(cdap, conn.flow_info.fd)) { -                        log_warn("Failed to add flow to CDAP."); -                        flow_dealloc(conn.flow_info.fd); -                        continue; -                } +        len = flow_read(fd, buf, ENROLL_BUF_LEN); +        if (len < 0) { +                log_dbg("No enrollment reply received."); +                return -1; +        } -                while (!(boot_r && members_r)) { -                        key = cdap_request_wait(cdap, &oc, &name, &data, -                                                (size_t *) &len , &flags); -                        assert(key >= 0); -                        assert(name); - -                        if (data != NULL) { -                                free(data); -                                log_warn("Received data with enroll request."); -                        } - -                        if (oc != CDAP_READ) { -                                log_warn("Invalid request."); -                                cdap_reply_send(cdap, key, -1, NULL, 0); -                                free(name); -                                continue; -                        } - -                        if (strcmp(name, boot_ro) == 0) { -                                boot_r = true; -                        } else if (strcmp(name, members_ro) == 0) { -                                members_r = true; -                        } else if (strcmp(name, TIME_PATH) == 0) { -                                struct timespec t; -                                uint64_t buf[2]; -                                clock_gettime(CLOCK_REALTIME, &t); -                                buf[0] = hton64(t.tv_sec); -                                buf[1] = hton64(t.tv_nsec); -                                cdap_reply_send(cdap, key, 0, buf, sizeof(buf)); -                                free(name); -                                continue; -                        } else { -                                log_warn("Illegal read: %s.", name); -                                cdap_reply_send(cdap, key, -1, NULL, 0); -                                free(name); -                                continue; -                        } - -                        len = rib_pack(name, &buf, PACK_HASH_ROOT); -                        if (len < 0) { -                                log_err("Failed to pack %s.", name); -                                cdap_reply_send(cdap, key, -1, NULL, 0); -                                free(name); -                                continue; -                        } - -                        log_dbg("Packed %s (%zu bytes).", name, len); - -                        free(name); - -                        if (cdap_reply_send(cdap, key, 0, buf, len)) { -                                log_err("Failed to send CDAP reply."); -                                free(buf); -                                continue; -                        } - -                        free(buf); -                } +        log_dbg("Received enrollment info (%zd bytes).", len); -                log_dbg("Sent boot info to new member."); +        reply = enroll_msg__unpack(NULL, len, buf); +        if (reply == NULL) { +                log_dbg("No enrollment response."); +                return -1; +        } -                cdap_del_flow(cdap, conn.flow_info.fd); -                flow_dealloc(conn.flow_info.fd); +        if (reply->code != ENROLL_CODE__ENROLL_BOOT) { +                log_dbg("Failed to unpack enrollment response."); +                enroll_msg__free_unpacked(reply, NULL); +                return -1; +        } -                boot_r = members_r = false; +        if (!(reply->has_t_sec && reply->has_t_nsec)) { +                log_dbg("No time in response message."); +                enroll_msg__free_unpacked(reply, NULL); +                return -1;          } +        clock_gettime(CLOCK_REALTIME, &rtt); + +        delta_t = ts_diff_ms(&t0, &rtt); + +        rtt.tv_sec  = reply->t_sec; +        rtt.tv_nsec = reply->t_nsec; + +        if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET) +                log_warn("Clock offset above threshold."); + +        strcpy(enroll.conf.dif_info.dif_name, reply->conf->dif_info->dif_name); +        enroll.conf.type           = reply->conf->ipcp_type; +        enroll.conf.addr_size      = reply->conf->addr_size; +        enroll.conf.fd_size        = reply->conf->fd_size; +        enroll.conf.has_ttl        = reply->conf->has_ttl; +        enroll.conf.addr_auth_type = reply->conf->addr_auth_type; +        enroll.conf.routing_type   = reply->conf->routing_type; +        enroll.conf.dif_info.dir_hash_algo +                = reply->conf->dif_info->dir_hash_algo; + +        enroll_msg__free_unpacked(reply, NULL); +          return 0;  } -int enroll_boot(const char * dst) +static ssize_t enroll_pack(uint8_t ** buf)  { -        struct cdap * cdap; -        cdap_key_t *  key; -        uint8_t *     data; -        size_t        len; -        struct conn   conn; +        enroll_msg_t      msg      = ENROLL_MSG__INIT; +        ipcp_config_msg_t config   = IPCP_CONFIG_MSG__INIT; +        dif_info_msg_t    dif_info = DIF_INFO_MSG__INIT; +        struct timespec   now; +        ssize_t           len; + +        clock_gettime(CLOCK_REALTIME, &now); + +        msg.code       = ENROLL_CODE__ENROLL_BOOT; +        msg.has_t_sec  = true; +        msg.t_sec      = now.tv_sec; +        msg.has_t_nsec = true; +        msg.t_nsec     = now.tv_nsec; +        msg.conf       = &config; + +        config.ipcp_type          = enroll.conf.type; +        config.has_addr_size      = true; +        config.addr_size          = enroll.conf.addr_size; +        config.has_fd_size        = true; +        config.fd_size            = enroll.conf.fd_size; +        config.has_has_ttl        = true; +        config.has_ttl            = enroll.conf.has_ttl; +        config.has_addr_auth_type = true; +        config.addr_auth_type     = enroll.conf.addr_auth_type; +        config.has_routing_type   = true; +        config.routing_type       = enroll.conf.routing_type; +        config.dif_info           = &dif_info; + +        dif_info.dif_name      = (char *) enroll.conf.dif_info.dif_name; +        dif_info.dir_hash_algo = enroll.conf.dif_info.dir_hash_algo; + +        len = enroll_msg__get_packed_size(&msg); + +        *buf = malloc(len); +        if (*buf == NULL) +                return -1; -        struct timespec t0; -        struct timespec rtt; +        enroll_msg__pack(&msg, *buf); -        ssize_t delta_t; +        return len; +} -        char * boot_ro    = BOOT_PATH; -        char * members_ro = MEMBERS_PATH; +static void * enroll_handle(void * o) +{ +        struct conn    conn; +        uint8_t        buf[ENROLL_BUF_LEN]; +        uint8_t *      reply; +        ssize_t        len; +        enroll_msg_t * msg; -        cdap = cdap_create(); -        if (cdap == NULL) { -                log_err("Failed to instantiate CDAP."); -                return -1; -        } +        (void) o; -        if (connmgr_alloc(enroll.ae, dst, NULL, &conn)) { -                log_err("Failed to get connection."); -                cdap_destroy(cdap); -                return -1; -        } +        while (true) { +                if (connmgr_wait(AEID_ENROLL, &conn)) { +                        log_err("Failed to get next connection."); +                        continue; +                } -        if (cdap_add_flow(cdap, conn.flow_info.fd)) { -                log_warn("Failed to add flow to CDAP."); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; -        } +                len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN); +                if (len < 0) { +                        log_err("Failed to read from flow."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        log_dbg("Getting boot information from %s.", dst); +                msg = enroll_msg__unpack(NULL, len, buf); +                if (msg == NULL) { +                        log_err("Failed to unpack message."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        clock_gettime(CLOCK_REALTIME, &t0); +                if (msg->code != ENROLL_CODE__ENROLL_REQ) { +                        log_err("Wrong message type."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        enroll_msg__free_unpacked(msg, NULL); +                        continue; +                } -        key = cdap_request_send(cdap, CDAP_READ, TIME_PATH, NULL, 0, 0); -        if (key == NULL || key[0] == INVALID_CDAP_KEY) { -                log_err("Failed to send CDAP request."); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; -        } +                log_dbg("Enrolling a new neighbor."); -        if (cdap_reply_wait(cdap, key[0], &data, &len)) { -                log_err("Failed to get CDAP reply."); -                free(key); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; -        } +                enroll_msg__free_unpacked(msg, NULL); -        free(key); +                len = enroll_pack(&reply); +                if (reply == NULL) { +                        log_err("Failed to pack enrollment message."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        clock_gettime(CLOCK_REALTIME, &rtt); +                log_dbg("Sending enrollment info (%zd bytes).", len); -        delta_t = ts_diff_ms(&t0, &rtt); +                if (flow_write(conn.flow_info.fd, reply, len)) { +                        log_err("Failed respond to enrollment request."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        free(reply); +                        continue; +                } -        assert(len == 2 * sizeof (uint64_t)); +                free(reply); -        rtt.tv_sec  = ntoh64(((uint64_t *) data)[0]); -        rtt.tv_nsec = ntoh64(((uint64_t *) data)[1]); +                len = flow_read(conn.flow_info.fd, buf, ENROLL_BUF_LEN); +                if (len < 0) { +                        log_err("Failed to read from flow."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        if (labs(ts_diff_ms(&t0, &rtt)) - delta_t > ENROLL_WARN_TIME_OFFSET) -                log_warn("Clock offset above threshold."); +                msg = enroll_msg__unpack(NULL, len, buf); +                if (msg == NULL) { +                        log_err("Failed to unpack message."); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        free(data); +                if (msg->code != ENROLL_CODE__ENROLL_DONE || !msg->has_result) { +                        log_err("Wrong message type."); +                        enroll_msg__free_unpacked(msg, NULL); +                        connmgr_dealloc(AEID_ENROLL, &conn); +                        continue; +                } -        key = cdap_request_send(cdap, CDAP_READ, boot_ro, NULL, 0, 0); -        if (key == NULL || key[0] == INVALID_CDAP_KEY) { -                log_err("Failed to send CDAP request."); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; -        } +                if (msg->result == 0) +                        log_dbg("Neighbor enrollment successful."); +                else +                        log_dbg("Neigbor reported failed enrollment."); -        if (cdap_reply_wait(cdap, key[0], &data, &len)) { -                log_err("Failed to get CDAP reply."); -                free(key); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; +                connmgr_dealloc(AEID_ENROLL, &conn);          } -        free(key); +        return 0; +} -        log_dbg("Packed information received (%zu bytes).", len); +int enroll_boot(struct conn * conn, +                const char *  dst) +{ +        log_dbg("Getting boot information from %s.", dst); -        if (rib_unpack(data, len, UNPACK_CREATE)) { -                log_warn("Error unpacking RIB data."); -                rib_del(boot_ro); -                free(data); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); +        if (send_rcv_enroll_msg(conn->flow_info.fd)) { +                log_err("Failed to enroll.");                  return -1;          } -        log_dbg("Packed information inserted into RIB."); +        return 0; +} -        key = cdap_request_send(cdap, CDAP_READ, members_ro, NULL, 0, 0); -        if (key == NULL || key[0] == INVALID_CDAP_KEY) { -                log_err("Failed to send CDAP request."); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); -                return -1; -        } +int enroll_done(struct conn * conn, +                int           result) +{ +        enroll_msg_t msg = ENROLL_MSG__INIT; +        uint8_t      buf[ENROLL_BUF_LEN]; +        ssize_t       len; -        if (cdap_reply_wait(cdap, key[0], &data, &len)) { -                log_err("Failed to get CDAP reply."); -                free(key); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); +        msg.code       = ENROLL_CODE__ENROLL_DONE; +        msg.has_result = true; +        msg.result     = result; + +        len = enroll_msg__get_packed_size(&msg); +        if (len < 0) { +                log_dbg("Failed pack request message.");                  return -1;          } -        free(key); - -        log_dbg("Packed information received (%zu bytes).", len); +        enroll_msg__pack(&msg, buf); -        if (rib_unpack(data, len, UNPACK_CREATE)) { -                log_warn("Error unpacking RIB data."); -                rib_del(boot_ro); -                free(data); -                cdap_destroy(cdap); -                flow_dealloc(conn.flow_info.fd); +        if (flow_write(conn->flow_info.fd, buf, len)) { +                log_dbg("Failed to send acknowledgment.");                  return -1;          } -        log_dbg("Packed information inserted into RIB."); +        return 0; +} + +void enroll_bootstrap(const struct ipcp_config * conf) +{ +        assert(conf); -        cdap_destroy(cdap); -        flow_dealloc(conn.flow_info.fd); +        memcpy(&enroll.conf, conf, sizeof(enroll.conf)); +} -        return 0; +struct ipcp_config * enroll_get_conf(void) +{ +        return &enroll.conf;  }  int enroll_init(void)  {          struct conn_info info; -        enroll.cdap = cdap_create(); -        if (enroll.cdap == NULL) { -                log_err("Failed to instantiate CDAP."); -                return -1; -        } -          memset(&info, 0, sizeof(info));          strcpy(info.ae_name, ENROLL_AE); -        strcpy(info.protocol, CDAP_PROTO); +        strcpy(info.protocol, ENROLL_PROTO);          info.pref_version = 1;          info.pref_syntax  = PROTO_GPB; +        info.addr         = 0; -        enroll.ae = connmgr_ae_create(info); -        if (enroll.ae == NULL) { -                cdap_destroy(enroll.cdap); +        if (connmgr_ae_init(AEID_ENROLL, &info, NULL)) { +                log_err("Failed to register with connmgr.");                  return -1;          } +        enroll.state = ENROLL_INIT; +          return 0;  }  void enroll_fini(void)  { -        pthread_join(enroll.listener, NULL); -        cdap_destroy(enroll.cdap); -        connmgr_ae_destroy(enroll.ae); +        if (enroll.state == ENROLL_RUNNING) +                pthread_join(enroll.listener, NULL); + +        connmgr_ae_fini(AEID_ENROLL);  }  int enroll_start(void)  { -        if (pthread_create(&enroll.listener, NULL, enroll_handle, enroll.cdap)) +        if (pthread_create(&enroll.listener, NULL, enroll_handle, NULL))                  return -1; +        enroll.state = ENROLL_RUNNING; +          return 0;  }  void enroll_stop(void)  { -        pthread_cancel(enroll.listener); +        if (enroll.state == ENROLL_RUNNING) +                pthread_cancel(enroll.listener); + +        enroll.state = ENROLL_INIT;  } diff --git a/src/ipcpd/normal/enroll.h b/src/ipcpd/normal/enroll.h index 9b50f6bb..3b277e44 100644 --- a/src/ipcpd/normal/enroll.h +++ b/src/ipcpd/normal/enroll.h @@ -23,14 +23,26 @@  #ifndef OUROBOROS_IPCPD_NORMAL_ENROLL_H  #define OUROBOROS_IPCPD_NORMAL_ENROLL_H -int  enroll_init(void); +#include <ouroboros/ipcp.h> -void enroll_fini(void); +#include "ae.h" -int  enroll_start(void); +int                  enroll_init(void); -void enroll_stop(void); +void                 enroll_fini(void); -int  enroll_boot(const char * dst); +int                  enroll_start(void); + +void                 enroll_stop(void); + +void                 enroll_bootstrap(const struct ipcp_config * conf); + +int                  enroll_boot(struct conn * conn, +                                 const char *  dst); + +int                  enroll_done(struct conn * conn, +                                 int           result); + +struct ipcp_config * enroll_get_conf(void);  #endif /* OUROBOROS_IPCPD_NORMAL_ENROLL_H */ diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/enroll.proto index e63752c0..2347fb8f 100644 --- a/src/ipcpd/normal/pol-gam-ops.h +++ b/src/ipcpd/normal/enroll.proto @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Graph adjacency manager policy ops + * Enrollment message   *   *    Dimitri Staessens <dimitri.staessens@ugent.be>   *    Sander Vrijders   <sander.vrijders@ugent.be> @@ -20,17 +20,20 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifndef OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H -#define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H +syntax = "proto2"; -#include <ouroboros/cacep.h> -#include <ouroboros/qos.h> +import "ipcp_config.proto"; -struct pol_gam_ops { -        void * (* create)(struct nbs * nbs, -                          struct ae *  ae); - -        void   (* destroy)(void * o); +enum enroll_code { +        ENROLL_REQ  = 1; +        ENROLL_BOOT = 2; +        ENROLL_DONE = 4;  }; -#endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */ +message enroll_msg { +        required enroll_code     code   = 1; +        optional ipcp_config_msg conf   = 2; +        optional int64           t_sec  = 3; +        optional uint32          t_nsec = 4; +        optional int32           result = 5; +};
\ No newline at end of file diff --git a/src/ipcpd/normal/flow_alloc.proto b/src/ipcpd/normal/flow_alloc.proto index 717a1a81..eb078674 100644 --- a/src/ipcpd/normal/flow_alloc.proto +++ b/src/ipcpd/normal/flow_alloc.proto @@ -23,16 +23,16 @@  syntax = "proto2";  enum flow_alloc_code { -        FLOW_REQ     = 1; -        FLOW_REPLY   = 2; +        FLOW_REQ   = 1; +        FLOW_REPLY = 2;  };  message flow_alloc_msg { -        required flow_alloc_code code  = 1; -        optional bytes hash            = 2; -        optional uint32 qc             = 3; -        optional sint32 response       = 4; -        optional uint32 r_fd           = 5; -        optional uint32 s_fd           = 6; -        optional uint64 s_addr         = 7; +        required flow_alloc_code code = 1; +        optional bytes hash           = 2; +        optional uint32 qc            = 3; +        optional sint32 response      = 4; +        optional uint32 r_fd          = 5; +        optional uint32 s_fd          = 6; +        optional uint64 s_addr        = 7;  }; diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c deleted file mode 100644 index 3b4cc5de..00000000 --- a/src/ipcpd/normal/gam.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - *  Data transfer graph adjacency manager - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#define _POSIX_C_SOURCE 200112L - -#define OUROBOROS_PREFIX "dt-gam" - -#include <ouroboros/cdap.h> -#include <ouroboros/dev.h> -#include <ouroboros/logs.h> -#include <ouroboros/list.h> -#include <ouroboros/errno.h> -#include <ouroboros/rib.h> - -#include "ipcp.h" -#include "gam.h" -#include "pol-gam-ops.h" -#include "pol/complete.h" - -#include <assert.h> -#include <stdlib.h> -#include <pthread.h> -#include <string.h> - -struct gam { -        struct pol_gam_ops * ops; -        void *               ops_o; -}; - -struct gam * gam_create(enum pol_gam gam_type, -                        struct nbs * nbs, -                        struct ae *  ae) -{ -        struct gam * gam; - -        gam = malloc(sizeof(*gam)); -        if (gam == NULL) -                return NULL; - -        switch (gam_type) { -        case COMPLETE: -                gam->ops = &complete_ops; -                break; -        default: -                log_err("Unknown gam policy: %d.", gam_type); -                return NULL; -        } - -        gam->ops_o = gam->ops->create(nbs, ae); -        if (gam->ops_o == NULL) { -                free(gam); -                return NULL; -        } - -        return gam; -} - -void gam_destroy(struct gam * gam) -{ -        assert(gam); - -        gam->ops->destroy(gam->ops_o); -        free(gam); -} diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h deleted file mode 100644 index 3dd01a75..00000000 --- a/src/ipcpd/normal/gam.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Data transfer graph adjacency manager - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_IPCPD_NORMAL_GAM_H -#define OUROBOROS_IPCPD_NORMAL_GAM_H - -#include <ouroboros/ipcp.h> -#include <ouroboros/cacep.h> - -#include "neighbors.h" - -struct gam * gam_create(enum pol_gam gam_type, -                        struct nbs * nbs, -                        struct ae *  ae); - -void         gam_destroy(struct gam * gam); - -#endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 53762415..0a41f883 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -54,50 +54,25 @@  #define THIS_TYPE IPCP_NORMAL -static int boot_components(void) +static int initialize_components(const struct ipcp_config * conf)  { -        char buf[256]; -        ssize_t len; -        enum pol_addr_auth pa; -        char path[RIB_MAX_PATH_LEN + 1]; - -        len = rib_read(BOOT_PATH "/general/dif_name", buf, 256); -        if (len < 0) { -                log_err("Failed to read DIF name: %zd.", len); -                return -1; +        if (rib_init()) { +                log_err("Failed to initialize RIB."); +                goto fail_rib_init;          } -        ipcpi.dif_name = strdup(buf); +        ipcpi.dif_name = strdup(conf->dif_info.dif_name);          if (ipcpi.dif_name == NULL) {                  log_err("Failed to set DIF name."); -                return -1; +                goto fail_dif_name;          } -        len = rib_read(BOOT_PATH "/general/dir_hash_algo", -                       &ipcpi.dir_hash_algo, sizeof(ipcpi.dir_hash_algo)); -        if (len < 0) { -                log_err("Failed to read hash length: %zd.", len); -                goto fail_addr_auth; -        } - -        ipcpi.dir_hash_algo = ntoh32(ipcpi.dir_hash_algo); +        ipcpi.dir_hash_algo = conf->dif_info.dir_hash_algo;          assert(ipcp_dir_hash_len() != 0); -        if (rib_add(MEMBERS_PATH, ipcpi.name)) { -                log_err("Failed to add name to " MEMBERS_PATH); -                goto fail_addr_auth; -        } - -        log_dbg("Starting components."); - -        if (rib_read(BOOT_PATH "/dt/addr_auth/type", &pa, sizeof(pa)) -            != sizeof(pa)) { -                log_err("Failed to read policy for address authority."); -                goto fail_addr_auth; -        } - -        if (addr_auth_init(pa)) { +        if (addr_auth_init(conf->addr_auth_type, +                           &conf->addr_size)) {                  log_err("Failed to init address authority.");                  goto fail_addr_auth;          } @@ -105,40 +80,84 @@ static int boot_components(void)          ipcpi.dt_addr = addr_auth_address();          if (ipcpi.dt_addr == 0) {                  log_err("Failed to get a valid address."); -                goto fail_dir; -        } - -        path[0] = '\0'; -        rib_path_append(rib_path_append(path, MEMBERS_NAME), ipcpi.name); -        if (rib_write(path, &ipcpi.dt_addr, sizeof(&ipcpi.dt_addr))) { -                log_err("Failed to write address to member object."); -                goto fail_dir; +                goto fail_addr_auth;          }          log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr); -        log_dbg("Starting ribmgr."); -          if (ribmgr_init()) {                  log_err("Failed to initialize RIB manager.");                  goto fail_ribmgr;          } -        log_dbg("Ribmgr started."); - -        if (dt_init()) { -                log_err("Failed to initialize data transfer ae."); +        if (dt_init(conf->routing_type, +                    conf->addr_size, +                    conf->fd_size, +                    conf->has_ttl)) { +                log_err("Failed to initialize data transfer component.");                  goto fail_dt;          }          if (fa_init()) { -                log_err("Failed to initialize flow allocator ae."); +                log_err("Failed to initialize flow allocator component.");                  goto fail_fa;          } -        if (dt_start()) { -                log_err("Failed to start data transfer ae."); -                goto fail_dt_start; +        if (dir_init()) { +                log_err("Failed to initialize directory."); +                goto fail_dir; +        } + +        ipcp_set_state(IPCP_INIT); + +        return 0; + + fail_dir: +        fa_fini(); + fail_fa: +        dt_fini(); + fail_dt: +        ribmgr_fini(); + fail_ribmgr: +        addr_auth_fini(); + fail_addr_auth: +        free(ipcpi.dif_name); + fail_dif_name: +        rib_fini(); + fail_rib_init: +        return -1; +} + +static void finalize_components(void) +{ +        dir_fini(); + +        fa_fini(); + +        dt_fini(); + +        ribmgr_fini(); + +        addr_auth_fini(); + +        free(ipcpi.dif_name); + +        enroll_fini(); + +        connmgr_fini(); + +        rib_fini(); +} + +static int start_components(void) +{ +        assert(ipcp_get_state() == IPCP_INIT); + +        ipcp_set_state(IPCP_OPERATIONAL); + +        if (ribmgr_start()) { +                log_err("Failed to start RIB manager."); +                goto fail_ribmgr_start;          }          if (fa_start()) { @@ -146,20 +165,12 @@ static int boot_components(void)                  goto fail_fa_start;          } -        if (dir_init()) { -                log_err("Failed to initialize directory."); -                goto fail_dir; -        } -          if (enroll_start()) { -                log_err("Failed to start enroll."); +                log_err("Failed to start enrollment.");                  goto fail_enroll_start;          } -        ipcp_set_state(IPCP_OPERATIONAL); -          if (connmgr_start()) { -                ipcp_set_state(IPCP_INIT);                  log_err("Failed to start AP connection manager.");                  goto fail_connmgr_start;          } @@ -169,184 +180,163 @@ static int boot_components(void)   fail_connmgr_start:          enroll_stop();   fail_enroll_start: -        dir_fini(); - fail_dir:          fa_stop();   fail_fa_start: -        dt_stop(); - fail_dt_start: -        fa_fini(); - fail_fa: -        dt_fini(); - fail_dt: -        ribmgr_fini(); - fail_ribmgr: -        addr_auth_fini(); - fail_addr_auth: -        free(ipcpi.dif_name); - +        ribmgr_stop(); + fail_ribmgr_start: +        ipcp_set_state(IPCP_INIT);          return -1;  } -void shutdown_components(void) +static void stop_components(void)  { +        assert(ipcp_get_state() == IPCP_OPERATIONAL || +               ipcp_get_state() == IPCP_SHUTDOWN); +          connmgr_stop();          enroll_stop(); -        dir_fini(); -          fa_stop(); -        dt_stop(); +        ribmgr_stop(); -        fa_fini(); +        ipcp_set_state(IPCP_INIT); +} -        dt_fini(); +static int bootstrap_components(void) +{ +        if (dir_bootstrap()) { +                log_err("Failed to bootstrap directory."); +                dt_stop(); +                return -1; +        } -        ribmgr_fini(); +        return 0; +} -        addr_auth_fini(); +static int enroll_components(uint64_t peer) +{ +        if (dir_enroll(peer)) { +                log_err("Failed to enroll directory."); +                return -1; +        } -        free(ipcpi.dif_name); +        return 0;  }  static int normal_ipcp_enroll(const char *      dst,                                struct dif_info * info)  { -        if (rib_add(RIB_ROOT, MEMBERS_NAME)) { -                log_err("Failed to create members."); -                return -1; +        struct conn er_conn; +        struct conn dt_conn; + +        if (connmgr_alloc(AEID_ENROLL, dst, NULL, &er_conn)) { +                log_err("Failed to get connection."); +                goto fail_er_flow;          } -        /* Get boot state from peer */ -        if (enroll_boot(dst)) { -                log_err("Failed to boot IPCP components."); -                return -1; +        /* Get boot state from peer. */ +        if (enroll_boot(&er_conn, dst)) { +                log_err("Failed to get boot information."); +                goto fail_enroll_boot;          } -        if (boot_components()) { -                log_err("Failed to boot IPCP components."); -                return -1; +        if (initialize_components(enroll_get_conf())) { +                log_err("Failed to initialize IPCP components."); +                goto fail_enroll_boot; +        } + +        if (dt_start()) { +                log_err("Failed to initialize IPCP components."); +                goto fail_dt_start; +        } + +        if (connmgr_alloc(AEID_DT, dst, NULL, &dt_conn)) { +                log_err("Failed to create a data transfer flow."); +                goto fail_dt_flow; +        } + +        if (start_components()) { +                log_err("Failed to start components."); +                goto fail_start_comp; +        } + +        if (enroll_components(dt_conn.conn_info.addr)) { +                enroll_done(&er_conn, -1); +                log_err("Failed to enroll components."); +                goto fail_enroll_comp;          } +        if (enroll_done(&er_conn, 0)) +                log_warn("Failed to confirm enrollment with peer."); + +        if (connmgr_dealloc(AEID_DT, &dt_conn)) +                log_warn("Failed to deallocate data transfer flow."); + +        if (connmgr_dealloc(AEID_ENROLL, &er_conn)) +                log_warn("Failed to deallocate enrollment flow."); +          log_dbg("Enrolled with %s.", dst);          info->dir_hash_algo = ipcpi.dir_hash_algo;          strcpy(info->dif_name, ipcpi.dif_name);          return 0; -} - -const struct ros { -        char * parent; -        char * child; -} ros[] = { -        /* BOOT INFO */ -        {RIB_ROOT, BOOT_NAME}, -        /* OTHER RIB STRUCTURES */ -        {RIB_ROOT, MEMBERS_NAME}, - -        /* GENERAL IPCP INFO */ -        {BOOT_PATH, "general"}, - -        {BOOT_PATH "/general", "dif_name"}, -        {BOOT_PATH "/general", "dir_hash_algo"}, - -        /* DT COMPONENT */ -        {BOOT_PATH, "dt"}, - -        {BOOT_PATH "/dt", "gam"}, -        {BOOT_PATH "/dt/gam", "type"}, -        {BOOT_PATH "/dt/gam", "cacep"}, -        {BOOT_PATH "/dt", "const"}, -        {BOOT_PATH "/dt/const", "addr_size"}, -        {BOOT_PATH "/dt/const", "fd_size"}, -        {BOOT_PATH "/dt/const", "has_ttl"}, -        {BOOT_PATH "/dt", "addr_auth"}, -        {BOOT_PATH "/dt/addr_auth", "type"}, -        {BOOT_PATH "/dt", "routing"}, -        {BOOT_PATH "/dt/routing", "type"}, - -        /* RIB MGR COMPONENT */ -        {BOOT_PATH, "rm"}, -        {BOOT_PATH "/rm","gam"}, -        {BOOT_PATH "/rm/gam", "type"}, -        {BOOT_PATH "/rm/gam", "cacep"}, - -        {NULL, NULL} -}; -int normal_rib_init(void) -{ -        struct ros * r; - -        for (r = (struct ros *) ros; r->parent; ++r) { -                if (rib_add(r->parent, r->child)) { -                        log_err("Failed to create %s/%s", -                                r->parent, r->child); -                        return -1; -                } -        } - -        return 0; + fail_enroll_comp: +        stop_components(); + fail_start_comp: +        connmgr_dealloc(AEID_DT, &dt_conn); + fail_dt_flow: +        dt_stop(); + fail_dt_start: +        finalize_components(); + fail_enroll_boot: +        connmgr_dealloc(AEID_ENROLL, &er_conn); + fail_er_flow: +        return -1;  }  static int normal_ipcp_bootstrap(const struct ipcp_config * conf)  { -        uint32_t hash_algo; -          assert(conf);          assert(conf->type == THIS_TYPE); -        hash_algo = hton32((uint32_t) conf->dif_info.dir_hash_algo); +        enroll_bootstrap(conf); -        assert(ntoh32(hash_algo) != 0); - -        if (normal_rib_init()) { -                log_err("Failed to write initial structure to the RIB."); -                return -1; +        if (initialize_components(conf)) { +                log_err("Failed to init IPCP components."); +                goto fail_init;          } -        if (rib_write(BOOT_PATH "/general/dif_name", -                      conf->dif_info.dif_name, -                      strlen(conf->dif_info.dif_name) + 1) || -            rib_write(BOOT_PATH "/general/dir_hash_algo", -                      &hash_algo, -                      sizeof(hash_algo)) || -            rib_write(BOOT_PATH "/dt/const/addr_size", -                      &conf->addr_size, -                      sizeof(conf->addr_size)) || -            rib_write(BOOT_PATH "/dt/const/fd_size", -                      &conf->fd_size, -                      sizeof(conf->fd_size)) || -            rib_write(BOOT_PATH "/dt/const/has_ttl", -                      &conf->has_ttl, -                      sizeof(conf->has_ttl)) || -            rib_write(BOOT_PATH "/dt/gam/type", -                      &conf->dt_gam_type, -                      sizeof(conf->dt_gam_type)) || -            rib_write(BOOT_PATH "/rm/gam/type", -                      &conf->rm_gam_type, -                      sizeof(conf->rm_gam_type)) || -            rib_write(BOOT_PATH "/dt/addr_auth/type", -                      &conf->addr_auth_type, -                      sizeof(conf->addr_auth_type)) || -            rib_write(BOOT_PATH "/dt/routing/type", -                      &conf->routing_type, -                      sizeof(conf->routing_type))) { -                log_err("Failed to write boot info to RIB."); -                return -1; +        if (dt_start()) { +                log_err("Failed to initialize IPCP components."); +                goto fail_dt_start; +        }; + +        if (start_components()) { +                log_err("Failed to init IPCP components."); +                goto fail_start;          } -        if (boot_components()) { -                log_err("Failed to boot IPCP components."); -                return -1; +        if (bootstrap_components()) { +                log_err("Failed to bootstrap IPCP components."); +                goto fail_bootstrap;          }          log_dbg("Bootstrapped in DIF %s.", conf->dif_info.dif_name);          return 0; + + fail_bootstrap: +        stop_components(); + fail_start: +        dt_stop(); + fail_dt_start: +        finalize_components(); + fail_init: +        return -1;  }  static int normal_ipcp_query(const uint8_t * dst) @@ -357,6 +347,8 @@ static int normal_ipcp_query(const uint8_t * dst)  static struct ipcp_ops normal_ops = {          .ipcp_bootstrap       = normal_ipcp_bootstrap,          .ipcp_enroll          = normal_ipcp_enroll, +        .ipcp_connect         = connmgr_ipcp_connect, +        .ipcp_disconnect      = connmgr_ipcp_disconnect,          .ipcp_reg             = dir_reg,          .ipcp_unreg           = dir_unreg,          .ipcp_query           = normal_ipcp_query, @@ -378,18 +370,14 @@ int main(int    argc,                  goto fail_bind_api;          } -        if (rib_init()) { -                log_err("Failed to initialize RIB."); -                goto fail_rib_init; -        } - +        /* These components must be init at creation. */          if (connmgr_init()) {                  log_err("Failed to initialize connection manager.");                  goto fail_connmgr_init;          }          if (enroll_init()) { -                log_err("Failed to initialize enroll component."); +                log_err("Failed to initialize enrollment component.");                  goto fail_enroll_init;          } @@ -406,14 +394,10 @@ int main(int    argc,          ipcp_shutdown(); -        if (ipcp_get_state() == IPCP_SHUTDOWN) -                shutdown_components(); - -        enroll_fini(); - -        connmgr_fini(); - -        rib_fini(); +        if (ipcp_get_state() == IPCP_SHUTDOWN) { +                dt_stop(); +                stop_components(); +        }          irm_unbind_api(getpid(), ipcpi.name); @@ -428,8 +412,6 @@ int main(int    argc,   fail_enroll_init:          connmgr_fini();   fail_connmgr_init: -        rib_fini(); - fail_rib_init:          irm_unbind_api(getpid(), ipcpi.name);   fail_bind_api:         ipcp_fini(); diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c index 5da0f0df..c32e9aa2 100644 --- a/src/ipcpd/normal/neighbors.c +++ b/src/ipcpd/normal/neighbors.c @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Data transfer neighbors + * Neighbors   *   *    Dimitri Staessens <dimitri.staessens@ugent.be>   *    Sander Vrijders   <sander.vrijders@ugent.be> diff --git a/src/ipcpd/normal/neighbors.h b/src/ipcpd/normal/neighbors.h index 7047d027..9c5a6e50 100644 --- a/src/ipcpd/normal/neighbors.h +++ b/src/ipcpd/normal/neighbors.h @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Data transfer neighbors + * Neighbors   *   *    Dimitri Staessens <dimitri.staessens@ugent.be>   *    Sander Vrijders   <sander.vrijders@ugent.be> @@ -29,7 +29,7 @@  #include <ouroboros/fqueue.h>  #include <ouroboros/cacep.h> -#include "connmgr.h" +#include "ae.h"  enum nb_event {          NEIGHBOR_ADDED, @@ -40,14 +40,14 @@ enum nb_event {  typedef int (* nb_notify_t)(enum nb_event event,                              struct conn   conn); -struct nb_notifier { +struct nb {          struct list_head next; -        nb_notify_t      notify_call; +        struct conn      conn;  }; -struct nb { +struct nb_notifier {          struct list_head next; -        struct conn      conn; +        nb_notify_t      notify_call;  };  struct nbs { diff --git a/src/ipcpd/normal/pol-addr-auth-ops.h b/src/ipcpd/normal/pol-addr-auth-ops.h index a3b39298..5d90c64f 100644 --- a/src/ipcpd/normal/pol-addr-auth-ops.h +++ b/src/ipcpd/normal/pol-addr-auth-ops.h @@ -24,7 +24,7 @@  #define OUROBOROS_IPCPD_NORMAL_POL_ADDR_AUTH_OPS_H  struct pol_addr_auth_ops { -        int      (* init)(void); +        int      (* init)(const void * info);          int      (* fini)(void); diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c deleted file mode 100644 index 6c6e7372..00000000 --- a/src/ipcpd/normal/pol/complete.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Sets up a complete graph - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#define _POSIX_C_SOURCE 200112L - -#define OUROBOROS_PREFIX "complete" - -#include <ouroboros/qoscube.h> -#include <ouroboros/rib.h> -#include <ouroboros/dev.h> -#include <ouroboros/logs.h> -#include <ouroboros/errno.h> -#include <ouroboros/cacep.h> - -#include "neighbors.h" -#include "ribconfig.h" -#include "ipcp.h" -#include "ae.h" - -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#define COMPLETE_REFRESH 1000 /* ms */ - -struct complete { -        struct nbs * nbs; -        struct ae *  ae; -        pthread_t    allocator; -        pthread_t    listener; -}; - -static void * listener(void * o) -{ -        struct complete * complete; -        struct conn       conn; - -        complete = (struct complete *) o; - -        while (true) { -                if (connmgr_wait(complete->ae, &conn)) { -                        log_err("Error while getting next connection."); -                        continue; -                } - -                if (nbs_add(complete->nbs, conn)) { -                        log_err("Failed to add neighbor."); -                        continue; -                } -        } - -        return (void *) 0; -} - -static void path_reset(char * path) -{ -        path[strlen(MEMBERS_PATH)] = '\0'; -} - -static void * allocator(void * o) -{ -        qosspec_t         qs; -        ssize_t           len; -        char **           children; -        ssize_t           i; -        struct complete * complete; -        struct conn       conn; -        uint64_t          addr; -        char              path[RIB_MAX_PATH_LEN]; -        struct timespec   to = {(COMPLETE_REFRESH / 1000), -                                (COMPLETE_REFRESH % 1000) * 1000000}; - -        strcpy(path, MEMBERS_PATH); - -        complete = (struct complete *) o; - -        qosspec_init(&qs); - -        while (true) { -                len = rib_children(MEMBERS_PATH, &children); -                for (i = 0; i < len; ++i) { -                        if (strcmp(children[i], ipcpi.name) != 0) { -                                path_reset(path); -                                rib_path_append(path, children[i]); -                                if (rib_read(path, &addr, -                                             sizeof(addr)) != -                                    sizeof(addr)) { -                                        log_err("Failed to read address."); -                                        free(children[i]); -                                        continue; -                                } - -                                if (nbs_has(complete->nbs, addr)) { -                                        free(children[i]); -                                        continue; -                                } - -                                if (connmgr_alloc(complete->ae, children[i], -                                                  &qs, &conn)) { -                                        log_warn("Failed conn to neighbor."); -                                        free(children[i]); -                                        continue; -                                } - -                                if (nbs_add(complete->nbs, conn)) { -                                        log_err("Failed to add neighbor."); -                                        free(children[i]); -                                        continue; -                                } -                        } - -                        free(children[i]); -                } - -                if (len > 0) -                        free(children); - -                nanosleep(&to, NULL); -        } - -        return (void *) 0; -} - -void * complete_create(struct nbs * nbs, -                       struct ae *  ae) -{ -        struct complete * complete; - -        complete = malloc(sizeof(*complete)); -        if (complete == NULL) -                return NULL; - -        complete->nbs = nbs; -        complete->ae = ae; - -        if (pthread_create(&complete->allocator, NULL, -                           allocator, (void *) complete)) -                return NULL; - -        if (pthread_create(&complete->listener, NULL, -                           listener, (void *) complete)) -                return NULL; - -        return complete; -} - -void complete_destroy(void * ops_o) -{ -        struct complete * complete; - -        assert(ops_o); - -        complete = (struct complete *) ops_o; - -        pthread_cancel(complete->allocator); -        pthread_cancel(complete->listener); -        pthread_join(complete->allocator, NULL); -        pthread_join(complete->listener, NULL); - -        free(complete); -} diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h deleted file mode 100644 index 54c4a9ef..00000000 --- a/src/ipcpd/normal/pol/complete.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Sets up a complete graph - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H -#define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H - -#include <ouroboros/ipcp.h> -#include <ouroboros/qos.h> - -#include "pol-gam-ops.h" - -void * complete_create(struct nbs * nbs, -                       struct ae *  ae); - -void   complete_destroy(void * ops_o); - -struct pol_gam_ops complete_ops = { -        .create   = complete_create, -        .destroy  = complete_destroy -}; - -#endif /* OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H */ diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index 1fece07f..7a5a785e 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -42,47 +42,21 @@  #define NAME_LEN 8  #define REC_DIF_SIZE 10000 -/* convert 32 bit addr to a hex string */ -static void addr_name(char *   name, -                      uint32_t addr) -{ -        sprintf(name, "%8x", (uint32_t) (addr)); -} - -static int addr_taken(char *  name, -                      char ** members, -                      size_t  len) -{ -        size_t i; -        char path[RIB_MAX_PATH_LEN + 1]; - -        size_t reset; -        strcpy(path, MEMBERS_PATH); - -        reset = strlen(path); - -        for (i = 0; i < len; ++i) { -                ssize_t j; -                ssize_t c; -                char ** addrs; -                rib_path_append(path, members[i]); -                c = rib_children(path, &addrs); -                for (j = 0; j < c; ++j) -                        if (strcmp(addrs[j], name) == 0) { -                                freepp(char, addrs, c); -                                return 1; -                        } -                freepp(char, addrs, c); -                path[reset] = '\0'; -        } - -        return 0; -} +struct { +        uint8_t addr_size; +} flat;  #define INVALID_ADDRESS 0 -int flat_init(void) +int flat_init(const void * info)  { +        flat.addr_size = *((uint8_t *) info); + +        if (flat.addr_size != 4) { +                log_err("Flat address policy mandates 4 byte addresses."); +                return -1; +        } +          return 0;  } @@ -94,66 +68,12 @@ int flat_fini(void)  uint64_t flat_address(void)  {          struct timespec t; - -        char path[RIB_MAX_PATH_LEN]; -        char name[NAME_LEN + 1]; -        uint32_t addr; -        uint8_t addr_size; - -        char ** members; -        ssize_t n_members; - -        strcpy(path, MEMBERS_PATH); - -        if (!rib_has(path)) { -                log_err("Could not read members from RIB."); -                return INVALID_ADDRESS; -        } - -        if (rib_read("/" BOOT_NAME "/dt/const/addr_size", -                     &addr_size, sizeof(addr_size)) != sizeof(addr_size)) { -                log_err("Failed to read address size."); -                return INVALID_ADDRESS; -        } - -        if (addr_size != 4) { -                log_err("Flat address policy mandates 4 byte addresses."); -                return INVALID_ADDRESS; -        } - -        n_members = rib_children(path, &members); -        if (n_members > REC_DIF_SIZE) -                log_warn("DIF exceeding recommended size for flat addresses."); - -        rib_path_append(path, ipcpi.name); - -        if (!rib_has(path)) { -                log_err("This ipcp is not a member."); -                freepp(char, members, n_members); -                return INVALID_ADDRESS; -        } +        uint32_t        addr;          clock_gettime(CLOCK_REALTIME, &t);          srand(t.tv_nsec); -        assert(n_members > 0); - -        do { -                addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF; -                addr_name(name, addr); -        } while (addr_taken(name, members, n_members)); - -        freepp(char, members, n_members); - -        if (rib_add(path, name)) { -                log_err("Failed to add address to RIB."); -                return INVALID_ADDRESS; -        } - -        if (rib_write(path, &addr, sizeof(addr))) { -                log_err("Failed to write address in RIB."); -                return INVALID_ADDRESS; -        } +        addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF;          return addr;  } diff --git a/src/ipcpd/normal/pol/flat.h b/src/ipcpd/normal/pol/flat.h index af49d283..57af591e 100644 --- a/src/ipcpd/normal/pol/flat.h +++ b/src/ipcpd/normal/pol/flat.h @@ -25,8 +25,10 @@  #include "pol-addr-auth-ops.h" -int      flat_init(void); +int      flat_init(const void * info); +  int      flat_fini(void); +  uint64_t flat_address(void);  struct pol_addr_auth_ops flat_ops = { diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c index 9dfed5c0..512ced7f 100644 --- a/src/ipcpd/normal/pol/link_state.c +++ b/src/ipcpd/normal/pol/link_state.c @@ -130,10 +130,6 @@ static int link_state_neighbor_event(enum nb_event event,          size_t    len;          uint8_t * data; -        /* Only announce the flow if our address is bigger */ -        if (ipcpi.dt_addr < conn.conn_info.addr) -                return 0; -          path[0] = '\0';          sprintf(fso_name, "%" PRIu64 "-%" PRIu64,                  ipcpi.dt_addr, conn.conn_info.addr); @@ -305,42 +301,42 @@ int link_state_init(struct nbs * nbs)  {          link_state.graph = graph_create();          if (link_state.graph == NULL) -                return -1; +                goto fail_graph; -        if (rib_add(RIB_ROOT, ROUTING_NAME)) { -                graph_destroy(link_state.graph); -                return -1; -        } +        if (rib_add(RIB_ROOT, ROUTING_NAME)) +                goto fail_rib_add;          link_state.nbs = nbs;          link_state.nb_notifier.notify_call = link_state_neighbor_event; -        if (nbs_reg_notifier(link_state.nbs, &link_state.nb_notifier)) { -                graph_destroy(link_state.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } +        if (nbs_reg_notifier(link_state.nbs, &link_state.nb_notifier)) +                goto fail_nbs_reg_notifier;          link_state.set = ro_set_create(); -        if (link_state.set == NULL) { -                nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); -                graph_destroy(link_state.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } +        if (link_state.set == NULL) +                goto fail_ro_set_create;          link_state.queue = rqueue_create(); -        if (link_state.queue == NULL) { -                ro_set_destroy(link_state.set); -                nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); -                graph_destroy(link_state.graph); -                rib_del(ROUTING_PATH); -                return -1; -        } +        if (link_state.queue == NULL) +                goto fail_rqueue_create; -        pthread_create(&link_state.rib_listener, NULL, rib_listener, NULL); +        if (pthread_create(&link_state.rib_listener, NULL, rib_listener, NULL)) +                goto fail_listener_create;          return 0; + + fail_listener_create: +        ro_set_destroy(link_state.set); + fail_rqueue_create: +        ro_set_destroy(link_state.set); + fail_ro_set_create: +        nbs_unreg_notifier(link_state.nbs, &link_state.nb_notifier); + fail_nbs_reg_notifier: +        rib_del(ROUTING_PATH); + fail_rib_add: +        graph_destroy(link_state.graph); + fail_graph: +        return -1;  }  void link_state_fini(void) diff --git a/src/ipcpd/normal/ribconfig.h b/src/ipcpd/normal/ribconfig.h index 3a9b6ecb..f6d10133 100644 --- a/src/ipcpd/normal/ribconfig.h +++ b/src/ipcpd/normal/ribconfig.h @@ -27,11 +27,7 @@  #define RIB_MAX_PATH_LEN 256  #define DLR          "/" -#define BOOT_NAME    "boot" -#define MEMBERS_NAME "members"  #define ROUTING_NAME "fsdb" -#define BOOT_PATH    DLR BOOT_NAME -#define MEMBERS_PATH DLR MEMBERS_NAME  #define ROUTING_PATH DLR ROUTING_NAME  #endif /* OUROBOROS_IPCPD_NORMAL_RIB_CONFIG_H */ diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index ab2aa430..a5e7d6ce 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -35,10 +35,11 @@  #include <ouroboros/rib.h>  #include "ae.h" -#include "gam.h" +#include "connmgr.h" +#include "ipcp.h" +#include "neighbors.h"  #include "ribconfig.h"  #include "ribmgr.h" -#include "ipcp.h"  #include <stdlib.h>  #include <pthread.h> @@ -46,10 +47,12 @@  #include <errno.h>  #include <assert.h> +#define MGMT_AE          "Management"  #define RIB_SYNC_TIMEOUT 1  enum ribmgr_state {          RIBMGR_NULL = 0, +        RIBMGR_INIT,          RIBMGR_OPERATIONAL,          RIBMGR_SHUTDOWN  }; @@ -60,7 +63,6 @@ struct {          pthread_t          reader;          pthread_t          sync; -        struct gam *       gam;          struct nbs *       nbs;          struct ae *        ae; @@ -300,9 +302,8 @@ static void * sync_rib(void *o)                          rib_path_append(path, children[--ch]);                          free(children[ch]); -                        /* Only sync fsdb and members */ -                        if (strcmp(path, MEMBERS_PATH) == 0 -                            || strcmp(path, ROUTING_PATH) == 0) +                        /* Sync fsdb */ +                        if (strcmp(path, ROUTING_PATH) == 0)                                  ribmgr_sync(path);                  } @@ -314,7 +315,6 @@ static void * sync_rib(void *o)  int ribmgr_init(void)  { -        enum pol_gam     pg;          struct conn_info info;          memset(&info, 0, sizeof(info)); @@ -323,82 +323,90 @@ int ribmgr_init(void)          strcpy(info.protocol, CDAP_PROTO);          info.pref_version = 1;          info.pref_syntax = PROTO_GPB; -        /* NOTE: Use the same name as the DT AE of this IPCP */ -        info.addr = ipcpi.dt_addr; +        info.addr = 0;          ribmgr.nbs = nbs_create();          if (ribmgr.nbs == NULL) {                  log_err("Failed to create neighbors."); -                return -1; -        } - -        ribmgr.ae = connmgr_ae_create(info); -        if (ribmgr.ae == NULL) { -                log_err("Failed to create AE struct."); -                nbs_destroy(ribmgr.nbs); -                return -1; +                goto fail_nbs_create;          } -        if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg)) -            != sizeof(pg)) { -                log_err("Failed to read policy for ribmgr gam."); -                connmgr_ae_destroy(ribmgr.ae); -                nbs_destroy(ribmgr.nbs); -                return -1; -        } +        if (connmgr_ae_init(AEID_MGMT, &info, ribmgr.nbs)) { +                log_err("Failed to register with connmgr."); +                goto fail_connmgr_ae_init; +        };          ribmgr.cdap = cdap_create();          if (ribmgr.cdap == NULL) {                  log_err("Failed to create CDAP instance."); -                connmgr_ae_destroy(ribmgr.ae); -                nbs_destroy(ribmgr.nbs); -                return -1; +                goto fail_cdap_create;          }          ribmgr.nb_notifier.notify_call = ribmgr_neighbor_event;          if (nbs_reg_notifier(ribmgr.nbs, &ribmgr.nb_notifier)) {                  log_err("Failed to register notifier."); -                cdap_destroy(ribmgr.cdap); -                connmgr_ae_destroy(ribmgr.ae); -                nbs_destroy(ribmgr.nbs); -                return -1; +                goto fail_nbs_reg_notifier;          } -        ribmgr.gam = gam_create(pg, ribmgr.nbs, ribmgr.ae); -        if (ribmgr.gam == NULL) { -                log_err("Failed to create gam."); -                nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier); -                cdap_destroy(ribmgr.cdap); -                connmgr_ae_destroy(ribmgr.ae); -                nbs_destroy(ribmgr.nbs); -                return -1; +        if (pthread_rwlock_init(&ribmgr.state_lock, NULL)) { +                log_err("Failed to init rwlock."); +                goto fail_rwlock_init;          } -        pthread_rwlock_init(&ribmgr.state_lock, NULL); - -        ribmgr.state = RIBMGR_OPERATIONAL; - -        pthread_create(&ribmgr.sync, NULL, sync_rib, NULL); - -        pthread_create(&ribmgr.reader, NULL, reader, NULL); +        ribmgr.state = RIBMGR_INIT;          return 0; + + fail_rwlock_init: +        nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier); + fail_nbs_reg_notifier: +        cdap_destroy(ribmgr.cdap); + fail_cdap_create: +        connmgr_ae_fini(AEID_MGMT); + fail_connmgr_ae_init: +        nbs_destroy(ribmgr.nbs); + fail_nbs_create: +        return -1;  }  void ribmgr_fini(void)  { -        ribmgr_set_state(RIBMGR_SHUTDOWN); - -        pthread_cancel(ribmgr.reader); - -        pthread_join(ribmgr.reader, NULL); -        pthread_join(ribmgr.sync, NULL); +        if (ribmgr_get_state() == RIBMGR_SHUTDOWN) { +                pthread_join(ribmgr.reader, NULL); +                pthread_join(ribmgr.sync, NULL); +        }          nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier);          cdap_destroy(ribmgr.cdap); -        gam_destroy(ribmgr.gam); -        connmgr_ae_destroy(ribmgr.ae);          nbs_destroy(ribmgr.nbs); + +        connmgr_ae_fini(AEID_MGMT); +} + +int ribmgr_start(void) +{ +        ribmgr_set_state(RIBMGR_OPERATIONAL); + +        if (pthread_create(&ribmgr.sync, NULL, sync_rib, NULL)) { +                ribmgr_set_state(RIBMGR_NULL); +                return -1; +        } + +        if (pthread_create(&ribmgr.reader, NULL, reader, NULL)) { +                ribmgr_set_state(RIBMGR_SHUTDOWN); +                pthread_cancel(ribmgr.reader); +                return -1; +        } + +        return 0; +} + +void ribmgr_stop(void) +{ +        if (ribmgr_get_state() == RIBMGR_OPERATIONAL) { +                ribmgr_set_state(RIBMGR_SHUTDOWN); +                pthread_cancel(ribmgr.reader); +        }  }  int ribmgr_disseminate(char *           path, diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 7411aedd..20f87548 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -42,6 +42,10 @@ int  ribmgr_init(void);  void ribmgr_fini(void); +int  ribmgr_start(void); + +void ribmgr_stop(void); +  int  ribmgr_disseminate(char *           path,                          enum diss_target target,                          enum diss_freq   freq, diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c index c00ec67c..04e6fd76 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -29,36 +29,35 @@  #include "routing.h"  #include "pol/link_state.h" -struct { -        struct pol_routing_ops * ops; -} routing; + +struct pol_routing_ops * r_ops;  int routing_init(enum pol_routing pr,                   struct nbs *     nbs)  {          switch (pr) {          case LINK_STATE: -                routing.ops = &link_state_ops; +                r_ops = &link_state_ops;                  break;          default:                  log_err("Unknown routing type.");                  return -1;          } -        return routing.ops->init(nbs); +        return r_ops->init(nbs);  }  struct routing_i * routing_i_create(struct pff * pff)  { -        return routing.ops->routing_i_create(pff); +        return r_ops->routing_i_create(pff);  }  void routing_i_destroy(struct routing_i * instance)  { -        return routing.ops->routing_i_destroy(instance); +        return r_ops->routing_i_destroy(instance);  }  void routing_fini(void)  { -        routing.ops->fini(); +        r_ops->fini();  } diff --git a/src/ipcpd/normal/sdu_sched.c b/src/ipcpd/normal/sdu_sched.c index f3550d5c..10b0f02f 100644 --- a/src/ipcpd/normal/sdu_sched.c +++ b/src/ipcpd/normal/sdu_sched.c @@ -117,6 +117,8 @@ struct sdu_sched * sdu_sched_create(next_sdu_t callback)          if (sdu_sched == NULL)                  goto fail_malloc; +        assert(callback); +          sdu_sched->callback = callback;          for (i = 0; i < QOS_CUBE_MAX; ++i) { @@ -170,6 +172,8 @@ void sdu_sched_add(struct sdu_sched * sdu_sched,  {          qoscube_t qc; +        assert(sdu_sched); +          ipcp_flow_get_qoscube(fd, &qc);          flow_set_add(sdu_sched->set[qc], fd);  } @@ -179,6 +183,8 @@ void sdu_sched_del(struct sdu_sched * sdu_sched,  {          qoscube_t qc; +        assert(sdu_sched); +          ipcp_flow_get_qoscube(fd, &qc);          flow_set_del(sdu_sched->set[qc], fd);  } diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index bcf5abe2..3d186d7a 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -1216,6 +1216,8 @@ static int eth_llc_ipcp_flow_dealloc(int fd)  static struct ipcp_ops eth_llc_ops = {          .ipcp_bootstrap       = eth_llc_ipcp_bootstrap,          .ipcp_enroll          = NULL, +        .ipcp_connect         = NULL, +        .ipcp_disconnect      = NULL,          .ipcp_reg             = eth_llc_ipcp_reg,          .ipcp_unreg           = eth_llc_ipcp_unreg,          .ipcp_query           = eth_llc_ipcp_query, diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 55fe19a6..0bf57741 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -1092,7 +1092,9 @@ static int ipcp_udp_flow_dealloc(int fd)  static struct ipcp_ops udp_ops = {          .ipcp_bootstrap       = ipcp_udp_bootstrap, -        .ipcp_enroll          = NULL,                       /* shim */ +        .ipcp_enroll          = NULL, +        .ipcp_connect         = NULL, +        .ipcp_disconnect      = NULL,          .ipcp_reg             = ipcp_udp_reg,          .ipcp_unreg           = ipcp_udp_unreg,          .ipcp_query           = ipcp_udp_query, | 
