diff options
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, |