diff options
96 files changed, 1666 insertions, 1300 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index ba56dc33..d4060d5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,14 +10,10 @@ git_version_gen()  include(GNUInstallDirs)  set(PACKAGE_NAME        "${CMAKE_PROJECT_NAME}") -set(PACKAGE_DESCRIPTION "The Ouroboros prototype" -  CACHE STRING          "Package description") -set(PACKAGE_URL         "None" -  CACHE STRING          "Package URL") -set(PACKAGE_BUGREPORT   "None" -  CACHE STRING          "Packaged bug-report email") -set(PACKAGE_VERSION     "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}" -  CACHE STRING          "Package version") +set(PACKAGE_DESCRIPTION "The Ouroboros prototype") +set(PACKAGE_URL         "None") +set(PACKAGE_BUGREPORT   "None") +set(PACKAGE_VERSION     "${PACKAGE_VERSION_MAJOR}.${PACKAGE_VERSION_MINOR}")  if (APPLE)    set(CMAKE_MACOSX_RPATH 1) @@ -72,15 +68,11 @@ test_and_set_c_compiler_flag_global(-Wunreachable-code)  test_and_set_c_compiler_flag_global(-Wdeclaration-after-statement)  test_and_set_c_compiler_flag_global(-fmax-errors=5) -configure_file( -  "${CMAKE_CURRENT_SOURCE_DIR}/ouroboros.pc.in" -  "${CMAKE_CURRENT_BINARY_DIR}/ouroboros.pc" -  @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ouroboros.pc.in" +  "${CMAKE_CURRENT_BINARY_DIR}/ouroboros.pc" @ONLY) -if (NOT APPLE) -  install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ouroboros.pc" -    DESTINATION "/usr/lib/pkgconfig") -endif () +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/ouroboros.pc" +  DESTINATION "usr/lib/pkgconfig")  enable_testing()  add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) @@ -88,15 +80,13 @@ add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})  find_package(ProtobufC REQUIRED)  include_directories(${PROTOBUF_C_INCLUDE_DIRS}) -add_subdirectory(src)  add_subdirectory(include) +add_subdirectory(src)  add_subdirectory(doc)  # Uninstall target -configure_file( -  "${CMAKE_SOURCE_DIR}/cmake/CmakeUninstall.cmake.in" -  "${CMAKE_BINARY_DIR}/cmake/CmakeUninstall.cmake" -  IMMEDIATE @ONLY) +configure_file("${CMAKE_SOURCE_DIR}/cmake/CmakeUninstall.cmake.in" +  "${CMAKE_BINARY_DIR}/cmake/CmakeUninstall.cmake" IMMEDIATE @ONLY)  add_custom_target(uninstall    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_BINARY_DIR}/cmake/CmakeUninstall.cmake) diff --git a/doc/man/CMakeLists.txt b/doc/man/CMakeLists.txt index f0ce5df4..eadd385e 100644 --- a/doc/man/CMakeLists.txt +++ b/doc/man/CMakeLists.txt @@ -20,6 +20,8 @@ find_program(GZIP_EXECUTABLE    NAMES gzip    DOC "Will gzip the man pages") +mark_as_advanced(GZIP_EXECUTABLE) +  if (GZIP_EXECUTABLE)    foreach (m ${MAN_NAMES})      set(md ${CMAKE_CURRENT_BINARY_DIR}/${m}.gz) diff --git a/include/ouroboros/CMakeLists.txt b/include/ouroboros/CMakeLists.txt index 8f57d4d7..e39759fd 100644 --- a/include/ouroboros/CMakeLists.txt +++ b/include/ouroboros/CMakeLists.txt @@ -1,7 +1,3 @@ -configure_file( -  "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" -  "${CMAKE_CURRENT_BINARY_DIR}/config.h") -  set(HEADER_FILES    cacep.h    cdap.h diff --git a/include/ouroboros/config.h.in b/include/ouroboros/config.h.in deleted file mode 100644 index d5871624..00000000 --- a/include/ouroboros/config.h.in +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Configuration information - * - *    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 - * version 2.1 as published by the Free Software Foundation. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_CONFIG -#define OUROBOROS_CONFIG - -#define PROJECT_NAME           "@CMAKE_PROJECT_NAME@" -#define PROJECT_VERSION        "@PACKAGE_VERSION@" -#define INSTALL_PREFIX         "@CMAKE_INSTALL_PREFIX@" -#define _POSIX_C_SOURCE        200809L -#define __XSI_VISIBLE          500 -#ifdef __FreeBSD__ -#define __BSD_VISIBLE          1 -#endif -#ifdef __APPLE__ -#define _BSD_SOURCE -#define _DARWIN_C_SOURCE -#endif -#define IPCP_SHIM_UDP_EXEC     "@IPCP_SHIM_UDP_TARGET@" -#define IPCP_SHIM_ETH_LLC_EXEC "@IPCP_SHIM_ETH_LLC_TARGET@" -#define IPCP_NORMAL_EXEC       "@IPCP_NORMAL_TARGET@" -#define IPCP_LOCAL_EXEC        "@IPCP_LOCAL_TARGET@" -#cmakedefine HAVE_ROBUST_MUTEX -#cmakedefine HAVE_SYS_RANDOM -#cmakedefine HAVE_LIBGCRYPT -#cmakedefine HAVE_OPENSSL -#cmakedefine HAVE_NETMAP -#cmakedefine HAVE_BPF -#define AP_MAX_FLOWS           2048 -#define AP_RES_FDS             64 -#define AP_MAX_FQUEUES         64 -#define SHM_RDRB_BLOCK_SIZE    sysconf(_SC_PAGESIZE) -#define SHM_RDRB_MULTI_BLOCK -#define SHM_RDRB_NAME          "/ouroboros.rdrb" -#define LOCKFILE_NAME          "/ouroboros.lockfile" -#define SHM_BUFFER_SIZE        1 << 14 -#define DU_BUFF_HEADSPACE      128 -#define DU_BUFF_TAILSPACE      0 -#define SHM_RBUFF_LOCKLESS     0 -#define SHM_RBUFF_PREFIX       "/ouroboros.rbuff." -#define SHM_FLOW_SET_PREFIX    "/ouroboros.sets." -#define IRMD_MAX_FLOWS         4096 -/* IRMD dynamic threadpooling */ -#define IRMD_MIN_THREADS       16 -#define IRMD_ADD_THREADS       32 -/* IPCP dynamic threadpooling */ -#define IPCP_MIN_THREADS       4 -#define IPCP_ADD_THREADS       16 -#define IPCP_SCHED_THREADS     2 -#define IPCPD_MAX_CONNS        IRMD_MAX_FLOWS -#ifdef __APPLE__ -#define PTHREAD_COND_CLOCK     CLOCK_REALTIME -#else -#define PTHREAD_COND_CLOCK     CLOCK_MONOTONIC -#endif -#define PFT_SIZE               1 << 12 -/* Timeout values */ -#define IRMD_ACCEPT_TIMEOUT    100 -#define IRMD_REQ_ARR_TIMEOUT   500 -#define IRMD_FLOW_TIMEOUT      5000 -#define IPCP_ACCEPT_TIMEOUT    100 -#define SOCKET_TIMEOUT         1000 -#define BOOTSTRAP_TIMEOUT      5000 -#define ENROLL_TIMEOUT         60000 -#define REG_TIMEOUT            10000 -#define QUERY_TIMEOUT          3000 -#define CDAP_REPLY_TIMEOUT     1000 - -#endif /* OUROBOROS_CONFIG */ diff --git a/include/ouroboros/endian.h b/include/ouroboros/endian.h index 18df0e99..00c7e043 100644 --- a/include/ouroboros/endian.h +++ b/include/ouroboros/endian.h @@ -24,42 +24,18 @@  #define OUROBOROS_ENDIAN_H  #if defined(__linux__) || defined(__CYGWIN__) || \ -  (defined(__MACH__) && !defined(__APPLE__)) - -#ifndef _BSD_SOURCE -#define _BSD_SOURCE -#endif -#ifndef __USE_BSD -#define __USE_BSD -#endif -#ifndef _DEFAULT_SOURCE +        (defined(__MACH__) && !defined(__APPLE__))  #define _DEFAULT_SOURCE -#endif -  #include <endian.h> -#include <features.h> - -#define betoh16(x) be16toh(x) -#define letoh16(x) le16toh(x) -#define betoh32(x) be32toh(x) -#define letoh32(x) le32toh(x) -#define betoh64(x) be64toh(x) -#define letoh64(x) le64toh(x) - -#elif defined(__NetBSD__) || defined(__FreeBSD__) - +#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)  #include <sys/endian.h> - -#define betoh16(x) be16toh(x) -#define letoh16(x) le16toh(x) -#define betoh32(x) be32toh(x) -#define letoh32(x) le32toh(x) -#define betoh64(x) be64toh(x) -#define letoh64(x) le64toh(x) -  #elif defined(__APPLE__) -  #include <libkern/OSByteOrder.h> +#else +#error OS currently not supported +#endif + +#if defined (__APPLE__)  #define htobe16(x) OSSwapHostToBigInt16(x)  #define htole16(x) OSSwapHostToLittleInt16(x) @@ -76,13 +52,14 @@  #define betoh64(x) OSSwapBigToHostInt64(x)  #define letoh64(x) OSSwapLittleToHostInt64(x) -#elif defined(__OpenBSD__) - -#include <sys/endian.h> +#elif !defined(__OpenBSD__) -#else - -#error OS currently not supported +#define betoh16(x) be16toh(x) +#define letoh16(x) le16toh(x) +#define betoh32(x) be32toh(x) +#define letoh32(x) le32toh(x) +#define betoh64(x) be64toh(x) +#define letoh64(x) le64toh(x)  #endif diff --git a/include/ouroboros/frct_pci.h b/include/ouroboros/frct_pci.h new file mode 100644 index 00000000..3a93ac1c --- /dev/null +++ b/include/ouroboros/frct_pci.h @@ -0,0 +1,69 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information of FRCT + * + *    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 + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_FRCT_PCI_H +#define OUROBOROS_LIB_FRCT_PCI_H + +#include <ouroboros/shm_du_buff.h> + +#include <stdint.h> +#include <stdbool.h> + +struct frct_pci { +        uint8_t  type; +        uint8_t  flags; +        uint64_t seqno; +        uint64_t lwe; +        uint64_t rwe; +}; + +enum pdu_types { +        PDU_TYPE_DATA        = 0x01, +        PDU_TYPE_ACK         = 0x02, +        PDU_TYPE_FC          = 0x04, +        PDU_TYPE_ACK_AND_FC  = (PDU_TYPE_ACK | PDU_TYPE_FC), +        PDU_TYPE_CONFIG      = 0x08, +        PDU_TYPE_RENDEZ_VOUS = 0x10 +}; + +enum config_flags { +        CONF_RESOURCE_CONTROL = 0x01, +        CONF_RELIABLE         = 0x02, +        CONF_ERROR_CHECK      = 0x04, +        CONF_ORDERED          = 0x08, +        CONF_PARTIAL          = 0x10 +}; + +enum data_flags { +        FLAG_DATA_RUN       = 0x01, +        FLAG_MORE_FRAGMENTS = 0x02 +}; + +int frct_pci_ser(struct shm_du_buff * sdb, +                 struct frct_pci *    pci, +                 bool                 error_check); + +int frct_pci_des(struct shm_du_buff * sdb, +                 struct frct_pci *    pci, +                 bool                 error_check); + +#endif /* OUROBOROS_LIB_FRCT_PCI_H */ diff --git a/include/ouroboros/hash.h b/include/ouroboros/hash.h index db47c9fe..b2896293 100644 --- a/include/ouroboros/hash.h +++ b/include/ouroboros/hash.h @@ -23,12 +23,15 @@  #ifndef OUROBOROS_LIB_HASH_H  #define OUROBOROS_LIB_HASH_H +#include "config.h" +  #include <ouroboros/endian.h>  #ifdef HAVE_LIBGCRYPT  #include <gcrypt.h>  #endif  #include <stdint.h> +#include <stddef.h>  /* Hash algorithms */  enum hash_algo { @@ -58,8 +61,13 @@ enum hash_algo {  uint16_t hash_len(enum hash_algo algo); +void mem_hash(enum hash_algo  algo, +              void *          dst, +              const uint8_t * buf, +              size_t          len); +  void str_hash(enum hash_algo algo, -              void *         buf, +              void *         dst,                const char *   str);  #endif /* OUROBOROS_LIB_HASH_H */ diff --git a/include/ouroboros/shm_flow_set.h b/include/ouroboros/shm_flow_set.h index 5c498336..be2f836b 100644 --- a/include/ouroboros/shm_flow_set.h +++ b/include/ouroboros/shm_flow_set.h @@ -58,6 +58,6 @@ void                  shm_flow_set_notify(struct shm_flow_set * set,  ssize_t               shm_flow_set_wait(const struct shm_flow_set * shm_set,                                          size_t                      idx,                                          int *                       fqueue, -                                        const struct timespec *     timeout); +                                        const struct timespec *     abstime);  #endif /* OUROBOROS_SHM_FLOW_SET_H */ diff --git a/include/ouroboros/shm_rbuff.h b/include/ouroboros/shm_rbuff.h index 1557e50c..55d03b41 100644 --- a/include/ouroboros/shm_rbuff.h +++ b/include/ouroboros/shm_rbuff.h @@ -50,7 +50,7 @@ int                shm_rbuff_write(struct shm_rbuff * rb,  ssize_t            shm_rbuff_read(struct shm_rbuff * rb);  ssize_t            shm_rbuff_read_b(struct shm_rbuff *      rb, -                                    const struct timespec * timeout); +                                    const struct timespec * abstime);  size_t             shm_rbuff_queued(struct shm_rbuff * rb); diff --git a/include/ouroboros/timerwheel.h b/include/ouroboros/timerwheel.h new file mode 100644 index 00000000..b0c9ee29 --- /dev/null +++ b/include/ouroboros/timerwheel.h @@ -0,0 +1,47 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Ring buffer for incoming SDUs + * + *    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 + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_LIB_TIMERWHEEL_H +#define OUROBOROS_LIB_TIMERWHEEL_H + +struct timerwheel; + +struct timerwheel * timerwheel_create(time_t resolution, +                                      time_t max_delay); + +void                timerwheel_destroy(struct timerwheel * tw); + +struct tw_f *       timerwheel_start(struct timerwheel * tw, +                                     void (* func)(void *), +                                     void *              arg, +                                     time_t              delay); /* ms */ + +int                 timerwheel_restart(struct timerwheel * tw, +                                       struct tw_f *       f, +                                       time_t              delay); /* ms */ + +void                timerwheel_stop(struct timerwheel * tw, +                                    struct tw_f *       f); + +void                timerwheel_move(struct timerwheel * tw); + +#endif /* OUROBOROS_LIB_TIMERWHEEL_H */ diff --git a/include/ouroboros/wrap/CMakeLists.txt b/include/ouroboros/wrap/CMakeLists.txt index eb44ed33..435b3b70 100644 --- a/include/ouroboros/wrap/CMakeLists.txt +++ b/include/ouroboros/wrap/CMakeLists.txt @@ -1,10 +1,9 @@ -find_package(SWIG) -  include_directories(${CMAKE_SOURCE_DIR}/include)  include_directories(${CMAKE_BINARY_DIR}/include) +find_package(SWIG)  if (NOT SWIG_FOUND) -  message(STATUS "SWIG not found: Bindings for other languages disabled.") +  message(STATUS "SWIG not found: Bindings for other languages disabled")  else ()    include(${SWIG_USE_FILE})    include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -12,7 +11,7 @@ else ()    find_package(PythonLibs)    if (NOT PYTHONLIBS_FOUND) -    message(STATUS "Python not found: Python bindings will not be built.") +    message(STATUS "Python not found: Python bindings will not be built")    else ()      include_directories(${PYTHON_INCLUDE_PATH}) @@ -55,3 +54,5 @@ else ()        DESTINATION ${PYTHON_MODULE_PATH})    endif ()  endif () + +mark_as_advanced(SWIG_EXECUTABLE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0037d437..54fdd8ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,4 @@ +add_subdirectory(lib)  add_subdirectory(ipcpd)  add_subdirectory(irmd) -add_subdirectory(nsmd) -add_subdirectory(lib)  add_subdirectory(tools) diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index 0ead1fed..6356b1ba 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,14 +1,22 @@ +set(IPCP_ACCEPT_TIMEOUT 100 CACHE STRING +  "Timeout for accept in IPCP mainloop threads (ms)") +set(IPCP_SCHED_THREADS 2 CACHE STRING +  "Number of scheduler threads in the normal IPCP") +set(IPCP_MIN_THREADS 4 CACHE STRING +  "Minimum number of worker threads in the IPCP") +set(IPCP_ADD_THREADS 4 CACHE STRING +  "Number of extra threads to start when an IPCP faces thread starvation") +  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_subdirectory(local)  add_subdirectory(normal)  add_subdirectory(shim-udp)  add_subdirectory(shim-eth-llc) -if (NOT APPLE) -  add_subdirectory(tests) -endif () + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" +  "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) diff --git a/src/ipcpd/timerwheel.h b/src/ipcpd/config.h.in index 37a6d06a..0bef20be 100644 --- a/src/ipcpd/timerwheel.h +++ b/src/ipcpd/config.h.in @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * Ring buffer for incoming SDUs + * IPC process configuration   *   *    Dimitri Staessens <dimitri.staessens@ugent.be>   *    Sander Vrijders   <sander.vrijders@ugent.be> @@ -20,20 +20,30 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifndef OUROBOROS_IPCPD_TIMERWHEEL_H -#define OUROBOROS_IPCPD_TIMERWHEEL_H +#define PTHREAD_COND_CLOCK  @PTHREAD_COND_CLOCK@ -struct timerwheel; +#define SYS_MAX_FLOWS       @SYS_MAX_FLOWS@ +#define AP_RES_FDS          @AP_RES_FDS@ +#define AP_MAX_FLOWS        @AP_MAX_FLOWS@ -struct timerwheel * timerwheel_create(unsigned int resolution, -                                      unsigned int max_delay); +#define IPCP_ACCEPT_TIMEOUT @IPCP_ACCEPT_TIMEOUT@ -void                timerwheel_destroy(struct timerwheel * tw); +#define SOCKET_TIMEOUT      @SOCKET_TIMEOUT@ -int                 timerwheel_add(struct timerwheel * tw, -                                   void (* func)(void *), -                                   void *              arg, -                                   size_t              arg_len, -                                   unsigned int        delay); /* ms */ +#define SHM_BUFFER_SIZE     @SHM_BUFFER_SIZE@ -#endif /* OUROBOROS_IPCPD_TIMERWHEEL_H */ +#define IPCP_MIN_THREADS    @IPCP_MIN_THREADS@ +#define IPCP_ADD_THREADS    @IPCP_ADD_THREADS@ + +/* normal IPCP */ +#define IPCP_SCHED_THREADS  @IPCP_SCHED_THREADS@ +#define PFT_SIZE            @PFT_SIZE@ + +/* shim-udp */ +#define NSUPDATE_EXEC       "@NSUPDATE_EXECUTABLE@" +#define NSLOOKUP_EXEC       "@NSLOOKUP_EXECUTABLE@" + +/* shim-eth-llc */ +#cmakedefine HAVE_NETMAP +#cmakedefine HAVE_BPF +#cmakedefine HAVE_RAW_SOCKETS diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 368c6eb8..300c22f4 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -20,9 +20,13 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +#define __XSI_VISIBLE   500 + +#include "config.h" +  #define OUROBOROS_PREFIX "ipcpd/ipcp" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/logs.h>  #include <ouroboros/time_utils.h> @@ -533,7 +537,6 @@ int ipcp_init(int               argc,          ipcpi.irmd_fd   = -1;          ipcpi.state     = IPCP_NULL; -        ipcpi.shim_data = NULL;          ipcpi.sock_path = ipcp_sock_path(getpid());          if (ipcpi.sock_path == NULL) @@ -597,20 +600,10 @@ int ipcp_init(int               argc,          ipcpi.alloc_id = -1;          ipcpi.csockfd  = -1; -        if (type != IPCP_NORMAL) { -                ipcpi.shim_data = shim_data_create(); -                if (ipcpi.shim_data == NULL) { -                        ret = -ENOMEM; -                        goto fail_shim_data; -                } -        } -          pthread_condattr_destroy(&cattr);          return 0; - fail_shim_data: -        pthread_cond_destroy(&ipcpi.acc_cond);   fail_acc_cond:          pthread_cond_destroy(&ipcpi.cmd_cond);   fail_cmd_cond: @@ -702,8 +695,6 @@ void ipcp_fini()          free(ipcpi.sock_path); -        shim_data_destroy(ipcpi.shim_data); -          pthread_cond_destroy(&ipcpi.state_cond);          pthread_mutex_destroy(&ipcpi.state_mtx);          pthread_cond_destroy(&ipcpi.alloc_cond); diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index 422670d7..cd18d198 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -20,16 +20,14 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifndef IPCPD_IPCP_H -#define IPCPD_IPCP_H +#ifndef OUROBOROS_IPCPD_IPCP_H +#define OUROBOROS_IPCPD_IPCP_H -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/ipcp.h> +#include <ouroboros/qoscube.h>  #include <ouroboros/sockets.h> -#include "shim-data.h" -  #include <pthread.h>  #include <time.h>  #include <signal.h> @@ -80,8 +78,6 @@ struct ipcp {          struct ipcp_ops *  ops;          int                irmd_fd; -        struct shim_data * shim_data; -          enum ipcp_state    state;          pthread_rwlock_t   state_lock;          pthread_mutex_t    state_mtx; @@ -136,4 +132,4 @@ uint8_t *       ipcp_hash_dup(const uint8_t * hash);  void            ipcp_hash_str(char            buf[],                                const uint8_t * hash); -#endif +#endif /* OUROBOROS_IPCPD_IPCP_H */ diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt index 824b4ca6..925092bd 100644 --- a/src/ipcpd/local/CMakeLists.txt +++ b/src/ipcpd/local/CMakeLists.txt @@ -12,7 +12,7 @@ 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 INTERNAL "")  set(SHIM_LOCAL_SOURCES    # Add source files here diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index 241a47eb..37d23fc3 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "ipcpd-local" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/logs.h>  #include <ouroboros/errno.h> @@ -33,6 +36,7 @@  #include <ouroboros/local-dev.h>  #include "ipcp.h" +#include "shim-data.h"  #include <string.h>  #include <stdlib.h> @@ -44,18 +48,20 @@  #define THIS_TYPE IPCP_LOCAL  struct { -        int                   in_out[IRMD_MAX_FLOWS]; -        flow_set_t *          flows; -        fqueue_t *            fq; +        struct shim_data * shim_data; -        pthread_rwlock_t      lock; -        pthread_t             sduloop; +        int                in_out[SYS_MAX_FLOWS]; +        flow_set_t *       flows; +        fqueue_t *         fq; + +        pthread_rwlock_t   lock; +        pthread_t          sduloop;  } local_data;  static int local_data_init(void)  {          int i; -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  local_data.in_out[i] = -1;          local_data.flows = flow_set_create(); @@ -68,12 +74,20 @@ static int local_data_init(void)                  return -ENOMEM;          } +        local_data.shim_data = shim_data_create(); +        if (local_data.shim_data == NULL) { +                fqueue_destroy(local_data.fq); +                flow_set_destroy(local_data.flows); +                return -ENOMEM; +        } +          pthread_rwlock_init(&local_data.lock, NULL);          return 0;  }  static void local_data_fini(void){ +        shim_data_destroy(local_data.shim_data);          flow_set_destroy(local_data.flows);          fqueue_destroy(local_data.fq);          pthread_rwlock_destroy(&local_data.lock); @@ -142,7 +156,7 @@ static int ipcp_local_reg(const uint8_t * hash)                  return -ENOMEM;          } -        if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) { +        if (shim_data_reg_add_entry(local_data.shim_data, hash_dup)) {                  log_dbg("Failed to add " HASH_FMT " to local registry.",                          HASH_VAL(hash));                  free(hash_dup); @@ -156,7 +170,7 @@ static int ipcp_local_reg(const uint8_t * hash)  static int ipcp_local_unreg(const uint8_t * hash)  { -        shim_data_reg_del_entry(ipcpi.shim_data, hash); +        shim_data_reg_del_entry(local_data.shim_data, hash);          log_info("Unregistered " HASH_FMT ".",  HASH_VAL(hash)); @@ -167,7 +181,7 @@ static int ipcp_local_query(const uint8_t * hash)  {          int ret; -        ret = (shim_data_reg_has(ipcpi.shim_data, hash) ? 0 : -1); +        ret = (shim_data_reg_has(local_data.shim_data, hash) ? 0 : -1);          return ret;  } diff --git a/src/ipcpd/normal/CMakeLists.txt b/src/ipcpd/normal/CMakeLists.txt index 8c2d4efc..7a40e94c 100644 --- a/src/ipcpd/normal/CMakeLists.txt +++ b/src/ipcpd/normal/CMakeLists.txt @@ -12,7 +12,7 @@ include_directories(${CURRENT_BINARY_PARENT_DIR})  include_directories(${CMAKE_SOURCE_DIR}/include)  include_directories(${CMAKE_BINARY_DIR}/include) -set(IPCP_NORMAL_TARGET ipcpd-normal CACHE STRING "IPCP_NORMAL_TARGET") +set(IPCP_NORMAL_TARGET ipcpd-normal CACHE INTERNAL "")  protobuf_generate_c(FLOW_ALLOC_SRCS FLOW_ALLOC_HDRS flow_alloc.proto)  protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto) @@ -20,6 +20,10 @@ protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto)  # Add GPB sources of policies last  protobuf_generate_c(FSO_SRCS FSO_HDRS pol/fso.proto) +math(EXPR PFT_EXPR "1 << 12") +set(PFT_SIZE ${PFT_EXPR} CACHE STRING +  "Size of the PDU forwarding table") +  set(SOURCE_FILES    # Add source files here    addr_auth.c @@ -56,4 +60,7 @@ endif (CMAKE_BUILD_TYPE MATCHES Debug)  install(TARGETS ipcpd-normal RUNTIME DESTINATION sbin)  add_subdirectory(pol/tests) -add_subdirectory(tests) + +if (NOT GNU) +  add_subdirectory(tests) +endif () diff --git a/src/ipcpd/normal/addr_auth.c b/src/ipcpd/normal/addr_auth.c index 56b41384..e327e2fa 100644 --- a/src/ipcpd/normal/addr_auth.c +++ b/src/ipcpd/normal/addr_auth.c @@ -22,7 +22,6 @@  #define OUROBOROS_PREFIX "addr_auth" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include "addr_auth.h" diff --git a/src/ipcpd/normal/connmgr.c b/src/ipcpd/normal/connmgr.c index 1513c12a..a83d71c3 100644 --- a/src/ipcpd/normal/connmgr.c +++ b/src/ipcpd/normal/connmgr.c @@ -20,14 +20,16 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #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 <ouroboros/list.h> +#include <ouroboros/logs.h>  #include "ae.h"  #include "connmgr.h" @@ -58,15 +60,39 @@ struct {          pthread_t        acceptor;          struct list_head aes; -        pthread_mutex_t  aes_lock; +        pthread_rwlock_t aes_lock;  } connmgr; -static int add_ae_conn(struct ae *        ae, + +static int get_info_by_name(const char *       name, +                            struct conn_info * info) +{ +        struct list_head * p; + +        pthread_rwlock_rdlock(&connmgr.aes_lock); + +        list_for_each(p, &connmgr.aes) { +                struct ae * ae = list_entry(p, struct ae, next); +                if (strcmp(ae->info.ae_name, name) == 0) { +                        memcpy(info, &ae->info, sizeof(*info)); +                        pthread_rwlock_unlock(&connmgr.aes_lock); +                        return 0; +                } +        } + +        pthread_rwlock_unlock(&connmgr.aes_lock); + +        return -1; +} + +static int add_ae_conn(const char *       name,                         int                fd,                         qosspec_t          qs,                         struct conn_info * rcv_info)  { -        struct ae_conn * ae_conn = NULL; +        struct ae_conn *   ae_conn; +        struct list_head * p; +        struct ae *        ae = NULL;          ae_conn = malloc(sizeof(*ae_conn));          if (ae_conn == NULL) { @@ -74,40 +100,45 @@ static int add_ae_conn(struct ae *        ae,                  return -1;          } -        ae_conn->conn.conn_info = *rcv_info; +        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_rwlock_wrlock(&connmgr.aes_lock); + +        list_for_each(p, &connmgr.aes) { +                ae = list_entry(p, struct ae, next); +                if (strcmp(ae->info.ae_name, name) == 0) +                        break; +        } + +        /* Check if entry was removed during allocation. */ +        if (ae == NULL || strcmp(ae->info.ae_name, name) != 0) { +                pthread_rwlock_unlock(&connmgr.aes_lock); +                return -1; +        } +          pthread_mutex_lock(&ae->conn_lock); +          list_add(&ae_conn->next, &ae->conn_list);          pthread_cond_signal(&ae->conn_cond); -        pthread_mutex_unlock(&ae->conn_lock); -        return 0; -} +        pthread_mutex_unlock(&ae->conn_lock); -static struct ae * find_ae_by_name(char * name) -{ -        struct list_head * p = NULL; +        pthread_rwlock_unlock(&connmgr.aes_lock); -        list_for_each(p, &connmgr.aes) { -                struct ae * ae = list_entry(p, struct ae, next); -                if (strcmp(ae->info.ae_name, name) == 0) -                        return ae; -        } - -        return NULL; +        return 0;  }  static void * flow_acceptor(void * o)  {          int               fd;          qosspec_t         qs; +        struct conn_info  snd_info;          struct conn_info  rcv_info;          struct conn_info  fail_info; -        struct ae *       ae = NULL;          (void) o; @@ -132,25 +163,23 @@ static void * flow_acceptor(void * o)                          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 { +                if (get_info_by_name(rcv_info.ae_name, &snd_info)) { +                        log_err("Failed to get info for %s.", rcv_info.ae_name);                          cacep_snd(fd, &fail_info);                          flow_dealloc(fd); +                        continue; +                } + +                if (cacep_snd(fd, &snd_info)) { +                        log_err("Failed to respond to request."); +                        flow_dealloc(fd); +                        continue; +                } + +                if (add_ae_conn(rcv_info.ae_name, fd, qs, &rcv_info)) { +                        log_err("Failed to add new connection."); +                        flow_dealloc(fd); +                        continue;                  }          } @@ -159,11 +188,11 @@ static void * flow_acceptor(void * o)  int connmgr_init(void)  { -        list_head_init(&connmgr.aes); - -        if (pthread_mutex_init(&connmgr.aes_lock, NULL)) +        if (pthread_rwlock_init(&connmgr.aes_lock, NULL))                  return -1; +        list_head_init(&connmgr.aes); +          return 0;  } @@ -178,13 +207,12 @@ int connmgr_start(void)  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; +        struct list_head * p; +        struct list_head * h;          pthread_mutex_lock(&ae->conn_lock); @@ -204,20 +232,22 @@ static void destroy_ae(struct ae * ae)  void connmgr_fini(void)  { -        struct list_head * p = NULL; -        struct list_head * n = NULL; +        struct list_head * p; +        struct list_head * h; + +        pthread_join(connmgr.acceptor, NULL); -        pthread_mutex_lock(&connmgr.aes_lock); +        pthread_rwlock_wrlock(&connmgr.aes_lock); -        list_for_each_safe(p, n, &connmgr.aes) { +        list_for_each_safe(p, h, &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_rwlock_unlock(&connmgr.aes_lock); -        pthread_mutex_destroy(&connmgr.aes_lock); +        pthread_rwlock_destroy(&connmgr.aes_lock);  }  struct ae * connmgr_ae_create(struct conn_info info) @@ -226,42 +256,46 @@ struct ae * connmgr_ae_create(struct conn_info info)          ae = malloc(sizeof(*ae));          if (ae == NULL) -                return NULL; +                goto fail_malloc;          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_mutex_init(&ae->conn_lock, NULL)) +                goto fail_mutex_init; -        if (pthread_cond_init(&ae->conn_cond, NULL)) { -                pthread_mutex_destroy(&ae->conn_lock); -                free(ae); -                return NULL; -        } +        if (pthread_cond_init(&ae->conn_cond, NULL)) +                goto fail_cond_init; + +        pthread_rwlock_wrlock(&connmgr.aes_lock); -        pthread_mutex_lock(&connmgr.aes_lock);          list_add(&ae->next, &connmgr.aes); -        pthread_mutex_unlock(&connmgr.aes_lock); + +        pthread_rwlock_unlock(&connmgr.aes_lock);          return ae; + + fail_cond_init: +        pthread_mutex_destroy(&ae->conn_lock); + fail_mutex_init: +        free(ae); + fail_malloc: +        return NULL;  }  void connmgr_ae_destroy(struct ae * ae)  {          assert(ae); -        pthread_mutex_lock(&connmgr.aes_lock); +        pthread_rwlock_wrlock(&connmgr.aes_lock);          list_del(&ae->next); -        destroy_ae(ae); +        pthread_rwlock_unlock(&connmgr.aes_lock); -        pthread_mutex_unlock(&connmgr.aes_lock); +        destroy_ae(ae);  }  int connmgr_alloc(struct ae *   ae, @@ -311,7 +345,7 @@ int connmgr_alloc(struct ae *   ae,  int connmgr_wait(struct ae *   ae,                   struct conn * conn)  { -        struct ae_conn * ae_conn = NULL; +        struct ae_conn * ae_conn;          assert(ae);          assert(conn); diff --git a/src/ipcpd/normal/dht.c b/src/ipcpd/normal/dht.c index f41541d2..65e26406 100644 --- a/src/ipcpd/normal/dht.c +++ b/src/ipcpd/normal/dht.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "dht" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/bitmap.h>  #include <ouroboros/errno.h> diff --git a/src/ipcpd/normal/dir.c b/src/ipcpd/normal/dir.c index 231ba110..feae7013 100644 --- a/src/ipcpd/normal/dir.c +++ b/src/ipcpd/normal/dir.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "directory" -#include <ouroboros/config.h>  #include <ouroboros/endian.h>  #include <ouroboros/errno.h>  #include <ouroboros/logs.h> diff --git a/src/ipcpd/normal/dt.c b/src/ipcpd/normal/dt.c index 290c409d..173266f4 100644 --- a/src/ipcpd/normal/dt.c +++ b/src/ipcpd/normal/dt.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "dt-ae" -#include <ouroboros/config.h>  #include <ouroboros/bitmap.h>  #include <ouroboros/errno.h>  #include <ouroboros/logs.h> diff --git a/src/ipcpd/normal/dt_pci.c b/src/ipcpd/normal/dt_pci.c index e139cf91..9e6dfa89 100644 --- a/src/ipcpd/normal/dt_pci.c +++ b/src/ipcpd/normal/dt_pci.c @@ -20,7 +20,6 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h>  #include <ouroboros/errno.h>  #include <ouroboros/rib.h> diff --git a/src/ipcpd/normal/enroll.c b/src/ipcpd/normal/enroll.c index be1596d0..a33239a0 100644 --- a/src/ipcpd/normal/enroll.c +++ b/src/ipcpd/normal/enroll.c @@ -19,9 +19,11 @@   * along with this program; if not, write to the Free Software   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ + +#define _POSIX_C_SOURCE 199309L +  #define OUROBOROS_PREFIX "enrollment" -#include <ouroboros/config.h>  #include <ouroboros/endian.h>  #include <ouroboros/errno.h>  #include <ouroboros/cdap.h> @@ -322,6 +324,7 @@ int enroll_init(void)  void enroll_fini(void)  { +        pthread_join(enroll.listener, NULL);          cdap_destroy(enroll.cdap);          connmgr_ae_destroy(enroll.ae);  } @@ -337,5 +340,4 @@ int enroll_start(void)  void enroll_stop(void)  {          pthread_cancel(enroll.listener); -        pthread_join(enroll.listener, NULL);  } diff --git a/src/ipcpd/normal/fa.c b/src/ipcpd/normal/fa.c index 2488f017..682dc5c6 100644 --- a/src/ipcpd/normal/fa.c +++ b/src/ipcpd/normal/fa.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "flow-allocator" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/fqueue.h>  #include <ouroboros/rib.h> diff --git a/src/ipcpd/normal/gam.c b/src/ipcpd/normal/gam.c index 9997506c..3b4cc5de 100644 --- a/src/ipcpd/normal/gam.c +++ b/src/ipcpd/normal/gam.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "dt-gam" -#include <ouroboros/config.h>  #include <ouroboros/cdap.h>  #include <ouroboros/dev.h>  #include <ouroboros/logs.h> diff --git a/src/ipcpd/normal/main.c b/src/ipcpd/normal/main.c index 27fefdb6..53762415 100644 --- a/src/ipcpd/normal/main.c +++ b/src/ipcpd/normal/main.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #define OUROBOROS_PREFIX "normal-ipcp" -#include <ouroboros/config.h>  #include <ouroboros/endian.h>  #include <ouroboros/logs.h>  #include <ouroboros/ipcp-dev.h> @@ -156,6 +159,7 @@ static int boot_components(void)          ipcp_set_state(IPCP_OPERATIONAL);          if (connmgr_start()) { +                ipcp_set_state(IPCP_INIT);                  log_err("Failed to start AP connection manager.");                  goto fail_connmgr_start;          } @@ -163,7 +167,6 @@ static int boot_components(void)          return 0;   fail_connmgr_start: -        ipcp_set_state(IPCP_INIT);          enroll_stop();   fail_enroll_start:          dir_fini(); diff --git a/src/ipcpd/normal/neighbors.c b/src/ipcpd/normal/neighbors.c index 0ac5e958..5da0f0df 100644 --- a/src/ipcpd/normal/neighbors.c +++ b/src/ipcpd/normal/neighbors.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 199309L +  #define OUROBOROS_PREFIX "neighbors" -#include <ouroboros/config.h>  #include <ouroboros/qoscube.h>  #include <ouroboros/ipcp-dev.h>  #include <ouroboros/errno.h> diff --git a/src/ipcpd/normal/pff.c b/src/ipcpd/normal/pff.c index acf4db1a..d6c9ddee 100644 --- a/src/ipcpd/normal/pff.c +++ b/src/ipcpd/normal/pff.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "pff" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/hashtable.h>  #include <ouroboros/errno.h> diff --git a/src/ipcpd/normal/pol/complete.c b/src/ipcpd/normal/pol/complete.c index e31f345a..6c6e7372 100644 --- a/src/ipcpd/normal/pol/complete.c +++ b/src/ipcpd/normal/pol/complete.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "complete" -#include <ouroboros/config.h>  #include <ouroboros/qoscube.h>  #include <ouroboros/rib.h>  #include <ouroboros/dev.h> diff --git a/src/ipcpd/normal/pol/flat.c b/src/ipcpd/normal/pol/flat.c index 966d0d03..1fece07f 100644 --- a/src/ipcpd/normal/pol/flat.c +++ b/src/ipcpd/normal/pol/flat.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "flat-addr-auth" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/errno.h>  #include <ouroboros/time_utils.h> diff --git a/src/ipcpd/normal/pol/graph.c b/src/ipcpd/normal/pol/graph.c index 7ec9c035..3611f0b0 100644 --- a/src/ipcpd/normal/pol/graph.c +++ b/src/ipcpd/normal/pol/graph.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "graph" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/errno.h>  #include <ouroboros/list.h> diff --git a/src/ipcpd/normal/pol/link_state.c b/src/ipcpd/normal/pol/link_state.c index 322b22d7..9dfed5c0 100644 --- a/src/ipcpd/normal/pol/link_state.c +++ b/src/ipcpd/normal/pol/link_state.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "link-state-routing" -#include <ouroboros/config.h>  #include <ouroboros/errno.h>  #include <ouroboros/list.h>  #include <ouroboros/logs.h> diff --git a/src/ipcpd/normal/pol/tests/graph_test.c b/src/ipcpd/normal/pol/tests/graph_test.c index 30201800..87574187 100644 --- a/src/ipcpd/normal/pol/tests/graph_test.c +++ b/src/ipcpd/normal/pol/tests/graph_test.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200112L +  #include <ouroboros/utils.h>  #include <stdio.h> diff --git a/src/ipcpd/normal/ribmgr.c b/src/ipcpd/normal/ribmgr.c index ee81581f..ab2aa430 100644 --- a/src/ipcpd/normal/ribmgr.c +++ b/src/ipcpd/normal/ribmgr.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "rib-manager" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/cdap.h>  #include <ouroboros/list.h> diff --git a/src/ipcpd/normal/routing.c b/src/ipcpd/normal/routing.c index 5bf985fb..c00ec67c 100644 --- a/src/ipcpd/normal/routing.c +++ b/src/ipcpd/normal/routing.c @@ -20,9 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L +  #define OUROBOROS_PREFIX "routing" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include "routing.h" diff --git a/src/ipcpd/normal/sdu_sched.c b/src/ipcpd/normal/sdu_sched.c index b46f2563..f3550d5c 100644 --- a/src/ipcpd/normal/sdu_sched.c +++ b/src/ipcpd/normal/sdu_sched.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 199309L + +#include "config.h" +  #define OUROBOROS_PREFIX "sdu-scheduler" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/errno.h> diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index 0b81a36a..747a210b 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #include <ouroboros/list.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/errno.h> diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h index 4fd1ad3d..983f97f6 100644 --- a/src/ipcpd/shim-data.h +++ b/src/ipcpd/shim-data.h @@ -20,8 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifndef IPCPD_IPCP_DATA_H -#define IPCPD_IPCP_DATA_H +#ifndef OUROBOROS_IPCPD_IPCP_DATA_H +#define OUROBOROS_IPCPD_IPCP_DATA_H  #include <ouroboros/qoscube.h>  #include <ouroboros/list.h> @@ -93,4 +93,4 @@ void               shim_data_dir_query_destroy(struct dir_query * query);  int                shim_data_dir_query_wait(struct dir_query *      query,                                              const struct timespec * timeout); -#endif /* IPCPD_SHIM_DATA_H */ +#endif /* OUROBOROS_IPCPD_SHIM_DATA_H */ diff --git a/src/ipcpd/shim-eth-llc/CMakeLists.txt b/src/ipcpd/shim-eth-llc/CMakeLists.txt index 21003cf0..e10a715f 100644 --- a/src/ipcpd/shim-eth-llc/CMakeLists.txt +++ b/src/ipcpd/shim-eth-llc/CMakeLists.txt @@ -15,26 +15,59 @@ include_directories(${CMAKE_BINARY_DIR}/include)  find_path(NETMAP_C_INCLUDE_DIR    net/netmap_user.h    HINTS /usr/include /usr/local/include -  ) +) + +mark_as_advanced(NETMAP_C_INCLUDE_DIR) + +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") +  set(DISABLE_RAW_SOCKETS FALSE CACHE BOOL +    "Disable raw socket support for LLC shim") +  if (NOT DISABLE_RAW_SOCKETS) +    message(STATUS "Raw socket support for shim-eth-llc enabled") +    set(HAVE_RAW_SOCKETS TRUE PARENT_SCOPE) +    set(HAVE_LLC TRUE) +  else () +    message(STATUS "Raw socket support for shim-eth-llc disabled by user") +  endif () +endif () -find_path(BPF_C_INCLUDE_DIR -  net/bpf.h -  HINTS /usr/include /usr/local/include +if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") +  find_path(BPF_C_INCLUDE_DIR +            net/bpf.h +            HINTS /usr/include /usr/local/include    ) -if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux" AND -    NOT BPF_C_INCLUDE_DIR STREQUAL "BPF_C_INCLUDE_DIR-NOTFOUND") -  message(STATUS "Found Berkeley Packet Filter headers in ${BPF_C_INCLUDE_DIR}") -  set(HAVE_BPF "1" CACHE STRING "Have Berkeley Packet Filter") +  mark_as_advanced(BPF_C_INCLUDE_DIR) + +  if (BPF_C_INCLUDE_DIR) +    set(DISABLE_BPF FALSE CACHE BOOL +        "Disable Berkeley Packet Filter support for LLC shim") +    if (NOT DISABLE_BPF) +      message(STATUS "Berkeley Packet Filter support " +                     "for shim-eth-llc enabled") +      set(HAVE_BPF TRUE PARENT_SCOPE) +      set(HAVE_LLC TRUE) +    else () +      message(STATUS "Berkeley Packet Filter support " +                     "for shim-eth-llc disabled by user") +    endif () +  endif ()  endif () -if (NOT NETMAP_C_INCLUDE_DIR STREQUAL "NETMAP_C_INCLUDE_DIR-NOTFOUND") -  message(STATUS "Found netmap headers in ${NETMAP_C_INCLUDE_DIR}") -  set(HAVE_NETMAP "1" CACHE STRING "Have netmap") -  test_and_set_c_compiler_flag_global(-std=c99) +if (NETMAP_C_INCLUDE_DIR) +  set(DISABLE_NETMAP FALSE CACHE BOOL +      "Disable netmap support for LLC shim") +  if (NOT DISABLE_NETMAP) +    message(STATUS "Netmap support for shim-eth-llc enabled") +    set(HAVE_NETMAP TRUE PARENT_SCOPE) +    test_and_set_c_compiler_flag_global(-std=c99) +    set(HAVE_LLC TRUE) +  else () +    message(STATUS "Netmap support for shim-eth-llc disabled by user") +  endif ()  endif () -if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux") +if (HAVE_LLC)    message(STATUS "Supported raw Ethernet API found, building shim-eth-llc")    protobuf_generate_c(SHIM_ETH_LLC_PROTO_SRCS SHIM_ETH_LLC_PROTO_HDRS      shim_eth_llc_messages.proto) @@ -44,8 +77,7 @@ if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux")      ${CMAKE_CURRENT_SOURCE_DIR}/main.c    ) -  set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc -      CACHE STRING "IPCP_SHIM_ETH_LLC_TARGET") +  set(IPCP_SHIM_ETH_LLC_TARGET ipcpd-shim-eth-llc CACHE INTERNAL "")    add_executable(ipcpd-shim-eth-llc ${SHIM_ETH_LLC_SOURCES} ${IPCP_SOURCES}      ${SHIM_ETH_LLC_PROTO_SRCS}) @@ -55,7 +87,8 @@ if (HAVE_NETMAP OR HAVE_BPF OR CMAKE_SYSTEM_NAME STREQUAL "Linux")    endif ()    if (HAVE_NETMAP AND NOT APPLE) -    target_include_directories(ipcpd-shim-eth-llc PUBLIC ${NETMAP_C_INCLUDE_DIR}) +    target_include_directories(ipcpd-shim-eth-llc PUBLIC +      ${NETMAP_C_INCLUDE_DIR})    endif ()    target_link_libraries(ipcpd-shim-eth-llc LINK_PUBLIC ouroboros diff --git a/src/ipcpd/shim-eth-llc/main.c b/src/ipcpd/shim-eth-llc/main.c index 55406a00..bcf5abe2 100644 --- a/src/ipcpd/shim-eth-llc/main.c +++ b/src/ipcpd/shim-eth-llc/main.c @@ -20,9 +20,17 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#ifdef __APPLE__ +#define _BSD_SOURCE +#define _DARWIN_C_SOURCE +#else +#define _POSIX_C_SOURCE 200112L +#endif + +#include "config.h" +  #define OUROBOROS_PREFIX "ipcpd/shim-eth-llc" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/errno.h>  #include <ouroboros/list.h> @@ -35,6 +43,7 @@  #include <ouroboros/time_utils.h>  #include "ipcp.h" +#include "shim-data.h"  #include "shim_eth_llc_messages.pb-c.h"  #include <signal.h> @@ -79,6 +88,7 @@  #endif  #define THIS_TYPE                 IPCP_SHIM_ETH_LLC +  #define MGMT_SAP                  0x01  #define MAC_SIZE                  6  #define LLC_HEADER_SIZE           3 @@ -117,6 +127,8 @@ struct mgmt_frame {  };  struct { +        struct shim_data * shim_data; +  #if defined(HAVE_NETMAP)          struct nm_desc *   nmd;          uint8_t            hw_addr[MAC_SIZE]; @@ -125,7 +137,7 @@ struct {  #elif defined(HAVE_BPF)          int                bpf;          uint8_t            hw_addr[MAC_SIZE]; -#elif defined __linux__ +#elif defined HAVE_RAW_SOCKETS          int                s_fd;          struct sockaddr_ll device;  #endif /* HAVE_NETMAP */ @@ -154,7 +166,7 @@ static int eth_llc_data_init(void)          int                ret = -ENOMEM;          pthread_condattr_t cattr; -        eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * IRMD_MAX_FLOWS); +        eth_llc_data.fd_to_ef = malloc(sizeof(struct ef) * SYS_MAX_FLOWS);          if (eth_llc_data.fd_to_ef == NULL)                  goto fail_fd_to_ef; @@ -177,12 +189,16 @@ static int eth_llc_data_init(void)          for (i = 0; i < MAX_SAPS; ++i)                  eth_llc_data.ef_to_fd[i] = -1; -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) { +        for (i = 0; i < SYS_MAX_FLOWS; ++i) {                  eth_llc_data.fd_to_ef[i].sap   = -1;                  eth_llc_data.fd_to_ef[i].r_sap = -1;                  memset(ð_llc_data.fd_to_ef[i].r_addr, 0, MAC_SIZE);          } +        eth_llc_data.shim_data = shim_data_create(); +        if (eth_llc_data.shim_data == NULL) +                goto fail_shim_data; +          ret = -1;          if (pthread_rwlock_init(ð_llc_data.flows_lock, NULL)) @@ -206,6 +222,7 @@ static int eth_llc_data_init(void)          list_head_init(ð_llc_data.mgmt_frames);          return 0; +   fail_mgmt_cond:          pthread_condattr_destroy(&cattr);   fail_condattr: @@ -213,6 +230,8 @@ static int eth_llc_data_init(void)   fail_mgmt_lock:          pthread_rwlock_destroy(ð_llc_data.flows_lock);   fail_flows_lock: +        shim_data_destroy(eth_llc_data.shim_data); + fail_shim_data:          fqueue_destroy(eth_llc_data.fq);   fail_fq:          flow_set_destroy(eth_llc_data.np1_flows); @@ -232,12 +251,13 @@ void eth_llc_data_fini(void)          nm_close(eth_llc_data.nmd);  #elif defined(HAVE_BPF)          close(eth_llc_data.bpf); -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)          close(eth_llc_data.s_fd);  #endif          pthread_cond_destroy(ð_llc_data.mgmt_cond);          pthread_mutex_destroy(ð_llc_data.mgmt_lock);          pthread_rwlock_destroy(ð_llc_data.flows_lock); +        shim_data_destroy(eth_llc_data.shim_data);          fqueue_destroy(eth_llc_data.fq);          flow_set_destroy(eth_llc_data.np1_flows);          bmp_destroy(eth_llc_data.saps); @@ -280,7 +300,7 @@ static int eth_llc_ipcp_send_frame(const uint8_t * dst_addr,          memcpy(llc_frame->src_hwaddr,  #if defined(HAVE_NETMAP) || defined(HAVE_BPF)                 eth_llc_data.hw_addr, -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)                 eth_llc_data.device.sll_addr,  #endif /* HAVE_NETMAP */                 MAC_SIZE); @@ -306,7 +326,7 @@ static int eth_llc_ipcp_send_frame(const uint8_t * dst_addr,                  return -1;          } -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)          if (sendto(eth_llc_data.s_fd,                     frame,                     frame_len, @@ -475,7 +495,7 @@ static int eth_llc_ipcp_name_query_req(const uint8_t * hash,  {          shim_eth_llc_msg_t msg = SHIM_ETH_LLC_MSG__INIT; -        if (shim_data_reg_has(ipcpi.shim_data, hash)) { +        if (shim_data_reg_has(eth_llc_data.shim_data, hash)) {                  msg.code      = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REPLY;                  msg.has_hash  = true;                  msg.hash.len  = ipcp_dir_hash_len(); @@ -495,11 +515,11 @@ static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,          memcpy(&address, r_addr, MAC_SIZE); -        shim_data_dir_add_entry(ipcpi.shim_data, hash, address); +        shim_data_dir_add_entry(eth_llc_data.shim_data, hash, address); -        pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock); +        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock); -        list_for_each(pos, &ipcpi.shim_data->dir_queries) { +        list_for_each(pos, ð_llc_data.shim_data->dir_queries) {                  struct dir_query * e =                          list_entry(pos, struct dir_query, next);                  if (memcmp(e->hash, hash, ipcp_dir_hash_len()) == 0) { @@ -507,7 +527,7 @@ static int eth_llc_ipcp_name_query_reply(const uint8_t * hash,                  }          } -        pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock); +        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock);          return 0;  } @@ -526,7 +546,7 @@ static int eth_llc_ipcp_mgmt_frame(const uint8_t * buf,          switch (msg->code) {          case SHIM_ETH_LLC_MSG_CODE__FLOW_REQ: -                if (shim_data_reg_has(ipcpi.shim_data, msg->hash.data)) { +                if (shim_data_reg_has(eth_llc_data.shim_data, msg->hash.data)) {                          eth_llc_ipcp_sap_req(msg->ssap,                                               r_addr,                                               msg->hash.data, @@ -614,7 +634,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)          struct nm_pkthdr       hdr;  #elif defined(HAVE_BPF)          uint8_t                buf[BPF_BLEN]; -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)          uint8_t                buf[ETH_FRAME_SIZE];  #endif          int                    frame_len = 0; @@ -641,7 +661,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)                  }  #elif defined(HAVE_BPF)                  frame_len = read(eth_llc_data.bpf, buf, BPF_BLEN); -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)                  frame_len = recv(eth_llc_data.s_fd, buf,                                   SHIM_ETH_LLC_MAX_SDU_SIZE, 0);  #endif @@ -659,7 +679,7 @@ static void * eth_llc_ipcp_sdu_reader(void * o)  #if !defined(HAVE_BPF)      #if defined(HAVE_NETMAP)                  if (memcmp(eth_llc_data.hw_addr, -    #elif defined(__linux__) +    #elif defined(HAVE_RAW_SOCKETS)                  if (memcmp(eth_llc_data.device.sll_addr,      #endif /* HAVE_NETMAP */                             llc_frame->dst_hwaddr, @@ -792,7 +812,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)          int              disable = 0;          int              blen;          struct timeval   tv = {0, EVENT_WAIT_TIMEOUT}; -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)          struct timeval   tv = {0, EVENT_WAIT_TIMEOUT};  #endif /* HAVE_NETMAP */ @@ -825,8 +845,10 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)                  log_dbg("Interface %s found.", conf->if_name);      #if defined(HAVE_NETMAP) || defined(HAVE_BPF) -                memcpy(eth_llc_data.hw_addr, LLADDR((struct sockaddr_dl *)(ifa)->ifa_addr), MAC_SIZE); -    #else +                memcpy(eth_llc_data.hw_addr, +                       LLADDR((struct sockaddr_dl *) (ifa)->ifa_addr), +                       MAC_SIZE); +    #elif defined (HAVE_RAW_SOCKETS)                  memcpy(&ifr.ifr_addr, ifa->ifa_addr, sizeof(*ifa->ifa_addr));      #endif                  break; @@ -927,7 +949,7 @@ static int eth_llc_ipcp_bootstrap(const struct ipcp_config * conf)          }          log_info("Using Berkeley Packet Filter."); -#elif defined(__linux__) +#elif defined(HAVE_RAW_SOCKETS)          memset(&(eth_llc_data.device), 0, sizeof(eth_llc_data.device));          eth_llc_data.device.sll_ifindex  = idx;          eth_llc_data.device.sll_family   = AF_PACKET; @@ -991,7 +1013,7 @@ static int eth_llc_ipcp_reg(const uint8_t * hash)                  return -ENOMEM;          } -        if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) { +        if (shim_data_reg_add_entry(eth_llc_data.shim_data, hash_dup)) {                  log_err("Failed to add " HASH_FMT " to local registry.",                          HASH_VAL(hash));                  free(hash_dup); @@ -1005,7 +1027,7 @@ static int eth_llc_ipcp_reg(const uint8_t * hash)  static int eth_llc_ipcp_unreg(const uint8_t * hash)  { -        shim_data_reg_del_entry(ipcpi.shim_data, hash); +        shim_data_reg_del_entry(eth_llc_data.shim_data, hash);          return 0;  } @@ -1019,7 +1041,7 @@ static int eth_llc_ipcp_query(const uint8_t * hash)          struct dir_query * query;          int                ret; -        if (shim_data_dir_has(ipcpi.shim_data, hash)) +        if (shim_data_dir_has(eth_llc_data.shim_data, hash))                  return 0;          msg.code      = SHIM_ETH_LLC_MSG_CODE__NAME_QUERY_REQ; @@ -1033,18 +1055,18 @@ static int eth_llc_ipcp_query(const uint8_t * hash)          if (query == NULL)                  return -1; -        pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock); -        list_add(&query->next, &ipcpi.shim_data->dir_queries); -        pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock); +        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock); +        list_add(&query->next, ð_llc_data.shim_data->dir_queries); +        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock);          eth_llc_ipcp_send_mgmt_frame(&msg, r_addr);          ret = shim_data_dir_query_wait(query, &timeout); -        pthread_mutex_lock(&ipcpi.shim_data->dir_queries_lock); +        pthread_mutex_lock(ð_llc_data.shim_data->dir_queries_lock);          list_del(&query->next);          shim_data_dir_query_destroy(query); -        pthread_mutex_unlock(&ipcpi.shim_data->dir_queries_lock); +        pthread_mutex_unlock(ð_llc_data.shim_data->dir_queries_lock);          return ret;  } @@ -1066,11 +1088,11 @@ static int eth_llc_ipcp_flow_alloc(int             fd,                  return -1;          } -        if (!shim_data_dir_has(ipcpi.shim_data, hash)) { +        if (!shim_data_dir_has(eth_llc_data.shim_data, hash)) {                  log_err("Destination unreachable.");                  return -1;          } -        addr = shim_data_dir_get_addr(ipcpi.shim_data, hash); +        addr = shim_data_dir_get_addr(eth_llc_data.shim_data, hash);          pthread_rwlock_wrlock(ð_llc_data.flows_lock); diff --git a/src/ipcpd/shim-udp/CMakeLists.txt b/src/ipcpd/shim-udp/CMakeLists.txt index 3ff8dd5f..eff3f5d0 100644 --- a/src/ipcpd/shim-udp/CMakeLists.txt +++ b/src/ipcpd/shim-udp/CMakeLists.txt @@ -15,18 +15,14 @@ include_directories(${CMAKE_BINARY_DIR}/include)  protobuf_generate_c(SHIM_UDP_PROTO_SRCS SHIM_UDP_PROTO_HDRS    shim_udp_messages.proto) -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 INTERNAL "")  set(SHIM_UDP_SOURCES    # Add source files here    ${CMAKE_CURRENT_SOURCE_DIR}/main.c)  add_executable(ipcpd-shim-udp ${SHIM_UDP_SOURCES} ${IPCP_SOURCES} -  ${SHIM_UDP_PROTO_SRCS} "${CMAKE_CURRENT_BINARY_DIR}/shim_udp_config.h") +  ${SHIM_UDP_PROTO_SRCS})  target_link_libraries(ipcpd-shim-udp LINK_PUBLIC ouroboros    ${PROTOBUF_C_LIBRARY}) @@ -40,10 +36,12 @@ find_program(NSLOOKUP_EXECUTABLE    NAMES nslookup    DOC "The nslookup tool that resolves DNS names") +mark_as_advanced(NSLOOKUP_EXECUTABLE NSUPDATE_EXECUTABLE) +  include(AddCompileFlags) -if (${NSUPDATE_EXECUTABLE} STREQUAL "NSUPDATE_EXECUTABLE-NOTFOUND") +if (NOT NSUPDATE_EXECUTABLE)    message(STATUS "Could not find nsupdate. Disabling DDNS functionality.") -elseif (${NSLOOKUP_EXECUTABLE} STREQUAL "NSLOOKUP_EXECUTABLE-NOTFOUND") +elseif (NOT NSLOOKUP_EXECUTABLE)    message(STATUS "Could not find nslookup. Disabling DNS lookups.")  else ()    message(STATUS "Found nsupdate: ${NSUPDATE_EXECUTABLE}") @@ -56,6 +54,3 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)  endif (CMAKE_BUILD_TYPE MATCHES Debug)  install(TARGETS ipcpd-shim-udp RUNTIME DESTINATION sbin) - -# Enable once ipcp-shim-udp has tests -# add_subdirectory(tests) diff --git a/src/ipcpd/shim-udp/main.c b/src/ipcpd/shim-udp/main.c index 195e3bc0..55fe19a6 100644 --- a/src/ipcpd/shim-udp/main.c +++ b/src/ipcpd/shim-udp/main.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #define OUROBOROS_PREFIX "ipcpd/shim-udp" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/list.h>  #include <ouroboros/utils.h> @@ -32,9 +35,9 @@  #include <ouroboros/errno.h>  #include <ouroboros/logs.h> -#include "shim_udp_messages.pb-c.h"  #include "ipcp.h" -#include "shim_udp_config.h" +#include "shim-data.h" +#include "shim_udp_messages.pb-c.h"  #include <string.h>  #include <sys/socket.h> @@ -68,6 +71,8 @@ struct uf {  };  struct { +        struct shim_data * shim_data; +          uint32_t           ip_addr;          uint32_t           dns_addr;          /* listen server */ @@ -79,7 +84,7 @@ struct {          fd_set             flow_fd_s;          /* bidir mappings of (n - 1) file descriptor to (n) flow descriptor */          int                uf_to_fd[FD_SETSIZE]; -        struct uf          fd_to_uf[IRMD_MAX_FLOWS]; +        struct uf          fd_to_uf[SYS_MAX_FLOWS];          pthread_rwlock_t   flows_lock;          pthread_t          sduloop; @@ -98,7 +103,7 @@ static int udp_data_init(void)          for (i = 0; i < FD_SETSIZE; ++i)                  udp_data.uf_to_fd[i] = -1; -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) { +        for (i = 0; i < SYS_MAX_FLOWS; ++i) {                  udp_data.fd_to_uf[i].skfd = -1;                  udp_data.fd_to_uf[i].udp = -1;          } @@ -115,6 +120,13 @@ static int udp_data_init(void)                  return -ENOMEM;          } +        udp_data.shim_data = shim_data_create(); +        if (udp_data.shim_data == NULL) { +                fqueue_destroy(udp_data.fq); +                flow_set_destroy(udp_data.np1_flows); +                return -ENOMEM; +        } +          pthread_rwlock_init(&udp_data.flows_lock, NULL);          pthread_cond_init(&udp_data.fd_set_cond, NULL);          pthread_mutex_init(&udp_data.fd_set_lock, NULL); @@ -127,6 +139,8 @@ static void udp_data_fini(void)          flow_set_destroy(udp_data.np1_flows);          fqueue_destroy(udp_data.fq); +        shim_data_destroy(udp_data.shim_data); +          pthread_rwlock_destroy(&udp_data.flows_lock);          pthread_mutex_destroy(&udp_data.fd_set_lock);          pthread_cond_destroy(&udp_data.fd_set_cond); @@ -322,7 +336,7 @@ static int udp_port_to_fd(int udp_port)  {          int i; -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  if (udp_data.fd_to_uf[i].udp == udp_port)                          return i; @@ -765,7 +779,7 @@ static int ipcp_udp_reg(const uint8_t * hash)                  return -ENOMEM;          } -        if (shim_data_reg_add_entry(ipcpi.shim_data, hash_dup)) { +        if (shim_data_reg_add_entry(udp_data.shim_data, hash_dup)) {                  log_err("Failed to add " HASH_FMT " to local registry.",                          HASH_VAL(hash));                  free(hash_dup); @@ -794,7 +808,7 @@ static int ipcp_udp_reg(const uint8_t * hash)                          dnsstr, hashstr, DNS_TTL, ipstr);                  if (ddns_send(cmd)) { -                        shim_data_reg_del_entry(ipcpi.shim_data, hash_dup); +                        shim_data_reg_del_entry(udp_data.shim_data, hash_dup);                          return -1;                  }          } @@ -835,7 +849,7 @@ static int ipcp_udp_unreg(const uint8_t * hash)          }  #endif -        shim_data_reg_del_entry(ipcpi.shim_data, hash); +        shim_data_reg_del_entry(udp_data.shim_data, hash);          log_dbg("Unregistered " HASH_FMT ".", HASH_VAL(hash)); @@ -855,7 +869,7 @@ static int ipcp_udp_query(const uint8_t * hash)          ipcp_hash_str(hashstr, hash); -        if (shim_data_dir_has(ipcpi.shim_data, hash)) +        if (shim_data_dir_has(udp_data.shim_data, hash))                  return 0;  #ifdef CONFIG_OUROBOROS_ENABLE_DNS @@ -880,7 +894,7 @@ static int ipcp_udp_query(const uint8_t * hash)          }  #endif -        if (shim_data_dir_add_entry(ipcpi.shim_data, hash, ip_addr)) { +        if (shim_data_dir_add_entry(udp_data.shim_data, hash, ip_addr)) {                  log_err("Failed to add directory entry.");                  return -1;          } @@ -926,12 +940,12 @@ static int ipcp_udp_flow_alloc(int             fd,                  return -1;          } -        if (!shim_data_dir_has(ipcpi.shim_data, dst)) { +        if (!shim_data_dir_has(udp_data.shim_data, dst)) {                  log_dbg("Could not resolve destination.");                  close(skfd);                  return -1;          } -        ip_addr = (uint32_t) shim_data_dir_get_addr(ipcpi.shim_data, dst); +        ip_addr = (uint32_t) shim_data_dir_get_addr(udp_data.shim_data, dst);          /* connect to server (store the remote IP address in the fd) */          memset((char *) &r_saddr, 0, sizeof(r_saddr)); diff --git a/src/ipcpd/shim-udp/shim_udp_config.h.in b/src/ipcpd/shim-udp/shim_udp_config.h.in deleted file mode 100644 index c32210e9..00000000 --- a/src/ipcpd/shim-udp/shim_udp_config.h.in +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Configuration information specific for the shim UDP - * - *    Sander Vrijders <sander.vrijders@intec.ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#ifndef OUROBOROS_SHIM_UDP_CONFIG -#define OUROBOROS_SHIM_UDP_CONFIG - -#define NSUPDATE_EXEC "@NSUPDATE_EXECUTABLE@" -#define NSLOOKUP_EXEC "@NSLOOKUP_EXECUTABLE@" - -#endif diff --git a/src/ipcpd/shim-udp/tests/CMakeLists.txt b/src/ipcpd/shim-udp/tests/CMakeLists.txt deleted file mode 100644 index bdd7defb..00000000 --- a/src/ipcpd/shim-udp/tests/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -get_filename_component(PARENT_SOURCE_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(PARENT_BINARY_PATH ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) -get_filename_component(PARENT_DIR ${PARENT_SOURCE_PATH} NAME) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${PARENT_SOURCE_PATH}) -include_directories(${PARENT_BINARY_PATH}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -create_test_sourcelist(${PARENT_DIR}_tests test_suite.c -                       # Add new tests here -                       shim_udp_test.c -) - -add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${IPCP_SOURCES} ${${PARENT_DIR}_tests}) -target_link_libraries(${PARENT_DIR}_test ouroboros) - -include(MacroAddCompileFlags) -MACRO_ADD_COMPILE_FLAGS(${PARENT_DIR}_test -DMAKE_CHECK) - -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}) -  get_filename_component(test_name ${test} NAME_WE) -  add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) -endforeach(test) diff --git a/src/ipcpd/shim-udp/tests/shim_udp_test.c b/src/ipcpd/shim-udp/tests/shim_udp_test.c deleted file mode 100644 index 88669a9e..00000000 --- a/src/ipcpd/shim-udp/tests/shim_udp_test.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Test of the Shim UDP IPCP Daemon - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#include <ouroboros/config.h> -#include <ouroboros/ipcp.h> -#include <ouroboros/utils.h> -#include <ouroboros/shm_du_map.h> -#include <sys/types.h> -#include <stdlib.h> -#include "main.c" - -#include <ouroboros/logs.h> - -struct ipcp * _ipcp; - -int shim_udp_test(int argc, char ** argv) -{ -        struct shm_du_map * dum; -        char * ipcp_name = "test-shim-ipcp"; -        int i = 0; - -        char bogus[16]; -        memset(&bogus, 0, 16); - -        struct ipcp_config conf; -        memset(&conf, 0, sizeof conf); -        conf.dif_name = strdup("test-dif"); -        conf.type = IPCP_SHIM_UDP; -        conf.ip_addr = 0; - -        dum = shm_du_map_create(); -        if (dum == NULL) { -                log_err("Failed to create shared memory."); -                exit(1); -        } - -        _ipcp = ipcp_udp_create(ipcp_name); -        if (_ipcp == NULL) { -                log_err("Could not instantiate shim IPCP."); -                shm_du_map_destroy(dum); -                exit(1); -        } - -        if (ipcp_udp_bootstrap(&conf)) { -                log_err("Could not bootstrap."); -        } - -        if (ipcp_udp_name_reg("bogus name")) { -                log_err("Failed to register application."); -                shm_du_map_destroy(dum); -                exit(1); -        } - -        if (ipcp_udp_name_unreg("bogus name")) { -                log_err("Failed to unregister application."); -                shm_du_map_destroy(dum); -                exit(1); -        } - -        for (i = 0; i  < 1000; ++i) { -                sprintf(bogus, "bogus name %4d", i); -                if (ipcp_udp_name_reg(bogus)) { -                         log_err("Failed to register application %s.", bogus); -                         shm_du_map_destroy(dum); -                         exit(1); -                } -        } - -        for (i = 0; i  < 1000; ++i) { -                sprintf(bogus, "bogus name %4d", i); -                if(ipcp_udp_name_unreg(bogus)) { -                         log_err("Failed to unregister application %s.", bogus); -                         shm_du_map_destroy(dum); -                         exit(1); -                } -        } - -        shm_du_map_destroy(dum); - -        exit(0); -} diff --git a/src/ipcpd/tests/CMakeLists.txt b/src/ipcpd/tests/CMakeLists.txt deleted file mode 100644 index 9b5eeaa1..00000000 --- a/src/ipcpd/tests/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -get_filename_component(CURRENT_SOURCE_PARENT_DIR -  ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CURRENT_BINARY_PARENT_DIR -  ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CURRENT_SOURCE_PARENT_DIR}) -include_directories(${CURRENT_BINARY_PARENT_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -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 -  timerwheel_test.c -  ) - -add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) -target_link_libraries(${PARENT_DIR}_test ouroboros) - -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}) -  get_filename_component(test_name ${test} NAME_WE) -  add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) -endforeach (test) diff --git a/src/ipcpd/timerwheel.c b/src/ipcpd/timerwheel.c deleted file mode 100644 index 6086181a..00000000 --- a/src/ipcpd/timerwheel.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * Timerwheel - * - *    Dimitri Staessens <dimitri.staessens@ugent.be> - *    Sander Vrijders   <sander.vrijders@ugent.be> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#include <ouroboros/config.h> -#include <ouroboros/time_utils.h> -#include <ouroboros/errno.h> -#include <ouroboros/list.h> - -#include <pthread.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -#define FRAC 10 /* accuracy of the timer */ - -#define tw_used(tw) ((tw->head + tw->elements - tw->tail) & (tw->elements - 1)); -#define tw_free(tw) (tw_used(tw) + 1 < tw->elements) -#define tw_empty(tw) (tw->head == tw->tail) - -enum tw_state { -        TW_NULL = 0, -        TW_RUNNING, -        TW_DESTROY -}; - -struct tw_f { -        struct list_head next; -        void (* func)(void *); -        void * arg; -}; - -struct tw_el { -        struct list_head funcs; -        struct timespec  expiry; -}; - -struct timerwheel { -        struct tw_el *   wheel; - -        struct timespec  intv; - -        size_t           pos; - -        struct list_head wq; - -        pthread_cond_t   work; -        pthread_mutex_t  lock; - -        int              resolution; -        unsigned int     elements; - -        enum tw_state    state; -        pthread_mutex_t  s_lock; - -        pthread_t        ticker; -        pthread_t        worker; -}; - -static void tw_el_fini(struct tw_el * e) -{ -        struct list_head * p; -        struct list_head * h; - -        list_for_each_safe(p, h, &e->funcs) { -                struct tw_f * f = list_entry(p, struct tw_f, next); -                list_del(&f->next); -                if (f->arg != NULL) -                        free(f->arg); -        } -} - -static enum tw_state tw_get_state(struct timerwheel * tw) -{ -        enum tw_state state; - -        assert(tw); - -        pthread_mutex_lock(&tw->s_lock); - -        state = tw->state; - -        pthread_mutex_unlock(&tw->s_lock); - -        return state; -} - -static void tw_set_state(struct timerwheel * tw, enum tw_state state) -{ -        assert(tw); -        assert(state != TW_NULL); - -        pthread_mutex_lock(&tw->s_lock); - -        tw->state = state; - -        pthread_mutex_unlock(&tw->s_lock); -} - -static void * worker(void * o) -{ -        struct list_head * p; -        struct list_head * h; - -        struct timerwheel * tw = (struct timerwheel *) o; -        struct timespec dl; -        struct timespec now; - -        clock_gettime(PTHREAD_COND_CLOCK, &now); - -        ts_add(&now, &tw->intv, &dl); - -        pthread_mutex_lock(&tw->lock); - -        while (tw_get_state(tw) == TW_RUNNING) { -                if (pthread_cond_timedwait(&tw->work, &tw->lock, &dl) -                    == ETIMEDOUT) -                        ts_add(&dl, &tw->intv, &dl); - -                list_for_each_safe(p, h, &tw->wq) { -                        struct tw_f * f = list_entry(p, struct tw_f, next); -                        list_del(&f->next); -                        pthread_mutex_unlock(&tw->lock); -                        f->func(f->arg); -                        if (f->arg != NULL) -                                free(f->arg); -                        free(f); - -                        pthread_mutex_lock(&tw->lock); -                } -        } - -        pthread_mutex_unlock(&tw->lock); - -        return (void *) o; -} - -static void * movement(void * o) -{ -        struct timerwheel * tw = (struct timerwheel *) o; -        struct timespec now = {0, 0}; -        long ms = tw->resolution * tw->elements; -        struct timespec total = {ms / 1000, -                                 (ms % 1000) * MILLION}; -        struct list_head * p; -        struct list_head * h; - -        while (tw_get_state(tw) == TW_RUNNING) { -                clock_gettime(CLOCK_MONOTONIC, &now); - -                pthread_mutex_lock(&tw->lock); - -                if (ts_diff_us(&tw->wheel[tw->pos].expiry, &now) < 0) { -                        pthread_mutex_unlock(&tw->lock); -                        nanosleep(&tw->intv, NULL); -                        continue; -                } - -                list_for_each_safe(p, h, &tw->wheel[tw->pos].funcs) { -                        struct tw_f * f = list_entry(p, struct tw_f, next); -                        list_del(&f->next); -                        list_add(&f->next, &tw->wq); -                } - -                ts_add(&tw->wheel[tw->pos].expiry, -                       &total, -                       &tw->wheel[tw->pos].expiry); - -                tw->pos = (tw->pos + 1) & (tw->elements - 1); - -                pthread_cond_signal(&tw->work); - -                pthread_mutex_unlock(&tw->lock); -        } - -        return (void *) 0; -} - -struct timerwheel * timerwheel_create(unsigned int resolution, -                                      unsigned int max_delay) -{ -        struct timespec now = {0, 0}; -        struct timespec res_ts = {resolution / 1000, -                                  (resolution % 1000) * MILLION}; -        unsigned long i; - -        struct timerwheel * tw; - -        pthread_condattr_t cattr; - -        assert(resolution != 0); - -        tw = malloc(sizeof(*tw)); -        if (tw == NULL) -                return NULL; - -        if (pthread_mutex_init(&tw->lock, NULL)) -                return NULL; - -        tw->elements = 1; - -        while (tw->elements < max_delay / resolution) -                tw->elements <<= 1; - -        tw->wheel = malloc(sizeof(*tw->wheel) * tw->elements); -        if (tw->wheel == NULL) { -                free(tw); -                return NULL; -        } - -        tw->resolution = resolution; - -        tw->intv.tv_sec = (tw->resolution / FRAC) / 1000; -        tw->intv.tv_nsec = ((tw->resolution / FRAC) % 1000) * MILLION; - -        list_head_init(&tw->wq); - -        if (pthread_mutex_init(&tw->lock, NULL)) { -                free(tw->wheel); -                free(tw); -                return NULL; -        } - -        if (pthread_mutex_init(&tw->s_lock, NULL)) { -                pthread_mutex_destroy(&tw->lock); -                free(tw->wheel); -                free(tw); -                return NULL; -        } - -        if (pthread_condattr_init(&cattr)) { -                pthread_mutex_destroy(&tw->lock); -                free(tw->wheel); -                free(tw); -                return NULL; -        } -#ifndef __APPLE__ -        pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); -#endif -        if (pthread_cond_init(&tw->work, &cattr)) { -                pthread_mutex_destroy(&tw->s_lock); -                pthread_mutex_destroy(&tw->lock); -                free(tw->wheel); -                free(tw); -                return NULL; -        } - -        tw->pos = 0; -        tw->state = TW_RUNNING; - -        clock_gettime(CLOCK_MONOTONIC, &now); -        now.tv_nsec -= (now.tv_nsec % MILLION); - -        for (i = 0; i < tw->elements; ++i) { -                list_head_init(&tw->wheel[i].funcs); -                tw->wheel[i].expiry = now; -                ts_add(&now, &res_ts, &now); -        } - -        if (pthread_create(&tw->worker, NULL, worker, (void *) tw)) { -                pthread_cond_destroy(&tw->work); -                pthread_mutex_destroy(&tw->s_lock); -                pthread_mutex_destroy(&tw->lock); -                free(tw->wheel); -                free(tw); -                return NULL; -        } - -        if (pthread_create(&tw->ticker, NULL, movement, (void *) tw)) { -                tw_set_state(tw, TW_DESTROY); -                pthread_join(tw->worker, NULL); -                pthread_cond_destroy(&tw->work); -                pthread_mutex_destroy(&tw->s_lock); -                pthread_mutex_destroy(&tw->lock); -                free(tw->wheel); -                free(tw); -                return NULL; -        } - -        return tw; -} - -void timerwheel_destroy(struct timerwheel * tw) -{ -        unsigned long i; - -        struct list_head * p; -        struct list_head * h; - -        tw_set_state(tw, TW_DESTROY); - -        pthread_join(tw->ticker, NULL); -        pthread_join(tw->worker, NULL); - -        for (i = 0; i < tw->elements; ++i) -                tw_el_fini(&tw->wheel[i]); - -        pthread_mutex_lock(&tw->lock); - -        list_for_each_safe(p, h, &tw->wq) { -                struct tw_f * f = list_entry(p, struct tw_f, next); -                list_del(&f->next); -                if (f->arg != NULL) -                        free(f->arg); -                free(f); -        } - -        pthread_mutex_unlock(&tw->lock); - -        pthread_cond_destroy(&tw->work); -        pthread_mutex_destroy(&tw->lock); -        pthread_mutex_destroy(&tw->s_lock); - -        free(tw->wheel); -        free(tw); -} - -int timerwheel_add(struct timerwheel * tw, -                   void (* func)(void *), -                   void * arg, -                   size_t arg_len, -                   unsigned int delay) -{ -        int pos; -        struct tw_f * f = malloc(sizeof(*f)); -        if (f == NULL) -                return -ENOMEM; - -        f->func = func; -        f->arg = malloc(arg_len); -        if (f->arg == NULL) { -                free(f); -                return -ENOMEM; -        } - -        memcpy(f->arg, arg, arg_len); - -        assert(delay < tw->elements * tw->resolution); - -        pthread_mutex_lock(&tw->lock); - -        pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1); -        list_add(&f->next, &tw->wheel[pos].funcs); - -        pthread_mutex_unlock(&tw->lock); - -        return 0; -} diff --git a/src/irmd/CMakeLists.txt b/src/irmd/CMakeLists.txt index 930c7b05..3339991a 100644 --- a/src/irmd/CMakeLists.txt +++ b/src/irmd/CMakeLists.txt @@ -4,6 +4,28 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})  include_directories(${CMAKE_SOURCE_DIR}/include)  include_directories(${CMAKE_BINARY_DIR}/include) +set(IRMD_ACCEPT_TIMEOUT 100 CACHE STRING +  "Timeout for accept in IRMD mainloop threads (ms)") +set(IRMD_REQ_ARR_TIMEOUT 500 CACHE STRING +  "Timeout for an application to respond to a new flow (ms)") +set(IRMD_FLOW_TIMEOUT 5000 CACHE STRING +  "Timeout for a flow allocation response (ms)") +set(BOOTSTRAP_TIMEOUT 5000 CACHE STRING +  "Timeout for an IPCP to bootstrap (ms)") +set(ENROLL_TIMEOUT 60000 CACHE STRING +  "Timeout for an IPCP to enroll (ms)") +set(REG_TIMEOUT 10000 CACHE STRING +  "Timeout for registering a name (ms)") +set(QUERY_TIMEOUT 3000 CACHE STRING +  "Timeout to query a name with an IPCP (ms)") +set(IRMD_MIN_THREADS 8 CACHE STRING +  "Minimum number of worker threads in the IRMd.") +set(IRMD_ADD_THREADS 8 CACHE STRING +  "Number of extra threads to start when the IRMD faces thread starvation") + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" +  "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) +  set(SOURCE_FILES    # Add source files here    api_table.c diff --git a/src/irmd/api_table.c b/src/irmd/api_table.c index 5765916e..df56dd02 100644 --- a/src/irmd/api_table.c +++ b/src/irmd/api_table.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #include <ouroboros/list.h>  #include <ouroboros/errno.h>  #include <ouroboros/time_utils.h> diff --git a/src/irmd/config.h.in b/src/irmd/config.h.in new file mode 100644 index 00000000..eb396bbc --- /dev/null +++ b/src/irmd/config.h.in @@ -0,0 +1,46 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Configuration for the IPC Resource Manager + * + *    Dimitri Staessens <dimitri.staessens@ugent.be> + *    Sander Vrijders   <sander.vrijders@ugent.be> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#define IPCP_SHIM_UDP_EXEC     "@IPCP_SHIM_UDP_TARGET@" +#define IPCP_SHIM_ETH_LLC_EXEC "@IPCP_SHIM_ETH_LLC_TARGET@" +#define IPCP_NORMAL_EXEC       "@IPCP_NORMAL_TARGET@" +#define IPCP_LOCAL_EXEC        "@IPCP_LOCAL_TARGET@" + +#define INSTALL_PREFIX         "@CMAKE_INSTALL_PREFIX@" + +#define PTHREAD_COND_CLOCK     @PTHREAD_COND_CLOCK@ + +#define SOCKET_TIMEOUT         @SOCKET_TIMEOUT@ + +#define IRMD_ACCEPT_TIMEOUT    @IRMD_ACCEPT_TIMEOUT@ +#define IRMD_REQ_ARR_TIMEOUT   @IRMD_REQ_ARR_TIMEOUT@ +#define IRMD_FLOW_TIMEOUT      @IRMD_FLOW_TIMEOUT@ + +#define BOOTSTRAP_TIMEOUT      @BOOTSTRAP_TIMEOUT@ +#define ENROLL_TIMEOUT         @ENROLL_TIMEOUT@ +#define REG_TIMEOUT            @REG_TIMEOUT@ +#define QUERY_TIMEOUT          @QUERY_TIMEOUT@ + +#define SYS_MAX_FLOWS          @SYS_MAX_FLOWS@ + +#define IRMD_MIN_THREADS       @IRMD_MIN_THREADS@ +#define IRMD_ADD_THREADS       @IRMD_ADD_THREADS@ diff --git a/src/irmd/ipcp.c b/src/irmd/ipcp.c index f3f97811..e1689b91 100644 --- a/src/irmd/ipcp.c +++ b/src/irmd/ipcp.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 199309L + +#include "config.h" +  #define OUROBOROS_PREFIX "irmd/ipcp" -#include <ouroboros/config.h>  #include <ouroboros/logs.h>  #include <ouroboros/errno.h>  #include <ouroboros/utils.h> @@ -49,9 +52,9 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t        api,                                  ipcp_msg_t * msg)  {         int            sockfd    = 0; -       buffer_t       buf; +       uint8_t        buf[IPCP_MSG_BUF_SIZE];         char *         sock_path = NULL; -       ssize_t        count     = 0; +       ssize_t        len;         ipcp_msg_t *   recv_msg  = NULL;         struct timeval tv; @@ -70,14 +73,8 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t        api,         free(sock_path); -       buf.len = ipcp_msg__get_packed_size(msg); -       if (buf.len == 0) { -               close(sockfd); -               return NULL; -       } - -       buf.data = malloc(IPCP_MSG_BUF_SIZE); -       if (buf.data == NULL) { +       len = ipcp_msg__get_packed_size(msg); +       if (len == 0) {                 close(sockfd);                 return NULL;         } @@ -110,18 +107,16 @@ ipcp_msg_t * send_recv_ipcp_msg(pid_t        api,                 log_warn("Failed to set timeout on socket.");         pthread_cleanup_push(close_ptr, (void *) &sockfd); -       pthread_cleanup_push((void (*)(void *)) free, (void *) buf.data); -       ipcp_msg__pack(msg, buf.data); +       ipcp_msg__pack(msg, buf); -       if (write(sockfd, buf.data, buf.len) != -1) -               count = read(sockfd, buf.data, IPCP_MSG_BUF_SIZE); +       if (write(sockfd, buf, len) != -1) +               len = read(sockfd, buf, IPCP_MSG_BUF_SIZE); -       if (count > 0) -               recv_msg = ipcp_msg__unpack(NULL, count, buf.data); +       if (len > 0) +               recv_msg = ipcp_msg__unpack(NULL, len, buf);         pthread_cleanup_pop(true); -       pthread_cleanup_pop(true);         return recv_msg;  } diff --git a/src/irmd/irm_flow.c b/src/irmd/irm_flow.c index ae5585a2..e335ef48 100644 --- a/src/irmd/irm_flow.c +++ b/src/irmd/irm_flow.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 199309L + +#include "config.h" +  #define OUROBOROS_PREFIX "irm_flow" -#include <ouroboros/config.h>  #include <ouroboros/errno.h>  #include <ouroboros/logs.h>  #include <ouroboros/time_utils.h> diff --git a/src/irmd/main.c b/src/irmd/main.c index a7c2bd4c..66c230c8 100644 --- a/src/irmd/main.c +++ b/src/irmd/main.c @@ -20,9 +20,13 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200812L +#define __XSI_VISIBLE   500 + +#include "config.h" +  #define OUROBOROS_PREFIX "irmd" -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/errno.h>  #include <ouroboros/sockets.h> @@ -2070,7 +2074,7 @@ static int irm_init(void)          list_head_init(&irmd.registry);          list_head_init(&irmd.irm_flows); -        irmd.port_ids = bmp_create(IRMD_MAX_FLOWS, 0); +        irmd.port_ids = bmp_create(SYS_MAX_FLOWS, 0);          if (irmd.port_ids == NULL) {                  log_err("Failed to create port_ids bitmap.");                  goto fail_port_ids; diff --git a/src/irmd/registry.c b/src/irmd/registry.c index ad6a10d4..3cc9b5f5 100644 --- a/src/irmd/registry.c +++ b/src/irmd/registry.c @@ -20,9 +20,12 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #define OUROBOROS_PREFIX "registry" -#include <ouroboros/config.h>  #include <ouroboros/errno.h>  #include <ouroboros/logs.h>  #include <ouroboros/irm.h> diff --git a/src/irmd/registry.h b/src/irmd/registry.h index d1733f6c..486843a2 100644 --- a/src/irmd/registry.h +++ b/src/irmd/registry.h @@ -23,7 +23,6 @@  #ifndef OUROBOROS_IRMD_REGISTRY_H  #define OUROBOROS_IRMD_REGISTRY_H -#include <ouroboros/config.h>  #include <ouroboros/hash.h>  #include <ouroboros/ipcp.h>  #include <ouroboros/list.h> diff --git a/src/irmd/utils.c b/src/irmd/utils.c index 5a3da732..08699a05 100644 --- a/src/irmd/utils.c +++ b/src/irmd/utils.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L +  #include <stdlib.h>  #include <string.h> diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 550bbc08..9d8fbf9c 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -15,7 +15,7 @@ protobuf_generate_c(CACEP_PROTO_SRCS CACEP_PROTO_HDRS cacep.proto)  if (NOT APPLE)    find_library(LIBRT_LIBRARIES rt)    if (NOT LIBRT_LIBRARIES) -    message(FATAL_ERROR "Could not find librt.") +    message(FATAL_ERROR "Could not find librt")    endif ()  else ()    set(LIBRT_LIBRARIES "") @@ -23,7 +23,7 @@ endif ()  find_library(LIBPTHREAD_LIBRARIES pthread)  if (NOT LIBPTHREAD_LIBRARIES) -  message(FATAL_ERROR "Could not find libpthread.") +  message(FATAL_ERROR "Could not find libpthread")  endif ()  include(CheckSymbolExists) @@ -31,30 +31,60 @@ list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200809L)  list(APPEND CMAKE_REQUIRED_DEFINITIONS -D__XSI_VISIBLE=500)  list(APPEND CMAKE_REQUIRED_LIBRARIES pthread)  check_symbol_exists(pthread_mutexattr_setrobust pthread.h HAVE_ROBUST_MUTEX) -set(HAVE_ROBUST_MUTEX CACHE STRING "Have robust mutexes") + +if (HAVE_ROBUST_MUTEX) +  set(DISABLE_ROBUST_MUTEXES FALSE CACHE BOOL "Disable robust mutex support") +  if (NOT DISABLE_ROBUST_MUTEXES) +    message(STATUS "Robust mutex support enabled") +    set(HAVE_ROBUST_MUTEX TRUE) +  else () +    message(STATUS "Robust mutex support disabled by user") +    set(HAVE_ROBUST_MUTEX FALSE) +  endif () +endif ()  find_library(LIBGCRYPT_LIBRARIES gcrypt)  if (LIBGCRYPT_LIBRARIES) -  find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h HINTS /usr/include /usr/local/include) -  if (NOT LIBGCRYPT_INCLUDE_DIR STREQUAL "GRYPT_INCLUDE_DIR-NOTFOUND") +  find_path(LIBGCRYPT_INCLUDE_DIR gcrypt.h +            HINTS /usr/include /usr/local/include) +  if (LIBGCRYPT_INCLUDE_DIR)      file(STRINGS ${LIBGCRYPT_INCLUDE_DIR}/gcrypt.h GCSTR        REGEX "^#define GCRYPT_VERSION ")      string(REGEX REPLACE "^#define GCRYPT_VERSION \"(.*)\".*$" "\\1"        GCVER "${GCSTR}") -    message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES} (found version \"${GCVER}\")") +    message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}" +                   "(found version \"${GCVER}\")")      if (NOT GCVER VERSION_LESS "1.7.0") -      set(HAVE_LIBGCRYPT "1" CACHE STRING "Have libgcrypt") +      set (DISABLE_LIBGCRYPT FALSE CACHE BOOL "Disable libgcrypt support") +      if (NOT DISABLE_LIBGCRYPT) +        message(STATUS "libgcrypt support enabled") +        set(HAVE_LIBGCRYPT TRUE) +      else () +        message(STATUS "libgcrpyt support disabled by user") +      endif() +    else () +      message(STATUS "Install version > \"1.7.0\" to enable libgcrypt support")      endif()    endif () -else () +endif () + +if (NOT HAVE_LIBGCRYPT)    set(LIBGCRYPT_LIBRARIES "")    set(LIBGCRYPT_INCLUDE_DIR "")  endif ()  find_package(OpenSSL)  if (OPENSSL_FOUND) -  set(HAVE_OPENSSL "1" CACHE STRING "Have OpenSSL") -else () +  set (DISABLE_OPENSSL FALSE CACHE BOOL "Disable OpenSSL support") +  if (NOT DISABLE_OPENSSL) +    message(STATUS "OpenSSL support enabled") +    set(HAVE_OPENSSL TRUE) +  else() +    message(STATUS "OpenSSL support disabled by user") +  endif() +endif () + +if (NOT HAVE_OPENSSL)    set (OPENSSL_INCLUDE_DIR "")  endif () @@ -62,9 +92,9 @@ if (APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")    set(SYS_RND_HDR "")  else ()    find_path(SYS_RND_HDR sys/random.h PATH /usr/include/ /usr/local/include/) -  if (NOT SYS_RND_HDR STREQUAL "SYS_RND_HDR-NOTFOUND") +  if (SYS_RND_HDR)      message(STATUS "Found sys/random.h in ${SYS_RND_HDR}") -    set(HAVE_SYS_RANDOM "1" CACHE STRING "Have random header") +    set(HAVE_SYS_RANDOM TRUE)    else ()      set(SYS_RND_HDR "")    endif () @@ -73,10 +103,52 @@ endif()  if (NOT ((CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") OR APPLE OR    HAVE_SYS_RANDOM OR HAVE_OPENSSL OR HAVE_LIBGCRYPT))    message(FATAL_ERROR "No secure random generator found, " -                      "please install libgcrypt (> 1.7.0) or OpenSSL" -    ) +                      "please install libgcrypt (> 1.7.0) or OpenSSL")  endif () +mark_as_advanced(LIBRT_LIBRARIES LIBPTHREAD_LIBRARIES +  LIBGCRYPT_LIBRARIES OPENSSL_LIBRARIES SYS_RND_INCLUDE_DIR +  LIBGCRYPT_INCLUDE_DIR SYS_RND_HDR) + +math(EXPR SHM_BUFFER_EXPR "1 << 20") +set(SHM_BUFFER_SIZE ${SHM_BUFFER_EXPR} CACHE STRING +    "Number of blocks in SDU buffer, must be a power of 2") +set(SYS_MAX_FLOWS 4096 CACHE STRING +  "Maximum number of total flows for this system") +set(AP_MAX_FLOWS 1024 CACHE STRING +  "Maximum number of flows in an application") +set(AP_RES_FDS 64 CACHE STRING +  "Number of reserved flow descriptors per application") +set(AP_MAX_FQUEUES 32 CACHE STRING +  "Maximum number of flow sets per application") +set(DU_BUFF_HEADSPACE 128 CACHE STRING +  "Bytes of headspace to reserve for future headers") +set(DU_BUFF_TAILSPACE 16 CACHE STRING +  "Bytes of tailspace to reserve for future tails") +if (NOT APPLE) +  set(PTHREAD_COND_CLOCK "CLOCK_MONOTONIC" CACHE STRING +    "Clock to use for condition variable timing") +else () +  set (PTHREAD_COND_CLOCK "CLOCK_REALTIME" CACHE INTERNAL +    "Clock to use for condition variable timing") +endif () +set(SOCKET_TIMEOUT 1000 CACHE STRING +  "Default timeout for responses from IPCPs (ms)") +set(CDAP_REPLY_TIMEOUT 6000 CACHE STRING +  "Timeout for CDAP to wait for reply") +set(SHM_PREFIX "ouroboros" CACHE STRING +  "String to prepend to POSIX shared memory filenames") +set(SHM_RBUFF_PREFIX "/${SHM_PREFIX}.rbuff." CACHE INTERNAL +  "Prefix for rbuff POSIX shared memory filenames") +set(SHM_LOCKFILE_NAME "/${SHM_PREFIX}.lockfile" CACHE INTERNAL +  "Filename for the POSIX shared memory lockfile") +set(SHM_FLOW_SET_PREFIX "/${SHM_PREFIX}.set." CACHE INTERNAL +  "Prefix for the POSIX shared memory flow set") +set(SHM_RDRB_NAME "/${SHM_PREFIX}.rdrb" CACHE INTERNAL +  "Name for the main POSIX shared memory buffer") +set(SHM_RDRB_BLOCK_SIZE "sysconf(_SC_PAGESIZE)" CACHE STRING +  "SDU buffer block size, multiple of pagesize for performance") +  set(SOURCE_FILES    # Add source files here    bitmap.c @@ -86,6 +158,7 @@ set(SOURCE_FILES    cdap_req.c    crc32.c    dev.c +  frct_pci.c    hash.c    hashtable.c    irm.c @@ -93,7 +166,6 @@ set(SOURCE_FILES    lockfile.c    logs.c    md5.c -  nsm.c    qos.c    qoscube.c    random.c @@ -104,10 +176,14 @@ set(SOURCE_FILES    shm_rdrbuff.c    sockets.c    time_utils.c +  timerwheel.c    tpm.c    utils.c    ) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" +  "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) +  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}) diff --git a/src/lib/cacep.c b/src/lib/cacep.c index 55d11b0f..722adca1 100644 --- a/src/lib/cacep.c +++ b/src/lib/cacep.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 199309L +  #include <ouroboros/cacep.h>  #include <ouroboros/dev.h>  #include <ouroboros/errno.h> diff --git a/src/lib/cdap.c b/src/lib/cdap.c index bf8d5816..679771f5 100644 --- a/src/lib/cdap.c +++ b/src/lib/cdap.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L +  #include <ouroboros/cdap.h>  #include <ouroboros/bitmap.h>  #include <ouroboros/dev.h> diff --git a/src/lib/cdap_req.c b/src/lib/cdap_req.c index 7aded62f..a9b85525 100644 --- a/src/lib/cdap_req.c +++ b/src/lib/cdap_req.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #include <ouroboros/time_utils.h>  #include <ouroboros/errno.h> diff --git a/src/lib/cdap_req.h b/src/lib/cdap_req.h index 89f4145a..4c9cd15b 100644 --- a/src/lib/cdap_req.h +++ b/src/lib/cdap_req.h @@ -23,7 +23,6 @@  #ifndef OUROBOROS_CDAP_REQ_H  #define OUROBOROS_CDAP_REQ_H -#include <ouroboros/config.h>  #include <ouroboros/cdap.h>  #include <ouroboros/list.h>  #include <ouroboros/utils.h> diff --git a/src/lib/config.h.in b/src/lib/config.h.in new file mode 100644 index 00000000..e9c43389 --- /dev/null +++ b/src/lib/config.h.in @@ -0,0 +1,57 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Ouroboros library configuration + * + *    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 + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#cmakedefine HAVE_SYS_RANDOM +#cmakedefine HAVE_LIBGCRYPT +#cmakedefine HAVE_OPENSSL + +#define SYS_MAX_FLOWS       @SYS_MAX_FLOWS@ + +#cmakedefine                SHM_RBUFF_LOCKLESS + +#define SHM_RBUFF_PREFIX    "@SHM_RBUFF_PREFIX@" +#define SHM_LOCKFILE_NAME   "@SHM_LOCKFILE_NAME@" +#define SHM_FLOW_SET_PREFIX "@SHM_FLOW_SET_PREFIX@" +#define SHM_RDRB_NAME       "@SHM_RDRB_NAME@" +#define SHM_RDRB_BLOCK_SIZE @SHM_RDRB_BLOCK_SIZE@ +#define SHM_BUFFER_SIZE     @SHM_BUFFER_SIZE@ + +#if defined(__linux__) || (defined(__MACH__) && !defined(__APPLE__)) +/* Avoid a bug in robust mutex implementation of glibc 2.25 */ +    #include <features.h> +    #if !defined(__GLIBC__) || !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 25) +    #cmakedefine HAVE_ROBUST_MUTEX +    #endif +#else +#cmakedefine HAVE_ROBUST_MUTEX +#endif + +#define PTHREAD_COND_CLOCK  @PTHREAD_COND_CLOCK@ + +#define AP_MAX_FLOWS        @AP_MAX_FLOWS@ +#define AP_RES_FDS          @AP_RES_FDS@ +#define AP_MAX_FQUEUES      @AP_MAX_FQUEUES@ + +#define DU_BUFF_HEADSPACE   @DU_BUFF_HEADSPACE@ +#define DU_BUFF_TAILSPACE   @DU_BUFF_TAILSPACE@ + +#define CDAP_REPLY_TIMEOUT  @CDAP_REPLY_TIMEOUT@ diff --git a/src/lib/dev.c b/src/lib/dev.c index 9354855b..b6c6087f 100644 --- a/src/lib/dev.c +++ b/src/lib/dev.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #include <ouroboros/errno.h>  #include <ouroboros/dev.h>  #include <ouroboros/ipcp-dev.h> @@ -34,6 +37,8 @@  #include <ouroboros/utils.h>  #include <ouroboros/fqueue.h>  #include <ouroboros/qoscube.h> +#include <ouroboros/timerwheel.h> +#include <ouroboros/frct_pci.h>  #include <stdlib.h>  #include <string.h> @@ -41,8 +46,14 @@  #define BUF_SIZE 1500 +#define TW_ELEMENTS   6000 +#define TW_RESOLUTION 1   /* ms */ + +#define MPL 2000 /* ms */ +  struct flow_set {          size_t idx; +        bool   np1_set;  };  struct fqueue { @@ -59,6 +70,22 @@ enum port_state {          PORT_DESTROY  }; +struct frcti { +        bool          used; + +        struct tw_f * snd_inact; +        bool          snd_drf; +        uint64_t      snd_lwe; +        uint64_t      snd_rwe; + +        struct tw_f * rcv_inact; +        bool          rcv_drf; +        uint64_t      rcv_lwe; +        uint64_t      rcv_rwe; + +        uint8_t       conf_flags; +}; +  struct port {          int             fd; @@ -89,10 +116,13 @@ struct {          struct shm_rdrbuff *  rdrb;          struct shm_flow_set * fqset; +        struct timerwheel *   tw; +          struct bmp *          fds;          struct bmp *          fqueues;          struct flow *         flows;          struct port *         ports; +        struct frcti *        frcti;          pthread_rwlock_t      lock;  } ai; @@ -203,6 +233,268 @@ static int api_announce(char * ap_name)          return ret;  } +/* Call under flows lock */ +static int finalize_write(int    fd, +                          size_t idx) +{ +        if (shm_rbuff_write(ai.flows[fd].tx_rb, idx) < 0) +                return -ENOTALLOC; + +        shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id); + +        return 0; +} + +static int frcti_init(int fd) +{ +        struct frcti * frcti; + +        frcti = &(ai.frcti[fd]); + +        frcti->used = true; + +        frcti->snd_drf = true; +        frcti->snd_lwe = 0; +        frcti->snd_rwe = 0; + +        frcti->rcv_drf = true; +        frcti->rcv_lwe = 0; +        frcti->rcv_rwe = 0; + +        frcti->conf_flags = CONF_ERROR_CHECK; + +        return 0; +} + +static void frcti_clear(int fd) +{ +        struct frcti * frcti; + +        frcti = &(ai.frcti[fd]); + +        frcti->used = false; +        frcti->snd_inact = NULL; +        frcti->rcv_inact = NULL; +} + +static void frcti_fini(int fd) +{ +        struct frcti * frcti; + +        frcti = &(ai.frcti[fd]); + +        /* FIXME: We actually need to wait until these timers become NULL. */ +        if (frcti->snd_inact != NULL) +                timerwheel_stop(ai.tw, frcti->snd_inact); + +        if (frcti->rcv_inact != NULL) +                timerwheel_stop(ai.tw, frcti->rcv_inact); + +        frcti_clear(fd); +} + +static int frcti_configure(int         fd, +                           qosspec_t * qos) +{ +        /* FIXME: Send configuration message here to other side. */ + +        (void) fd; +        (void) qos; + +        return 0; +} + +static void frcti_snd_inactivity(void * arg) +{ +        struct frcti *  frcti; + +        pthread_rwlock_wrlock(&ai.lock); + +        frcti = (struct frcti * ) arg; + +        frcti->snd_drf = true; +        frcti->snd_inact = NULL; + +        pthread_rwlock_unlock(&ai.lock); +} + +/* Called under flows lock */ +static int frcti_write(int                  fd, +                       struct shm_du_buff * sdb) +{ +        struct frcti *  frcti; +        struct frct_pci pci; + +        memset(&pci, 0, sizeof(pci)); + +        frcti = &(ai.frcti[fd]); + +        pthread_rwlock_unlock(&ai.lock); + +        timerwheel_move(ai.tw); + +        pthread_rwlock_rdlock(&ai.lock); + +        /* +         * Set the DRF in the first packet of a new run of SDUs, +         * otherwise simply recharge the timer. +         */ +        if (frcti->snd_drf) { +                frcti->snd_inact = timerwheel_start(ai.tw, frcti_snd_inactivity, +                                                    frcti, 2 * MPL); +                if (frcti->snd_inact == NULL) +                        return -1; + +                pci.flags |= FLAG_DATA_RUN; +                frcti->snd_drf = false; +        } else { +                if (timerwheel_restart(ai.tw, frcti->snd_inact, 2 * MPL)) +                        return -1; +        } + +        pci.seqno = frcti->snd_lwe++; +        pci.type |= PDU_TYPE_DATA; + +        if (frct_pci_ser(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK)) +                return -1; + +        if (finalize_write(fd, shm_du_buff_get_idx(sdb))) +                return -ENOTALLOC; + +        return 0; +} + +static void frcti_rcv_inactivity(void * arg) +{ +        struct frcti *  frcti; + +        pthread_rwlock_wrlock(&ai.lock); + +        frcti = (struct frcti * ) arg; + +        frcti->rcv_drf = true; +        frcti->rcv_inact = NULL; + +        pthread_rwlock_unlock(&ai.lock); +} + +static ssize_t frcti_read(int fd) +{ +        ssize_t              idx = -1; +        struct timespec      abstime; +        struct frcti *       frcti; +        struct frct_pci      pci; +        struct shm_du_buff * sdb; + +        timerwheel_move(ai.tw); + +        pthread_rwlock_rdlock(&ai.lock); + +        if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) { +                idx = shm_rbuff_read(ai.flows[fd].rx_rb); +                pthread_rwlock_unlock(&ai.lock); +        } else { +                struct shm_rbuff * rb   = ai.flows[fd].rx_rb; +                bool timeo = ai.flows[fd].timesout; +                struct timespec timeout = ai.flows[fd].rcv_timeo; + +                pthread_rwlock_unlock(&ai.lock); + +                if (timeo) { +                        clock_gettime(PTHREAD_COND_CLOCK, &abstime); +                        ts_add(&abstime, &timeout, &abstime); +                        idx = shm_rbuff_read_b(rb, &abstime); +                } else { +                        idx = shm_rbuff_read_b(rb, NULL); +                } +        } + +        if (idx < 0) +                return idx; + +        pthread_rwlock_rdlock(&ai.lock); + +        frcti = &(ai.frcti[fd]); + +        sdb = shm_rdrbuff_get(ai.rdrb, idx); + +        /* SDU may be corrupted. */ +        if (frct_pci_des(sdb, &pci, frcti->conf_flags & CONF_ERROR_CHECK)) { +                pthread_rwlock_unlock(&ai.lock); +                shm_rdrbuff_remove(ai.rdrb, idx); +                return -EAGAIN; +        } + +        /* We don't accept packets when there is no inactivity timer. */ +        if (frcti->rcv_drf && !(pci.flags & FLAG_DATA_RUN)) { +                pthread_rwlock_unlock(&ai.lock); +                shm_rdrbuff_remove(ai.rdrb, idx); +                return -EAGAIN; +        } + +        /* +         * If there is an inactivity timer and the DRF is set, +         * reset the state of the connection. +         */ +        if (pci.flags & FLAG_DATA_RUN) { +                frcti->rcv_drf = true; +                if (frcti->rcv_inact != NULL) +                        timerwheel_stop(ai.tw, frcti->rcv_inact); +                frcti->rcv_lwe = pci.seqno; +        } + +        /* +         * Start receiver inactivity if this packet has the DRF, +         * otherwise simply restart it. +         */ +        if (frcti->rcv_drf) { +                frcti->rcv_inact = timerwheel_start(ai.tw, frcti_rcv_inactivity, +                                                    frcti, 3 * MPL); +                if (frcti->rcv_inact == NULL) { +                        pthread_rwlock_unlock(&ai.lock); +                        shm_rdrbuff_remove(ai.rdrb, idx); +                        return -EAGAIN; +                } + +                frcti->rcv_drf = false; +        } else { +                if (timerwheel_restart(ai.tw, frcti->rcv_inact, 3 * MPL)) { +                        pthread_rwlock_unlock(&ai.lock); +                        shm_rdrbuff_remove(ai.rdrb, idx); +                        return -EAGAIN; +                } +        } + +        pthread_rwlock_unlock(&ai.lock); + +        return idx; +} + +static int frcti_event_wait(struct flow_set *       set, +                            struct fqueue *         fq, +                            const struct timespec * timeout) +{ +        int ret; + +        assert(set); +        assert(fq); + +        timerwheel_move(ai.tw); + +        /* +         * FIXME: Return the fq only if a data SDU +         * for the application is available. +         */ + +        ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, timeout); +        if (ret == -ETIMEDOUT) { +                fq->fqsize = 0; +                return -ETIMEDOUT; +        } + +        return ret; +} +  static void flow_clear(int fd)  {          assert(!(fd < 0)); @@ -230,6 +522,9 @@ static void flow_fini(int fd)          if (ai.flows[fd].set != NULL)                  shm_flow_set_close(ai.flows[fd].set); +        if (ai.frcti[fd].used) +                frcti_fini(fd); +          flow_clear(fd);  } @@ -316,10 +611,16 @@ int ouroboros_init(const char * ap_name)          if (ai.flows == NULL)                  goto fail_flows; -        for (i = 0; i < AP_MAX_FLOWS; ++i) +        ai.frcti = malloc(sizeof(*ai.frcti) * AP_MAX_FLOWS); +        if (ai.frcti == NULL) +                goto fail_frcti; + +        for (i = 0; i < AP_MAX_FLOWS; ++i) {                  flow_clear(i); +                frcti_clear(i); +        } -        ai.ports = malloc(sizeof(*ai.ports) * IRMD_MAX_FLOWS); +        ai.ports = malloc(sizeof(*ai.ports) * SYS_MAX_FLOWS);          if (ai.ports == NULL)                  goto fail_ports; @@ -334,7 +635,7 @@ int ouroboros_init(const char * ap_name)                  }          } -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) { +        for (i = 0; i < SYS_MAX_FLOWS; ++i) {                  ai.ports[i].state = PORT_INIT;                  if (pthread_mutex_init(&ai.ports[i].state_lock, NULL)) {                          int j; @@ -353,24 +654,33 @@ int ouroboros_init(const char * ap_name)          if (pthread_rwlock_init(&ai.lock, NULL))                  goto fail_lock; +        ai.tw = timerwheel_create(TW_RESOLUTION, +                                  TW_RESOLUTION * TW_ELEMENTS); +        if (ai.tw == NULL) +                goto fail_timerwheel; +          return 0; + fail_timerwheel: +        pthread_rwlock_destroy(&ai.lock);   fail_lock: -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  pthread_cond_destroy(&ai.ports[i].state_cond);   fail_state_cond: -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  pthread_mutex_destroy(&ai.ports[i].state_lock);   fail_announce:          free(ai.ap_name);   fail_ap_name:          free(ai.ports);   fail_ports: +        free(ai.frcti); + fail_frcti:          free(ai.flows);   fail_flows:          shm_rdrbuff_close(ai.rdrb);   fail_rdrb: -      shm_flow_set_destroy(ai.fqset); +        shm_flow_set_destroy(ai.fqset);   fail_fqset:          bmp_destroy(ai.fqueues);   fail_fqueues: @@ -402,13 +712,16 @@ void ouroboros_fini()                  }          } -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) { +        for (i = 0; i < SYS_MAX_FLOWS; ++i) {                  pthread_mutex_destroy(&ai.ports[i].state_lock);                  pthread_cond_destroy(&ai.ports[i].state_cond);          }          shm_rdrbuff_close(ai.rdrb); +        if (ai.tw != NULL) +                timerwheel_destroy(ai.tw); +          free(ai.flows);          free(ai.ports); @@ -463,9 +776,15 @@ int flow_accept(qosspec_t *             qs,          if (fd < 0)                  return fd; +        pthread_rwlock_wrlock(&ai.lock); + +        frcti_init(fd); +          if (qs != NULL)                  *qs = ai.flows[fd].spec; +        pthread_rwlock_unlock(&ai.lock); +          return fd;  } @@ -505,7 +824,7 @@ int flow_alloc(const char *            dst_name,                  return -EIRMD;          } -        if (recv_msg->result !=  0) { +        if (recv_msg->result != 0) {                  int res =  recv_msg->result;                  irm_msg__free_unpacked(recv_msg, NULL);                  return res; @@ -520,6 +839,22 @@ int flow_alloc(const char *            dst_name,          irm_msg__free_unpacked(recv_msg, NULL); +        if (fd < 0) +                return fd; + +        pthread_rwlock_wrlock(&ai.lock); + +        frcti_init(fd); + +        if (frcti_configure(fd, qs)) { +                flow_fini(fd); +                bmp_release(ai.fds, fd); +                pthread_rwlock_unlock(&ai.lock); +                return -1; +        } + +        pthread_rwlock_unlock(&ai.lock); +          return fd;  } @@ -720,34 +1055,31 @@ ssize_t flow_write(int          fd,                          return idx;                  } -                if (shm_rbuff_write(ai.flows[fd].tx_rb, idx) < 0) { -                        shm_rdrbuff_remove(ai.rdrb, idx); -                        pthread_rwlock_unlock(&ai.lock); -                        return -ENOTALLOC; -                }          } else { /* blocking */ -                struct shm_rdrbuff * rdrb = ai.rdrb; -                struct shm_rbuff * tx_rb  = ai.flows[fd].tx_rb; -                  pthread_rwlock_unlock(&ai.lock); -                assert(tx_rb); - -                idx = shm_rdrbuff_write_b(rdrb, +                idx = shm_rdrbuff_write_b(ai.rdrb,                                            DU_BUFF_HEADSPACE,                                            DU_BUFF_TAILSPACE,                                            buf,                                            count); -                if (shm_rbuff_write(tx_rb, idx) < 0) { -                        shm_rdrbuff_remove(rdrb, idx); -                        return -ENOTALLOC; -                } -                  pthread_rwlock_rdlock(&ai.lock);          } -        shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id); +        if (!ai.frcti[fd].used) { +                if (finalize_write(fd, idx)) { +                        pthread_rwlock_unlock(&ai.lock); +                        shm_rdrbuff_remove(ai.rdrb, idx); +                        return -ENOTALLOC; +                } +        } else { +                if (frcti_write(fd, shm_rdrbuff_get(ai.rdrb, idx))) { +                        pthread_rwlock_unlock(&ai.lock); +                        shm_rdrbuff_remove(ai.rdrb, idx); +                        return -1; +                } +        }          pthread_rwlock_unlock(&ai.lock); @@ -772,21 +1104,12 @@ ssize_t flow_read(int    fd,                  return -ENOTALLOC;          } -        if (ai.flows[fd].oflags & FLOW_O_NONBLOCK) { -                idx = shm_rbuff_read(ai.flows[fd].rx_rb); -                pthread_rwlock_unlock(&ai.lock); -        } else { -                struct shm_rbuff * rb   = ai.flows[fd].rx_rb; -                bool timeo = ai.flows[fd].timesout; -                struct timespec timeout = ai.flows[fd].rcv_timeo; - -                pthread_rwlock_unlock(&ai.lock); +        pthread_rwlock_unlock(&ai.lock); -                if (timeo) -                        idx = shm_rbuff_read_b(rb, &timeout); -                else -                        idx = shm_rbuff_read_b(rb, NULL); -        } +        if (!ai.frcti[fd].used) +                idx = shm_rbuff_read(ai.flows[fd].rx_rb); +        else +                idx = frcti_read(fd);          if (idx < 0) {                  assert(idx == -EAGAIN || idx == -ETIMEDOUT); @@ -823,6 +1146,8 @@ struct flow_set * flow_set_create()                  return NULL;          } +        set->np1_set = false; +          pthread_rwlock_unlock(&ai.lock);          return set; @@ -891,6 +1216,9 @@ int flow_set_add(struct flow_set * set,          for (i = 0; i < sdus; i++)                  shm_flow_set_notify(ai.fqset, ai.flows[fd].port_id); +        if (ai.frcti[fd].used) +                set->np1_set = true; +          pthread_rwlock_unlock(&ai.lock);          return ret; @@ -960,7 +1288,9 @@ int flow_event_wait(struct flow_set *       set,                      struct fqueue *         fq,                      const struct timespec * timeout)  { -        ssize_t ret; +        ssize_t           ret; +        struct timespec   abstime; +        struct timespec * t = NULL;          if (set == NULL || fq == NULL)                  return -EINVAL; @@ -970,7 +1300,18 @@ int flow_event_wait(struct flow_set *       set,          assert(!fq->next); -        ret = shm_flow_set_wait(ai.fqset, set->idx, fq->fqueue, timeout); +        if (timeout != NULL) { +                clock_gettime(PTHREAD_COND_CLOCK, &abstime); +                ts_add(&abstime, timeout, &abstime); +                t = &abstime; +        } + +        if (set->np1_set) +                ret = frcti_event_wait(set, fq, t); +        else +                ret = shm_flow_set_wait(ai.fqset, set->idx, +                                        fq->fqueue, t); +          if (ret == -ETIMEDOUT) {                  fq->fqsize = 0;                  return -ETIMEDOUT; @@ -1132,9 +1473,8 @@ int ipcp_flow_read(int                   fd,  {          ssize_t idx = -1;          int port_id = -1; -        struct shm_rbuff * rb; -        assert(fd >=0); +        assert(fd >= 0);          assert(sdb);          pthread_rwlock_rdlock(&ai.lock); @@ -1144,11 +1484,13 @@ int ipcp_flow_read(int                   fd,                  return -ENOTALLOC;          } -        rb = ai.flows[fd].rx_rb; -          pthread_rwlock_unlock(&ai.lock); -        idx = shm_rbuff_read(rb); +        if (!ai.frcti[fd].used) +                idx = shm_rbuff_read(ai.flows[fd].rx_rb); +        else +                idx = frcti_read(fd); +          if (idx < 0)                  return idx; @@ -1160,8 +1502,6 @@ int ipcp_flow_read(int                   fd,  int ipcp_flow_write(int                  fd,                      struct shm_du_buff * sdb)  { -        size_t idx; -          if (sdb == NULL)                  return -EINVAL; @@ -1179,10 +1519,17 @@ int ipcp_flow_write(int                  fd,          assert(ai.flows[fd].tx_rb); -        idx = shm_du_buff_get_idx(sdb); - -        shm_rbuff_write(ai.flows[fd].tx_rb, idx); -        shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id); +        if (!ai.frcti[fd].used) { +                if (finalize_write(fd, shm_du_buff_get_idx(sdb))) { +                        pthread_rwlock_unlock(&ai.lock); +                        return -ENOTALLOC; +                } +        } else { +                if (frcti_write(fd, sdb)) { +                        pthread_rwlock_unlock(&ai.lock); +                        return -1; +                } +        }          pthread_rwlock_unlock(&ai.lock); @@ -1274,32 +1621,11 @@ int local_flow_write(int    fd,                  return -ENOTALLOC;          } -        shm_rbuff_write(ai.flows[fd].tx_rb, idx); - -        shm_flow_set_notify(ai.flows[fd].set, ai.flows[fd].port_id); - -        pthread_rwlock_unlock(&ai.lock); - -        return 0; -} - -int ipcp_read_shim(int                   fd, -                   struct shm_du_buff ** sdb) -{ -        ssize_t idx; - -        pthread_rwlock_rdlock(&ai.lock); - -        assert(ai.flows[fd].rx_rb); - -        idx = shm_rbuff_read(ai.flows[fd].rx_rb); -        if (idx < 0) { +        if (finalize_write(fd, idx)) {                  pthread_rwlock_unlock(&ai.lock); -                return -EAGAIN; +                return -ENOTALLOC;          } -        *sdb = shm_rdrbuff_get(ai.rdrb, idx); -          pthread_rwlock_unlock(&ai.lock);          return 0; diff --git a/src/lib/frct_pci.c b/src/lib/frct_pci.c new file mode 100644 index 00000000..5ee14829 --- /dev/null +++ b/src/lib/frct_pci.c @@ -0,0 +1,112 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Protocol Control Information of FRCT + * + *    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 + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#include <ouroboros/frct_pci.h> +#include <ouroboros/hash.h> +#include <ouroboros/errno.h> + +#define OUROBOROS_PREFIX "frct-pci" +#include <ouroboros/logs.h> + +#include <assert.h> +#include <string.h> + +#define TYPE_SIZE  1 +#define SEQNO_SIZE 8 +#define FLAGS_SIZE 1 + +/* FIXME: Head size will differ on type */ +#define HEAD_SIZE TYPE_SIZE + FLAGS_SIZE + SEQNO_SIZE + +int frct_pci_ser(struct shm_du_buff * sdb, +                 struct frct_pci *    pci, +                 bool                 error_check) +{ +        uint8_t * head; +        uint8_t * tail; + +        assert(sdb); +        assert(pci); + +        head = shm_du_buff_head_alloc(sdb, HEAD_SIZE); +        if (head == NULL) +                return -EPERM; + +        memcpy(head, &pci->type, TYPE_SIZE); +        memcpy(head + TYPE_SIZE, &pci->flags, FLAGS_SIZE); +        memcpy(head + TYPE_SIZE + FLAGS_SIZE, &pci->seqno, SEQNO_SIZE); + +        if (error_check) { +                tail = shm_du_buff_tail_alloc(sdb, hash_len(HASH_CRC32)); +                if (tail == NULL) { +                        shm_du_buff_head_release(sdb, HEAD_SIZE); +                        return -EPERM; +                } + +                *((uint32_t *) tail) = 0; +                mem_hash(HASH_CRC32, (uint32_t *) tail, head, tail - head); +        } + +        return 0; +} + +int frct_pci_des(struct shm_du_buff * sdb, +                 struct frct_pci *    pci, +                 bool                 error_check) +{ +        uint8_t * head; +        uint8_t * tail; +        uint32_t  crc; +        uint32_t  crc2; + +        assert(sdb); +        assert(pci); + +        head = shm_du_buff_head(sdb); + +         /* FIXME: Depending on the type a different deserialization */ +        memcpy(&pci->type, head, TYPE_SIZE); +        memcpy(&pci->flags, head + TYPE_SIZE, FLAGS_SIZE); +        memcpy(&pci->seqno, head + TYPE_SIZE + FLAGS_SIZE, SEQNO_SIZE); + +        if (error_check) { +                tail = shm_du_buff_tail(sdb); +                if (tail == NULL) +                        return -EPERM; + +                mem_hash(HASH_CRC32, &crc, head, +                         tail - head - hash_len(HASH_CRC32)); + +                memcpy(&crc2, tail - hash_len(HASH_CRC32), +                       hash_len(HASH_CRC32)); + +                /* Corrupted SDU */ +                if (crc != crc2) +                        return -1; + +                shm_du_buff_tail_release(sdb, hash_len(HASH_CRC32)); +        } + +        shm_du_buff_head_release(sdb, HEAD_SIZE); + +        return 0; +} diff --git a/src/lib/hash.c b/src/lib/hash.c index d8cabfd3..09e5be8c 100644 --- a/src/lib/hash.c +++ b/src/lib/hash.c @@ -23,7 +23,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#include "config.h" +  #include <ouroboros/hash.h>  #ifndef HAVE_LIBGCRYPT @@ -64,45 +65,46 @@ uint16_t hash_len(enum hash_algo algo)  #endif  } -void str_hash(enum hash_algo algo, -              void *         buf, -              const char *   str) +void mem_hash(enum hash_algo  algo, +              void *          dst, +              const uint8_t * buf, +              size_t          len)  {  #ifdef HAVE_LIBGCRYPT -        gcry_md_hash_buffer(algo, buf, str, strlen(str)); +        gcry_md_hash_buffer(algo, dst, buf, len);  #else          struct sha3_ctx sha3_ctx;          struct md5_ctx md5_ctx;          switch (algo) {          case HASH_CRC32: -                memset(buf, 0, CRC32_HASH_LEN); -                crc32((uint32_t *) buf, str, strlen(str)); +                memset(dst, 0, CRC32_HASH_LEN); +                crc32((uint32_t *) dst, buf, len);                  break;          case HASH_MD5:                  rhash_md5_init(&md5_ctx); -                rhash_md5_update(&md5_ctx, str, strlen(str)); -                rhash_md5_final(&md5_ctx, (uint8_t *) buf); +                rhash_md5_update(&md5_ctx, buf, len); +                rhash_md5_final(&md5_ctx, (uint8_t *) dst);                  break;          case HASH_SHA3_224:                  rhash_sha3_224_init(&sha3_ctx); -                rhash_sha3_update(&sha3_ctx, str, strlen(str)); -                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                rhash_sha3_update(&sha3_ctx, buf, len); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);                  break;          case HASH_SHA3_256:                  rhash_sha3_256_init(&sha3_ctx); -                rhash_sha3_update(&sha3_ctx, str, strlen(str)); -                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                rhash_sha3_update(&sha3_ctx, buf, len); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);                  break;          case HASH_SHA3_384:                  rhash_sha3_384_init(&sha3_ctx); -                rhash_sha3_update(&sha3_ctx, str, strlen(str)); -                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                rhash_sha3_update(&sha3_ctx, buf, len); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);                  break;          case HASH_SHA3_512:                  rhash_sha3_512_init(&sha3_ctx); -                rhash_sha3_update(&sha3_ctx, str, strlen(str)); -                rhash_sha3_final(&sha3_ctx, (uint8_t *) buf); +                rhash_sha3_update(&sha3_ctx, buf, len); +                rhash_sha3_final(&sha3_ctx, (uint8_t *) dst);                  break;          default:                  assert(false); @@ -110,3 +112,10 @@ void str_hash(enum hash_algo algo,          }  #endif  } + +void str_hash(enum hash_algo algo, +              void *         dst, +              const char *   str) +{ +        return mem_hash(algo, dst, (const uint8_t *) str, strlen(str)); +} diff --git a/src/lib/irm.c b/src/lib/irm.c index a6075d33..4232cec1 100644 --- a/src/lib/irm.c +++ b/src/lib/irm.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L +  #include <ouroboros/errno.h>  #include <ouroboros/hash.h>  #include <ouroboros/irm.h> diff --git a/src/lib/lockfile.c b/src/lib/lockfile.c index e2e4d289..4a3dcb91 100644 --- a/src/lib/lockfile.c +++ b/src/lib/lockfile.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #include <ouroboros/lockfile.h>  #include <stdlib.h> @@ -47,7 +50,7 @@ struct lockfile * lockfile_create() {          mask = umask(0); -        fd = shm_open(LOCKFILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666); +        fd = shm_open(SHM_LOCKFILE_NAME, O_CREAT | O_EXCL | O_RDWR, 0666);          if (fd == -1) {                  free(lf);                  return NULL; @@ -69,7 +72,7 @@ struct lockfile * lockfile_create() {          close (fd);          if (lf->api == MAP_FAILED) { -                shm_unlink(LOCKFILE_NAME); +                shm_unlink(SHM_LOCKFILE_NAME);                  free(lf);                  return NULL;          } @@ -85,7 +88,7 @@ struct lockfile * lockfile_open() {          if (lf == NULL)                  return NULL; -        fd = shm_open(LOCKFILE_NAME, O_RDWR, 0666); +        fd = shm_open(SHM_LOCKFILE_NAME, O_RDWR, 0666);          if (fd < 0) {                  free(lf);                  return NULL; @@ -100,7 +103,7 @@ struct lockfile * lockfile_open() {          close(fd);          if (lf->api == MAP_FAILED) { -                shm_unlink(LOCKFILE_NAME); +                shm_unlink(SHM_LOCKFILE_NAME);                  free(lf);                  return NULL;          } @@ -126,7 +129,7 @@ void lockfile_destroy(struct lockfile * lf)          munmap(lf->api, LF_SIZE); -        shm_unlink(LOCKFILE_NAME); +        shm_unlink(SHM_LOCKFILE_NAME);          free(lf);  } diff --git a/src/lib/md5.c b/src/lib/md5.c index a4d92de3..3394f406 100644 --- a/src/lib/md5.c +++ b/src/lib/md5.c @@ -1,7 +1,7 @@  /*   * Ouroboros - Copyright (C) 2016 - 2017   * - * SHA3 algorithm + * MD5 algorithm   *   *    Dimitri Staessens <dimitri.staessens@ugent.be>   *    Sander Vrijders   <sander.vrijders@ugent.be> diff --git a/src/lib/nsm.c b/src/lib/nsm.c deleted file mode 100644 index 2dd5729b..00000000 --- a/src/lib/nsm.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Ouroboros - Copyright (C) 2016 - 2017 - * - * The API to instruct the global Namespace Manager - * - *    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 - * version 2.1 as published by the Free Software Foundation. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., http://www.fsf.org/about/contact/. - */ - -#include <ouroboros/nsm.h> - -int nsm_reg(char * name, -            char ** dafs, -            size_t dafs_size) -{ -        (void) name; -        (void) dafs; -        (void) dafs_size; - -        return -1; -} - -int nsm_unreg(char * name, -              char ** dafs, -              size_t dafs_size) -{ -        (void) name; -        (void) dafs; -        (void) dafs_size; - - -        return -1; -} - -ssize_t nsm_resolve(char * name, -                    char ** dafs) -{ -        (void) name; -        (void) dafs; - -        return -1; -} diff --git a/src/lib/random.c b/src/lib/random.c index 66aefaa3..27719b26 100644 --- a/src/lib/random.c +++ b/src/lib/random.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#include "config.h" +  #include <ouroboros/random.h>  #if defined(__APPLE__) /* Barf */ diff --git a/src/lib/rib.c b/src/lib/rib.c index e8cf97d4..104dc0cc 100644 --- a/src/lib/rib.c +++ b/src/lib/rib.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #include <ouroboros/errno.h>  #include <ouroboros/list.h>  #include <ouroboros/rib.h> diff --git a/src/lib/shm_flow_set.c b/src/lib/shm_flow_set.c index cd6946d4..78fdce36 100644 --- a/src/lib/shm_flow_set.c +++ b/src/lib/shm_flow_set.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #include <ouroboros/lockfile.h>  #include <ouroboros/time_utils.h>  #include <ouroboros/shm_flow_set.h> @@ -38,11 +41,22 @@  #include <string.h>  #include <assert.h> +/* + * pthread_cond_timedwait has a WONTFIX bug as of glibc 2.25 where it + * doesn't test pthread cancellation when passed an expired timeout + * with the clock set to CLOCK_MONOTONIC. + */ +#if ((defined(__linux__) || (defined(__MACH__) && !defined(__APPLE__)))        \ +     && (defined(__GLIBC__) && ((__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2025)) \ +     && (PTHREAD_COND_CLOCK == CLOCK_MONOTONIC)) +#define HAVE_CANCEL_BUG +#endif +  #define FN_MAX_CHARS 255  #define FQUEUESIZE ((SHM_BUFFER_SIZE) * sizeof(int)) -#define SHM_FLOW_SET_FILE_SIZE (IRMD_MAX_FLOWS * sizeof(ssize_t)          \ +#define SHM_FLOW_SET_FILE_SIZE (SYS_MAX_FLOWS * sizeof(ssize_t)           \                                  + AP_MAX_FQUEUES * sizeof(size_t)         \                                  + AP_MAX_FQUEUES * sizeof(pthread_cond_t) \                                  + AP_MAX_FQUEUES * FQUEUESIZE             \ @@ -109,7 +123,7 @@ struct shm_flow_set * shm_flow_set_create()          }          set->mtable  = shm_base; -        set->heads   = (size_t *) (set->mtable + IRMD_MAX_FLOWS); +        set->heads   = (size_t *) (set->mtable + SYS_MAX_FLOWS);          set->conds   = (pthread_cond_t *)(set->heads + AP_MAX_FQUEUES);          set->fqueues = (int *) (set->conds + AP_MAX_FQUEUES);          set->lock    = (pthread_mutex_t *) @@ -132,7 +146,7 @@ struct shm_flow_set * shm_flow_set_create()                  pthread_cond_init(&set->conds[i], &cattr);          } -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  set->mtable[i] = -1;          set->api = getpid(); @@ -175,7 +189,7 @@ struct shm_flow_set * shm_flow_set_open(pid_t api)          }          set->mtable  = shm_base; -        set->heads   = (size_t *) (set->mtable + IRMD_MAX_FLOWS); +        set->heads   = (size_t *) (set->mtable + SYS_MAX_FLOWS);          set->conds   = (pthread_cond_t *)(set->heads + AP_MAX_FQUEUES);          set->fqueues = (int *) (set->conds + AP_MAX_FQUEUES);          set->lock    = (pthread_mutex_t *) @@ -233,7 +247,7 @@ void shm_flow_set_zero(struct shm_flow_set * set,          pthread_mutex_lock(set->lock); -        for (i = 0; i < IRMD_MAX_FLOWS; ++i) +        for (i = 0; i < SYS_MAX_FLOWS; ++i)                  if (set->mtable[i] == (ssize_t) idx)                          set->mtable[i] = -1; @@ -248,7 +262,7 @@ int shm_flow_set_add(struct shm_flow_set * set,                       int                   port_id)  {          assert(set); -        assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS); +        assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);          assert(idx < AP_MAX_FQUEUES);          pthread_mutex_lock(set->lock); @@ -270,7 +284,7 @@ void shm_flow_set_del(struct shm_flow_set * set,                        int                   port_id)  {          assert(set); -        assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS); +        assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);          assert(idx < AP_MAX_FQUEUES);          pthread_mutex_lock(set->lock); @@ -288,7 +302,7 @@ int shm_flow_set_has(struct shm_flow_set * set,          int ret = 0;          assert(set); -        assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS); +        assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);          assert(idx < AP_MAX_FQUEUES);          pthread_mutex_lock(set->lock); @@ -305,7 +319,7 @@ void shm_flow_set_notify(struct shm_flow_set * set,                           int                   port_id)  {          assert(set); -        assert(!(port_id < 0) && port_id < IRMD_MAX_FLOWS); +        assert(!(port_id < 0) && port_id < SYS_MAX_FLOWS);          pthread_mutex_lock(set->lock); @@ -326,10 +340,9 @@ void shm_flow_set_notify(struct shm_flow_set * set,  ssize_t shm_flow_set_wait(const struct shm_flow_set * set,                            size_t                      idx,                            int *                       fqueue, -                          const struct timespec *     timeout) +                          const struct timespec *     abstime)  {          ssize_t ret = 0; -        struct timespec abstime;          assert(set);          assert(idx < AP_MAX_FQUEUES); @@ -341,22 +354,23 @@ ssize_t shm_flow_set_wait(const struct shm_flow_set * set,          if (pthread_mutex_lock(set->lock) == EOWNERDEAD)                  pthread_mutex_consistent(set->lock);  #endif -        if (timeout != NULL) { -                clock_gettime(PTHREAD_COND_CLOCK, &abstime); -                ts_add(&abstime, timeout, &abstime); -        }          pthread_cleanup_push((void(*)(void *))pthread_mutex_unlock,                               (void *) set->lock);          while (set->heads[idx] == 0 && ret != -ETIMEDOUT) { -                if (timeout != NULL) +                if (abstime != NULL) {                          ret = -pthread_cond_timedwait(set->conds + idx,                                                        set->lock, -                                                      &abstime); -                else +                                                      abstime); +#ifdef HAVE_CANCEL_BUG +                        if (ret == -ETIMEDOUT) +                                pthread_testcancel(); +#endif +                } else {                          ret = -pthread_cond_wait(set->conds + idx,                                                   set->lock); +                }  #ifdef HAVE_ROBUST_MUTEX                  if (ret == -EOWNERDEAD)                          pthread_mutex_consistent(set->lock); diff --git a/src/lib/shm_rbuff.c b/src/lib/shm_rbuff.c index 7f8af9f5..93108332 100644 --- a/src/lib/shm_rbuff.c +++ b/src/lib/shm_rbuff.c @@ -19,9 +19,12 @@   * License along with this library; if not, write to the Free Software   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> -#if ((SHM_RBUFF_LOCKLESS > 0) &&                        \ +#define _POSIX_C_SOURCE 200809L + +#include "config.h" + +#if (defined(SHM_RBUFF_LOCKLESS) &&                            \       (defined(__GNUC__) || defined (__clang__)))  #include "shm_rbuff_ll.c"  #else diff --git a/src/lib/shm_rbuff_ll.c b/src/lib/shm_rbuff_ll.c index 33e236b0..ec0199c0 100644 --- a/src/lib/shm_rbuff_ll.c +++ b/src/lib/shm_rbuff_ll.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#include "config.h" +  #include <ouroboros/shm_rbuff.h>  #include <ouroboros/lockfile.h>  #include <ouroboros/time_utils.h> @@ -281,9 +282,8 @@ ssize_t shm_rbuff_read(struct shm_rbuff * rb)  }  ssize_t shm_rbuff_read_b(struct shm_rbuff *      rb, -                         const struct timespec * timeout) +                         const struct timespec * abstime)  { -        struct timespec abstime;          ssize_t idx = -1;          assert(rb); @@ -293,11 +293,6 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff *      rb,          if (idx != -EAGAIN)                  return idx; -        if (timeout != NULL) { -                clock_gettime(PTHREAD_COND_CLOCK, &abstime); -                ts_add(&abstime, timeout, &abstime); -        } -  #ifndef HAVE_ROBUST_MUTEX          pthread_mutex_lock(rb->lock);  #else @@ -308,10 +303,10 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff *      rb,                               (void *) rb->lock);          while (shm_rbuff_empty(rb) && (idx != -ETIMEDOUT)) { -                if (timeout != NULL) +                if (abstime != NULL)                          idx = -pthread_cond_timedwait(rb->add,                                                        rb->lock, -                                                      &abstime); +                                                      abstime);                  else                          idx = -pthread_cond_wait(rb->add, rb->lock);  #ifdef HAVE_ROBUST_MUTEX diff --git a/src/lib/shm_rbuff_pthr.c b/src/lib/shm_rbuff_pthr.c index 44001458..9567762f 100644 --- a/src/lib/shm_rbuff_pthr.c +++ b/src/lib/shm_rbuff_pthr.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L +  #include <ouroboros/shm_rbuff.h>  #include <ouroboros/lockfile.h>  #include <ouroboros/time_utils.h> @@ -284,18 +285,12 @@ ssize_t shm_rbuff_read(struct shm_rbuff * rb)  }  ssize_t shm_rbuff_read_b(struct shm_rbuff *      rb, -                         const struct timespec * timeout) +                         const struct timespec * abstime)  { -        struct timespec abstime;          ssize_t idx = -1;          assert(rb); -        if (timeout != NULL) { -                clock_gettime(PTHREAD_COND_CLOCK, &abstime); -                ts_add(&abstime, timeout, &abstime); -        } -  #ifndef HAVE_ROBUST_MUTEX          pthread_mutex_lock(rb->lock);  #else @@ -306,10 +301,10 @@ ssize_t shm_rbuff_read_b(struct shm_rbuff *      rb,                               (void *) rb->lock);          while (shm_rbuff_empty(rb) && (idx != -ETIMEDOUT)) { -                if (timeout != NULL) +                if (abstime != NULL)                          idx = -pthread_cond_timedwait(rb->add,                                                        rb->lock, -                                                      &abstime); +                                                      abstime);                  else                          idx = -pthread_cond_wait(rb->add, rb->lock);  #ifdef HAVE_ROBUST_MUTEX diff --git a/src/lib/shm_rdrbuff.c b/src/lib/shm_rdrbuff.c index 0919b1e0..447f8b35 100644 --- a/src/lib/shm_rdrbuff.c +++ b/src/lib/shm_rdrbuff.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200809L + +#include "config.h" +  #include <ouroboros/errno.h>  #include <ouroboros/shm_rdrbuff.h>  #include <ouroboros/shm_du_buff.h> diff --git a/src/lib/sockets.c b/src/lib/sockets.c index 7f0c4dd4..9f1b326e 100644 --- a/src/lib/sockets.c +++ b/src/lib/sockets.c @@ -20,7 +20,6 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h>  #include <ouroboros/errno.h>  #include <ouroboros/sockets.h>  #include <ouroboros/utils.h> @@ -96,40 +95,32 @@ static void close_ptr(void * o)  irm_msg_t * send_recv_irm_msg(irm_msg_t * msg)  { -        int sockfd; -        buffer_t buf; -        ssize_t count = 0; -        irm_msg_t * recv_msg = NULL; +        int         sockfd; +        uint8_t     buf[IRM_MSG_BUF_SIZE]; +        ssize_t     len; +        irm_msg_t * recv_msg;          sockfd = client_socket_open(IRM_SOCK_PATH);          if (sockfd < 0)                  return NULL; -        buf.len = irm_msg__get_packed_size(msg); -        if (buf.len == 0) { -                close(sockfd); -                return NULL; -        } - -        buf.data = malloc(IRM_MSG_BUF_SIZE); -        if (buf.data == NULL) { +        len = irm_msg__get_packed_size(msg); +        if (len == 0) {                  close(sockfd);                  return NULL;          }          pthread_cleanup_push(close_ptr, &sockfd); -        pthread_cleanup_push((void (*)(void *)) free, (void *) buf.data); -        irm_msg__pack(msg, buf.data); +        irm_msg__pack(msg, buf); -        if (write(sockfd, buf.data, buf.len) != -1) -                count = read(sockfd, buf.data, IRM_MSG_BUF_SIZE); +        if (write(sockfd, buf, len) != -1) +                len = read(sockfd, buf, IRM_MSG_BUF_SIZE); -        if (count > 0) -                recv_msg = irm_msg__unpack(NULL, count, buf.data); +        if (len > 0) +                recv_msg = irm_msg__unpack(NULL, len, buf);          pthread_cleanup_pop(true); -        pthread_cleanup_pop(true);          return recv_msg;  } diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index 41c2074a..0223262a 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -1,6 +1,12 @@  get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY)  get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) +if (NOT (APPLE OR GNU)) +  set(TIMERWHEEL_TEST "timerwheel_test.c") +else () +  set(TIMERWHEEL_TEST "") +endif () +  create_test_sourcelist(${PARENT_DIR}_tests test_suite.c    # Add new tests here    bitmap_test.c @@ -11,6 +17,7 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c    rib_test.c    sha3_test.c    time_utils_test.c +  ${TIMERWHEEL_TEST}    )  add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) diff --git a/src/lib/tests/rib_test.c b/src/lib/tests/rib_test.c index e1fa427d..6a2446b9 100644 --- a/src/lib/tests/rib_test.c +++ b/src/lib/tests/rib_test.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 199309L +  #include <ouroboros/time_utils.h>  #include <ouroboros/rib.h>  #include <ouroboros/rqueue.h> diff --git a/src/ipcpd/tests/timerwheel_test.c b/src/lib/tests/timerwheel_test.c index 6ba1b890..d7478487 100644 --- a/src/ipcpd/tests/timerwheel_test.c +++ b/src/lib/tests/timerwheel_test.c @@ -51,6 +51,9 @@ int timerwheel_test(int argc, char ** argv)          int check_total = 0;          int i; +        int var = 5; + +        struct tw_f * f;          (void) argc;          (void) argv; @@ -75,13 +78,12 @@ int timerwheel_test(int argc, char ** argv)          for (i = 0; i < additions; ++i) {                  int delay = rand() % (resolution * elements); -                int var = rand() % 5;                  check_total += var; -                if (timerwheel_add(tw, -                                   (void (*)(void *)) add, -                                   (void *) &var, -                                   sizeof(var), -                                   delay)) { +                f = timerwheel_start(tw, +                                     (void (*)(void *)) add, +                                     (void *) &var, +                                     delay); +                if (f == NULL) {                          printf("Failed to add function.");                          return -1;                  } @@ -89,14 +91,12 @@ int timerwheel_test(int argc, char ** argv)          nanosleep(&wait, NULL); -        /* On some systems and VMs, the scheduler may be too slow. */ -        if (total != check_total) -                nanosleep(&wait, NULL); +        timerwheel_move(tw);          timerwheel_destroy(tw);          if (total != check_total) { -                printf("Totals do not match.\n"); +                printf("Totals do not match: %d and %d.\n", total, check_total);                  return -1;          } diff --git a/src/lib/time_utils.c b/src/lib/time_utils.c index 2dec4524..22937d4b 100644 --- a/src/lib/time_utils.c +++ b/src/lib/time_utils.c @@ -20,7 +20,8 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 199309L +  #include <ouroboros/time_utils.h>  #include <stddef.h> diff --git a/src/lib/timerwheel.c b/src/lib/timerwheel.c new file mode 100644 index 00000000..2952c5d3 --- /dev/null +++ b/src/lib/timerwheel.c @@ -0,0 +1,232 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2017 + * + * Timerwheel + * + *    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 + * version 2.1 as published by the Free Software Foundation. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#define _POSIX_C_SOURCE 200112L + +#include "config.h" + +#include <ouroboros/time_utils.h> +#include <ouroboros/errno.h> +#include <ouroboros/list.h> + +#include <pthread.h> +#include <stdlib.h> +#include <assert.h> +#include <string.h> + +#define FRAC 10 /* accuracy of the timer */ + +#define tw_used(tw) ((tw->head + tw->elements - tw->tail) & (tw->elements - 1)); +#define tw_free(tw) (tw_used(tw) + 1 < tw->elements) +#define tw_empty(tw) (tw->head == tw->tail) + +struct tw_f { +        struct list_head next; +        void (* func)(void *); +        void * arg; +}; + +struct tw_el { +        struct list_head funcs; +        struct timespec  expiry; +}; + +struct timerwheel { +        struct tw_el *   wheel; + +        struct timespec  intv; + +        size_t           pos; + +        pthread_mutex_t  lock; + +        time_t           resolution; +        unsigned int     elements; +}; + +static void tw_el_fini(struct tw_el * e) +{ +        struct list_head * p; +        struct list_head * h; + +        list_for_each_safe(p, h, &e->funcs) { +                struct tw_f * f = list_entry(p, struct tw_f, next); +                list_del(&f->next); +        } +} + +void timerwheel_move(struct timerwheel * tw) +{ +        struct timespec now = {0, 0}; +        long ms = tw->resolution * tw->elements; +        struct timespec total = {ms / 1000, +                                 (ms % 1000) * MILLION}; +        struct list_head * p; +        struct list_head * h; + +        clock_gettime(CLOCK_MONOTONIC, &now); + +        pthread_mutex_lock(&tw->lock); + +        while (ts_diff_us(&tw->wheel[tw->pos].expiry, &now) > 0) { +                list_for_each_safe(p, h, &tw->wheel[tw->pos].funcs) { +                        struct tw_f * f = list_entry(p, struct tw_f, next); +                        list_del(&f->next); +                        f->func(f->arg); +                        free(f); +                } + +                ts_add(&tw->wheel[tw->pos].expiry, +                       &total, +                       &tw->wheel[tw->pos].expiry); + +                tw->pos = (tw->pos + 1) & (tw->elements - 1); +        } + +        pthread_mutex_unlock(&tw->lock); +} + +struct timerwheel * timerwheel_create(time_t resolution, +                                      time_t max_delay) +{ +        struct timespec now = {0, 0}; +        struct timespec res_ts = {resolution / 1000, +                                  (resolution % 1000) * MILLION}; +        unsigned long i; + +        struct timerwheel * tw; + +        assert(resolution != 0); + +        tw = malloc(sizeof(*tw)); +        if (tw == NULL) +                return NULL; + +        if (pthread_mutex_init(&tw->lock, NULL)) +                return NULL; + +        tw->elements = 1; + +        while (tw->elements < max_delay / resolution) +                tw->elements <<= 1; + +        tw->wheel = malloc(sizeof(*tw->wheel) * tw->elements); +        if (tw->wheel == NULL) +                goto fail_wheel_malloc; + +        tw->resolution = resolution; + +        tw->intv.tv_sec = (tw->resolution / FRAC) / 1000; +        tw->intv.tv_nsec = ((tw->resolution / FRAC) % 1000) * MILLION; + +        if (pthread_mutex_init(&tw->lock, NULL)) +                goto fail_lock_init; + +        tw->pos = 0; + +        clock_gettime(CLOCK_MONOTONIC, &now); +        now.tv_nsec -= (now.tv_nsec % MILLION); + +        for (i = 0; i < tw->elements; ++i) { +                list_head_init(&tw->wheel[i].funcs); +                tw->wheel[i].expiry = now; +                ts_add(&now, &res_ts, &now); +        } + +        return tw; + + fail_lock_init: +         free(tw->wheel); + fail_wheel_malloc: +         free(tw); +         return NULL; +} + +void timerwheel_destroy(struct timerwheel * tw) +{ +        unsigned long i; + +        for (i = 0; i < tw->elements; ++i) +                tw_el_fini(&tw->wheel[i]); + +        pthread_mutex_destroy(&tw->lock); +        free(tw->wheel); +        free(tw); +} + +struct tw_f * timerwheel_start(struct timerwheel * tw, +                               void (* func)(void *), +                               void *              arg, +                               time_t              delay) +{ +        int pos; +        struct tw_f * f = malloc(sizeof(*f)); +        if (f == NULL) +                return NULL; + +        f->func = func; +        f->arg = arg; + +        assert(delay < tw->elements * tw->resolution); + +        pthread_mutex_lock(&tw->lock); + +        pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1); +        list_add(&f->next, &tw->wheel[pos].funcs); + +        pthread_mutex_unlock(&tw->lock); + +        return f; +} + +int timerwheel_restart(struct timerwheel * tw, +                       struct tw_f *       f, +                       time_t              delay) +{ +        int pos; + +        assert(tw); +        assert(delay < tw->elements * tw->resolution); + +        pthread_mutex_lock(&tw->lock); + +        list_del(&f->next); +        pos = (tw->pos + delay / tw->resolution) & (tw->elements - 1); +        list_add(&f->next, &tw->wheel[pos].funcs); + +        pthread_mutex_unlock(&tw->lock); + +        return 0; +} + +void timerwheel_stop(struct timerwheel * tw, +                     struct tw_f *       f) +{ +        assert(tw); + +        pthread_mutex_lock(&tw->lock); + +        list_del(&f->next); +        free(f); + +        pthread_mutex_unlock(&tw->lock); +} diff --git a/src/lib/tpm.c b/src/lib/tpm.c index 739996c4..dd71d276 100644 --- a/src/lib/tpm.c +++ b/src/lib/tpm.c @@ -20,7 +20,10 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#include <ouroboros/config.h> +#define _POSIX_C_SOURCE 200112L + +#include "config.h" +  #include <ouroboros/errno.h>  #include <ouroboros/list.h>  #include <ouroboros/time_utils.h> diff --git a/src/nsmd/CMakeLists.txt b/src/nsmd/CMakeLists.txt deleted file mode 100644 index 2995b725..00000000 --- a/src/nsmd/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -set(SOURCE_FILES -  # Add source files here -  main.c -  ) - -add_executable(nsmd ${SOURCE_FILES}) - -target_link_libraries(nsmd LINK_PUBLIC ouroboros) - -include(AddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES Debug) -  add_compile_flags(nsmd -DCONFIG_OUROBOROS_DEBUG) -endif (CMAKE_BUILD_TYPE MATCHES Debug) - -install(TARGETS nsmd RUNTIME DESTINATION sbin) - -# Enable once nsmd has tests -# add_subdirectory(tests) diff --git a/src/nsmd/main.c b/src/nsmd/main.c deleted file mode 100644 index 537aaa81..00000000 --- a/src/nsmd/main.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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., http://www.fsf.org/about/contact/. - */ - -#define OUROBOROS_PREFIX "nsmd" - -#include <ouroboros/logs.h> - -int main(void) -{ -        log_dbg("Test of the NSMd"); - -        return 0; -} diff --git a/src/nsmd/tests/CMakeLists.txt b/src/nsmd/tests/CMakeLists.txt deleted file mode 100644 index 68bd762d..00000000 --- a/src/nsmd/tests/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -get_filename_component(tmp ".." ABSOLUTE) -get_filename_component(src_folder "${tmp}" NAME) - -create_test_sourcelist(${src_folder}_tests test_suite.c -                       # Add new tests here -) - -add_executable(${src_folder}_test EXCLUDE_FROM_ALL ${${src_folder}_tests}) -target_link_libraries(${src_folder}_test ouroboros) - -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}) -  get_filename_component(test_name ${test} NAME_WE) -  add_test(${test_name} ${C_TEST_PATH}/${src_folder}_test ${test_name}) -endforeach(test) diff --git a/src/tools/operf/operf.c b/src/tools/operf/operf.c index d2dfeaa3..e54fbc6b 100644 --- a/src/tools/operf/operf.c +++ b/src/tools/operf/operf.c @@ -21,6 +21,7 @@   */  #define _POSIX_C_SOURCE 199506L +#define __XSI_VISIBLE   500  #include <ouroboros/fqueue.h>  #include <ouroboros/dev.h> diff --git a/src/tools/operf/operf_client.c b/src/tools/operf/operf_client.c index a905b05e..4ad26d13 100644 --- a/src/tools/operf/operf_client.c +++ b/src/tools/operf/operf_client.c @@ -24,10 +24,6 @@  #include <ouroboros/fcntl.h>  #include <ouroboros/time_utils.h> -#ifdef __FreeBSD__ -#define __XSI_VISIBLE 500 -#endif -  #include <signal.h>  #include <stdlib.h>  #include <sys/time.h> diff --git a/src/tools/operf/operf_server.c b/src/tools/operf/operf_server.c index 3b43ece4..c016ad63 100644 --- a/src/tools/operf/operf_server.c +++ b/src/tools/operf/operf_server.c @@ -20,10 +20,6 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifdef __FreeBSD__ -#define __XSI_VISIBLE 500 -#endif -  #include <stdlib.h>  #include <signal.h>  #include <arpa/inet.h> diff --git a/src/tools/oping/CMakeLists.txt b/src/tools/oping/CMakeLists.txt index f129a02b..b95add7e 100644 --- a/src/tools/oping/CMakeLists.txt +++ b/src/tools/oping/CMakeLists.txt @@ -9,6 +9,8 @@ if(NOT LIBM_LIBRARIES)    message(FATAL_ERROR "libm not found")  endif() +mark_as_advanced(LIBM_LIBRARIES) +  set(SOURCE_FILES    # Add source files here    oping.c diff --git a/src/tools/oping/oping.c b/src/tools/oping/oping.c index be87343e..13132815 100644 --- a/src/tools/oping/oping.c +++ b/src/tools/oping/oping.c @@ -21,6 +21,7 @@   */  #define _POSIX_C_SOURCE 199506L +#define __XSI_VISIBLE   500  #include <ouroboros/fqueue.h>  #include <ouroboros/dev.h> diff --git a/src/tools/oping/oping_client.c b/src/tools/oping/oping_client.c index d0fc2d66..db0ef199 100644 --- a/src/tools/oping/oping_client.c +++ b/src/tools/oping/oping_client.c @@ -24,10 +24,6 @@  #include <ouroboros/fcntl.h>  #include <ouroboros/time_utils.h> -#ifdef __FreeBSD__ -#define __XSI_VISIBLE 500 -#endif -  #include <signal.h>  #include <stdlib.h>  #include <sys/time.h> diff --git a/src/tools/oping/oping_server.c b/src/tools/oping/oping_server.c index 3a7f061c..57d1fd7c 100644 --- a/src/tools/oping/oping_server.c +++ b/src/tools/oping/oping_server.c @@ -20,10 +20,6 @@   * Foundation, Inc., http://www.fsf.org/about/contact/.   */ -#ifdef __FreeBSD__ -#define __XSI_VISIBLE 500 -#endif -  #include <stdlib.h>  #include <signal.h>  #include <arpa/inet.h> | 
