diff options
Diffstat (limited to 'src')
144 files changed, 3032 insertions, 1551 deletions
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index 9c77683a..00baa762 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,14 +1,14 @@ set(IPCP_SOURCES - # Add source files here - ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c - ${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c - ${CMAKE_CURRENT_SOURCE_DIR}/timerwheel.c -) + # Add source files here + ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c + ${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c + ${CMAKE_CURRENT_SOURCE_DIR}/timerwheel.c + ) add_subdirectory(local) add_subdirectory(normal) add_subdirectory(shim-udp) -if(NOT APPLE) +if (NOT APPLE) add_subdirectory(shim-eth-llc) -endif() +endif () add_subdirectory(tests) diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 19b3a721..8646121a 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -3,7 +3,8 @@ * * IPC process main loop * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -191,7 +192,6 @@ static void * ipcp_main_loop(void * o) ret_msg.result = ipcpi.ops->ipcp_flow_alloc(fd, msg->dst_name, - msg->src_ae_name, msg->qoscube); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index de7d72b0..a64ab65c 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -3,7 +3,8 @@ * * IPC process structure * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -50,7 +51,6 @@ struct ipcp_ops { int (* ipcp_flow_alloc)(int fd, char * dst_ap_name, - char * src_ae_name, qoscube_t qos); int (* ipcp_flow_alloc_resp)(int fd, @@ -66,7 +66,7 @@ struct ipcp { enum ipcp_type type; char * dif_name; - uint64_t address; + uint64_t dt_addr; struct ipcp_ops * ops; int irmd_fd; diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt index cc19aad0..824b4ca6 100644 --- a/src/ipcpd/local/CMakeLists.txt +++ b/src/ipcpd/local/CMakeLists.txt @@ -12,18 +12,18 @@ include_directories(${CURRENT_BINARY_PARENT_DIR}) include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) -SET(IPCP_LOCAL_TARGET ipcpd-local CACHE STRING "IPCP_LOCAL") +set(IPCP_LOCAL_TARGET ipcpd-local CACHE STRING "IPCP_LOCAL") set(SHIM_LOCAL_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-local ${SHIM_LOCAL_SOURCES} ${IPCP_SOURCES}) -target_link_libraries (ipcpd-local LINK_PUBLIC ouroboros) +add_executable(ipcpd-local ${SHIM_LOCAL_SOURCES} ${IPCP_SOURCES}) +target_link_libraries(ipcpd-local LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-local -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-local -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-local RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index edb22be6..38a901c0 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -3,7 +3,8 @@ * * Local IPC process * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -220,7 +221,6 @@ static int ipcp_local_name_query(char * name) static int ipcp_local_flow_alloc(int fd, char * dst_name, - char * src_ae_name, qoscube_t cube) { int out_fd = -1; @@ -228,7 +228,6 @@ static int ipcp_local_flow_alloc(int fd, log_dbg("Allocating flow to %s on fd %d.", dst_name, fd); assert(dst_name); - assert(src_ae_name); pthread_rwlock_rdlock(&ipcpi.state_lock); @@ -240,7 +239,7 @@ static int ipcp_local_flow_alloc(int fd, pthread_rwlock_wrlock(&local_data.lock); - out_fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); + out_fd = ipcp_flow_req_arr(getpid(), dst_name, cube); if (out_fd < 0) { log_dbg("Flow allocation failed."); pthread_rwlock_unlock(&local_data.lock); diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index f2e48cbc..06292c50 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -14,33 +14,37 @@ include_directories(${CMAKE_BINARY_DIR}/include) set(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET") -protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS - flow_alloc.proto) +protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto) +protobuf_generate_c(FSO_SRCS FSO_HDRS fso.proto) set(SOURCE_FILES # Add source files here addr_auth.c + connmgr.c dir.c enroll.c fmgr.c frct.c gam.c + graph.c main.c + neighbors.c pff.c ribmgr.c + routing.c shm_pci.c # Add policies last pol/complete.c pol/flat.c ) -add_executable (ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} - ${FLOW_ALLOC_SRCS}) -target_link_libraries (ipcpd-normal LINK_PUBLIC ouroboros) +add_executable(ipcpd-normal ${SOURCE_FILES} ${IPCP_SOURCES} + ${FLOW_ALLOC_SRCS} ${FSO_SRCS}) +target_link_libraries(ipcpd-normal LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - macro_add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-normal -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index 210744af..5b3c6170 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -3,7 +3,8 @@ * * Address authority * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -25,47 +26,36 @@ #include <ouroboros/logs.h> #include "addr_auth.h" +#include "pol-addr-auth-ops.h" #include "pol/flat.h" #include <stdlib.h> #include <assert.h> -struct addr_auth * addr_auth_create(enum pol_addr_auth type) -{ - struct addr_auth * tmp; - - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) { - log_err("Failed to malloc addr auth."); - return NULL; - } +struct addr_auth { + struct pol_addr_auth_ops * ops; +} addr_auth; +int addr_auth_init(enum pol_addr_auth type) +{ switch (type) { case FLAT_RANDOM: - tmp->address = flat_address; - tmp->type = type; + addr_auth.ops = &flat_ops; break; default: log_err("Unknown address authority type."); - free(tmp); - return NULL; + return -1; } - return tmp; + return addr_auth.ops->init(); } -int addr_auth_destroy(struct addr_auth * instance) +uint64_t addr_auth_address(void) { - assert(instance); - - switch (instance->type) { - case FLAT_RANDOM: - break; - default: - log_err("Unknown address authority type."); - } - - free(instance); + return addr_auth.ops->address(); +} - return 0; +int addr_auth_fini(void) +{ + return addr_auth.ops->fini(); } diff --git a/src/ipcpd/normal/addr_auth.h b/src/ipcpd/normal/addr_auth.h index 8d67bc66..fbe7d790 100644 --- a/src/ipcpd/normal/addr_auth.h +++ b/src/ipcpd/normal/addr_auth.h @@ -3,7 +3,8 @@ * * Address authority * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -26,13 +27,10 @@ #include <stdint.h> -struct addr_auth { - enum pol_addr_auth type; - uint64_t (* address)(void); -}; +int addr_auth_init(enum pol_addr_auth type); -struct addr_auth * addr_auth_create(enum pol_addr_auth type); +int addr_auth_fini(void); -int addr_auth_destroy(struct addr_auth * instance); +uint64_t addr_auth_address(void); #endif /* OUROBOROS_IPCPD_NORMAL_ADDR_AUTH_H */ diff --git a/src/ipcpd/normal/ae.h b/src/ipcpd/normal/ae.h index 882625dd..aafef625 100644 --- a/src/ipcpd/normal/ae.h +++ b/src/ipcpd/normal/ae.h @@ -3,8 +3,8 @@ * * Application Entities for the normal IPC process * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c new file mode 100644 index 00000000..b97d2b23 --- /dev/null +++ b/src/ipcpd/normal/connmgr.c @@ -0,0 +1,358 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Handles AE connections + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "normal-ipcp" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/dev.h> +#include <ouroboros/cacep.h> +#include <ouroboros/cdap.h> +#include <ouroboros/errno.h> + +#include "ae.h" +#include "connmgr.h" +#include "enroll.h" +#include "fmgr.h" +#include "frct.h" +#include "ipcp.h" +#include "ribmgr.h" + +#include <pthread.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +struct ae_conn { + struct list_head next; + struct conn conn; +}; + +struct ae { + struct list_head next; + struct conn_info info; + + struct list_head conn_list; + pthread_cond_t conn_cond; + pthread_mutex_t conn_lock; +}; + +struct { + pthread_t acceptor; + + struct list_head aes; + pthread_mutex_t aes_lock; +} connmgr; + +static int add_ae_conn(struct ae * ae, + int fd, + qosspec_t qs, + struct conn_info * rcv_info) +{ + struct ae_conn * ae_conn = NULL; + + ae_conn = malloc(sizeof(*ae_conn)); + if (ae_conn == 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; + + list_head_init(&ae_conn->next); + + 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); + + return 0; +} + +static struct ae * find_ae_by_name(char * name) +{ + struct list_head * p = NULL; + + list_for_each(p, &connmgr.aes) { + struct ae * ae = list_entry(p, struct ae, next); + if (strcmp(ae->info.ae_name, name) == 0) + return ae; + } + + return NULL; +} + +static void * flow_acceptor(void * o) +{ + int fd; + qosspec_t qs; + struct conn_info rcv_info; + struct conn_info fail_info; + struct ae * ae = NULL; + + (void) o; + + memset(&fail_info, 0, sizeof(fail_info)); + + while (true) { + pthread_rwlock_rdlock(&ipcpi.state_lock); + + if (ipcp_get_state() != IPCP_OPERATIONAL) { + pthread_rwlock_unlock(&ipcpi.state_lock); + log_info("Shutting down flow acceptor."); + return 0; + } + + pthread_rwlock_unlock(&ipcpi.state_lock); + + fd = flow_accept(&qs); + if (fd < 0) { + if (fd != -EIRMD) + log_warn("Flow accept failed: %d", fd); + continue; + } + + if (flow_alloc_resp(fd, 0)) { + log_err("Failed to respond to flow alloc request."); + continue; + } + + if (cacep_rcv(fd, &rcv_info)) { + log_err("Error establishing application connection."); + flow_dealloc(fd); + continue; + } + + pthread_mutex_lock(&connmgr.aes_lock); + ae = find_ae_by_name(rcv_info.ae_name); + pthread_mutex_unlock(&connmgr.aes_lock); + + if (ae != NULL) { + if (cacep_snd(fd, &ae->info)) { + log_err("Failed to respond to req."); + flow_dealloc(fd); + continue; + } + + if (add_ae_conn(ae, fd, qs, &rcv_info)) { + log_err("Failed to add ae conn."); + flow_dealloc(fd); + continue; + } + } else { + cacep_snd(fd, &fail_info); + flow_dealloc(fd); + } + } + + return (void *) 0; +} + +int connmgr_init(void) +{ + list_head_init(&connmgr.aes); + + if (pthread_mutex_init(&connmgr.aes_lock, NULL)) + return -1; + + return 0; +} + +int connmgr_start(void) +{ + pthread_create(&connmgr.acceptor, NULL, flow_acceptor, NULL); + + return 0; +} + +void connmgr_stop(void) +{ + pthread_cancel(connmgr.acceptor); + pthread_join(connmgr.acceptor, NULL); +} + +static void destroy_ae(struct ae * ae) +{ + struct list_head * p = NULL; + struct list_head * h = NULL; + + pthread_mutex_lock(&ae->conn_lock); + + 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); + } + + pthread_mutex_unlock(&ae->conn_lock); + + pthread_cond_destroy(&ae->conn_cond); + pthread_mutex_destroy(&ae->conn_lock); + + free(ae); +} + +void connmgr_fini(void) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + pthread_mutex_lock(&connmgr.aes_lock); + + list_for_each_safe(p, n, &connmgr.aes) { + struct ae * e = list_entry(p, struct ae, next); + list_del(&e->next); + destroy_ae(e); + } + + pthread_mutex_unlock(&connmgr.aes_lock); + + pthread_mutex_destroy(&connmgr.aes_lock); +} + +struct ae * connmgr_ae_create(struct conn_info info) +{ + struct ae * ae; + + ae = malloc(sizeof(*ae)); + if (ae == NULL) + return NULL; + + list_head_init(&ae->next); + list_head_init(&ae->conn_list); + + ae->info = info; + + if (pthread_mutex_init(&ae->conn_lock, NULL)) { + free(ae); + return NULL; + } + + if (pthread_cond_init(&ae->conn_cond, NULL)) { + pthread_mutex_destroy(&ae->conn_lock); + free(ae); + return NULL; + } + + pthread_mutex_lock(&connmgr.aes_lock); + list_add(&ae->next, &connmgr.aes); + pthread_mutex_unlock(&connmgr.aes_lock); + + return ae; +} + +void connmgr_ae_destroy(struct ae * ae) +{ + assert(ae); + + pthread_mutex_lock(&connmgr.aes_lock); + + list_del(&ae->next); + + destroy_ae(ae); + + pthread_mutex_unlock(&connmgr.aes_lock); +} + +int connmgr_alloc(struct ae * ae, + char * dst_name, + qosspec_t * qs, + struct conn * conn) +{ + assert(ae); + assert(dst_name); + assert(conn); + + memset(&conn->conn_info, 0, sizeof(conn->conn_info)); + + conn->flow_info.fd = flow_alloc(dst_name, qs); + if (conn->flow_info.fd < 0) { + log_err("Failed to allocate flow to %s.", dst_name); + return -1; + } + + if (qs != NULL) + conn->flow_info.qs = *qs; + else + memset(&conn->flow_info.qs, 0, sizeof(conn->flow_info.qs)); + + if (flow_alloc_res(conn->flow_info.fd)) { + log_err("Flow allocation to %s failed.", dst_name); + flow_dealloc(conn->flow_info.fd); + return -1; + } + + if (cacep_snd(conn->flow_info.fd, &ae->info)) { + log_err("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."); + 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) { + flow_dealloc(conn->flow_info.fd); + return -1; + } + + return 0; +} + +int connmgr_wait(struct ae * ae, + struct conn * conn) +{ + struct ae_conn * ae_conn; + + assert(ae); + assert(conn); + + pthread_mutex_lock(&ae->conn_lock); + + pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, + (void *) &ae->conn_lock); + + while (list_is_empty(&ae->conn_list)) + pthread_cond_wait(&ae->conn_cond, &ae->conn_lock); + + ae_conn = list_first_entry((&ae->conn_list), struct ae_conn, next); + if (ae_conn == NULL) { + pthread_mutex_unlock(&ae->conn_lock); + return -1; + } + + *conn = ae_conn->conn; + + list_del(&ae_conn->next); + free(ae_conn); + + pthread_cleanup_pop(true); + + return 0; +} diff --git a/src/ipcpd/normal/connmgr.h b/src/ipcpd/normal/connmgr.h new file mode 100644 index 00000000..c0356f6d --- /dev/null +++ b/src/ipcpd/normal/connmgr.h @@ -0,0 +1,57 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Handles the different AP connections + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_CONNMGR_H +#define OUROBOROS_IPCPD_NORMAL_CONNMGR_H + +#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; +}; + +int connmgr_init(void); + +void connmgr_fini(void); + +int connmgr_start(void); + +void connmgr_stop(void); + +struct ae * connmgr_ae_create(struct conn_info info); + +void connmgr_ae_destroy(struct ae * ae); + +int connmgr_alloc(struct ae * ae, + char * dst_name, + qosspec_t * qs, + struct conn * conn); + +int connmgr_wait(struct ae * ae, + struct conn * conn); + +#endif /* OUROBOROS_IPCPD_NORMAL_CONNMGR_H */ diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index 55d6e3f6..ae9793c6 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -3,8 +3,8 @@ * * DIF directory * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/normal/dir.h b/src/ipcpd/normal/dir.h index 925fc823..04e722f3 100644 --- a/src/ipcpd/normal/dir.h +++ b/src/ipcpd/normal/dir.h @@ -3,7 +3,8 @@ * * DIF directory * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/normal/dt_const.h b/src/ipcpd/normal/dt_const.h index c94e9395..327f51b8 100644 --- a/src/ipcpd/normal/dt_const.h +++ b/src/ipcpd/normal/dt_const.h @@ -3,8 +3,8 @@ * * Data Transfer Constants for the IPCP * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index bc5d2a20..7e15be11 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -3,7 +3,8 @@ * * Enrollment Task * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -22,27 +23,37 @@ #include <ouroboros/config.h> #include <ouroboros/endian.h> -#include <ouroboros/time_utils.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 "ribconfig.h" #include <assert.h> #include <stdlib.h> #include <string.h> +#include <pthread.h> /* Symbolic, will return current time */ #define TIME_NAME "localtime" #define TIME_PATH DLR TIME_NAME #define ENROLL_WARN_TIME_OFFSET 20 -int enroll_handle(int fd) +struct { + struct ae * ae; + pthread_t listener; +} enroll; + +static void * enroll_handle(void * o) { - struct cdap * ci; + struct cdap * cdap; + struct conn conn; cdap_key_t key; enum cdap_opcode oc; char * name; @@ -59,103 +70,105 @@ int enroll_handle(int fd) char * members_ro = MEMBERS_PATH; char * dif_ro = DIF_PATH; - if (flow_alloc_resp(fd, 0) < 0) { - flow_dealloc(fd); - log_err("Could not respond to request."); - return -1; - } - - ci = cdap_create(fd); - if (ci == NULL) { - flow_dealloc(fd); - log_err("Failed to create CDAP instance."); - return -1; - } - - while (!(boot_r && members_r && dif_name_r)) { - key = cdap_request_wait(ci, &oc, &name, &data, - (size_t *) &len , &flags); - assert(key >= 0); - assert(name); + (void) o; - if (data != NULL) { - free(data); - log_warn("Received data with enrollment request."); + while (true) { + cdap = cdap_create(); + if (cdap == NULL) { + log_err("Failed to instantiate CDAP."); + continue; } - if (oc != CDAP_READ) { - log_warn("Invalid request."); - cdap_reply_send(ci, key, -1, NULL, 0); - cdap_destroy(ci); - flow_dealloc(fd); - free(name); - return -1; + if (connmgr_wait(enroll.ae, &conn)) { + log_err("Failed to get next connection."); + cdap_destroy(cdap); + continue; } - if (strcmp(name, boot_ro) == 0) { - boot_r = true; - } else if (strcmp(name, members_ro) == 0) { - members_r = true; - } else if (strcmp(name, dif_ro) == 0) { - dif_name_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(ci, key, 0, buf, sizeof(buf)); - free(name); + 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); continue; - } else { - log_warn("Illegal read: %s.", name); - cdap_reply_send(ci, key, -1, NULL, 0); - cdap_destroy(ci); - flow_dealloc(fd); - free(name); - return -1; } - len = rib_pack(name, &buf, PACK_HASH_ROOT); - if (len < 0) { - log_err("Failed to pack %s.", name); - cdap_reply_send(ci, key, -1, NULL, 0); - cdap_destroy(ci); - flow_dealloc(fd); - free(name); - return -1; - } + while (!(boot_r && members_r && dif_name_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, dif_ro) == 0) { + dif_name_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); - log_dbg("Packed %s (%zu bytes).", name, len); + free(name); - free(name); + if (cdap_reply_send(cdap, key, 0, buf, len)) { + log_err("Failed to send CDAP reply."); + free(buf); + continue; + } - if (cdap_reply_send(ci, key, 0, buf, len)) { - log_err("Failed to send CDAP reply."); - cdap_destroy(ci); - flow_dealloc(fd); - return -1; + free(buf); } - free(buf); - } + log_dbg("Sent boot info to new member."); - log_dbg("Sent boot info to new member."); - - cdap_destroy(ci); - - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + } return 0; } int enroll_boot(char * dst_name) { - struct cdap * ci; - cdap_key_t key; + struct cdap * cdap; + cdap_key_t * key; uint8_t * data; size_t len; - int fd; + struct conn conn; struct timespec t0; struct timespec rtt; @@ -166,22 +179,22 @@ int enroll_boot(char * dst_name) char * members_ro = MEMBERS_PATH; char * dif_ro = DIF_PATH; - fd = flow_alloc(dst_name, ENROLL_AE, NULL); - if (fd < 0) { - log_err("Failed to allocate flow."); + cdap = cdap_create(); + if (cdap == NULL) { + log_err("Failed to instantiate CDAP."); return -1; } - if (flow_alloc_res(fd)) { - log_err("Flow allocation failed."); - flow_dealloc(fd); + if (connmgr_alloc(enroll.ae, dst_name, NULL, &conn)) { + log_err("Failed to get connection."); + cdap_destroy(cdap); return -1; } - ci = cdap_create(fd); - if (ci == NULL) { - log_err("Failed to create CDAP instance."); - flow_dealloc(fd); + 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; } @@ -189,26 +202,29 @@ int enroll_boot(char * dst_name) clock_gettime(CLOCK_REALTIME, &t0); - key = cdap_request_send(ci, CDAP_READ, TIME_PATH, NULL, 0, 0); - if (key < 0) { + key = cdap_request_send(cdap, CDAP_READ, TIME_PATH, NULL, 0, 0); + if (key == NULL) { log_err("Failed to send CDAP request."); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key[0], &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_destroy(ci); - flow_dealloc(fd); + free(key); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } + free(key); + clock_gettime(CLOCK_REALTIME, &rtt); delta_t = ts_diff_ms(&t0, &rtt); - assert (len == 2 * sizeof (uint64_t)); + assert(len == 2 * sizeof (uint64_t)); rtt.tv_sec = ntoh64(((uint64_t *) data)[0]); rtt.tv_nsec = ntoh64(((uint64_t *) data)[1]); @@ -218,93 +234,138 @@ int enroll_boot(char * dst_name) free(data); - key = cdap_request_send(ci, CDAP_READ, boot_ro, NULL, 0, 0); - if (key < 0) { + key = cdap_request_send(cdap, CDAP_READ, boot_ro, NULL, 0, 0); + if (key == NULL) { log_err("Failed to send CDAP request."); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key[0], &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_destroy(ci); - flow_dealloc(fd); + free(key); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } + free(key); + log_dbg("Packed information received (%zu bytes).", len); if (rib_unpack(data, len, UNPACK_CREATE)) { log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - key = cdap_request_send(ci, CDAP_READ, members_ro, NULL, 0, 0); - if (key < 0) { + key = cdap_request_send(cdap, CDAP_READ, members_ro, NULL, 0, 0); + if (key == NULL) { log_err("Failed to send CDAP request."); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key[0], &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_destroy(ci); - flow_dealloc(fd); + free(key); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } + free(key); + log_dbg("Packed information received (%zu bytes).", len); if (rib_unpack(data, len, UNPACK_CREATE)) { log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - key = cdap_request_send(ci, CDAP_READ, dif_ro, NULL, 0, 0); - if (key < 0) { + key = cdap_request_send(cdap, CDAP_READ, dif_ro, NULL, 0, 0); + if (key == NULL) { log_err("Failed to send CDAP request."); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } - if (cdap_reply_wait(ci, key, &data, &len)) { + if (cdap_reply_wait(cdap, key[0], &data, &len)) { log_err("Failed to get CDAP reply."); - cdap_destroy(ci); - flow_dealloc(fd); + free(key); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } + free(key); + log_dbg("Packed information received (%zu bytes).", len); if (rib_unpack(data, len, UNPACK_CREATE)) { log_warn("Error unpacking RIB data."); rib_del(boot_ro); free(data); - cdap_destroy(ci); - flow_dealloc(fd); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); return -1; } log_dbg("Packed information inserted into RIB."); - cdap_destroy(ci); + cdap_destroy(cdap); + flow_dealloc(conn.flow_info.fd); + + return 0; +} + +int enroll_init(void) +{ + struct conn_info info; + + memset(&info, 0, sizeof(info)); + + strcpy(info.ae_name, ENROLL_AE); + strcpy(info.protocol, CDAP_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_GPB; + + enroll.ae = connmgr_ae_create(info); + if (enroll.ae == NULL) + return -1; + + return 0; +} - flow_dealloc(fd); +void enroll_fini(void) +{ + connmgr_ae_destroy(enroll.ae); +} + +int enroll_start(void) +{ + if (pthread_create(&enroll.listener, NULL, enroll_handle, NULL)) + return -1; return 0; } + +void enroll_stop(void) +{ + pthread_cancel(enroll.listener); + pthread_join(enroll.listener, NULL); +} diff --git a/src/ipcpd/normal/enroll.h b/src/ipcpd/normal/enroll.h index 2980c380..05f950ba 100644 --- a/src/ipcpd/normal/enroll.h +++ b/src/ipcpd/normal/enroll.h @@ -3,7 +3,8 @@ * * Enrollment Task * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -22,8 +23,14 @@ #ifndef OUROBOROS_IPCPD_NORMAL_ENROLL_H #define OUROBOROS_IPCPD_NORMAL_ENROLL_H -int enroll_handle(int fd); +int enroll_init(void); -int enroll_boot(char * dst_name); +void enroll_fini(void); + +int enroll_start(void); + +void enroll_stop(void); + +int enroll_boot(char * dst_name); #endif /* OUROBOROS_IPCPD_NORMAL_ENROLL_H */ diff --git a/src/ipcpd/normal/flow_alloc.proto b/src/ipcpd/normal/flow_alloc.proto index 16e8be2c..3b08f047 100644 --- a/src/ipcpd/normal/flow_alloc.proto +++ b/src/ipcpd/normal/flow_alloc.proto @@ -31,7 +31,6 @@ enum flow_alloc_code { message flow_alloc_msg { required flow_alloc_code code = 1; optional string dst_name = 2; - optional string src_ae_name = 3; - optional uint32 qoscube = 4; - optional sint32 response = 5; + optional uint32 qoscube = 3; + optional sint32 response = 4; }; diff --git a/src/ipcpd/normal/fmgr.c b/src/ipcpd/normal/fmgr.c index c2b53abf..790b34dd 100644 --- a/src/ipcpd/normal/fmgr.c +++ b/src/ipcpd/normal/fmgr.c @@ -3,7 +3,8 @@ * * Flow manager of the IPC Process * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -31,12 +32,16 @@ #include <ouroboros/cacep.h> #include <ouroboros/rib.h> +#include "connmgr.h" #include "fmgr.h" #include "frct.h" #include "ipcp.h" #include "shm_pci.h" -#include "gam.h" #include "ribconfig.h" +#include "pff.h" +#include "neighbors.h" +#include "gam.h" +#include "routing.h" #include <stdlib.h> #include <stdbool.h> @@ -48,19 +53,7 @@ typedef FlowAllocMsg flow_alloc_msg_t; #define FD_UPDATE_TIMEOUT 100000 /* nanoseconds */ -struct nm1_flow { - struct list_head next; - int fd; - qosspec_t qs; - struct cacep_info * info; -}; - struct { - flow_set_t * nm1_set[QOS_CUBE_MAX]; - fqueue_t * nm1_fqs[QOS_CUBE_MAX]; - struct list_head nm1_flows; - pthread_rwlock_t nm1_flows_lock; - flow_set_t * np1_set[QOS_CUBE_MAX]; fqueue_t * np1_fqs[QOS_CUBE_MAX]; pthread_rwlock_t np1_flows_lock; @@ -69,15 +62,45 @@ struct { int np1_cep_id_to_fd[IPCPD_MAX_CONNS]; pthread_t np1_sdu_reader; + + flow_set_t * nm1_set[QOS_CUBE_MAX]; + fqueue_t * nm1_fqs[QOS_CUBE_MAX]; pthread_t nm1_sdu_reader; - pthread_t nm1_flow_wait; - /* FIXME: Replace with PFF */ - int fd; + struct pff * pff[QOS_CUBE_MAX]; + struct routing_i * routing[QOS_CUBE_MAX]; struct gam * gam; + struct nbs * nbs; + struct ae * ae; + + struct nb_notifier nb_notifier; } fmgr; +static int fmgr_neighbor_event(enum nb_event event, + struct conn conn) +{ + qoscube_t cube; + + /* We are only interested in neighbors being added and removed. */ + switch (event) { + case NEIGHBOR_ADDED: + ipcp_flow_get_qoscube(conn.flow_info.fd, &cube); + flow_set_add(fmgr.nm1_set[cube], conn.flow_info.fd); + log_dbg("Added fd %d to flow set.", conn.flow_info.fd); + break; + case NEIGHBOR_REMOVED: + ipcp_flow_get_qoscube(conn.flow_info.fd, &cube); + flow_set_del(fmgr.nm1_set[cube], conn.flow_info.fd); + log_dbg("Removed fd %d from flow set.", conn.flow_info.fd); + break; + default: + break; + } + + return 0; +} + static void * fmgr_np1_sdu_reader(void * o) { struct shm_du_buff * sdb; @@ -162,7 +185,7 @@ void * fmgr_nm1_sdu_reader(void * o) shm_pci_des(sdb, &pci); - if (pci.dst_addr != ipcpi.address) { + if (pci.dst_addr != ipcpi.dt_addr) { log_dbg("PDU needs to be forwarded."); if (pci.ttl == 0) { @@ -171,12 +194,20 @@ void * fmgr_nm1_sdu_reader(void * o) continue; } - /* - * FIXME: Dropping for now, since - * we don't have a PFF yet - */ - ipcp_flow_del(sdb); - continue; + fd = pff_nhop(fmgr.pff[i], pci.dst_addr); + if (fd < 0) { + log_err("No next hop for %lu", + pci.dst_addr); + ipcp_flow_del(sdb); + continue; + } + + if (ipcp_flow_write(fd, sdb)) { + log_err("Failed to write SDU to fd %d.", + fd); + ipcp_flow_del(sdb); + continue; + } } shm_pci_shrink(sdb); @@ -192,49 +223,6 @@ void * fmgr_nm1_sdu_reader(void * o) return (void *) 0; } -static void * fmgr_nm1_flow_wait(void * o) -{ - qoscube_t cube; - struct cacep_info * info; - int fd; - qosspec_t qs; - struct nm1_flow * flow; - - (void) o; - - while (true) { - if (gam_flow_wait(fmgr.gam, &fd, &info, &qs)) { - log_err("Failed to get next flow descriptor."); - continue; - } - - ipcp_flow_get_qoscube(fd, &cube); - flow_set_add(fmgr.nm1_set[cube], fd); - - /* FIXME: Temporary, until we have a PFF */ - fmgr.fd = fd; - - pthread_rwlock_wrlock(&fmgr.nm1_flows_lock); - flow = malloc(sizeof(*flow)); - if (flow == NULL) { - free(info); - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); - continue; - } - - flow->info = info; - flow->fd = fd; - flow->qs = qs; - - list_head_init(&flow->next); - list_add(&flow->next, &fmgr.nm1_flows); - - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); - } - - return (void *) 0; -} - static void fmgr_destroy_flows(void) { int i; @@ -247,13 +235,28 @@ static void fmgr_destroy_flows(void) } } -int fmgr_init(void) +static void fmgr_destroy_routing(void) { - enum pol_cacep pc; - enum pol_gam pg; + int i; + for (i = 0; i < QOS_CUBE_MAX; ++i) + routing_i_destroy(fmgr.routing[i]); +} + +static void fmgr_destroy_pff(void) +{ int i; + for (i = 0; i < QOS_CUBE_MAX; ++i) + pff_destroy(fmgr.pff[i]); +} + +int fmgr_init(void) +{ + int i; + int j; + struct conn_info info; + for (i = 0; i < AP_MAX_FLOWS; ++i) fmgr.np1_fd_to_cep_id[i] = INVALID_CEP_ID; @@ -286,81 +289,139 @@ int fmgr_init(void) } } - if (rib_read(BOOT_PATH "/dt/gam/type", &pg, sizeof(pg)) - != sizeof(pg)) { - log_err("Failed to read policy for ribmgr gam."); + strcpy(info.ae_name, DT_AE); + strcpy(info.protocol, FRCT_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_FIXED; + info.addr = ipcpi.dt_addr; + + fmgr.ae = connmgr_ae_create(info); + if (fmgr.ae == NULL) { + log_err("Failed to create AE struct."); + fmgr_destroy_flows(); return -1; } - if (rib_read(BOOT_PATH "/dt/gam/cacep", &pc, sizeof(pc)) - != sizeof(pc)) { - log_err("Failed to read CACEP policy for ribmgr gam."); + fmgr.nbs = nbs_create(); + if (fmgr.nbs == NULL) { + log_err("Failed to create neighbors struct."); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); return -1; } - /* FIXME: Implement cacep policies */ - (void) pc; + fmgr.nb_notifier.notify_call = fmgr_neighbor_event; + if (nbs_reg_notifier(fmgr.nbs, &fmgr.nb_notifier)) { + log_err("Failed to register notifier."); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } - fmgr.gam = gam_create(pg, DT_AE); - if (fmgr.gam == NULL) { - log_err("Failed to create graph adjacency manager."); + if (routing_init(fmgr.nbs)) { + log_err("Failed to init routing."); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); return -1; } - list_head_init(&fmgr.nm1_flows); + if (pthread_rwlock_init(&fmgr.np1_flows_lock, NULL)) { + routing_fini(); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } - pthread_rwlock_init(&fmgr.nm1_flows_lock, NULL); - pthread_rwlock_init(&fmgr.np1_flows_lock, NULL); + for (i = 0; i < QOS_CUBE_MAX; ++i) { + fmgr.pff[i] = pff_create(); + if (fmgr.pff[i] == NULL) { + for (j = 0; j < i; ++j) + pff_destroy(fmgr.pff[j]); + pthread_rwlock_destroy(&fmgr.np1_flows_lock); + routing_fini(); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } - pthread_create(&fmgr.np1_sdu_reader, NULL, fmgr_np1_sdu_reader, NULL); - pthread_create(&fmgr.nm1_sdu_reader, NULL, fmgr_nm1_sdu_reader, NULL); - pthread_create(&fmgr.nm1_flow_wait, NULL, fmgr_nm1_flow_wait, NULL); + fmgr.routing[i] = routing_i_create(fmgr.pff[i]); + if (fmgr.routing[i] == NULL) { + for (j = 0; j < i; ++j) + routing_i_destroy(fmgr.routing[j]); + fmgr_destroy_pff(); + pthread_rwlock_destroy(&fmgr.np1_flows_lock); + routing_fini(); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + nbs_destroy(fmgr.nbs); + fmgr_destroy_flows(); + connmgr_ae_destroy(fmgr.ae); + return -1; + } + } return 0; } void fmgr_fini() { - struct list_head * pos = NULL; - struct list_head * n = NULL; - qoscube_t cube; + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); - pthread_cancel(fmgr.np1_sdu_reader); - pthread_cancel(fmgr.nm1_sdu_reader); - pthread_cancel(fmgr.nm1_flow_wait); + fmgr_destroy_routing(); - pthread_join(fmgr.np1_sdu_reader, NULL); - pthread_join(fmgr.nm1_sdu_reader, NULL); - pthread_join(fmgr.nm1_flow_wait, NULL); + fmgr_destroy_pff(); - gam_destroy(fmgr.gam); + routing_fini(); + + fmgr_destroy_flows(); + + connmgr_ae_destroy(fmgr.ae); + + nbs_destroy(fmgr.nbs); +} + +int fmgr_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; + } - pthread_rwlock_wrlock(&fmgr.nm1_flows_lock); - - list_for_each_safe(pos, n, &fmgr.nm1_flows) { - struct nm1_flow * flow = - list_entry(pos, struct nm1_flow, next); - list_del(&flow->next); - flow_dealloc(flow->fd); - ipcp_flow_get_qoscube(flow->fd, &cube); - flow_set_del(fmgr.nm1_set[cube], flow->fd); - free(flow->info->name); - free(flow->info); - free(flow); + fmgr.gam = gam_create(pg, fmgr.nbs, fmgr.ae); + if (fmgr.gam == NULL) { + log_err("Failed to init dt graph adjacency manager."); + nbs_unreg_notifier(fmgr.nbs, &fmgr.nb_notifier); + return -1; } - pthread_rwlock_unlock(&fmgr.nm1_flows_lock); + pthread_create(&fmgr.np1_sdu_reader, NULL, fmgr_np1_sdu_reader, NULL); + pthread_create(&fmgr.nm1_sdu_reader, NULL, fmgr_nm1_sdu_reader, NULL); - pthread_rwlock_destroy(&fmgr.nm1_flows_lock); - pthread_rwlock_destroy(&fmgr.np1_flows_lock); + return 0; +} - fmgr_destroy_flows(); +void fmgr_stop(void) +{ + pthread_cancel(fmgr.np1_sdu_reader); + pthread_cancel(fmgr.nm1_sdu_reader); + + pthread_join(fmgr.np1_sdu_reader, NULL); + pthread_join(fmgr.nm1_sdu_reader, NULL); + + gam_destroy(fmgr.gam); } int fmgr_np1_alloc(int fd, char * dst_ap_name, - char * src_ae_name, qoscube_t cube) { cep_id_t cep_id; @@ -406,7 +467,6 @@ int fmgr_np1_alloc(int fd, msg.code = FLOW_ALLOC_CODE__FLOW_REQ; msg.dst_name = dst_ap_name; - msg.src_ae_name = src_ae_name; msg.has_qoscube = true; msg.qoscube = cube; @@ -546,7 +606,6 @@ int fmgr_np1_post_buf(cep_id_t cep_id, case FLOW_ALLOC_CODE__FLOW_REQ: fd = ipcp_flow_req_arr(getpid(), msg->dst_name, - msg->src_ae_name, msg->qoscube); if (fd < 0) { flow_alloc_msg__free_unpacked(msg, NULL); @@ -615,24 +674,20 @@ int fmgr_np1_post_sdu(cep_id_t cep_id, return 0; } -int fmgr_nm1_flow_arr(int fd, - qosspec_t qs) -{ - assert(fmgr.gam); - - if (gam_flow_arr(fmgr.gam, fd, qs)) { - log_err("Failed to hand to graph adjacency manager."); - return -1; - } - - return 0; -} - int fmgr_nm1_write_sdu(struct pci * pci, struct shm_du_buff * sdb) { + int fd; + if (pci == NULL || sdb == NULL) + return -EINVAL; + + fd = pff_nhop(fmgr.pff[pci->qos_id], pci->dst_addr); + if (fd < 0) { + log_err("Could not get nhop for address %lu", pci->dst_addr); + ipcp_flow_del(sdb); return -1; + } if (shm_pci_ser(sdb, pci)) { log_err("Failed to serialize PDU."); @@ -640,8 +695,8 @@ int fmgr_nm1_write_sdu(struct pci * pci, return -1; } - if (ipcp_flow_write(fmgr.fd, sdb)) { - log_err("Failed to write SDU to fd %d.", fmgr.fd); + if (ipcp_flow_write(fd, sdb)) { + log_err("Failed to write SDU to fd %d.", fd); ipcp_flow_del(sdb); return -1; } @@ -653,9 +708,17 @@ int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf) { buffer_t * buffer; + int fd; if (pci == NULL || buf == NULL || buf->data == NULL) + return -EINVAL; + + fd = pff_nhop(fmgr.pff[pci->qos_id], pci->dst_addr); + if (fd < 0) { + log_err("Could not get nhop for address %lu", pci->dst_addr); + free(buf->data); return -1; + } buffer = shm_pci_ser_buf(buf, pci); if (buffer == NULL) { @@ -664,7 +727,7 @@ int fmgr_nm1_write_buf(struct pci * pci, return -1; } - if (flow_write(fmgr.fd, buffer->data, buffer->len) == -1) { + if (flow_write(fd, buffer->data, buffer->len) == -1) { log_err("Failed to write buffer to fd."); free(buffer); return -1; diff --git a/src/ipcpd/normal/fmgr.h b/src/ipcpd/normal/fmgr.h index 3c61f55a..b4d0b65a 100644 --- a/src/ipcpd/normal/fmgr.h +++ b/src/ipcpd/normal/fmgr.h @@ -3,7 +3,8 @@ * * Flow manager of the IPC Process * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -32,9 +33,12 @@ int fmgr_init(void); void fmgr_fini(void); +int fmgr_start(void); + +void fmgr_stop(void); + int fmgr_np1_alloc(int fd, char * dst_ap_name, - char * src_ae_name, qoscube_t qos); int fmgr_np1_alloc_resp(int fd, @@ -54,8 +58,4 @@ int fmgr_nm1_write_sdu(struct pci * pci, int fmgr_nm1_write_buf(struct pci * pci, buffer_t * buf); -int fmgr_nm1_flow_arr(int fd, - qosspec_t qs); - - #endif /* OUROBOROS_IPCPD_NORMAL_FMGR_H */ diff --git a/src/ipcpd/normal/frct.c b/src/ipcpd/normal/frct.c index 915feaf8..62cbf9f7 100644 --- a/src/ipcpd/normal/frct.c +++ b/src/ipcpd/normal/frct.c @@ -3,7 +3,8 @@ * * The Flow and Retransmission control component * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -198,12 +199,12 @@ int frct_fini() return 0; } -int frct_nm1_post_sdu(struct pci * pci, +int frct_nm1_post_sdu(struct pci * pci, struct shm_du_buff * sdb) { struct frct_i * instance; - buffer_t buf; - cep_id_t id; + buffer_t buf; + cep_id_t id; if (pci == NULL || sdb == NULL) return -1; @@ -267,8 +268,8 @@ cep_id_t frct_i_create(uint64_t address, qoscube_t cube) { struct frct_i * instance; - struct pci pci; - cep_id_t id; + struct pci pci; + cep_id_t id; if (buf == NULL || buf->data == NULL) return INVALID_CEP_ID; @@ -285,7 +286,7 @@ cep_id_t frct_i_create(uint64_t address, pci.pdu_type = PDU_TYPE_MGMT; pci.dst_addr = address; - pci.src_addr = ipcpi.address; + pci.src_addr = ipcpi.dt_addr; pci.dst_cep_id = 0; pci.src_cep_id = id; pci.seqno = 0; @@ -304,7 +305,7 @@ int frct_i_accept(cep_id_t id, buffer_t * buf, qoscube_t cube) { - struct pci pci; + struct pci pci; struct frct_i * instance; if (buf == NULL || buf->data == NULL) @@ -330,7 +331,7 @@ int frct_i_accept(cep_id_t id, pci.pdu_type = PDU_TYPE_MGMT; pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.address; + pci.src_addr = ipcpi.dt_addr; pci.dst_cep_id = instance->r_cep_id; pci.src_cep_id = instance->cep_id; pci.seqno = 0; @@ -347,7 +348,7 @@ int frct_i_accept(cep_id_t id, int frct_i_destroy(cep_id_t id, buffer_t * buf) { - struct pci pci; + struct pci pci; struct frct_i * instance; pthread_mutex_lock(&frct.instances_lock); @@ -367,7 +368,7 @@ int frct_i_destroy(cep_id_t id, pci.pdu_type = PDU_TYPE_MGMT; pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.address; + pci.src_addr = ipcpi.dt_addr; pci.dst_cep_id = instance->r_cep_id; pci.src_cep_id = instance->cep_id; pci.seqno = 0; @@ -390,7 +391,7 @@ int frct_i_destroy(cep_id_t id, int frct_i_write_sdu(cep_id_t id, struct shm_du_buff * sdb) { - struct pci pci; + struct pci pci; struct frct_i * instance; if (sdb == NULL) @@ -413,7 +414,7 @@ int frct_i_write_sdu(cep_id_t id, pci.pdu_type = PDU_TYPE_DTP; pci.dst_addr = instance->r_address; - pci.src_addr = ipcpi.address; + pci.src_addr = ipcpi.dt_addr; pci.dst_cep_id = instance->r_cep_id; pci.src_cep_id = instance->cep_id; pci.seqno = (instance->seqno)++; diff --git a/src/ipcpd/normal/frct.h b/src/ipcpd/normal/frct.h index 462b8cc3..a1dcb151 100644 --- a/src/ipcpd/normal/frct.h +++ b/src/ipcpd/normal/frct.h @@ -3,7 +3,8 @@ * * The Flow and Retransmission control component * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -27,6 +28,8 @@ #include "shm_pci.h" +#define FRCT_PROTO "FRCT" + struct frct_i; int frct_init(void); diff --git a/src/ipcpd/ipcp-ops.h b/src/ipcpd/normal/fso.proto index 6a42ec5c..32b281d6 100644 --- a/src/ipcpd/ipcp-ops.h +++ b/src/ipcpd/normal/fso.proto @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * IPC process ops + * Flow State Object message * * Dimitri Staessens <dimitri.staessens@intec.ugent.be> * Sander Vrijders <sander.vrijders@intec.ugent.be> @@ -20,32 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef IPCPD_IPCP_OPS_H -#define IPCPD_IPCP_OPS_H +syntax = "proto2"; -#include <ouroboros/irm_config.h> -#include <ouroboros/shared.h> - -struct ipcp_ops { - int (* ipcp_bootstrap)(struct dif_config * conf); - - int (* ipcp_enroll)(char * dif_name); - - int (* ipcp_name_reg)(char * name); - - int (* ipcp_name_unreg)(char * name); - - int (* ipcp_name_query)(char * name); - - int (* ipcp_flow_alloc)(int fd, - char * dst_ap_name, - char * src_ae_name, - qoscube_t qos); - - int (* ipcp_flow_alloc_resp)(int fd, - int response); - - int (* ipcp_flow_dealloc)(int fd); +message fso { + required uint64 s_addr = 1; + required uint64 d_addr = 2; + /* Add QoS parameters of link here */ }; - -#endif /* IPCPD_IPCP_OPS_H */ diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c index 9ee55261..643d83b0 100644 --- a/src/ipcpd/normal/gam.c +++ b/src/ipcpd/normal/gam.c @@ -1,10 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Data transfer graph adjacency manager * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -20,9 +20,10 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "graph-adjacency-manager" +#define OUROBOROS_PREFIX "dt-gam" #include <ouroboros/config.h> +#include <ouroboros/cdap.h> #include <ouroboros/dev.h> #include <ouroboros/logs.h> #include <ouroboros/list.h> @@ -39,271 +40,43 @@ #include <pthread.h> #include <string.h> -struct ga { - struct list_head next; - - qosspec_t qs; - int fd; - struct cacep_info * info; -}; - struct gam { - struct list_head gas; - pthread_mutex_t gas_lock; - pthread_cond_t gas_cond; - - char * ae_name; - struct pol_gam_ops * ops; void * ops_o; }; struct gam * gam_create(enum pol_gam gam_type, - const char * ae_name) + struct nbs * nbs, + struct ae * ae) { - struct gam * tmp; + struct gam * gam; - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) + gam = malloc(sizeof(*gam)); + if (gam == NULL) return NULL; switch (gam_type) { case COMPLETE: - tmp->ops = &complete_ops; + gam->ops = &complete_ops; break; default: log_err("Unknown gam policy: %d.", gam_type); - free(tmp); - return NULL; - } - - list_head_init(&tmp->gas); - - tmp->ae_name = strdup(ae_name); - if (tmp->ae_name == NULL) { - free(tmp); - return NULL; - } - - if (pthread_mutex_init(&tmp->gas_lock, NULL)) { - free(tmp->ae_name); - free(tmp); - return NULL; - } - - if (pthread_cond_init(&tmp->gas_cond, NULL)) { - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp->ae_name); - free(tmp); return NULL; } - tmp->ops_o = tmp->ops->create(tmp); - if (tmp->ops_o == NULL) { - pthread_cond_destroy(&tmp->gas_cond); - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp->ae_name); - free(tmp); + gam->ops_o = gam->ops->create(nbs, ae); + if (gam->ops_o == NULL) { + free(gam); return NULL; } - if (tmp->ops->start(tmp->ops_o)) { - pthread_cond_destroy(&tmp->gas_cond); - pthread_mutex_destroy(&tmp->gas_lock); - free(tmp->ae_name); - free(tmp); - return NULL; - } - - return tmp; -} - -void gam_destroy(struct gam * instance) -{ - struct list_head * p = NULL; - struct list_head * n = NULL; - - assert(instance); - - instance->ops->stop(instance->ops_o); - - pthread_mutex_lock(&instance->gas_lock); - - list_for_each_safe(p, n, &instance->gas) { - struct ga * e = list_entry(p, struct ga, next); - list_del(&e->next); - free(e->info->name); - free(e->info); - free(e); - } - - pthread_mutex_unlock(&instance->gas_lock); - - pthread_mutex_destroy(&instance->gas_lock); - pthread_cond_destroy(&instance->gas_cond); - - free(instance->ae_name); - instance->ops->destroy(instance->ops_o); - free(instance); -} - -static int add_ga(struct gam * instance, - int fd, - qosspec_t qs, - struct cacep_info * info) -{ - struct ga * ga; - - ga = malloc(sizeof(*ga)); - if (ga == NULL) - return -ENOMEM; - - ga->fd = fd; - ga->info = info; - ga->qs = qs; - - list_head_init(&ga->next); - - pthread_mutex_lock(&instance->gas_lock); - list_add(&ga->next, &instance->gas); - pthread_cond_signal(&instance->gas_cond); - pthread_mutex_unlock(&instance->gas_lock); - - log_info("Added %s flow to %s.", instance->ae_name, info->name); - - return 0; + return gam; } -int gam_flow_arr(struct gam * instance, - int fd, - qosspec_t qs) +void gam_destroy(struct gam * gam) { - struct cacep * cacep; - struct cacep_info * info; - - if (flow_alloc_resp(fd, instance->ops->accept_new_flow(instance->ops_o)) - < 0) { - log_err("Could not respond to new flow."); - return -1; - } - - cacep = cacep_create(fd, ipcpi.name, ipcpi.address); - if (cacep == NULL) { - log_err("Failed to create CACEP instance."); - return -1; - } - - info = cacep_auth_wait(cacep); - if (info == NULL) { - log_err("Other side failed to authenticate."); - cacep_destroy(cacep); - return -1; - } - - cacep_destroy(cacep); - - if (instance->ops->accept_flow(instance->ops_o, qs, info)) { - flow_dealloc(fd); - free(info->name); - free(info); - return 0; - } - - if (add_ga(instance, fd, qs, info)) { - log_err("Failed to add ga to graph adjacency manager list."); - free(info->name); - free(info); - return -1; - } - - return 0; -} - -int gam_flow_alloc(struct gam * instance, - char * dst_name, - qosspec_t qs) -{ - struct cacep * cacep; - struct cacep_info * info; - int fd; - - fd = flow_alloc(dst_name, instance->ae_name, NULL); - if (fd < 0) { - log_err("Failed to allocate flow to %s.", dst_name); - return -1; - } - - if (flow_alloc_res(fd)) { - log_err("Flow allocation to %s failed.", dst_name); - flow_dealloc(fd); - return -1; - } - - cacep = cacep_create(fd, ipcpi.name, ipcpi.address); - if (cacep == NULL) { - log_err("Failed to create CACEP instance."); - return -1; - } - - info = cacep_auth(cacep); - if (info == NULL) { - log_err("Failed to authenticate."); - cacep_destroy(cacep); - return -1; - } - - cacep_destroy(cacep); - - if (instance->ops->accept_flow(instance->ops_o, qs, info)) { - flow_dealloc(fd); - free(info->name); - free(info); - return 0; - } - - if (add_ga(instance, fd, qs, info)) { - log_err("Failed to add GA to graph adjacency manager list."); - free(info->name); - free(info); - return -1; - } - - return 0; -} - -int gam_flow_wait(struct gam * instance, - int * fd, - struct cacep_info ** info, - qosspec_t * qs) -{ - struct ga * ga; - - assert(fd); - assert(info); - assert(qs); - - pthread_mutex_lock(&instance->gas_lock); - - pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock, - (void *) &instance->gas_lock); - - while (list_is_empty(&instance->gas)) - pthread_cond_wait(&instance->gas_cond, &instance->gas_lock); - - ga = list_first_entry((&instance->gas), struct ga, next); - if (ga == NULL) { - pthread_mutex_unlock(&instance->gas_lock); - return -1; - } - - *fd = ga->fd; - *info = ga->info; - *qs = ga->qs; - - list_del(&ga->next); - free(ga); - - pthread_cleanup_pop(true); + assert(gam); - return 0; + gam->ops->destroy(gam->ops_o); + free(gam); } diff --git a/src/ipcpd/normal/gam.h b/src/ipcpd/normal/gam.h index 50f83df9..4ae0b1b3 100644 --- a/src/ipcpd/normal/gam.h +++ b/src/ipcpd/normal/gam.h @@ -1,10 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Data transfer graph adjacency manager * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -26,22 +26,12 @@ #include <ouroboros/cacep.h> #include <ouroboros/irm_config.h> -struct gam * gam_create(enum pol_gam gam_type, - const char * ae_name); - -void gam_destroy(struct gam * instance); +#include "neighbors.h" -int gam_flow_arr(struct gam * instance, - int fd, - qosspec_t qs); - -int gam_flow_alloc(struct gam * instance, - char * dst_name, - qosspec_t qs); +struct gam * gam_create(enum pol_gam gam_type, + struct nbs * nbs, + struct ae * ae); -int gam_flow_wait(struct gam * instance, - int * fd, - struct cacep_info ** info, - qosspec_t * qs); +void gam_destroy(struct gam * gam); #endif /* OUROBOROS_IPCPD_NORMAL_GAM_H */ diff --git a/src/ipcpd/normal/graph.c b/src/ipcpd/normal/graph.c new file mode 100644 index 00000000..85bb3fe2 --- /dev/null +++ b/src/ipcpd/normal/graph.c @@ -0,0 +1,277 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph structure + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "graph" + +#include <ouroboros/config.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/list.h> + +#include "graph.h" + +#include <assert.h> +#include <pthread.h> +#include <stdlib.h> + +static struct edge * find_edge_by_addr(struct vertex * vertex, + uint64_t dst_addr) +{ + struct list_head * p = NULL; + + list_for_each(p, &vertex->edges) { + struct edge * e = list_entry(p, struct edge, next); + if (e->dst_addr == dst_addr) + return e; + } + + return NULL; +} + +static struct vertex * find_vertex_by_addr(struct graph * graph, + uint64_t addr) +{ + struct list_head * p = NULL; + + list_for_each(p, &graph->vertices) { + struct vertex * e = list_entry(p, struct vertex, next); + if (e->addr == addr) + return e; + } + + return NULL; +} + +static int add_edge(struct vertex * vertex, + uint64_t dst_addr, + qosspec_t qs) +{ + struct edge * edge; + + edge = malloc(sizeof(*edge)); + if (edge == NULL) + return -ENOMEM; + + list_head_init(&edge->next); + edge->dst_addr = dst_addr; + edge->qs = qs; + + list_add(&edge->next, &vertex->edges); + + return 0; +} + +static void del_edge(struct edge * edge) +{ + list_del(&edge->next); + free(edge); +} + +static int add_vertex(struct graph * graph, + uint64_t addr) +{ + struct vertex * vertex; + struct list_head * p; + + vertex = malloc(sizeof(*vertex)); + if (vertex == NULL) + return -1; + + list_head_init(&vertex->next); + list_head_init(&vertex->edges); + vertex->addr = addr; + + list_for_each(p, &graph->vertices) { + struct vertex * v = list_entry(p, struct vertex, next); + if (v->addr > addr) + break; + } + + list_add_tail(&vertex->next, p); + + graph->nr_vertices++; + + return 0; +} + +static void del_vertex(struct graph * graph, + struct vertex * vertex) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + list_del(&vertex->next); + + list_for_each_safe(p, n, &vertex->edges) { + struct edge * e = list_entry(p, struct edge, next); + del_edge(e); + } + + free(vertex); + + graph->nr_vertices--; +} + +struct graph * graph_create(void) +{ + struct graph * graph; + + graph = malloc(sizeof(*graph)); + if (graph == NULL) + return NULL; + + if (pthread_mutex_init(&graph->lock, NULL)) { + free(graph); + return NULL; + } + + graph->nr_vertices = 0; + list_head_init(&graph->vertices); + + return graph; +} + +void graph_destroy(struct graph * graph) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + list_for_each_safe(p, n, &graph->vertices) { + struct vertex * e = list_entry(p, struct vertex, next); + del_vertex(graph, e); + } + + pthread_mutex_unlock(&graph->lock); + + pthread_mutex_destroy(&graph->lock); +} + +int graph_add_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + if (add_vertex(graph, s_addr)) { + pthread_mutex_unlock(&graph->lock); + return -ENOMEM; + } + } + + e = find_edge_by_addr(v, d_addr); + if (e != NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("Edge already exists."); + return -1; + } + + if (add_edge(v, d_addr, qs)) { + pthread_mutex_unlock(&graph->lock); + log_err("Failed to add edge."); + return -1; + } + + pthread_mutex_unlock(&graph->lock); + + return 0; +} + +int graph_update_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such vertex."); + return -1; + } + + e = find_edge_by_addr(v, d_addr); + if (e == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such edge."); + return -1; + } + + e->qs = qs; + + pthread_mutex_unlock(&graph->lock); + + return 0; +} + +int graph_del_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr) +{ + struct vertex * v; + struct edge * e; + + assert(graph); + + pthread_mutex_lock(&graph->lock); + + v = find_vertex_by_addr(graph, s_addr); + if (v == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such vertex."); + return -1; + } + + e = find_edge_by_addr(v, d_addr); + if (e == NULL) { + pthread_mutex_unlock(&graph->lock); + log_err("No such edge."); + return -1; + } + + del_edge(e); + + /* Removing vertex if it was the last edge */ + if (list_is_empty(&v->edges)) + del_vertex(graph, v); + + pthread_mutex_unlock(&graph->lock); + + return 0; +} diff --git a/src/ipcpd/normal/graph.h b/src/ipcpd/normal/graph.h new file mode 100644 index 00000000..9653efd7 --- /dev/null +++ b/src/ipcpd/normal/graph.h @@ -0,0 +1,67 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Graph structure + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_GRAPH_H +#define OUROBOROS_IPCPD_NORMAL_GRAPH_H + +#include <ouroboros/list.h> +#include <ouroboros/qos.h> + +#include <inttypes.h> + +struct edge { + struct list_head next; + uint64_t dst_addr; + qosspec_t qs; +}; + +struct vertex { + struct list_head next; + uint64_t addr; + struct list_head edges; +}; + +struct graph { + size_t nr_vertices; + struct list_head vertices; + pthread_mutex_t lock; +}; + +struct graph * graph_create(void); + +void graph_destroy(struct graph * graph); + +int graph_add_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs); + +int graph_update_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr, + qosspec_t qs); + +int graph_del_edge(struct graph * graph, + uint64_t s_addr, + uint64_t d_addr); + +#endif /* OUROBOROS_IPCPD_NORMAL_GRAPH_H */ diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index c41b6187..7acf3046 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -3,8 +3,8 @@ * * Normal IPC Process * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -24,7 +24,6 @@ #include <ouroboros/config.h> #include <ouroboros/logs.h> -#include <ouroboros/dev.h> #include <ouroboros/ipcp-dev.h> #include <ouroboros/time_utils.h> #include <ouroboros/irm.h> @@ -33,11 +32,10 @@ #include <ouroboros/errno.h> #include "addr_auth.h" -#include "ae.h" +#include "connmgr.h" #include "dir.h" #include "enroll.h" #include "fmgr.h" -#include "frct.h" #include "ipcp.h" #include "ribconfig.h" #include "ribmgr.h" @@ -45,17 +43,11 @@ #include <stdbool.h> #include <signal.h> #include <stdlib.h> -#include <pthread.h> #include <string.h> #include <assert.h> #include <inttypes.h> -#define THIS_TYPE IPCP_NORMAL - -struct { - pthread_t acceptor; - struct addr_auth * auth; -} normal; +#define THIS_TYPE IPCP_NORMAL void ipcp_sig_handler(int sig, siginfo_t * info, @@ -83,54 +75,6 @@ void ipcp_sig_handler(int sig, } } -static void * flow_acceptor(void * o) -{ - int fd; - char * ae_name; - qosspec_t qs; - - (void) o; - - while (true) { - pthread_rwlock_rdlock(&ipcpi.state_lock); - - if (ipcp_get_state() != IPCP_OPERATIONAL) { - pthread_rwlock_unlock(&ipcpi.state_lock); - log_info("Shutting down flow acceptor."); - return 0; - } - - pthread_rwlock_unlock(&ipcpi.state_lock); - - fd = flow_accept(&ae_name, &qs); - if (fd < 0) { - if (fd != -EIRMD) - log_warn("Flow accept failed: %d", fd); - continue; - } - - log_dbg("New flow allocation request for AE %s.", ae_name); - - if (strcmp(ae_name, ENROLL_AE) == 0) { - enroll_handle(fd); - } else if (strcmp(ae_name, MGMT_AE) == 0) { - ribmgr_flow_arr(fd, qs); - } else if (strcmp(ae_name, DT_AE) == 0) { - fmgr_nm1_flow_arr(fd, qs); - } else { - log_dbg("Flow allocation request for unknown AE %s.", - ae_name); - if (flow_alloc_resp(fd, -1)) - log_warn("Failed to reply to flow allocation."); - flow_dealloc(fd); - } - - free(ae_name); - } - - return (void *) 0; -} - /* * Boots the IPCP off information in the rib. * Common function after bootstrap or enroll. @@ -155,7 +99,7 @@ static int boot_components(void) } if (rib_add(MEMBERS_PATH, ipcpi.name)) { - log_warn("Failed to add name to " MEMBERS_PATH); + log_err("Failed to add name to " MEMBERS_PATH); return -1; } @@ -164,67 +108,80 @@ static int boot_components(void) if (rib_read(BOOT_PATH "/addr_auth/type", &pa, sizeof(pa)) != sizeof(pa)) { log_err("Failed to read policy for address authority."); + connmgr_fini(); return -1; } - normal.auth = addr_auth_create(pa); - if (normal.auth == NULL) { + if (addr_auth_init(pa)) { log_err("Failed to init address authority."); return -1; } - ipcpi.address = normal.auth->address(); - if (ipcpi.address == 0) { + ipcpi.dt_addr = addr_auth_address(); + if (ipcpi.dt_addr == 0) { log_err("Failed to get a valid address."); - addr_auth_destroy(normal.auth); + addr_auth_fini(); return -1; } - log_dbg("IPCP got address %" PRIu64 ".", ipcpi.address); + log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr); log_dbg("Starting ribmgr."); if (ribmgr_init()) { log_err("Failed to initialize RIB manager."); - addr_auth_destroy(normal.auth); + addr_auth_fini(); return -1; } if (dir_init()) { log_err("Failed to initialize directory."); ribmgr_fini(); - addr_auth_destroy(normal.auth); + addr_auth_fini(); return -1; } log_dbg("Ribmgr started."); - if (fmgr_init()) { + if (frct_init()) { + dir_fini(); + ribmgr_fini(); + addr_auth_fini(); + log_err("Failed to initialize FRCT."); + return -1; + } + + if (fmgr_start()) { + frct_fini(); dir_fini(); ribmgr_fini(); - addr_auth_destroy(normal.auth); + addr_auth_fini(); log_err("Failed to start flow manager."); return -1; } - if (frct_init()) { - fmgr_fini(); + + if (enroll_start()) { + fmgr_stop(); + frct_fini(); dir_fini(); ribmgr_fini(); - addr_auth_destroy(normal.auth); - log_err("Failed to initialize FRCT."); + addr_auth_fini(); + log_err("Failed to start enroll."); return -1; } ipcp_set_state(IPCP_OPERATIONAL); - if (pthread_create(&normal.acceptor, NULL, flow_acceptor, NULL)) { + if (connmgr_start()) { ipcp_set_state(IPCP_INIT); - fmgr_fini(); + enroll_stop(); + fmgr_stop(); + frct_fini(); dir_fini(); ribmgr_fini(); - addr_auth_destroy(normal.auth); - log_err("Failed to create acceptor thread."); + addr_auth_fini(); + log_err("Failed to start AP connection manager."); return -1; } @@ -233,18 +190,19 @@ static int boot_components(void) void shutdown_components(void) { - pthread_cancel(normal.acceptor); - pthread_join(normal.acceptor, NULL); + connmgr_stop(); + + enroll_stop(); frct_fini(); - fmgr_fini(); + fmgr_stop(); dir_fini(); ribmgr_fini(); - addr_auth_destroy(normal.auth); + addr_auth_fini(); } static int normal_ipcp_enroll(char * dst_name) @@ -339,11 +297,6 @@ int normal_rib_init(void) static int normal_ipcp_bootstrap(struct dif_config * conf) { - /* FIXME: get CACEP policies from conf */ - enum pol_cacep pol = NO_AUTH; - - (void) pol; - assert(conf); assert(conf->type == THIS_TYPE); @@ -391,12 +344,6 @@ static int normal_ipcp_bootstrap(struct dif_config * conf) rib_write(BOOT_PATH "/rm/gam/type", &conf->rm_gam_type, sizeof(conf->rm_gam_type)) || - rib_write(BOOT_PATH "/rm/gam/cacep", - &pol, - sizeof(pol)) || - rib_write(BOOT_PATH "/dt/gam/cacep", - &pol, - sizeof(pol)) || rib_write(BOOT_PATH "/addr_auth/type", &conf->addr_auth_type, sizeof(conf->addr_auth_type))) { @@ -424,9 +371,9 @@ static struct ipcp_ops normal_ops = { .ipcp_name_reg = dir_name_reg, .ipcp_name_unreg = dir_name_unreg, .ipcp_name_query = dir_name_query, - .ipcp_flow_alloc = NULL, /* fmgr_np1_alloc, */ - .ipcp_flow_alloc_resp = NULL, /* fmgr_np1_alloc_resp, */ - .ipcp_flow_dealloc = NULL, /* fmgr_np1_dealloc */ + .ipcp_flow_alloc = fmgr_np1_alloc, + .ipcp_flow_alloc_resp = fmgr_np1_alloc_resp, + .ipcp_flow_dealloc = fmgr_np1_dealloc }; int main(int argc, @@ -473,11 +420,44 @@ int main(int argc, exit(EXIT_FAILURE); } + if (connmgr_init()) { + log_err("Failed to initialize connection manager."); + ipcp_create_r(getpid(), -1); + rib_fini(); + irm_unbind_api(getpid(), ipcpi.name); + ipcp_fini(); + exit(EXIT_FAILURE); + } + + if (enroll_init()) { + log_err("Failed to initialize enroll component."); + ipcp_create_r(getpid(), -1); + connmgr_fini(); + rib_fini(); + irm_unbind_api(getpid(), ipcpi.name); + ipcp_fini(); + exit(EXIT_FAILURE); + } + + if (fmgr_init()) { + log_err("Failed to initialize flow manager component."); + ipcp_create_r(getpid(), -1); + enroll_fini(); + connmgr_fini(); + rib_fini(); + irm_unbind_api(getpid(), ipcpi.name); + ipcp_fini(); + exit(EXIT_FAILURE); + } + pthread_sigmask(SIG_BLOCK, &sigset, NULL); if (ipcp_boot() < 0) { log_err("Failed to boot IPCP."); ipcp_create_r(getpid(), -1); + fmgr_fini(); + enroll_fini(); + connmgr_fini(); rib_fini(); irm_unbind_api(getpid(), ipcpi.name); ipcp_fini(); @@ -490,6 +470,9 @@ int main(int argc, log_err("Failed to notify IRMd we are initialized."); ipcp_set_state(IPCP_NULL); ipcp_shutdown(); + fmgr_fini(); + enroll_fini(); + connmgr_fini(); rib_fini(); irm_unbind_api(getpid(), ipcpi.name); ipcp_fini(); @@ -501,6 +484,12 @@ int main(int argc, if (ipcp_get_state() == IPCP_SHUTDOWN) shutdown_components(); + fmgr_fini(); + + enroll_fini(); + + connmgr_fini(); + rib_fini(); irm_unbind_api(getpid(), ipcpi.name); diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c new file mode 100644 index 00000000..66da0462 --- /dev/null +++ b/src/ipcpd/normal/neighbors.c @@ -0,0 +1,213 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "neighbors" + +#include <ouroboros/config.h> +#include <ouroboros/shared.h> +#include <ouroboros/ipcp-dev.h> +#include <ouroboros/errno.h> +#include <ouroboros/logs.h> + +#include "neighbors.h" + +#include <stdlib.h> +#include <assert.h> +#include <inttypes.h> + +static void notify_listeners(enum nb_event event, + struct nb * nb, + struct nbs * nbs) +{ + struct list_head * p = NULL; + + list_for_each(p, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e->notify_call(event, nb->conn)) + log_err("Listener reported an error."); + } +} + +struct nbs * nbs_create(void) +{ + struct nbs * nbs; + + nbs = malloc(sizeof(*nbs)); + if (nbs == NULL) + return NULL; + + list_head_init(&nbs->list); + list_head_init(&nbs->notifiers); + + if (pthread_mutex_init(&nbs->list_lock, NULL)) + return NULL; + + if (pthread_mutex_init(&nbs->notifiers_lock, NULL)) { + pthread_mutex_destroy(&nbs->list_lock); + return NULL; + } + + return nbs; +} + +void nbs_destroy(struct nbs * nbs) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + list_del(&e->next); + free(e); + } + + pthread_mutex_unlock(&nbs->list_lock); + + pthread_mutex_destroy(&nbs->list_lock); + pthread_mutex_destroy(&nbs->notifiers_lock); +} + +int nbs_add(struct nbs * nbs, + struct conn conn) +{ + struct nb * nb; + + assert(nbs); + + nb = malloc(sizeof(*nb)); + if (nb == NULL) + return -ENOMEM; + + nb->conn = conn; + + list_head_init(&nb->next); + + pthread_mutex_lock(&nbs->list_lock); + + list_add(&nb->next, &nbs->list); + + notify_listeners(NEIGHBOR_ADDED, nb, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + + log_info("Added neighbor with fd %d and address %" PRIu64 " to list.", + conn.flow_info.fd, conn.conn_info.addr); + + return 0; +} + +int nbs_update_qos(struct nbs * nbs, + int fd, + qosspec_t qs) +{ + struct list_head * p = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each(p, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + e->conn.flow_info.qs = qs; + + notify_listeners(NEIGHBOR_QOS_CHANGE, e, nbs); + + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_del(struct nbs * nbs, + int fd) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + assert(nbs); + + pthread_mutex_lock(&nbs->list_lock); + + list_for_each_safe(p, n, &nbs->list) { + struct nb * e = list_entry(p, struct nb, next); + if (e->conn.flow_info.fd == fd) { + notify_listeners(NEIGHBOR_REMOVED, e, nbs); + list_del(&e->next); + free(e); + pthread_mutex_unlock(&nbs->list_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->list_lock); + + return -1; +} + +int nbs_reg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + assert(nbs); + assert(notify); + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_head_init(¬ify->next); + list_add(¬ify->next, &nbs->notifiers); + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return 0; +} + +int nbs_unreg_notifier(struct nbs * nbs, + struct nb_notifier * notify) +{ + struct list_head * p = NULL; + struct list_head * n = NULL; + + pthread_mutex_lock(&nbs->notifiers_lock); + + list_for_each_safe(p, n, &nbs->notifiers) { + struct nb_notifier * e = + list_entry(p, struct nb_notifier, next); + if (e == notify) { + list_del(&e->next); + pthread_mutex_unlock(&nbs->notifiers_lock); + return 0; + } + } + + pthread_mutex_unlock(&nbs->notifiers_lock); + + return -1; +} diff --git a/src/ipcpd/normal/neighbors.h b/src/ipcpd/normal/neighbors.h new file mode 100644 index 00000000..8714a9aa --- /dev/null +++ b/src/ipcpd/normal/neighbors.h @@ -0,0 +1,81 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Data transfer neighbors + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_NEIGHBORS_H +#define OUROBOROS_IPCPD_NORMAL_NEIGHBORS_H + +#include <ouroboros/irm_config.h> +#include <ouroboros/list.h> +#include <ouroboros/qos.h> +#include <ouroboros/fqueue.h> +#include <ouroboros/cacep.h> + +#include "connmgr.h" + +enum nb_event { + NEIGHBOR_ADDED, + NEIGHBOR_REMOVED, + NEIGHBOR_QOS_CHANGE +}; + +typedef int (* nb_notify_t)(enum nb_event event, + struct conn conn); + +struct nb_notifier { + struct list_head next; + nb_notify_t notify_call; +}; + +struct nb { + struct list_head next; + struct conn conn; +}; + +struct nbs { + struct list_head notifiers; + pthread_mutex_t notifiers_lock; + + struct list_head list; + pthread_mutex_t list_lock; +}; + +struct nbs * nbs_create(void); + +void nbs_destroy(struct nbs * nbs); + +int nbs_add(struct nbs * nbs, + struct conn conn); + +int nbs_update_qos(struct nbs * nbs, + int fd, + qosspec_t qs); + +int nbs_del(struct nbs * nbs, + int fd); + +int nbs_reg_notifier(struct nbs * nbs, + struct nb_notifier * notify); + +int nbs_unreg_notifier(struct nbs * nbs, + struct nb_notifier * notify); + +#endif diff --git a/src/ipcpd/normal/pff.c b/src/ipcpd/normal/pff.c index 2f7d554b..8cab7936 100644 --- a/src/ipcpd/normal/pff.c +++ b/src/ipcpd/normal/pff.c @@ -3,7 +3,8 @@ * * PDU Forwarding Function * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -55,15 +56,16 @@ struct pff * pff_create(void) return tmp; } -int pff_destroy(struct pff * instance) +void pff_destroy(struct pff * instance) { assert(instance); + pthread_mutex_lock(&instance->lock); htable_destroy(instance->table); + pthread_mutex_unlock(&instance->lock); + pthread_mutex_destroy(&instance->lock); free(instance); - - return 0; } int pff_add(struct pff * instance, uint64_t addr, int fd) diff --git a/src/ipcpd/normal/pff.h b/src/ipcpd/normal/pff.h index b4a1400b..667c341e 100644 --- a/src/ipcpd/normal/pff.h +++ b/src/ipcpd/normal/pff.h @@ -3,8 +3,8 @@ * * PDU Forwarding Function * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -25,8 +25,6 @@ #include <stdint.h> -struct pff; - /* * PFF will take a type in the future, * to allow different policies. @@ -34,7 +32,7 @@ struct pff; */ struct pff * pff_create(void); -int pff_destroy(struct pff * instance); +void pff_destroy(struct pff * instance); int pff_add(struct pff * instance, uint64_t addr, diff --git a/src/ipcpd/normal/pol-addr-auth-ops.h b/src/ipcpd/normal/pol-addr-auth-ops.h new file mode 100644 index 00000000..f0f473ef --- /dev/null +++ b/src/ipcpd/normal/pol-addr-auth-ops.h @@ -0,0 +1,34 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Address authority policy ops + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_POL_ADDR_AUTH_OPS_H +#define OUROBOROS_IPCPD_NORMAL_POL_ADDR_AUTH_OPS_H + +struct pol_addr_auth_ops { + int (* init)(void); + + int (* fini)(void); + + uint64_t (* address)(void); +}; + +#endif /* OUROBOROS_IPCPD_NORMAL_POL_ADDR_AUTH_OPS_H */ diff --git a/src/ipcpd/normal/pol-gam-ops.h b/src/ipcpd/normal/pol-gam-ops.h index 0721136c..cfe9cbc3 100644 --- a/src/ipcpd/normal/pol-gam-ops.h +++ b/src/ipcpd/normal/pol-gam-ops.h @@ -3,8 +3,8 @@ * * Graph adjacency manager policy ops * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -24,21 +24,13 @@ #define OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H #include <ouroboros/cacep.h> +#include <ouroboros/qos.h> struct pol_gam_ops { - void * (* create)(struct gam * instance); + void * (* create)(struct nbs * nbs, + struct ae * ae); void (* destroy)(void * o); - - int (* start)(void * o); - - int (* stop)(void * o); - - int (* accept_new_flow)(void * o); - - int (* accept_flow)(void * o, - qosspec_t qs, - const struct cacep_info * info); }; #endif /* OUROBOROS_IPCPD_NORMAL_POL_GAM_OPS_H */ diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c index 5faa1ae8..1f3f6031 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -1,10 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -20,35 +20,54 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define OUROBOROS_PREFIX "complete-graph-adjacency-manager" +#define OUROBOROS_PREFIX "complete" #include <ouroboros/config.h> -#include <ouroboros/logs.h> -#include <ouroboros/list.h> -#include <ouroboros/qos.h> +#include <ouroboros/shared.h> #include <ouroboros/rib.h> +#include <ouroboros/dev.h> +#include <ouroboros/logs.h> +#include <ouroboros/errno.h> +#include <ouroboros/cacep.h> -#include "ipcp.h" -#include "gam.h" +#include "neighbors.h" +#include "frct.h" #include "ribconfig.h" +#include "ipcp.h" +#include "ae.h" #include <string.h> #include <stdlib.h> #include <assert.h> -struct neighbor { - struct list_head next; - char * neighbor; +struct complete { + struct nbs * nbs; + struct ae * ae; + pthread_t allocator; + pthread_t listener; }; -struct complete { - struct list_head neighbors; - pthread_mutex_t neighbors_lock; +static void * listener(void * o) +{ + struct complete * complete; + struct conn conn; - pthread_t allocator; + complete = (struct complete *) o; - struct gam * gam; -}; + 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 * allocator(void * o) { @@ -56,19 +75,37 @@ static void * allocator(void * o) ssize_t len; char ** children; ssize_t i; - struct complete * complete = (struct complete *) o; + struct complete * complete; + struct conn conn; - assert(complete); - assert(complete->gam); + complete = (struct complete *) o; qs.delay = 0; qs.jitter = 0; + /* FIXME: implement QoS specs */ + qs.cube = QOS_CUBE_BE; + /* FIXME: subscribe to members to keep the graph complete. */ len = rib_children("/" MEMBERS_NAME, &children); for (i = 0; i < len; ++i) { - if (strcmp(children[i], ipcpi.name) < 0) - gam_flow_alloc(complete->gam, children[i], qs); + if (strcmp(children[i], ipcpi.name) < 0) { + if (connmgr_alloc(complete->ae, + children[i], + &qs, + &conn)) { + log_warn("Failed to get a 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]); } @@ -78,123 +115,41 @@ static void * allocator(void * o) return (void *) 0; } -void * complete_create(struct gam * gam) +void * complete_create(struct nbs * nbs, + struct ae * ae) { struct complete * complete; - assert(gam); - complete = malloc(sizeof(*complete)); if (complete == NULL) return NULL; - list_head_init(&complete->neighbors); - complete->gam = gam; - - if (pthread_mutex_init(&complete->neighbors_lock, NULL)) { - free(complete); - return NULL; - } - - return (void *) complete; -} - -int complete_start(void * o) -{ - struct complete * complete = (struct complete *) o; - - assert(complete); - assert(complete->gam); + complete->nbs = nbs; + complete->ae = ae; if (pthread_create(&complete->allocator, NULL, - allocator, (void *) complete)) { - pthread_mutex_destroy(&complete->neighbors_lock); - free(complete); - return -1; - } + allocator, (void *) complete)) + return NULL; - /* FIXME: Handle flooding of the flow allocator before detaching.*/ - pthread_join(complete->allocator, NULL); + if (pthread_create(&complete->listener, NULL, + listener, (void *) complete)) + return NULL; - return 0; + return complete; } -int complete_stop(void * o) +void complete_destroy(void * ops_o) { - (void) o; + struct complete * complete; - return 0; -} + assert(ops_o); -void complete_destroy(void * o) -{ - struct list_head * p = NULL; - struct list_head * n = NULL; - struct complete * complete = (struct complete *) o; - - list_for_each_safe(p, n, &complete->neighbors) { - struct neighbor * e = list_entry(p, struct neighbor, next); - list_del(&e->next); - free(e->neighbor); - free(e); - } + complete = (struct complete *) ops_o; - pthread_mutex_destroy(&complete->neighbors_lock); + pthread_cancel(complete->allocator); + pthread_cancel(complete->listener); + pthread_join(complete->allocator, NULL); + pthread_join(complete->listener, NULL); free(complete); } - -int complete_accept_new_flow(void * o) -{ - (void) o; - - return 0; -} - -int complete_accept_flow(void * o, - qosspec_t qs, - const struct cacep_info * info) -{ - struct list_head * pos = NULL; - struct neighbor * n; - struct complete * complete = (struct complete *) o; - - (void) qs; - - assert(complete); - - pthread_mutex_lock(&complete->neighbors_lock); - - list_for_each(pos, &complete->neighbors) { - struct neighbor * e = list_entry(pos, struct neighbor, next); - if (strcmp(e->neighbor, info->name) == 0) { - pthread_mutex_unlock(&complete->neighbors_lock); - return -1; - } - - assert(complete); - assert(&complete->neighbors_lock); - assert(pos->nxt); - } - - n = malloc(sizeof(*n)); - if (n == NULL) { - pthread_mutex_unlock(&complete->neighbors_lock); - return -1; - } - - list_head_init(&n->next); - - n->neighbor = strdup(info->name); - if (n->neighbor == NULL) { - pthread_mutex_unlock(&complete->neighbors_lock); - free(n); - return -1; - } - - list_add(&n->next, &complete->neighbors); - - pthread_mutex_unlock(&complete->neighbors_lock); - - return 0; -} diff --git a/src/ipcpd/normal/pol/complete.h b/src/ipcpd/normal/pol/complete.h index 3f08c2e5..46a535c2 100644 --- a/src/ipcpd/normal/pol/complete.h +++ b/src/ipcpd/normal/pol/complete.h @@ -1,10 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * Graph adjacency manager for IPC Process components + * Sets up a complete graph * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -23,30 +23,19 @@ #ifndef OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H #define OUROBOROS_IPCPD_NORMAL_POL_COMPLETE_H -#include "gam.h" -#include "pol-gam-ops.h" - -void * complete_create(struct gam * instance); - -void complete_destroy(void * o); +#include <ouroboros/irm_config.h> +#include <ouroboros/qos.h> -int complete_start(void * o); - -int complete_stop(void * o); +#include "pol-gam-ops.h" -int complete_accept_new_flow(void * o); +void * complete_create(struct nbs * nbs, + struct ae * ae); -int complete_accept_flow(void * o, - qosspec_t qs, - const struct cacep_info * info); +void complete_destroy(void * ops_o); struct pol_gam_ops complete_ops = { - .create = complete_create, - .destroy = complete_destroy, - .start = complete_start, - .stop = complete_stop, - .accept_new_flow = complete_accept_new_flow, - .accept_flow = complete_accept_flow + .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 d982f5ac..e709da7c 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -3,8 +3,8 @@ * * Policy for flat addresses in a distributed way * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -80,6 +80,16 @@ static int addr_taken(char * name, #define INVALID_ADDRESS 0 +int flat_init(void) +{ + return 0; +} + +int flat_fini(void) +{ + return 0; +} + uint64_t flat_address(void) { struct timespec t; diff --git a/src/ipcpd/normal/pol/flat.h b/src/ipcpd/normal/pol/flat.h index 73d7de8b..d45a89cd 100644 --- a/src/ipcpd/normal/pol/flat.h +++ b/src/ipcpd/normal/pol/flat.h @@ -3,7 +3,8 @@ * * Policy for flat addresses in a distributed way * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -22,8 +23,16 @@ #ifndef OUROBOROS_IPCPD_NORMAL_FLAT_H #define OUROBOROS_IPCPD_NORMAL_FLAT_H +#include "pol-addr-auth-ops.h" + int flat_init(void); int flat_fini(void); uint64_t flat_address(void); +struct pol_addr_auth_ops flat_ops = { + .init = flat_init, + .fini = flat_fini, + .address = flat_address +}; + #endif /* OUROBOROS_IPCPD_NORMAL_FLAT_H */ diff --git a/src/ipcpd/normal/ribconfig.h b/src/ipcpd/normal/ribconfig.h index 15b65ce2..5ecdaab3 100644 --- a/src/ipcpd/normal/ribconfig.h +++ b/src/ipcpd/normal/ribconfig.h @@ -31,9 +31,11 @@ #define MEMBERS_NAME "members" #define DIF_NAME "dif_name" #define DIR_NAME "directory" +#define ROUTING_NAME "fsdb" #define DIF_PATH DLR DIF_NAME #define DIR_PATH DLR DIR_NAME #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 f254bd50..ec465c6b 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -3,8 +3,8 @@ * * RIB manager of the IPC Process * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -45,35 +45,70 @@ #include <assert.h> struct { - flow_set_t * fs; - fqueue_t * fq; - struct gam * gam; + flow_set_t * fs; + fqueue_t * fq; + + struct gam * gam; + struct nbs * nbs; + struct ae * ae; + + struct nb_notifier nb_notifier; } ribmgr; +static int ribmgr_neighbor_event(enum nb_event event, + struct conn conn) +{ + /* We are only interested in neighbors being added and removed. */ + switch (event) { + case NEIGHBOR_ADDED: + flow_set_add(ribmgr.fs, conn.flow_info.fd); + break; + case NEIGHBOR_REMOVED: + flow_set_del(ribmgr.fs, conn.flow_info.fd); + break; + default: + break; + } + + return 0; +} int ribmgr_init(void) { - enum pol_cacep pc; - enum pol_gam pg; + enum pol_gam pg; + struct conn_info info; - if (rib_read(BOOT_PATH "/rm/gam/type", &pg, sizeof(pg)) - != sizeof(pg)) { - log_err("Failed to read policy for ribmgr gam."); + strcpy(info.ae_name, MGMT_AE); + strcpy(info.protocol, CDAP_PROTO); + info.pref_version = 1; + info.pref_syntax = PROTO_GPB; + + ribmgr.nbs = nbs_create(); + if (ribmgr.nbs == NULL) { + log_err("Failed to create neighbors."); return -1; } - if (rib_read(BOOT_PATH "/rm/gam/cacep", &pc, sizeof(pc)) - != sizeof(pc)) { - log_err("Failed to read CACEP policy for ribmgr gam."); + ribmgr.ae = connmgr_ae_create(info); + if (ribmgr.ae == NULL) { + log_err("Failed to create AE struct."); + nbs_destroy(ribmgr.nbs); return -1; } - /* FIXME: Implement cacep policies */ - (void) pc; + 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; + } - ribmgr.gam = gam_create(pg, MGMT_AE); + ribmgr.gam = gam_create(pg, ribmgr.nbs, ribmgr.ae); if (ribmgr.gam == NULL) { log_err("Failed to create gam."); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -81,6 +116,8 @@ int ribmgr_init(void) if (ribmgr.fs == NULL) { log_err("Failed to create flow set."); gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -89,6 +126,19 @@ int ribmgr_init(void) log_err("Failed to create fq."); flow_set_destroy(ribmgr.fs); gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); + return -1; + } + + ribmgr.nb_notifier.notify_call = ribmgr_neighbor_event; + if (nbs_reg_notifier(ribmgr.nbs, &ribmgr.nb_notifier)) { + log_err("Failed to register notifier."); + fqueue_destroy(ribmgr.fq); + flow_set_destroy(ribmgr.fs); + gam_destroy(ribmgr.gam); + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); return -1; } @@ -97,20 +147,12 @@ int ribmgr_init(void) void ribmgr_fini(void) { + nbs_unreg_notifier(ribmgr.nbs, &ribmgr.nb_notifier); flow_set_destroy(ribmgr.fs); fqueue_destroy(ribmgr.fq); gam_destroy(ribmgr.gam); -} - -int ribmgr_flow_arr(int fd, - qosspec_t qs) -{ - assert(ribmgr.gam); - - if (gam_flow_arr(ribmgr.gam, fd, qs)) - return -1; - - return 0; + connmgr_ae_destroy(ribmgr.ae); + nbs_destroy(ribmgr.nbs); } int ribmgr_disseminate(char * path, diff --git a/src/ipcpd/normal/ribmgr.h b/src/ipcpd/normal/ribmgr.h index 12f407ab..8922688a 100644 --- a/src/ipcpd/normal/ribmgr.h +++ b/src/ipcpd/normal/ribmgr.h @@ -3,7 +3,8 @@ * * RIB manager of the IPC Process * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -41,9 +42,6 @@ int ribmgr_init(void); void ribmgr_fini(void); -int ribmgr_flow_arr(int fd, - qosspec_t qs); - 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 new file mode 100644 index 00000000..0b82b70d --- /dev/null +++ b/src/ipcpd/normal/routing.c @@ -0,0 +1,302 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "routing" + +#include <ouroboros/config.h> +#include <ouroboros/errno.h> +#include <ouroboros/list.h> +#include <ouroboros/logs.h> +#include <ouroboros/rib.h> +#include <ouroboros/rqueue.h> + +#include "routing.h" +#include "ribmgr.h" +#include "ribconfig.h" +#include "ipcp.h" +#include "graph.h" + +#include <assert.h> +#include <stdlib.h> +#include <inttypes.h> +#include <string.h> + +#include "fso.pb-c.h" +typedef Fso fso_t; + +#define BUF_SIZE 256 + +struct routing_table_entry { + struct list_head next; + uint64_t dst; + uint64_t nhop; +}; + +struct routing_i { + struct pff * pff; +}; + +struct { + struct nbs * nbs; + struct nb_notifier nb_notifier; + + struct graph * graph; + + ro_set_t * set; + rqueue_t * queue; + pthread_t rib_listener; +} routing; + +struct routing_i * routing_i_create(struct pff * pff) +{ + struct routing_i * tmp; + + assert(pff); + + tmp = malloc(sizeof(*tmp)); + if (tmp == NULL) + return NULL; + + tmp->pff = pff; + + return tmp; +} + +void routing_i_destroy(struct routing_i * instance) +{ + assert(instance); + + free(instance); +} + +static int routing_neighbor_event(enum nb_event event, + struct conn conn) +{ + char path[RIB_MAX_PATH_LEN + 1]; + char fso_name[RIB_MAX_PATH_LEN + 1]; + fso_t fso = FSO__INIT; + size_t len; + uint8_t * data; + + sprintf(fso_name, "%" PRIx64 "-%" PRIx64, + ipcpi.dt_addr, conn.conn_info.addr); + rib_path_append(rib_path_append(path, ROUTING_PATH), fso_name); + + switch (event) { + case NEIGHBOR_ADDED: + fso.s_addr = ipcpi.dt_addr; + fso.d_addr = conn.conn_info.addr; + + len = fso__get_packed_size(&fso); + if (len == 0) + return -1; + + data = malloc(len); + if (data == NULL) + return -1; + + fso__pack(&fso, data); + + if (rib_add(ROUTING_PATH, fso_name)) { + log_err("Failed to add FSO."); + free(data); + return -1; + } + + if (rib_put(path, data, len)) { + log_err("Failed to put FSO in RIB."); + rib_del(path); + free(data); + return -1; + } + + log_dbg("Added %s to RIB.", path); + + break; + case NEIGHBOR_REMOVED: + if (rib_del(path)) { + log_err("Failed to remove FSO."); + return -1; + } + + log_dbg("Removed %s from RIB.", path); + + break; + case NEIGHBOR_QOS_CHANGE: + log_info("Not currently supported."); + break; + default: + log_info("Unsupported event for routing."); + break; + } + + return 0; +} + +static int read_fso(char * path, + int32_t flag) +{ + ssize_t len; + uint8_t ro[BUF_SIZE]; + fso_t * fso; + qosspec_t qs; + + len = rib_read(path, ro, BUF_SIZE); + if (len < 0) { + log_err("Failed to read FSO."); + return -1; + } + + fso = fso__unpack(NULL, len, ro); + if (fso == NULL) { + log_err("Failed to unpack."); + return -1; + } + + if (flag & RO_CREATE) { + if (graph_add_edge(routing.graph, + fso->s_addr, fso->d_addr, qs)) { + log_err("Failed to add edge to graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } else if (flag & RO_MODIFY) { + if (graph_update_edge(routing.graph, + fso->s_addr, fso->d_addr, qs)) { + log_err("Failed to update edge of graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } else if (flag & RO_DELETE) { + if (graph_del_edge(routing.graph, fso->s_addr, fso->d_addr)) { + log_err("Failed to del edge of graph."); + fso__free_unpacked(fso, NULL); + return -1; + } + } + + fso__free_unpacked(fso, NULL); + + return 0; +} + +static void * rib_listener(void * o) +{ + int32_t flag; + char path[RIB_MAX_PATH_LEN + 1]; + char ** children; + ssize_t len; + int i; + + (void) o; + + if (ro_set_add(routing.set, ROUTING_PATH, + RO_MODIFY | RO_CREATE | RO_DELETE)) { + log_err("Failed to add to RO set"); + return (void * ) -1; + } + + len = rib_children(ROUTING_PATH, &children); + if (len < 0) { + log_err("Failed to retrieve children."); + return (void *) -1; + } + + for (i = 0; i < len; i++) { + if (read_fso(children[i], RO_CREATE)) { + log_err("Failed to parse FSO."); + continue; + } + } + + while (rib_event_wait(routing.set, routing.queue, NULL)) { + flag = rqueue_next(routing.queue, path); + if (flag < 0) + continue; + + if (read_fso(children[i], flag)) { + log_err("Failed to parse FSO."); + continue; + } + } + + return (void *) 0; +} + +int routing_init(struct nbs * nbs) +{ + routing.graph = graph_create(); + if (routing.graph == NULL) + return -1; + + if (rib_add(RIB_ROOT, ROUTING_NAME)) { + graph_destroy(routing.graph); + return -1; + } + + routing.nbs = nbs; + + routing.nb_notifier.notify_call = routing_neighbor_event; + if (nbs_reg_notifier(routing.nbs, &routing.nb_notifier)) { + graph_destroy(routing.graph); + rib_del(ROUTING_PATH); + return -1; + } + + routing.set = ro_set_create(); + if (routing.set == NULL) { + nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); + graph_destroy(routing.graph); + rib_del(ROUTING_PATH); + return -1; + } + + routing.queue = rqueue_create(); + if (routing.queue == NULL) { + ro_set_destroy(routing.set); + nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); + graph_destroy(routing.graph); + rib_del(ROUTING_PATH); + return -1; + } + + pthread_create(&routing.rib_listener, NULL, rib_listener, NULL); + + return 0; +} + +void routing_fini(void) +{ + pthread_cancel(routing.rib_listener); + + pthread_join(routing.rib_listener, NULL); + + rqueue_destroy(routing.queue); + + ro_set_destroy(routing.set); + + graph_destroy(routing.graph); + + rib_del(ROUTING_PATH); + + nbs_unreg_notifier(routing.nbs, &routing.nb_notifier); +} diff --git a/src/ipcpd/normal/routing.h b/src/ipcpd/normal/routing.h new file mode 100644 index 00000000..0794ef28 --- /dev/null +++ b/src/ipcpd/normal/routing.h @@ -0,0 +1,45 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Routing component of the IPCP + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef OUROBOROS_IPCPD_NORMAL_ROUTING_H +#define OUROBOROS_IPCPD_NORMAL_ROUTING_H + +#include <ouroboros/qos.h> + +#include "pff.h" +#include "neighbors.h" + +#include <stdint.h> + +/* + * Routing will take a type in the future, + * to allow different policies. + */ +int routing_init(struct nbs * nbs); + +void routing_fini(void); + +struct routing_i * routing_i_create(struct pff * pff); + +void routing_i_destroy(struct routing_i * instance); + +#endif /* OUROBOROS_IPCPD_NORMAL_ROUTING_H */ diff --git a/src/ipcpd/normal/shm_pci.c b/src/ipcpd/normal/shm_pci.c index 0807a24f..1170adff 100644 --- a/src/ipcpd/normal/shm_pci.c +++ b/src/ipcpd/normal/shm_pci.c @@ -3,8 +3,8 @@ * * Protocol Control Information in Shared Memory Map * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/normal/shm_pci.h b/src/ipcpd/normal/shm_pci.h index 17ce5cdd..0c54c883 100644 --- a/src/ipcpd/normal/shm_pci.h +++ b/src/ipcpd/normal/shm_pci.h @@ -3,8 +3,8 @@ * * Protocol Control Information in Shared Memory Map * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index bec2486c..eb4ec33f 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -3,8 +3,8 @@ * * IPC process utilities * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h index 28087901..ac670b43 100644 --- a/src/ipcpd/shim-data.h +++ b/src/ipcpd/shim-data.h @@ -3,8 +3,8 @@ * * Utitilies for building IPC processes * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/ipcpd/shim-eth-llc/CMakeLists.txt b/src/ipcpd/shim-eth-llc/CMakeLists.txt index bd9add74..bd3049a2 100644 --- a/src/ipcpd/shim-eth-llc/CMakeLists.txt +++ b/src/ipcpd/shim-eth-llc/CMakeLists.txt @@ -15,21 +15,21 @@ include_directories(${CMAKE_BINARY_DIR}/include) protobuf_generate_c(SHIM_ETH_LLC_PROTO_SRCS SHIM_ETH_LLC_PROTO_HDRS shim_eth_llc_messages.proto) -SET(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc +set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc CACHE STRING "IPCP_SHIM_ETH_LLC_TARGET") set(SHIM_ETH_LLC_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES} - ${SHIM_ETH_LLC_PROTO_SRCS}) -target_link_libraries (ipcpd-shim-eth-llc LINK_PUBLIC ouroboros - ${PROTOBUF_C_LIBRARY}) +add_executable(ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES} + ${SHIM_ETH_LLC_PROTO_SRCS}) +target_link_libraries(ipcpd-shim-eth-llc LINK_PUBLIC ouroboros + ${PROTOBUF_C_LIBRARY}) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-eth-llc -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-shim-eth-llc -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-shim-eth-llc RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index cd913de4..8015d64a 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -3,7 +3,8 @@ * * Shim IPC process over Ethernet with LLC * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -334,7 +335,6 @@ static int eth_llc_ipcp_send_mgmt_frame(shim_eth_llc_msg_t * msg, static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr, uint8_t ssap, char * dst_name, - char * src_ae_name, qoscube_t cube) { shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; @@ -343,7 +343,6 @@ static int eth_llc_ipcp_sap_alloc(uint8_t * dst_addr, msg.has_ssap = true; msg.ssap = ssap; msg.dst_name = dst_name; - msg.src_ae_name = src_ae_name; msg.has_qoscube = true; msg.qoscube = cube; @@ -371,7 +370,6 @@ static int eth_llc_ipcp_sap_alloc_resp(uint8_t * dst_addr, static int eth_llc_ipcp_sap_req(uint8_t r_sap, uint8_t * r_addr, char * dst_name, - char * src_ae_name, qoscube_t cube) { int fd; @@ -380,7 +378,7 @@ static int eth_llc_ipcp_sap_req(uint8_t r_sap, pthread_rwlock_wrlock(ð_llc_data.flows_lock); /* reply to IRM */ - fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); + fd = ipcp_flow_req_arr(getpid(), dst_name, cube); if (fd < 0) { pthread_rwlock_unlock(ð_llc_data.flows_lock); pthread_rwlock_unlock(&ipcpi.state_lock); @@ -491,7 +489,6 @@ static int eth_llc_ipcp_mgmt_frame(uint8_t * buf, eth_llc_ipcp_sap_req(msg->ssap, r_addr, msg->dst_name, - msg->src_ae_name, msg->qoscube); } break; @@ -989,7 +986,6 @@ static int eth_llc_ipcp_name_query(char * name) static int eth_llc_ipcp_flow_alloc(int fd, char * dst_name, - char * src_ae_name, qoscube_t cube) { uint8_t ssap = 0; @@ -998,7 +994,7 @@ static int eth_llc_ipcp_flow_alloc(int fd, log_dbg("Allocating flow to %s.", dst_name); - if (dst_name == NULL || src_ae_name == NULL) + if (dst_name == NULL) return -1; if (cube != QOS_CUBE_BE && cube != QOS_CUBE_FRC) { @@ -1038,11 +1034,7 @@ static int eth_llc_ipcp_flow_alloc(int fd, memcpy(r_addr, &addr, MAC_SIZE); - if (eth_llc_ipcp_sap_alloc(r_addr, - ssap, - dst_name, - src_ae_name, - cube) < 0) { + if (eth_llc_ipcp_sap_alloc(r_addr, ssap, dst_name, cube) < 0) { pthread_rwlock_rdlock(&ipcpi.state_lock); pthread_rwlock_wrlock(ð_llc_data.flows_lock); bmp_release(eth_llc_data.saps, eth_llc_data.fd_to_ef[fd].sap); diff --git a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto index cedb0fd4..2d66428c 100644 --- a/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto +++ b/src/ipcpd/shim-eth-llc/shim_eth_llc_messages.proto @@ -32,9 +32,8 @@ enum shim_eth_llc_msg_code { message shim_eth_llc_msg { required shim_eth_llc_msg_code code = 1; optional string dst_name = 2; - optional string src_ae_name = 3; - optional uint32 ssap = 4; - optional uint32 dsap = 5; - optional uint32 qoscube = 6; - optional sint32 response = 7; + optional uint32 ssap = 3; + optional uint32 dsap = 4; + optional uint32 qoscube = 5; + optional sint32 response = 6; }; diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt index cc60cfb7..2560f242 100644 --- a/src/ipcpd/shim-udp/CMakeLists.txt +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -19,15 +19,15 @@ configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/shim_udp_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h") -SET(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") +set(IPCP_SHIM_UDP_TARGET ipcpd-shim-udp CACHE STRING "IPCP_SHIM_UDP_TARGET") set(SHIM_UDP_SOURCES # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/main.c) -add_executable (ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES} +add_executable(ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES} ${SHIM_UDP_PROTO_SRCS} "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h") -target_link_libraries (ipcpd-shim-udp LINK_PUBLIC ouroboros +target_link_libraries(ipcpd-shim-udp LINK_PUBLIC ouroboros ${PROTOBUF_C_LIBRARY}) # Find the nsupdate executable @@ -40,6 +40,7 @@ find_program(NSLOOKUP_EXECUTABLE NAMES nslookup DOC "The nslookup tool that resolves DNS names") +include(AddCompileFlags) if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND") message("-- Could not find nsupdate. Disabling DDNS functionality.") elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND") @@ -47,12 +48,11 @@ elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND") else () message("-- Found nsupdate: ${NSUPDATE_EXECUTABLE}") message("-- Found nslookup: ${NSLOOKUP_EXECUTABLE}") - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_ENABLE_DNS) -endif() + add_compile_flags(ipcpd-shim-udp -DCONFIG_OUROBOROS_ENABLE_DNS) +endif () -include(MacroAddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ipcpd-shim-udp -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION sbin) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 4d6fdc3b..3bbce79d 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -3,7 +3,8 @@ * * Shim IPC process over UDP * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -197,7 +198,6 @@ static int send_shim_udp_msg(shim_udp_msg_t * msg, static int ipcp_udp_port_alloc(uint32_t dst_ip_addr, uint16_t src_udp_port, char * dst_name, - char * src_ae_name, qoscube_t cube) { shim_udp_msg_t msg = SHIM_UDP_MSG__INIT; @@ -205,7 +205,6 @@ static int ipcp_udp_port_alloc(uint32_t dst_ip_addr, msg.code = SHIM_UDP_MSG_CODE__FLOW_REQ; msg.src_udp_port = src_udp_port; msg.dst_name = dst_name; - msg.src_ae_name = src_ae_name; msg.has_qoscube = true; msg.qoscube = cube; @@ -231,7 +230,6 @@ static int ipcp_udp_port_alloc_resp(uint32_t dst_ip_addr, static int ipcp_udp_port_req(struct sockaddr_in * c_saddr, char * dst_name, - char * src_ae_name, qoscube_t cube) { int skfd; @@ -275,7 +273,7 @@ static int ipcp_udp_port_req(struct sockaddr_in * c_saddr, pthread_rwlock_wrlock(&udp_data.flows_lock); /* reply to IRM */ - fd = ipcp_flow_req_arr(getpid(), dst_name, src_ae_name, cube); + fd = ipcp_flow_req_arr(getpid(), dst_name, cube); if (fd < 0) { pthread_rwlock_unlock(&udp_data.flows_lock); pthread_rwlock_unlock(&ipcpi.state_lock); @@ -397,7 +395,6 @@ static void * ipcp_udp_listener(void * o) c_saddr.sin_port = msg->src_udp_port; ipcp_udp_port_req(&c_saddr, msg->dst_name, - msg->src_ae_name, msg->qoscube); break; case SHIM_UDP_MSG_CODE__FLOW_REPLY: @@ -957,7 +954,6 @@ static int ipcp_udp_name_query(char * name) static int ipcp_udp_flow_alloc(int fd, char * dst_name, - char * src_ae_name, qoscube_t cube) { struct sockaddr_in r_saddr; /* server address */ @@ -969,10 +965,8 @@ static int ipcp_udp_flow_alloc(int fd, log_dbg("Allocating flow to %s.", dst_name); assert(dst_name); - assert(src_ae_name); - if (strlen(dst_name) > 255 - || strlen(src_ae_name) > 255) { + if (strlen(dst_name) > 255) { log_err("Name too long for this shim."); return -1; } @@ -1043,7 +1037,6 @@ static int ipcp_udp_flow_alloc(int fd, if (ipcp_udp_port_alloc(ip_addr, f_saddr.sin_port, dst_name, - src_ae_name, cube) < 0) { pthread_rwlock_rdlock(&ipcpi.state_lock); pthread_rwlock_wrlock(&udp_data.flows_lock); diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c index d4a5d8ed..d7bd0bb7 100644 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ b/src/ipcpd/shim-udp/tests/shim_udp_test.c @@ -3,7 +3,8 @@ * * Test of the Shim UDP IPCP Daemon * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/ipcpd/tests/CMakeLists.txt b/src/ipcpd/tests/CMakeLists.txt index 57a910c8..07430127 100644 --- a/src/ipcpd/tests/CMakeLists.txt +++ b/src/ipcpd/tests/CMakeLists.txt @@ -13,9 +13,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) create_test_sourcelist(${src_folder}_tests test_suite.c - # Add new tests here - timerwheel_test.c -) + # Add new tests here + timerwheel_test.c + ) add_executable(${src_folder}_test EXCLUDE_FROM_ALL ${${src_folder}_tests}) target_link_libraries(${src_folder}_test ouroboros) @@ -25,7 +25,7 @@ add_dependencies(check ${src_folder}_test) set(tests_to_run ${${src_folder}_tests}) remove(tests_to_run test_suite.c) -foreach(test ${tests_to_run}) +foreach (test ${tests_to_run}) get_filename_component(test_name ${test} NAME_WE) add_test(${test_name} ${C_TEST_PATH}/${src_folder}_test ${test_name}) -endforeach(test) +endforeach (test) diff --git a/src/ipcpd/tests/timerwheel_test.c b/src/ipcpd/tests/timerwheel_test.c index 23de403a..cf5b0333 100644 --- a/src/ipcpd/tests/timerwheel_test.c +++ b/src/ipcpd/tests/timerwheel_test.c @@ -3,7 +3,8 @@ * * Test of the timer wheel * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/ipcpd/timerwheel.c b/src/ipcpd/timerwheel.c index ef79bc14..d309bbf9 100644 --- a/src/ipcpd/timerwheel.c +++ b/src/ipcpd/timerwheel.c @@ -3,7 +3,8 @@ * * Timerwheel * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/ipcpd/timerwheel.h b/src/ipcpd/timerwheel.h index 8ef9437c..aa71c73d 100644 --- a/src/ipcpd/timerwheel.h +++ b/src/ipcpd/timerwheel.h @@ -3,7 +3,8 @@ * * Ring buffer for incoming SDUs * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -31,8 +32,8 @@ void timerwheel_destroy(struct timerwheel * tw); int timerwheel_add(struct timerwheel * tw, void (* func)(void *), - void * arg, - size_t arg_len, - unsigned int delay); /* ms */ + void * arg, + size_t arg_len, + unsigned int delay); /* ms */ #endif /* OUROBOROS_IPCPD_TIMERWHEEL_H */ diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index 16b53414..930c7b05 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -5,23 +5,23 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - api_table.c - apn_table.c - ipcp.c - irm_flow.c - main.c - registry.c - utils.c -) + # Add source files here + api_table.c + apn_table.c + ipcp.c + irm_flow.c + main.c + registry.c + utils.c + ) add_executable (irmd ${SOURCE_FILES}) target_link_libraries (irmd LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(irmd -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(irmd -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS irmd RUNTIME DESTINATION sbin) diff --git a/src/irmd/api_table.c b/src/irmd/api_table.c index 83153aac..3b80ac91 100644 --- a/src/irmd/api_table.c +++ b/src/irmd/api_table.c @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Application Instance Table * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/api_table.h b/src/irmd/api_table.h index df788bbc..c7998c7f 100644 --- a/src/irmd/api_table.h +++ b/src/irmd/api_table.h @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Application Instance Table * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/apn_table.c b/src/irmd/apn_table.c index 955618d8..d265e2f0 100644 --- a/src/irmd/apn_table.c +++ b/src/irmd/apn_table.c @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Application Process Table * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/apn_table.h b/src/irmd/apn_table.h index 550012bf..311c0f3d 100644 --- a/src/irmd/apn_table.h +++ b/src/irmd/apn_table.h @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Application Process Names Table * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index dcf77eec..06b66d3b 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -3,7 +3,8 @@ * * The API to instruct IPCPs * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -328,14 +329,13 @@ int ipcp_flow_alloc(pid_t api, int port_id, pid_t n_api, char * dst_name, - char * src_ae_name, qoscube_t cube) { ipcp_msg_t msg = IPCP_MSG__INIT; ipcp_msg_t * recv_msg = NULL; int ret = -1; - if (dst_name == NULL || src_ae_name == NULL) + if (dst_name == NULL) return -EINVAL; msg.code = IPCP_MSG_CODE__IPCP_FLOW_ALLOC; @@ -343,7 +343,6 @@ int ipcp_flow_alloc(pid_t api, msg.port_id = port_id; msg.has_api = true; msg.api = n_api; - msg.src_ae_name = src_ae_name; msg.dst_name = dst_name; msg.has_qoscube = true; msg.qoscube = cube; diff --git a/src/irmd/ipcp.h b/src/irmd/ipcp.h index 658aa2ea..bb868191 100644 --- a/src/irmd/ipcp.h +++ b/src/irmd/ipcp.h @@ -3,7 +3,8 @@ * * The API for the IRM to instruct IPCPs * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -52,7 +53,6 @@ int ipcp_flow_alloc(pid_t api, int port_id, pid_t n_api, char * dst_name, - char * src_ae_name, qoscube_t qos); int ipcp_flow_alloc_resp(pid_t api, diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c index d2482391..20d2511c 100644 --- a/src/irmd/irm_flow.c +++ b/src/irmd/irm_flow.c @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Flows * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/irm_flow.h b/src/irmd/irm_flow.h index dc60d139..9a439204 100644 --- a/src/irmd/irm_flow.h +++ b/src/irmd/irm_flow.h @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Flows * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/irmd/main.c b/src/irmd/main.c index cc13ccea..9eb34f38 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -3,8 +3,8 @@ * * The IPC Resource Manager * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -976,7 +976,6 @@ static int api_announce(pid_t api, } static struct irm_flow * flow_accept(pid_t api, - char ** dst_ae_name, qoscube_t * cube) { struct irm_flow * f = NULL; @@ -999,8 +998,10 @@ static struct irm_flow * flow_accept(pid_t api, log_err("Unknown instance %d calling accept.", api); return NULL; } + log_dbg("New instance (%d) of %s added.", api, e->apn); log_dbg("This instance accepts flows for:"); + list_for_each(p, &e->names) { struct str_el * s = list_entry(p, struct str_el, next); log_dbg(" %s", s->str); @@ -1064,9 +1065,6 @@ static struct irm_flow * flow_accept(pid_t api, *cube = re->qos; - if (dst_ae_name != NULL) - *dst_ae_name = re->req_ae_name; - log_info("Flow on port_id %d allocated.", f->port_id); pthread_rwlock_unlock(&irmd->flows_lock); @@ -1148,7 +1146,6 @@ static int flow_alloc_resp(pid_t n_api, static struct irm_flow * flow_alloc(pid_t api, char * dst_name, - char * src_ae_name, qoscube_t cube) { struct irm_flow * f; @@ -1197,7 +1194,7 @@ static struct irm_flow * flow_alloc(pid_t api, pthread_rwlock_unlock(&irmd->state_lock); if (ipcp_flow_alloc(ipcp, port_id, api, - dst_name, src_ae_name, cube) < 0) { + dst_name, cube) < 0) { pthread_rwlock_rdlock(&irmd->state_lock); pthread_rwlock_wrlock(&irmd->flows_lock); list_del(&f->next); @@ -1348,7 +1345,6 @@ static pid_t auto_execute(char ** argv) static struct irm_flow * flow_req_arr(pid_t api, char * dst_name, - char * ae_name, qoscube_t cube) { struct reg_entry * re = NULL; @@ -1363,8 +1359,7 @@ static struct irm_flow * flow_req_arr(pid_t api, struct timespec wt = {IRMD_REQ_ARR_TIMEOUT / 1000, (IRMD_REQ_ARR_TIMEOUT % 1000) * MILLION}; - log_dbg("Flow req arrived from IPCP %d for %s on AE %s.", - api, dst_name, ae_name); + log_dbg("Flow req arrived from IPCP %d for %s.", api, dst_name); pthread_rwlock_rdlock(&irmd->state_lock); pthread_rwlock_rdlock(&irmd->reg_lock); @@ -1469,7 +1464,6 @@ static struct irm_flow * flow_req_arr(pid_t api, pthread_rwlock_unlock(&irmd->flows_lock); pthread_rwlock_rdlock(&irmd->reg_lock); - re->req_ae_name = ae_name; re->qos = cube; reg_entry_set_state(re, REG_NAME_FLOW_ARRIVED); @@ -1926,7 +1920,6 @@ void * mainloop(void * o) case IRM_MSG_CODE__IRM_FLOW_ACCEPT: ret_msg.has_qoscube = true; e = flow_accept(msg->api, - &ret_msg.ae_name, (qoscube_t *) &ret_msg.qoscube); if (e == NULL) { ret_msg.has_result = true; @@ -1947,7 +1940,6 @@ void * mainloop(void * o) case IRM_MSG_CODE__IRM_FLOW_ALLOC: e = flow_alloc(msg->api, msg->dst_name, - msg->ae_name, msg->qoscube); if (e == NULL) { ret_msg.has_result = true; @@ -1970,7 +1962,6 @@ void * mainloop(void * o) case IRM_MSG_CODE__IPCP_FLOW_REQ_ARR: e = flow_req_arr(msg->api, msg->dst_name, - msg->ae_name, msg->qoscube); if (e == NULL) { ret_msg.has_result = true; @@ -2077,6 +2068,28 @@ static int irm_create(void) return -ENOMEM; } + if ((irmd->lf = lockfile_create()) == NULL) { + if ((irmd->lf = lockfile_open()) == NULL) { + log_err("Lockfile error."); + irm_destroy(); + return -1; + } + + if (kill(lockfile_owner(irmd->lf), 0) < 0) { + log_info("IRMd didn't properly shut down last time."); + shm_rdrbuff_destroy(shm_rdrbuff_open()); + log_info("Stale resources cleaned."); + lockfile_destroy(irmd->lf); + irmd->lf = lockfile_create(); + } else { + log_info("IRMd already running (%d), exiting.", + lockfile_owner(irmd->lf)); + lockfile_close(irmd->lf); + free(irmd); + return -1; + } + } + if (stat(SOCK_PATH, &st) == -1) { if (mkdir(SOCK_PATH, 0777)) { log_err("Failed to create sockets directory."); @@ -2104,28 +2117,6 @@ static int irm_create(void) return -1; } - if ((irmd->lf = lockfile_create()) == NULL) { - if ((irmd->lf = lockfile_open()) == NULL) { - log_err("Lockfile error."); - irm_destroy(); - return -1; - } - - if (kill(lockfile_owner(irmd->lf), 0) < 0) { - log_info("IRMd didn't properly shut down last time."); - shm_rdrbuff_destroy(shm_rdrbuff_open()); - log_info("Stale resources cleaned."); - lockfile_destroy(irmd->lf); - irmd->lf = lockfile_create(); - } else { - log_info("IRMd already running (%d), exiting.", - lockfile_owner(irmd->lf)); - lockfile_close(irmd->lf); - free(irmd); - return -1; - } - } - if (irmd->lf == NULL) { irm_destroy(); return -1; diff --git a/src/irmd/registry.c b/src/irmd/registry.c index 9512d664..a4588963 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Registry * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -52,7 +53,6 @@ static struct reg_entry * reg_entry_create(void) e->name = NULL; e->state = REG_NAME_NULL; - e->req_ae_name = NULL; e->response = -1; return e; diff --git a/src/irmd/registry.h b/src/irmd/registry.h index 67e4da40..cf4ea432 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -3,7 +3,8 @@ * * The IPC Resource Manager - Registry * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 @@ -62,7 +63,6 @@ struct reg_entry { struct list_head reg_apis; enum reg_name_state state; - char * req_ae_name; qoscube_t qos; int response; pthread_cond_t state_cond; diff --git a/src/irmd/utils.c b/src/irmd/utils.c index 7d63f020..97193b53 100644 --- a/src/irmd/utils.c +++ b/src/irmd/utils.c @@ -3,8 +3,8 @@ * * The IPC Resource Manager - Utilities * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/irmd/utils.h b/src/irmd/utils.h index 03296259..36ec3d8e 100644 --- a/src/irmd/utils.h +++ b/src/irmd/utils.h @@ -3,7 +3,8 @@ * * Utils of the IPC Resource Manager * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -44,6 +45,7 @@ int wildcard_match(const char * pattern, /* functions for copying and destroying arguments list */ char ** argvdup(char ** argv); + void argvfree(char ** argv); #endif /* OUROBOROS_IRM_UTILS_H */ diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 6af50782..f6a30ef7 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -9,22 +9,22 @@ protobuf_generate_c(IPCP_PROTO_SRCS IPCP_PROTO_HDRS ipcpd_messages.proto) protobuf_generate_c(DIF_CONFIG_PROTO_SRCS DIF_CONFIG_PROTO_HDRS dif_config.proto) protobuf_generate_c(CDAP_PROTO_SRCS CDAP_PROTO_HDRS cdap.proto) -protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto) protobuf_generate_c(RO_PROTO_SRCS RO_PROTO_HDRS ro.proto) +protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto) -if(NOT APPLE) +if (NOT APPLE) find_library(LIBRT_LIBRARIES rt) - if(NOT LIBRT_LIBRARIES) + if (NOT LIBRT_LIBRARIES) message(FATAL_ERROR "librt not found") - endif() -else() + endif () +else () set(LIBRT_LIBRARIES "") -endif() +endif () find_library(LIBPTHREAD_LIBRARIES pthread) -if(NOT LIBPTHREAD_LIBRARIES) +if (NOT LIBPTHREAD_LIBRARIES) message(FATAL_ERROR "libpthread not found") -endif() +endif () set(SOURCE_FILES # Add source files here @@ -52,15 +52,15 @@ set(SOURCE_FILES ) add_library(ouroboros SHARED ${SOURCE_FILES} ${IRM_PROTO_SRCS} - ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} - ${CDAP_PROTO_SRCS} ${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS}) + ${IPCP_PROTO_SRCS} ${DIF_CONFIG_PROTO_SRCS} ${CDAP_PROTO_SRCS} + ${CACEP_PROTO_SRCS} ${RO_PROTO_SRCS}) target_link_libraries(ouroboros ${LIBRT_LIBRARIES} ${LIBPTHREAD_LIBRARIES} ${PROTOBUF_C_LIBRARY}) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(ouroboros -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(ouroboros -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS ouroboros LIBRARY DESTINATION usr/lib) diff --git a/src/lib/bitmap.c b/src/lib/bitmap.c index 255f2b4d..93ffda77 100644 --- a/src/lib/bitmap.c +++ b/src/lib/bitmap.c @@ -3,8 +3,8 @@ * * Bitmap implementation * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Francesco Salvestrini <f.salvestrini@nextworks.it> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/btree.c b/src/lib/btree.c index 38302dae..10a900d6 100644 --- a/src/lib/btree.c +++ b/src/lib/btree.c @@ -3,8 +3,8 @@ * * B-trees * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/btree.h b/src/lib/btree.h index 79467099..f7c293c5 100644 --- a/src/lib/btree.h +++ b/src/lib/btree.h @@ -3,7 +3,8 @@ * * B-trees * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/cacep.c b/src/lib/cacep.c index 00557444..a2c5c3d2 100644 --- a/src/lib/cacep.c +++ b/src/lib/cacep.c @@ -1,9 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * The Common Application Connection Establishment Phase + * The Common Application Connection Establishment Protocol * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -29,93 +30,53 @@ #include <string.h> #include "cacep.pb-c.h" -typedef Cacep cacep_t; +typedef CacepMsg cacep_msg_t; -#define BUF_SIZE 2048 +#define BUF_SIZE 64 -struct cacep { - int fd; - char * name; - uint64_t address; -}; - -struct cacep * cacep_create(int fd, - const char * name, - uint64_t address) -{ - struct cacep * tmp; - - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) - return NULL; - - tmp->fd = fd; - tmp->address = address; - tmp->name = strdup(name); - if (tmp->name == NULL) { - free(tmp); - return NULL; - } - - return tmp; -} - -int cacep_destroy(struct cacep * instance) -{ - if (instance == NULL) - return 0; - - free(instance->name); - free(instance); - - return 0; -} - -static struct cacep_info * read_msg(struct cacep * instance) +int read_msg(int fd, + struct conn_info * info) { - struct cacep_info * tmp; - uint8_t buf[BUF_SIZE]; - cacep_t * msg; - ssize_t len; + uint8_t buf[BUF_SIZE]; + cacep_msg_t * msg; + ssize_t len; - len = flow_read(instance->fd, buf, BUF_SIZE); + len = flow_read(fd, buf, BUF_SIZE); if (len < 0) - return NULL; + return -1; - msg = cacep__unpack(NULL, len, buf); + msg = cacep_msg__unpack(NULL, len, buf); if (msg == NULL) - return NULL; + return -1; - tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) { - cacep__free_unpacked(msg, NULL); - return NULL; - } + strcpy(info->ae_name, msg->ae_name); + strcpy(info->protocol, msg->protocol); - tmp->addr = msg->address; - tmp->name = strdup(msg->name); - if (tmp->name == NULL) { - free(tmp); - cacep__free_unpacked(msg, NULL); - return NULL; - } + info->pref_version = msg->pref_version; + info->pref_syntax = msg->pref_syntax; + info->addr = msg->address; - cacep__free_unpacked(msg, NULL); + cacep_msg__free_unpacked(msg, NULL); - return tmp; + return 0; } -static int send_msg(struct cacep * instance) +static int send_msg(int fd, + const struct conn_info * info) { - cacep_t msg = CACEP__INIT; - int ret = 0; - uint8_t * data = NULL; - size_t len = 0; - - msg.name = instance->name; - msg.address = instance->address; + cacep_msg_t msg = CACEP_MSG__INIT; + uint8_t * data = NULL; + size_t len = 0; + + msg.ae_name = (char *) info->ae_name; + msg.protocol = (char *) info->protocol; + msg.address = info->addr; + msg.pref_version = info->pref_version; + msg.pref_syntax = info->pref_syntax; + if (msg.pref_syntax < 0) + return -1; - len = cacep__get_packed_size(&msg); + len = cacep_msg__get_packed_size(&msg); if (len == 0) return -1; @@ -123,49 +84,38 @@ static int send_msg(struct cacep * instance) if (data == NULL) return -ENOMEM; - cacep__pack(&msg, data); + cacep_msg__pack(&msg, data); - if (flow_write(instance->fd, data, len) < 0) - ret = -1; + if (flow_write(fd, data, len) < 0) { + free(data); + return -1; + } free(data); - return ret; + return 0; } -struct cacep_info * cacep_auth(struct cacep * instance) +int cacep_snd(int fd, + const struct conn_info * in) { - struct cacep_info * tmp; - - if (instance == NULL) - return NULL; - - if (send_msg(instance)) - return NULL; + if (in == NULL) + return -EINVAL; - tmp = read_msg(instance); - if (tmp == NULL) - return NULL; + if (send_msg(fd, in)) + return -1; - return tmp; + return 0; } -struct cacep_info * cacep_auth_wait(struct cacep * instance) +int cacep_rcv(int fd, + struct conn_info * out) { - struct cacep_info * tmp; - - if (instance == NULL) - return NULL; - - tmp = read_msg(instance); - if (tmp == NULL) - return NULL; + if (out == NULL) + return -EINVAL; - if (send_msg(instance)) { - free(tmp->name); - free(tmp); - return NULL; - } + if (read_msg(fd, out)) + return -1; - return tmp; + return 0; } diff --git a/src/lib/cacep.proto b/src/lib/cacep.proto index 603b095d..cdeaa0b7 100644 --- a/src/lib/cacep.proto +++ b/src/lib/cacep.proto @@ -1,10 +1,10 @@ /* * Ouroboros - Copyright (C) 2016 - 2017 * - * CACEP message + * Message for Connection Information in CACEP * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -23,7 +23,12 @@ syntax = "proto2"; -message cacep { - required string name = 1; - required uint64 address = 2; -} +message cacep_msg { + required string ae_name = 1; + required string protocol = 2; + required int32 pref_version = 3; + repeated int32 supp_version = 4; + required int32 pref_syntax = 5; + repeated int32 supp_syntax = 6; + required uint64 address = 7; +}
\ No newline at end of file diff --git a/src/lib/cdap.c b/src/lib/cdap.c index 6c46775c..0d1568b2 100644 --- a/src/lib/cdap.c +++ b/src/lib/cdap.c @@ -3,7 +3,8 @@ * * The Common Distributed Application Protocol * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -24,6 +25,7 @@ #include <ouroboros/cdap.h> #include <ouroboros/bitmap.h> #include <ouroboros/dev.h> +#include <ouroboros/fqueue.h> #include <ouroboros/fcntl.h> #include <ouroboros/errno.h> @@ -36,33 +38,46 @@ #include "cdap.pb-c.h" typedef Cdap cdap_t; -typedef Opcode opcode_t; typedef int32_t invoke_id_t; +#define CDAP_REPLY (CDAP_DELETE + 1) + #define INVALID_INVOKE_ID -1 #define IDS_SIZE 256 #define BUF_SIZE 2048 -struct cdap { +struct fd_el { + struct list_head next; + int fd; +}; + +struct cdap { + flow_set_t * set; + + size_t n_flows; + struct list_head flows; + pthread_rwlock_t flows_lock; struct bmp * ids; pthread_mutex_t ids_lock; - pthread_t reader; - struct list_head sent; pthread_rwlock_t sent_lock; struct list_head rcvd; pthread_cond_t rcvd_cond; pthread_mutex_t rcvd_lock; + + pthread_t reader; }; struct cdap_rcvd { struct list_head next; + int fd; + invoke_id_t iid; enum cdap_opcode opcode; @@ -131,7 +146,34 @@ static struct cdap_req * cdap_sent_get_by_key(struct cdap * instance, return NULL; } +static struct cdap_rcvd * cdap_rcvd_get_by_iid(struct cdap * instance, + invoke_id_t iid) +{ + struct list_head * p = NULL; + struct list_head * h = NULL; + struct cdap_rcvd * rcvd = NULL; + + assert(instance); + assert(iid >= 0); + + pthread_mutex_lock(&instance->rcvd_lock); + + list_for_each_safe(p, h, &instance->rcvd) { + rcvd = list_entry(p, struct cdap_rcvd, next); + if (rcvd->iid == iid) { + pthread_mutex_unlock(&instance->rcvd_lock); + list_del(&rcvd->next); + return rcvd; + } + } + + pthread_mutex_unlock(&instance->rcvd_lock); + + return NULL; +} + static struct cdap_req * cdap_sent_add(struct cdap * instance, + int fd, cdap_key_t key) { struct cdap_req * req; @@ -140,7 +182,7 @@ static struct cdap_req * cdap_sent_add(struct cdap * instance, assert(key >= 0); assert(!cdap_sent_has_key(instance, key)); - req = cdap_req_create(key); + req = cdap_req_create(fd, key); if (req == NULL) return NULL; @@ -207,6 +249,8 @@ static void cdap_rcvd_destroy(struct cdap * instance) free(r); } + pthread_cond_broadcast(&instance->rcvd_cond); + pthread_mutex_unlock(&instance->rcvd_lock); } @@ -219,9 +263,15 @@ static void * sdu_reader(void * o) uint8_t buf[BUF_SIZE]; ssize_t len; buffer_t data; + fqueue_t * fq; - while (true) { - len = flow_read(instance->fd, buf, BUF_SIZE); + fq = fqueue_create(); + if (fq == NULL) + return (void *) -1; + + while (flow_event_wait(instance->set, fq, NULL)) { + int fd = fqueue_next(fq); + len = flow_read(fd, buf, BUF_SIZE); if (len < 0) continue; @@ -229,41 +279,20 @@ static void * sdu_reader(void * o) if (msg == NULL) continue; - if (msg->opcode != OPCODE__REPLY) { + if (msg->opcode != CDAP_REPLY) { rcvd = malloc(sizeof(*rcvd)); if (rcvd == NULL) { cdap__free_unpacked(msg, NULL); continue; } - switch (msg->opcode) { - case OPCODE__START: - rcvd->opcode = CDAP_START; - break; - case OPCODE__STOP: - rcvd->opcode = CDAP_STOP; - break; - case OPCODE__READ: - rcvd->opcode = CDAP_READ; - break; - case OPCODE__WRITE: - rcvd->opcode = CDAP_WRITE; - break; - case OPCODE__CREATE: - rcvd->opcode = CDAP_CREATE; - break; - case OPCODE__DELETE: - rcvd->opcode = CDAP_DELETE; - break; - default: - cdap__free_unpacked(msg, NULL); - free(rcvd); - continue; - } + assert(msg->name); - rcvd->iid = msg->invoke_id; - rcvd->flags = msg->flags; - rcvd->name = strdup(msg->name); + rcvd->opcode = msg->opcode; + rcvd->iid = msg->invoke_id; + rcvd->flags = msg->flags; + rcvd->fd = fd; + rcvd->name = strdup(msg->name); if (rcvd->name == NULL) { cdap__free_unpacked(msg, NULL); free(rcvd); @@ -310,36 +339,32 @@ static void * sdu_reader(void * o) cdap_req_respond(req, msg->result, data); } - - cdap__free_unpacked(msg, NULL); } - return (void *) 0; } -struct cdap * cdap_create(int fd) +struct cdap * cdap_create() { struct cdap * instance = NULL; - int flags; - - if (fd < 0) - return NULL; - - flags = flow_get_flags(fd); - if (flags & FLOW_O_NONBLOCK) - return NULL; instance = malloc(sizeof(*instance)); if (instance == NULL) return NULL; + if (pthread_rwlock_init(&instance->flows_lock, NULL)) { + free(instance); + return NULL; + } + if (pthread_mutex_init(&instance->ids_lock, NULL)) { + pthread_rwlock_destroy(&instance->flows_lock); free(instance); return NULL; } if (pthread_mutex_init(&instance->rcvd_lock, NULL)) { pthread_mutex_destroy(&instance->ids_lock); + pthread_rwlock_destroy(&instance->flows_lock); free(instance); return NULL; } @@ -347,6 +372,7 @@ struct cdap * cdap_create(int fd) if (pthread_rwlock_init(&instance->sent_lock, NULL)) { pthread_mutex_destroy(&instance->rcvd_lock); pthread_mutex_destroy(&instance->ids_lock); + pthread_rwlock_destroy(&instance->flows_lock); free(instance); return NULL; } @@ -355,6 +381,7 @@ struct cdap * cdap_create(int fd) pthread_rwlock_destroy(&instance->sent_lock); pthread_mutex_destroy(&instance->rcvd_lock); pthread_mutex_destroy(&instance->ids_lock); + pthread_rwlock_destroy(&instance->flows_lock); free(instance); return NULL; } @@ -365,15 +392,29 @@ struct cdap * cdap_create(int fd) pthread_rwlock_destroy(&instance->sent_lock); pthread_mutex_destroy(&instance->rcvd_lock); pthread_mutex_destroy(&instance->ids_lock); + pthread_rwlock_destroy(&instance->flows_lock); + free(instance); + return NULL; + } + + instance->set = flow_set_create(); + if (instance->set == NULL) { + bmp_destroy(instance->ids); + pthread_cond_destroy(&instance->rcvd_cond); + pthread_rwlock_destroy(&instance->sent_lock); + pthread_mutex_destroy(&instance->rcvd_lock); + pthread_mutex_destroy(&instance->ids_lock); + pthread_rwlock_destroy(&instance->flows_lock); free(instance); return NULL; } + instance->n_flows = 0; + + list_head_init(&instance->flows); list_head_init(&instance->sent); list_head_init(&instance->rcvd); - instance->fd = fd; - pthread_create(&instance->reader, NULL, sdu_reader, instance); return instance; @@ -381,12 +422,29 @@ struct cdap * cdap_create(int fd) int cdap_destroy(struct cdap * instance) { + struct list_head * p; + struct list_head * h; + if (instance == NULL) return 0; pthread_cancel(instance->reader); pthread_join(instance->reader, NULL); + flow_set_destroy(instance->set); + + pthread_rwlock_wrlock(&instance->flows_lock); + + list_for_each_safe(p,h, &instance->flows) { + struct fd_el * e = list_entry(p, struct fd_el, next); + list_del(&e->next); + free(e); + } + + pthread_rwlock_unlock(&instance->flows_lock); + + pthread_rwlock_destroy(&instance->flows_lock); + pthread_mutex_lock(&instance->ids_lock); bmp_destroy(instance->ids); @@ -408,14 +466,71 @@ int cdap_destroy(struct cdap * instance) return 0; } -static int write_msg(struct cdap * instance, +int cdap_add_flow(struct cdap * instance, + int fd) +{ + struct fd_el * e; + + if (fd < 0) + return -EINVAL; + + e = malloc(sizeof(*e)); + if (e == NULL) + return -ENOMEM; + + e->fd = fd; + + pthread_rwlock_wrlock(&instance->flows_lock); + + if (flow_set_add(instance->set, fd)) { + pthread_rwlock_unlock(&instance->flows_lock); + return -1; + } + + list_add(&e->next, &instance->flows); + + ++instance->n_flows; + + pthread_rwlock_unlock(&instance->flows_lock); + + return 0; +} + +int cdap_del_flow(struct cdap * instance, + int fd) +{ + struct list_head * p; + struct list_head * h; + + if (fd < 0) + return -EINVAL; + + pthread_rwlock_wrlock(&instance->flows_lock); + + flow_set_del(instance->set, fd); + + list_for_each_safe(p, h, &instance->flows) { + struct fd_el * e = list_entry(p, struct fd_el, next); + if (e->fd == fd) { + list_del(&e->next); + free(e); + break; + } + } + + --instance->n_flows; + + pthread_rwlock_unlock(&instance->flows_lock); + + return 0; +} + +static int write_msg(int fd, cdap_t * msg) { - int ret; uint8_t * data; size_t len; - assert(instance); assert(msg); len = cdap__get_packed_size(msg); @@ -428,11 +543,14 @@ static int write_msg(struct cdap * instance, cdap__pack(msg, data); - ret = flow_write(instance->fd, data, len); + if (flow_write(fd, data, len)) { + free(data); + return -1; + } free(data); - return ret; + return 0; } static cdap_key_t invoke_id_to_key(invoke_id_t iid) @@ -451,75 +569,115 @@ static invoke_id_t key_to_invoke_id(cdap_key_t key) return (invoke_id_t) key; } -cdap_key_t cdap_request_send(struct cdap * instance, - enum cdap_opcode code, - const char * name, - const void * data, - size_t len, - uint32_t flags) +cdap_key_t * cdap_request_send(struct cdap * instance, + enum cdap_opcode code, + const char * name, + const void * data, + size_t len, + uint32_t flags) { - cdap_t msg = CDAP__INIT; - struct cdap_req * req; - invoke_id_t iid; - cdap_key_t key; + cdap_key_t * keys; + cdap_key_t * key; + cdap_t msg = CDAP__INIT; + struct list_head * p; + int ret; - if (instance == NULL || name == NULL) - return -EINVAL; + if (instance == NULL || name == NULL || code > CDAP_DELETE) + return NULL; + pthread_rwlock_rdlock(&instance->flows_lock); - iid = next_invoke_id(instance); - if (iid == INVALID_INVOKE_ID) - return INVALID_CDAP_KEY; + keys = malloc(sizeof(*keys) * (instance->n_flows + 1)); + if (keys == NULL) + return NULL; - switch (code) { - case CDAP_READ: - msg.opcode = OPCODE__READ; - break; - case CDAP_WRITE: - msg.opcode = OPCODE__WRITE; - break; - case CDAP_CREATE: - msg.opcode = OPCODE__CREATE; - break; - case CDAP_DELETE: - msg.opcode = OPCODE__DELETE; - break; - case CDAP_START: - msg.opcode = OPCODE__START; - break; - case CDAP_STOP: - msg.opcode = OPCODE__STOP; - break; - default: - release_invoke_id(instance, iid); - return -EINVAL; - } + memset(keys, INVALID_CDAP_KEY, sizeof(*keys) * (instance->n_flows + 1)); + + key = keys; + cdap__init(&msg); + + msg.opcode = code; msg.name = (char *) name; msg.has_flags = true; msg.flags = flags; - msg.invoke_id = iid; + if (data != NULL) { msg.has_value = true; msg.value.data = (uint8_t *) data; msg.value.len = len; } - key = invoke_id_to_key(iid); + list_for_each(p, &instance->flows) { + struct cdap_req * req; + invoke_id_t iid; + struct fd_el * e; + + iid = next_invoke_id(instance); + if (iid == INVALID_INVOKE_ID) { + pthread_rwlock_unlock(&instance->flows_lock); + while(key > keys) { + struct cdap_req * r = + cdap_sent_get_by_key(instance, + *(--key)); + cdap_sent_del(instance, r); + cdap_req_destroy(r); + } + + free(keys); + return NULL; + } - req = cdap_sent_add(instance, key); - if (req == NULL) { - release_invoke_id(instance, iid); - return INVALID_CDAP_KEY; - } + msg.invoke_id = iid; - if (write_msg(instance, &msg)) { - cdap_sent_del(instance, req); - release_invoke_id(instance, iid); - return INVALID_CDAP_KEY; + *key = invoke_id_to_key(iid); + + e = list_entry(p, struct fd_el, next); + + req = cdap_sent_add(instance, e->fd, *key); + if (req == NULL) { + pthread_rwlock_unlock(&instance->flows_lock); + while(key > keys) { + struct cdap_req * r = + cdap_sent_get_by_key(instance, + *(--key)); + cdap_sent_del(instance, r); + release_invoke_id(instance, + key_to_invoke_id(r->key)); + cdap_req_destroy(r); + } + release_invoke_id(instance, iid); + free(keys); + return NULL; + } + + ret = write_msg(e->fd, &msg); + if (ret == -ENOMEM) { + pthread_rwlock_unlock(&instance->flows_lock); + while(key >= keys) { + struct cdap_req * r = + cdap_sent_get_by_key(instance, *key); + cdap_sent_del(instance, r); + release_invoke_id(instance, + key_to_invoke_id(r->key)); + cdap_req_destroy(r); + } + + free(keys); + return NULL; + } + + if (ret < 0) { + release_invoke_id(instance, iid); + cdap_sent_del(instance, req); + } + + ++key; } - return key; + pthread_rwlock_unlock(&instance->flows_lock); + + return keys; } int cdap_reply_wait(struct cdap * instance, @@ -567,7 +725,6 @@ cdap_key_t cdap_request_wait(struct cdap * instance, uint32_t * flags) { struct cdap_rcvd * rcvd; - invoke_id_t iid; if (instance == NULL || opcode == NULL || name == NULL || data == NULL || len == NULL || flags == NULL) @@ -583,8 +740,6 @@ cdap_key_t cdap_request_wait(struct cdap * instance, rcvd = list_first_entry(&instance->rcvd, struct cdap_rcvd, next); - list_del(&rcvd->next); - pthread_cleanup_pop(true); *opcode = rcvd->opcode; @@ -593,11 +748,9 @@ cdap_key_t cdap_request_wait(struct cdap * instance, *len = rcvd->len; *flags = rcvd->flags; - iid = rcvd->iid; + rcvd->name = NULL; - free(rcvd); - - return invoke_id_to_key(iid); + return invoke_id_to_key(rcvd->iid); } int cdap_reply_send(struct cdap * instance, @@ -606,13 +759,17 @@ int cdap_reply_send(struct cdap * instance, const void * data, size_t len) { - cdap_t msg = CDAP__INIT; - invoke_id_t iid = key_to_invoke_id(key); + int fd; + cdap_t msg = CDAP__INIT; + invoke_id_t iid = key_to_invoke_id(key); + struct cdap_rcvd * rcvd = cdap_rcvd_get_by_iid(instance, iid); + if (rcvd == NULL) + return -EINVAL; if (instance == NULL) return -EINVAL; - msg.opcode = OPCODE__REPLY; + msg.opcode = CDAP_REPLY; msg.invoke_id = iid; msg.has_result = true; msg.result = result; @@ -623,5 +780,11 @@ int cdap_reply_send(struct cdap * instance, msg.value.len = len; } - return write_msg(instance, &msg); + fd = rcvd->fd; + + assert(rcvd->name == NULL); + + free(rcvd); + + return write_msg(fd, &msg); } diff --git a/src/lib/cdap.proto b/src/lib/cdap.proto index 5fde1658..120b2c97 100644 --- a/src/lib/cdap.proto +++ b/src/lib/cdap.proto @@ -23,18 +23,8 @@ syntax = "proto2"; -enum opcode { - CREATE = 1; - DELETE = 2; - READ = 3; - WRITE = 4; - START = 5; - STOP = 6; - REPLY = 7; -} - message cdap { - required opcode opcode = 1; + required uint32 opcode = 1; required uint32 invoke_id = 2; optional uint32 flags = 3; optional string name = 4; diff --git a/src/lib/cdap_req.c b/src/lib/cdap_req.c index 2f55b107..b60e73ad 100644 --- a/src/lib/cdap_req.c +++ b/src/lib/cdap_req.c @@ -3,8 +3,8 @@ * * CDAP - CDAP request management * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -30,7 +30,8 @@ #include <stdlib.h> #include <assert.h> -struct cdap_req * cdap_req_create(cdap_key_t key) +struct cdap_req * cdap_req_create(int fd, + cdap_key_t key) { struct cdap_req * creq = malloc(sizeof(*creq)); pthread_condattr_t cattr; @@ -38,10 +39,10 @@ struct cdap_req * cdap_req_create(cdap_key_t key) if (creq == NULL) return NULL; - creq->key = key; + creq->fd = fd; + creq->key = key; creq->state = REQ_INIT; - - creq->response = -1; + creq->response = -1; creq->data.data = NULL; creq->data.len = 0; @@ -65,17 +66,21 @@ void cdap_req_destroy(struct cdap_req * creq) pthread_mutex_lock(&creq->lock); - if (creq->state == REQ_DESTROY) { + switch(creq->state) { + case REQ_DESTROY: pthread_mutex_unlock(&creq->lock); return; - } - - if (creq->state == REQ_INIT) + case REQ_INIT: creq->state = REQ_NULL; - - if (creq->state == REQ_PENDING) { + pthread_cond_broadcast(&creq->cond); + break; + case REQ_PENDING: + case REQ_RESPONSE: creq->state = REQ_DESTROY; pthread_cond_broadcast(&creq->cond); + break; + default: + break; } while (creq->state != REQ_NULL) @@ -110,21 +115,25 @@ int cdap_req_wait(struct cdap_req * creq) creq->state = REQ_PENDING; pthread_cond_broadcast(&creq->cond); - while (creq->state == REQ_PENDING) { + while (creq->state == REQ_PENDING && ret != -ETIMEDOUT) ret = -pthread_cond_timedwait(&creq->cond, &creq->lock, &abstime); - if (ret == -ETIMEDOUT) - break; - } - if (creq->state == REQ_DESTROY) { + switch(creq->state) { + case REQ_DESTROY: ret = -1; + case REQ_PENDING: creq->state = REQ_NULL; pthread_cond_broadcast(&creq->cond); - } else { + break; + case REQ_RESPONSE: creq->state = REQ_DONE; pthread_cond_broadcast(&creq->cond); + break; + default: + assert(false); + break; } pthread_mutex_unlock(&creq->lock); diff --git a/src/lib/cdap_req.h b/src/lib/cdap_req.h index 2d69526b..fe8e3613 100644 --- a/src/lib/cdap_req.h +++ b/src/lib/cdap_req.h @@ -3,8 +3,8 @@ * * CDAP - CDAP request management * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -43,8 +43,8 @@ enum creq_state { struct cdap_req { struct list_head next; + int fd; struct timespec birth; - cdap_key_t key; int response; @@ -55,7 +55,8 @@ struct cdap_req { pthread_mutex_t lock; }; -struct cdap_req * cdap_req_create(cdap_key_t key); +struct cdap_req * cdap_req_create(int fd, + cdap_key_t key); void cdap_req_destroy(struct cdap_req * creq); diff --git a/src/lib/crc32.c b/src/lib/crc32.c index 8cafe5b5..549938b8 100644 --- a/src/lib/crc32.c +++ b/src/lib/crc32.c @@ -3,7 +3,8 @@ * * 32-bit Cyclic Redundancy Check * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/dev.c b/src/lib/dev.c index 4d85a5d9..bd706dc8 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -3,8 +3,8 @@ * * API for applications * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -382,8 +382,7 @@ void ap_fini() pthread_rwlock_destroy(&ai.data_lock); } -int flow_accept(char ** ae_name, - qosspec_t * spec) +int flow_accept(qosspec_t * spec) { irm_msg_t msg = IRM_MSG__INIT; irm_msg_t * recv_msg = NULL; @@ -451,18 +450,6 @@ int flow_accept(char ** ae_name, return -1; } - if (ae_name != NULL) { - *ae_name = strdup(recv_msg->ae_name); - if (*ae_name == NULL) { - reset_flow(fd); - bmp_release(ai.fds, fd); - pthread_rwlock_unlock(&ai.flows_lock); - pthread_rwlock_unlock(&ai.data_lock); - irm_msg__free_unpacked(recv_msg, NULL); - return -ENOMEM; - } - } - ai.flows[fd].port_id = recv_msg->port_id; ai.flows[fd].oflags = FLOW_O_DEFAULT; ai.flows[fd].api = recv_msg->api; @@ -531,7 +518,6 @@ int flow_alloc_resp(int fd, } int flow_alloc(const char * dst_name, - const char * src_ae_name, qosspec_t * spec) { irm_msg_t msg = IRM_MSG__INIT; @@ -541,12 +527,8 @@ int flow_alloc(const char * dst_name, if (dst_name == NULL) return -EINVAL; - if (src_ae_name == NULL) - src_ae_name = UNKNOWN_AE; - msg.code = IRM_MSG_CODE__IRM_FLOW_ALLOC; msg.dst_name = (char *) dst_name; - msg.ae_name = (char *) src_ae_name; msg.has_api = true; msg.has_qoscube = true; msg.qoscube = spec_to_cube(spec); @@ -1047,6 +1029,8 @@ int flow_set_add(struct flow_set * set, int fd) { int ret; + size_t sdus; + size_t i; if (set == NULL) return -EINVAL; @@ -1056,6 +1040,10 @@ int flow_set_add(struct flow_set * set, ret = shm_flow_set_add(ai.fqset, set->idx, ai.flows[fd].port_id); + sdus = shm_rbuff_queued(ai.flows[fd].rx_rb); + for (i = 0; i < sdus; i++) + shm_flow_set_notify(ai.fqset, ai.flows[fd].port_id); + pthread_rwlock_unlock(&ai.flows_lock); pthread_rwlock_unlock(&ai.data_lock); @@ -1270,7 +1258,6 @@ int ipcp_create_r(pid_t api, int ipcp_flow_req_arr(pid_t api, char * dst_name, - char * src_ae_name, qoscube_t cube) { irm_msg_t msg = IRM_MSG__INIT; @@ -1278,14 +1265,13 @@ int ipcp_flow_req_arr(pid_t api, int port_id = -1; int fd = -1; - if (dst_name == NULL || src_ae_name == NULL) + if (dst_name == NULL) return -EINVAL; msg.code = IRM_MSG_CODE__IPCP_FLOW_REQ_ARR; msg.has_api = true; msg.api = api; msg.dst_name = dst_name; - msg.ae_name = src_ae_name; msg.has_qoscube = true; msg.qoscube = cube; diff --git a/src/lib/hashtable.c b/src/lib/hashtable.c index f17accaf..0a534da7 100644 --- a/src/lib/hashtable.c +++ b/src/lib/hashtable.c @@ -3,7 +3,8 @@ * * Hash table with separate chaining on collisions * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto index 827bd370..da817944 100644 --- a/src/lib/ipcpd_messages.proto +++ b/src/lib/ipcpd_messages.proto @@ -45,11 +45,10 @@ message ipcp_msg { optional string name = 5; optional sint32 port_id = 6; optional string dst_name = 7; - optional string src_ae_name = 8; - optional sint32 qoscube = 9; - optional dif_config_msg conf = 10; - optional sint32 fd = 11; - optional sint32 api = 12; - optional sint32 response = 13; - optional sint32 result = 14; + optional sint32 qoscube = 8; + optional dif_config_msg conf = 9; + optional sint32 fd = 10; + optional sint32 api = 11; + optional sint32 response = 12; + optional sint32 result = 13; }; diff --git a/src/lib/irm.c b/src/lib/irm.c index b610a59e..0e4bfc40 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -3,7 +3,8 @@ * * The API to instruct the IRM * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/irmd_messages.proto b/src/lib/irmd_messages.proto index a0965f43..c25d2c18 100644 --- a/src/lib/irmd_messages.proto +++ b/src/lib/irmd_messages.proto @@ -52,17 +52,16 @@ enum irm_msg_code { message irm_msg { required irm_msg_code code = 1; optional string ap_name = 2; - optional string ae_name = 3; - optional sint32 api = 4; - optional uint32 ipcp_type = 5; - repeated string dif_name = 6; - repeated string args = 7; - optional sint32 response = 8; - optional string dst_name = 9; - optional sint32 port_id = 10; - optional sint32 qoscube = 11; - optional dif_config_msg conf = 12; - optional uint32 opts = 13; - repeated sint32 apis = 14; - optional sint32 result = 15; + optional sint32 api = 3; + optional uint32 ipcp_type = 4; + repeated string dif_name = 5; + repeated string args = 6; + optional sint32 response = 7; + optional string dst_name = 8; + optional sint32 port_id = 9; + optional sint32 qoscube = 10; + optional dif_config_msg conf = 11; + optional uint32 opts = 12; + repeated sint32 apis = 13; + optional sint32 result = 14; }; diff --git a/src/lib/list.c b/src/lib/list.c index 01fdf6e3..b6b4bbd2 100644 --- a/src/lib/list.c +++ b/src/lib/list.c @@ -3,8 +3,8 @@ * * Simple doubly linked list implementation. * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/lockfile.c b/src/lib/lockfile.c index 2868cb71..e84c6692 100644 --- a/src/lib/lockfile.c +++ b/src/lib/lockfile.c @@ -3,7 +3,8 @@ * * Lockfile for Ouroboros * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/logs.c b/src/lib/logs.c index 3184773f..e38f2a8b 100644 --- a/src/lib/logs.c +++ b/src/lib/logs.c @@ -3,8 +3,8 @@ * * Logging facilities * - * Sander Vrijders <sander.vrijders@intec.ugent.be> - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/nsm.c b/src/lib/nsm.c index 3fc98021..979f711e 100644 --- a/src/lib/nsm.c +++ b/src/lib/nsm.c @@ -3,7 +3,8 @@ * * The API to instruct the global Namespace Manager * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/rib.c b/src/lib/rib.c index af4abccf..8468e88c 100644 --- a/src/lib/rib.c +++ b/src/lib/rib.c @@ -3,8 +3,8 @@ * * Resource Information Base * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/sha3.c b/src/lib/sha3.c index b2f9de57..750038f2 100644 --- a/src/lib/sha3.c +++ b/src/lib/sha3.c @@ -3,6 +3,9 @@ * * SHA3 algorithm * + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> + * * This implementation is adapted and redistributed from the RHASH * project * @@ -47,7 +50,8 @@ #include "sha3.h" -#define IS_ALIGNED_64(p) (0 == (7 & ((const char*) (p) - (const char*) 0))) +#define IS_ALIGNED_64(p) (0 == (7 & ((const uint8_t *) (p) \ + - (const uint8_t *) 0))) #define I64(x) x##LL #define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n)))) @@ -307,8 +311,9 @@ void rhash_sha3_final(struct sha3_ctx * ctx, uint8_t * res) { size_t digest_length = 100 - ctx->block_size / 2; - const size_t block_size = ctx->block_size; - unsigned int i = 0; + size_t digest_words = digest_length / sizeof(uint64_t); + const size_t block_size = ctx->block_size; + size_t i = 0; if (!(ctx->rest & SHA3_FINALIZED)) { /* clear the rest of the data queue */ @@ -325,7 +330,7 @@ void rhash_sha3_final(struct sha3_ctx * ctx, assert(block_size > digest_length); if (res != NULL) { - for (i = 0; i < digest_length; i++) + for (i = 0; i < digest_words; i++) ctx->hash[i] = htole64(ctx->hash[i]); memcpy(res, ctx->hash, digest_length); diff --git a/src/lib/sha3.h b/src/lib/sha3.h index 413228a2..6ce67482 100644 --- a/src/lib/sha3.h +++ b/src/lib/sha3.h @@ -3,7 +3,8 @@ * * SHA3 algorithm * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This implementation is adapted and redistributed from the RHASH * project implementation of the sha3 algorithm diff --git a/src/lib/shm_flow_set.c b/src/lib/shm_flow_set.c index f561c514..615fbd2b 100644 --- a/src/lib/shm_flow_set.c +++ b/src/lib/shm_flow_set.c @@ -3,7 +3,8 @@ * * Management of flow_sets for fqueue * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/shm_rbuff.c b/src/lib/shm_rbuff.c index 0d0795aa..b8db7c19 100644 --- a/src/lib/shm_rbuff.c +++ b/src/lib/shm_rbuff.c @@ -3,7 +3,8 @@ * * Ring buffer for incoming SDUs * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License @@ -383,3 +384,23 @@ void shm_rbuff_fini(struct shm_rbuff * rb) #endif pthread_cleanup_pop(true); } + +size_t shm_rbuff_queued(struct shm_rbuff * rb) +{ + size_t ret; + + assert(rb); + +#ifdef __APPLE__ + pthread_mutex_lock(rb->lock); +#else + if (pthread_mutex_lock(rb->lock) == EOWNERDEAD) + pthread_mutex_consistent(rb->lock); +#endif + + ret = shm_rbuff_used(rb); + + pthread_mutex_unlock(rb->lock); + + return ret; +} diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c index eb51a278..0976c4bd 100644 --- a/src/lib/shm_rdrbuff.c +++ b/src/lib/shm_rdrbuff.c @@ -3,8 +3,8 @@ * * Random Deletion Ring Buffer for Data Units * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/sockets.c b/src/lib/sockets.c index e57cd748..3a26a2cf 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -3,7 +3,8 @@ * * The sockets layer to communicate between daemons * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index e4ea3920..a9f38c6f 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -2,14 +2,14 @@ get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) create_test_sourcelist(${PARENT_DIR}_tests test_suite.c - # Add new tests here - bitmap_test.c - btree_test.c - crc32_test.c - hashtable_test.c - rib_test.c - sha3_test.c -) + # Add new tests here + bitmap_test.c + btree_test.c + crc32_test.c + hashtable_test.c + rib_test.c + sha3_test.c + ) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) target_link_libraries(${PARENT_DIR}_test ouroboros) @@ -19,7 +19,7 @@ add_dependencies(check ${PARENT_DIR}_test) set(tests_to_run ${${PARENT_DIR}_tests}) remove(tests_to_run test_suite.c) -foreach(test ${tests_to_run}) +foreach (test ${tests_to_run}) get_filename_component(test_name ${test} NAME_WE) add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) -endforeach(test) +endforeach (test) diff --git a/src/lib/tests/bitmap_test.c b/src/lib/tests/bitmap_test.c index b1684f72..7480600e 100644 --- a/src/lib/tests/bitmap_test.c +++ b/src/lib/tests/bitmap_test.c @@ -3,7 +3,8 @@ * * Test of the bitmap * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/lib/tests/btree_test.c b/src/lib/tests/btree_test.c index 257a7e37..6981f63a 100644 --- a/src/lib/tests/btree_test.c +++ b/src/lib/tests/btree_test.c @@ -3,7 +3,8 @@ * * Test of the B-tree implementation * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/lib/tests/crc32_test.c b/src/lib/tests/crc32_test.c index 563d23b0..6a8ee9c3 100644 --- a/src/lib/tests/crc32_test.c +++ b/src/lib/tests/crc32_test.c @@ -3,7 +3,8 @@ * * Test of the CRC32 function * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/lib/tests/hashtable_test.c b/src/lib/tests/hashtable_test.c index fb7f1156..a5b0e469 100644 --- a/src/lib/tests/hashtable_test.c +++ b/src/lib/tests/hashtable_test.c @@ -3,7 +3,8 @@ * * Test of the hash table * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/lib/tests/rib_test.c b/src/lib/tests/rib_test.c index 8996c379..54926e10 100644 --- a/src/lib/tests/rib_test.c +++ b/src/lib/tests/rib_test.c @@ -3,7 +3,8 @@ * * Test of the RIB * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/lib/tests/sha3_test.c b/src/lib/tests/sha3_test.c index 30334f49..212452ef 100644 --- a/src/lib/tests/sha3_test.c +++ b/src/lib/tests/sha3_test.c @@ -3,7 +3,8 @@ * * Test of the SHA3 function * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * 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 diff --git a/src/lib/time_utils.c b/src/lib/time_utils.c index 3b791157..97e97b09 100644 --- a/src/lib/time_utils.c +++ b/src/lib/time_utils.c @@ -3,7 +3,8 @@ * * Time utilities * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/lib/utils.c b/src/lib/utils.c index 40d1c285..e97dddb0 100644 --- a/src/lib/utils.c +++ b/src/lib/utils.c @@ -3,7 +3,8 @@ * * Handy utilities * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * Dimitri Staessens <dimitri.staessens@ugent.be> + * Sander Vrijders <sander.vrijders@ugent.be> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License diff --git a/src/nsmd/CMakeLists.txt b/src/nsmd/CMakeLists.txt index b916170b..2995b725 100644 --- a/src/nsmd/CMakeLists.txt +++ b/src/nsmd/CMakeLists.txt @@ -5,17 +5,17 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - main.c -) + # Add source files here + main.c + ) -add_executable (nsmd ${SOURCE_FILES}) +add_executable(nsmd ${SOURCE_FILES}) -target_link_libraries (nsmd LINK_PUBLIC ouroboros) +target_link_libraries(nsmd LINK_PUBLIC ouroboros) -include(MacroAddCompileFlags) +include(AddCompileFlags) if (CMAKE_BUILD_TYPE MATCHES Debug) - MACRO_ADD_COMPILE_FLAGS(nsmd -DCONFIG_OUROBOROS_DEBUG) + add_compile_flags(nsmd -DCONFIG_OUROBOROS_DEBUG) endif (CMAKE_BUILD_TYPE MATCHES Debug) install(TARGETS nsmd RUNTIME DESTINATION sbin) diff --git a/src/nsmd/main.c b/src/nsmd/main.c index f3b87330..b85b39a9 100644 --- a/src/nsmd/main.c +++ b/src/nsmd/main.c @@ -1,10 +1,32 @@ -#define OUROBOROS_PREFIX "da" +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Normal IPC Process + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#define OUROBOROS_PREFIX "nsmd" #include <ouroboros/logs.h> int main(void) { - log_dbg("Test of the DA"); + log_dbg("Test of the NSMd"); return 0; } diff --git a/src/tools/cbr/CMakeLists.txt b/src/tools/cbr/CMakeLists.txt index 232bea36..1883141c 100644 --- a/src/tools/cbr/CMakeLists.txt +++ b/src/tools/cbr/CMakeLists.txt @@ -5,9 +5,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - cbr.c -) + # Add source files here + cbr.c + ) add_executable(cbr ${SOURCE_FILES}) diff --git a/src/tools/cbr/cbr.c b/src/tools/cbr/cbr.c index ef8a58ba..cd29c9ad 100644 --- a/src/tools/cbr/cbr.c +++ b/src/tools/cbr/cbr.c @@ -3,8 +3,8 @@ * * CBR traffic generator * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/cbr/cbr_client.c b/src/tools/cbr/cbr_client.c index 173dab24..16ade13d 100644 --- a/src/tools/cbr/cbr_client.c +++ b/src/tools/cbr/cbr_client.c @@ -3,8 +3,8 @@ * * A simple CBR generator * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -90,7 +90,7 @@ int client_main(char * server, printf("Client started, duration %d, rate %lu b/s, size %d B.\n", duration, rate, size); - fd = flow_alloc(server, NULL, NULL); + fd = flow_alloc(server, NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); return -1; diff --git a/src/tools/cbr/cbr_server.c b/src/tools/cbr/cbr_server.c index 7105ff09..9198858c 100644 --- a/src/tools/cbr/cbr_server.c +++ b/src/tools/cbr/cbr_server.c @@ -3,8 +3,8 @@ * * A simple CBR generator * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -164,7 +164,7 @@ static void * listener(void * o) server_settings.interval, server_settings.timeout); while (true) { - client_fd = flow_accept(NULL, &qs); + client_fd = flow_accept(&qs); if (client_fd < 0) { printf("Failed to accept flow.\n"); break; diff --git a/src/tools/echo/CMakeLists.txt b/src/tools/echo/CMakeLists.txt index 42bcdbfe..7cecfe50 100644 --- a/src/tools/echo/CMakeLists.txt +++ b/src/tools/echo/CMakeLists.txt @@ -5,9 +5,9 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - echo.c -) + # Add source files here + echo.c + ) add_executable(echo-app ${SOURCE_FILES}) diff --git a/src/tools/echo/echo.c b/src/tools/echo/echo.c index 3dd7527b..051a16c3 100644 --- a/src/tools/echo/echo.c +++ b/src/tools/echo/echo.c @@ -3,7 +3,8 @@ * * A simple echo application * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/echo/echo_client.c b/src/tools/echo/echo_client.c index 783188d5..f84de73a 100644 --- a/src/tools/echo/echo_client.c +++ b/src/tools/echo/echo_client.c @@ -3,7 +3,8 @@ * * A simple echo application * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -30,7 +31,7 @@ int client_main(void) char * message = "Client says hi!"; ssize_t count = 0; - fd = flow_alloc("echo", NULL, NULL); + fd = flow_alloc("echo", NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); return -1; diff --git a/src/tools/echo/echo_server.c b/src/tools/echo/echo_server.c index 8940a0b5..aa136485 100644 --- a/src/tools/echo/echo_server.c +++ b/src/tools/echo/echo_server.c @@ -3,7 +3,8 @@ * * A simple echo application * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -50,7 +51,7 @@ int server_main(void) } while (true) { - client_fd = flow_accept(NULL, &qs); + client_fd = flow_accept(&qs); if (client_fd < 0) { printf("Failed to accept flow.\n"); break; diff --git a/src/tools/irm/CMakeLists.txt b/src/tools/irm/CMakeLists.txt index f59d9af0..300ad982 100644 --- a/src/tools/irm/CMakeLists.txt +++ b/src/tools/irm/CMakeLists.txt @@ -5,28 +5,28 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(SOURCE_FILES - # Add source files here - irm.c - irm_bind_ap.c - irm_bind_api.c - irm_bind_ipcp.c - irm_ipcp_create.c - irm_ipcp_destroy.c - irm_ipcp_bootstrap.c - irm_ipcp_enroll.c - irm_unbind_ap.c - irm_unbind_api.c - irm_unbind_ipcp.c - irm_unbind.c - irm_bind.c - irm_ipcp.c - irm_register.c - irm_unregister.c - irm_utils.c -) + # Add source files here + irm.c + irm_bind_ap.c + irm_bind_api.c + irm_bind_ipcp.c + irm_ipcp_create.c + irm_ipcp_destroy.c + irm_ipcp_bootstrap.c + irm_ipcp_enroll.c + irm_unbind_ap.c + irm_unbind_api.c + irm_unbind_ipcp.c + irm_unbind.c + irm_bind.c + irm_ipcp.c + irm_register.c + irm_unregister.c + irm_utils.c + ) -add_executable (irm ${SOURCE_FILES}) +add_executable(irm ${SOURCE_FILES}) -target_link_libraries (irm LINK_PUBLIC ouroboros) +target_link_libraries(irm LINK_PUBLIC ouroboros) install(TARGETS irm RUNTIME DESTINATION sbin) diff --git a/src/tools/irm/irm.c b/src/tools/irm/irm.c index 85d03245..0e77e22a 100644 --- a/src/tools/irm/irm.c +++ b/src/tools/irm/irm.c @@ -3,7 +3,8 @@ * * A tool to instruct the IRM daemon * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_bind.c b/src/tools/irm/irm_bind.c index bb19d13c..bbe370db 100644 --- a/src/tools/irm/irm_bind.c +++ b/src/tools/irm/irm_bind.c @@ -3,8 +3,8 @@ * * Bind names in the processing system * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_bind_ap.c b/src/tools/irm/irm_bind_ap.c index dc66e399..d23f7035 100644 --- a/src/tools/irm/irm_bind_ap.c +++ b/src/tools/irm/irm_bind_ap.c @@ -3,8 +3,8 @@ * * Bind AP to a name * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_bind_api.c b/src/tools/irm/irm_bind_api.c index dd405347..6e171099 100644 --- a/src/tools/irm/irm_bind_api.c +++ b/src/tools/irm/irm_bind_api.c @@ -3,8 +3,8 @@ * * Bind AP-I to a name * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_bind_ipcp.c b/src/tools/irm/irm_bind_ipcp.c index 404207c0..81347080 100644 --- a/src/tools/irm/irm_bind_ipcp.c +++ b/src/tools/irm/irm_bind_ipcp.c @@ -3,8 +3,8 @@ * * Bind IPCP Instance to a name * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ipcp.c b/src/tools/irm/irm_ipcp.c index 59869a12..fef803d9 100644 --- a/src/tools/irm/irm_ipcp.c +++ b/src/tools/irm/irm_ipcp.c @@ -3,7 +3,8 @@ * * A tool to instruct the IRM daemon * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ipcp_bootstrap.c b/src/tools/irm/irm_ipcp_bootstrap.c index 10c89060..ac52c6c1 100644 --- a/src/tools/irm/irm_ipcp_bootstrap.c +++ b/src/tools/irm/irm_ipcp_bootstrap.c @@ -3,7 +3,8 @@ * * Bootstrap IPC Processes * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ipcp_create.c b/src/tools/irm/irm_ipcp_create.c index e8ed1186..494f01f5 100644 --- a/src/tools/irm/irm_ipcp_create.c +++ b/src/tools/irm/irm_ipcp_create.c @@ -3,7 +3,8 @@ * * Create IPC Processes * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ipcp_destroy.c b/src/tools/irm/irm_ipcp_destroy.c index 96808850..1c81c9ce 100644 --- a/src/tools/irm/irm_ipcp_destroy.c +++ b/src/tools/irm/irm_ipcp_destroy.c @@ -3,7 +3,8 @@ * * Destroy IPC Processes * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ipcp_enroll.c b/src/tools/irm/irm_ipcp_enroll.c index 3731fa81..05b3f6b6 100644 --- a/src/tools/irm/irm_ipcp_enroll.c +++ b/src/tools/irm/irm_ipcp_enroll.c @@ -3,7 +3,8 @@ * * Enroll IPC Processes * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_ops.h b/src/tools/irm/irm_ops.h index 514570f5..8f0e790e 100644 --- a/src/tools/irm/irm_ops.h +++ b/src/tools/irm/irm_ops.h @@ -3,7 +3,8 @@ * * Functions of the IRM tool that are one level deep * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -19,19 +20,47 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -int ipcp_cmd(int argc, char ** argv); -int do_create_ipcp(int argc, char ** argv); -int do_destroy_ipcp(int argc, char ** argv); -int do_bootstrap_ipcp(int argc, char ** argv); -int do_enroll_ipcp(int argc, char ** argv); - -int bind_cmd(int argc, char ** argv); -int do_bind_ap(int argc, char ** argv); -int do_bind_api(int argc, char ** argv); -int do_bind_ipcp(int argc, char ** argv); -int unbind_cmd(int argc, char ** argv); -int do_unbind_ap(int argc, char ** argv); -int do_unbind_api(int argc, char ** argv); -int do_unbind_ipcp(int argc, char ** argv); -int do_register(int argc, char ** argv); -int do_unregister(int argc, char ** argv); +int ipcp_cmd(int argc, + char ** argv); + +int do_create_ipcp(int argc, + char ** argv); + +int do_destroy_ipcp(int argc, + char ** argv); + +int do_bootstrap_ipcp(int argc, + char ** argv); + +int do_enroll_ipcp(int argc, + char ** argv); + +int bind_cmd(int argc, + char ** argv); + +int do_bind_ap(int argc, + char ** argv); + +int do_bind_api(int argc, + char ** argv); + +int do_bind_ipcp(int argc, + char ** argv); + +int unbind_cmd(int argc, + char ** argv); + +int do_unbind_ap(int argc, + char ** argv); + +int do_unbind_api(int argc, + char ** argv); + +int do_unbind_ipcp(int argc, + char ** argv); + +int do_register(int argc, + char ** argv); + +int do_unregister(int argc, + char ** argv); diff --git a/src/tools/irm/irm_register.c b/src/tools/irm/irm_register.c index cdb4b888..094268c0 100644 --- a/src/tools/irm/irm_register.c +++ b/src/tools/irm/irm_register.c @@ -3,8 +3,8 @@ * * Register names in IPCPs * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_unbind.c b/src/tools/irm/irm_unbind.c index 2a570547..e21f7993 100644 --- a/src/tools/irm/irm_unbind.c +++ b/src/tools/irm/irm_unbind.c @@ -3,8 +3,8 @@ * * Unbind names in the processing system * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_unbind_ap.c b/src/tools/irm/irm_unbind_ap.c index 779506bd..a1b07d36 100644 --- a/src/tools/irm/irm_unbind_ap.c +++ b/src/tools/irm/irm_unbind_ap.c @@ -3,8 +3,8 @@ * * Unbind AP names * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_unbind_api.c b/src/tools/irm/irm_unbind_api.c index 29e4a9c1..6200c21f 100644 --- a/src/tools/irm/irm_unbind_api.c +++ b/src/tools/irm/irm_unbind_api.c @@ -3,8 +3,8 @@ * * Unbind AP-I names * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_unbind_ipcp.c b/src/tools/irm/irm_unbind_ipcp.c index be7e995f..34af66e0 100644 --- a/src/tools/irm/irm_unbind_ipcp.c +++ b/src/tools/irm/irm_unbind_ipcp.c @@ -3,8 +3,8 @@ * * Unbind name from IPCP Instance * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_unregister.c b/src/tools/irm/irm_unregister.c index d8cadc33..18314e96 100644 --- a/src/tools/irm/irm_unregister.c +++ b/src/tools/irm/irm_unregister.c @@ -3,8 +3,8 @@ * * Unregister names from IPCPs * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_utils.c b/src/tools/irm/irm_utils.c index 25f8dc3a..24841b99 100644 --- a/src/tools/irm/irm_utils.c +++ b/src/tools/irm/irm_utils.c @@ -3,7 +3,8 @@ * * Handy helper functions for the IRM tool * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/irm/irm_utils.h b/src/tools/irm/irm_utils.h index b5a6f56f..d6d2232c 100644 --- a/src/tools/irm/irm_utils.h +++ b/src/tools/irm/irm_utils.h @@ -3,7 +3,8 @@ * * Handy helper functions for the IRM tool * - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -19,4 +20,5 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -int matches(const char * cmd, const char * pattern); +int matches(const char * cmd, + const char * pattern); diff --git a/src/tools/operf/CMakeLists.txt b/src/tools/operf/CMakeLists.txt index b63d24ee..906bab7b 100644 --- a/src/tools/operf/CMakeLists.txt +++ b/src/tools/operf/CMakeLists.txt @@ -10,9 +10,9 @@ if(NOT LIBM_LIBRARIES) endif() set(SOURCE_FILES - # Add source files here - operf.c -) + # Add source files here + operf.c + ) add_executable(operf ${SOURCE_FILES}) diff --git a/src/tools/operf/operf.c b/src/tools/operf/operf.c index 1d91ff42..7935d12c 100644 --- a/src/tools/operf/operf.c +++ b/src/tools/operf/operf.c @@ -3,8 +3,8 @@ * * Ouroboros perf application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c index 5b31e27b..d2f08ef4 100644 --- a/src/tools/operf/operf_client.c +++ b/src/tools/operf/operf_client.c @@ -3,8 +3,8 @@ * * Ouroboros ping application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -182,7 +182,7 @@ int client_main(void) client.sent = 0; client.rcvd = 0; - fd = flow_alloc(client.s_apn, NULL, NULL); + fd = flow_alloc(client.s_apn, NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); return -1; diff --git a/src/tools/operf/operf_server.c b/src/tools/operf/operf_server.c index 3c3b9788..3665d4cc 100644 --- a/src/tools/operf/operf_server.c +++ b/src/tools/operf/operf_server.c @@ -3,8 +3,8 @@ * * Ouroboros perf application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -108,7 +108,7 @@ void * accept_thread(void * o) printf("Ouroboros perf server started.\n"); while (true) { - fd = flow_accept(NULL, &qs); + fd = flow_accept(&qs); if (fd < 0) { printf("Failed to accept flow.\n"); break; diff --git a/src/tools/oping/CMakeLists.txt b/src/tools/oping/CMakeLists.txt index a8fc7d86..f129a02b 100644 --- a/src/tools/oping/CMakeLists.txt +++ b/src/tools/oping/CMakeLists.txt @@ -10,9 +10,9 @@ if(NOT LIBM_LIBRARIES) endif() set(SOURCE_FILES - # Add source files here - oping.c -) + # Add source files here + oping.c + ) add_executable(oping ${SOURCE_FILES}) diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index 64cb7dd8..7c9c108c 100644 --- a/src/tools/oping/oping.c +++ b/src/tools/oping/oping.c @@ -3,8 +3,8 @@ * * Ouroboros ping application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index 99c11a68..a91a126c 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -3,8 +3,8 @@ * * Ouroboros ping application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -213,7 +213,7 @@ int client_main(void) return -1; } - fd = flow_alloc(client.s_apn, NULL, NULL); + fd = flow_alloc(client.s_apn, NULL); if (fd < 0) { printf("Failed to allocate flow.\n"); return -1; diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index 24cd9bf1..e20e236d 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -3,8 +3,8 @@ * * Ouroboros ping application * - * Dimitri Staessens <dimitri.staessens@intec.ugent.be> - * Sander Vrijders <sander.vrijders@intec.ugent.be> + * 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 @@ -119,7 +119,7 @@ void * accept_thread(void * o) printf("Ouroboros ping server started.\n"); while (true) { - fd = flow_accept(NULL, &qs); + fd = flow_accept(&qs); if (fd < 0) { printf("Failed to accept flow.\n"); break; |