diff options
Diffstat (limited to 'src/ipcpd')
83 files changed, 789 insertions, 1050 deletions
diff --git a/src/ipcpd/CMakeLists.txt b/src/ipcpd/CMakeLists.txt index b3b049e3..609da54a 100644 --- a/src/ipcpd/CMakeLists.txt +++ b/src/ipcpd/CMakeLists.txt @@ -1,60 +1,30 @@ -set(CONNMGR_RCV_TIMEOUT 1000 CACHE STRING - "Timeout for the connection manager to wait for OCEP info (ms).") -set(IPCP_DEBUG_LOCAL FALSE CACHE BOOL - "Use PID as address for local debugging") -set(IPCP_QOS_CUBE_BE_PRIO 50 CACHE STRING - "Priority for best effort QoS cube (0-99)") -set(IPCP_QOS_CUBE_VIDEO_PRIO 90 CACHE STRING - "Priority for video QoS cube (0-99)") -set(IPCP_QOS_CUBE_VOICE_PRIO 99 CACHE STRING - "Priority for voice QoS cube (0-99)") -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_SCHED_THR_MUL 2 CACHE STRING - "Number of scheduler threads per QoS cube") -set(DISABLE_CORE_LOCK TRUE CACHE BOOL - "Disable locking performance threads to a core") -set(DHT_ENROLL_SLACK 50 CACHE STRING - "DHT enrollment waiting time (0-999, ms)") -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(IPCP_LINUX_TIMERSLACK_NS 1000 CACHE STRING - "Slack value for high resolution timers on Linux systems.") -endif () - -if ((IPCP_QOS_CUBE_BE_PRIO LESS 0) OR (IPCP_QOS_CUBE_BE_PRIO GREATER 99)) - message(FATAL_ERROR "Invalid priority for best effort QoS cube") -endif () - -if ((IPCP_QOS_CUBE_VIDEO_PRIO LESS 0) OR (IPCP_QOS_CUBE_VIDEO_PRIO GREATER 99)) - message(FATAL_ERROR "Invalid priority for video QoS cube") -endif () - -if ((IPCP_QOS_CUBE_VOICE_PRIO LESS 0) OR (IPCP_QOS_CUBE_VOICE_PRIO GREATER 99)) - message(FATAL_ERROR "Invalid priority for voice QoS cube") -endif () - -if ((DHT_ENROLL_SLACK LESS 0) OR (DHT_ENROLL_SLACK GREATER 999)) - message(FATAL_ERROR "Invalid DHT slack value") -endif () - +# IPCP (IPC Process) daemons build configuration +# Configuration options and validation are in cmake/config/ipcp/*.cmake +# Common sources shared by all IPCPs (absolute paths for subdirectories) set(IPCP_SOURCES - # Add source files here ${CMAKE_CURRENT_SOURCE_DIR}/ipcp.c ${CMAKE_CURRENT_SOURCE_DIR}/shim-data.c - ) +) -set (COMMON_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/common/enroll.c - ) +set(COMMON_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/common/enroll.c +) -add_subdirectory(local) -add_subdirectory(eth) -add_subdirectory(udp) -add_subdirectory(unicast) -add_subdirectory(broadcast) +set(IPCP_INCLUDE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include +) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY) + +add_subdirectory(local) +add_subdirectory(broadcast) +add_subdirectory(unicast) +if(HAVE_ETH) + add_subdirectory(eth) +endif() +add_subdirectory(udp) diff --git a/src/ipcpd/broadcast/CMakeLists.txt b/src/ipcpd/broadcast/CMakeLists.txt index d85f335e..6749f660 100644 --- a/src/ipcpd/broadcast/CMakeLists.txt +++ b/src/ipcpd/broadcast/CMakeLists.txt @@ -1,35 +1,20 @@ -get_filename_component(CURRENT_SOURCE_PARENT_DIR - ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CURRENT_BINARY_PARENT_DIR - ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +# Broadcast IPCP build configuration -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) - -set(IPCP_BROADCAST_TARGET ipcpd-broadcast CACHE INTERNAL "") -set(IPCP_BROADCAST_MPL 60 CACHE STRING - "Default maximum packet lifetime for the broadcast IPCP, in seconds") - -set(SOURCE_FILES - # Add source files here +set(BROADCAST_SOURCES connmgr.c dt.c main.c - ) +) + +add_executable(${IPCP_BROADCAST_TARGET} + ${BROADCAST_SOURCES} + ${IPCP_SOURCES} + ${COMMON_SOURCES} +) -add_executable(ipcpd-broadcast ${SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES} - ${LAYER_CONFIG_PROTO_SRCS}) -target_link_libraries(ipcpd-broadcast LINK_PUBLIC ouroboros-dev) +target_include_directories(${IPCP_BROADCAST_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS}) +target_link_libraries(${IPCP_BROADCAST_TARGET} PRIVATE ouroboros-dev) -include(AddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES "Debug*") - add_compile_flags(ipcpd-broadcast -DCONFIG_OUROBOROS_DEBUG) -endif () +ouroboros_target_debug_definitions(${IPCP_BROADCAST_TARGET}) -install(TARGETS ipcpd-broadcast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) +install(TARGETS ${IPCP_BROADCAST_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) diff --git a/src/ipcpd/broadcast/connmgr.c b/src/ipcpd/broadcast/connmgr.c index f297175d..a4d20ee7 100644 --- a/src/ipcpd/broadcast/connmgr.c +++ b/src/ipcpd/broadcast/connmgr.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Handles connections between components * diff --git a/src/ipcpd/broadcast/dt.c b/src/ipcpd/broadcast/dt.c index 938c9085..30e89a4f 100644 --- a/src/ipcpd/broadcast/dt.c +++ b/src/ipcpd/broadcast/dt.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Forward loop for broadcast * @@ -58,14 +58,13 @@ struct nb { }; struct { - struct list_head nbs; - size_t nbs_len; - pthread_rwlock_t nbs_lock; + struct llist nbs; + pthread_rwlock_t lock; - fset_t * set; + fset_t * set; - pthread_t reader; - pthread_t listener; + pthread_t reader; + pthread_t listener; } fwd; static int dt_add_nb(int fd) @@ -73,12 +72,12 @@ static int dt_add_nb(int fd) struct list_head * p; struct nb * nb; - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each(p, &fwd.nbs) { + llist_for_each(p, &fwd.nbs) { struct nb * el = list_entry(p, struct nb, next); if (el->fd == fd) { - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_warn("Already know neighbor on fd %d.", fd); return 0; } @@ -86,18 +85,16 @@ static int dt_add_nb(int fd) nb = malloc(sizeof(*nb)); if (nb == NULL) { - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_err("Failed to malloc neighbor struct."); return -ENOMEM; } nb->fd = fd; - list_add_tail(&nb->next, p); + llist_add_tail(&nb->next, &fwd.nbs); - ++fwd.nbs_len; - - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_dbg("Neighbor %d added.", fd); @@ -109,21 +106,20 @@ static int dt_del_nb(int fd) struct list_head * p; struct list_head * h; - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each_safe(p, h, &fwd.nbs) { + llist_for_each_safe(p, h, &fwd.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->fd == fd) { - list_del(&nb->next); - --fwd.nbs_len; - pthread_rwlock_unlock(&fwd.nbs_lock); + llist_del(&nb->next, &fwd.nbs); + pthread_rwlock_unlock(&fwd.lock); log_dbg("Neighbor %d deleted.", nb->fd); free(nb); return 0; } } - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); log_err("Neighbor not found on fd %d.", fd); @@ -157,11 +153,11 @@ static void dt_packet(uint8_t * buf, { struct list_head * p; - pthread_rwlock_rdlock(&fwd.nbs_lock); + pthread_rwlock_rdlock(&fwd.lock); - pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.nbs_lock); + pthread_cleanup_push(__cleanup_rwlock_unlock, &fwd.lock); - list_for_each(p, &fwd.nbs) { + llist_for_each(p, &fwd.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->fd != in_fd) flow_write(nb->fd, buf, len); /* FIXME: avoid copy. */ @@ -252,12 +248,12 @@ int dt_init(void) strcpy(info.comp_name, DT); strcpy(info.comp_name, DT_COMP); - list_head_init(&fwd.nbs); + llist_init(&fwd.nbs); if (notifier_reg(handle_event, NULL)) goto fail_notifier_reg; - if (pthread_rwlock_init(&fwd.nbs_lock, NULL)) + if (pthread_rwlock_init(&fwd.lock, NULL)) goto fail_lock_init; fwd.set = fset_create(); @@ -273,8 +269,6 @@ int dt_init(void) if (connmgr_comp_init(COMPID_DT, &info)) goto fail_connmgr_comp_init; - fwd.nbs_len = 0; - return 0; fail_connmgr_comp_init: @@ -286,7 +280,7 @@ int dt_init(void) fail_pthread_create_reader: fset_destroy(fwd.set); fail_fset_create: - pthread_rwlock_destroy(&fwd.nbs_lock); + pthread_rwlock_destroy(&fwd.lock); fail_lock_init: notifier_unreg(handle_event); fail_notifier_reg: @@ -308,15 +302,15 @@ void dt_fini(void) fset_destroy(fwd.set); - pthread_rwlock_wrlock(&fwd.nbs_lock); + pthread_rwlock_wrlock(&fwd.lock); - list_for_each_safe(p, h, &fwd.nbs) { + llist_for_each_safe(p, h, &fwd.nbs) { struct nb * n = list_entry(p, struct nb, next); - list_del(&n->next); + llist_del(&n->next, &fwd.nbs); free(n); } - pthread_rwlock_unlock(&fwd.nbs_lock); + pthread_rwlock_unlock(&fwd.lock); - pthread_rwlock_destroy(&fwd.nbs_lock); + pthread_rwlock_destroy(&fwd.lock); } diff --git a/src/ipcpd/broadcast/dt.h b/src/ipcpd/broadcast/dt.h index 8d3b83f8..2472831e 100644 --- a/src/ipcpd/broadcast/dt.h +++ b/src/ipcpd/broadcast/dt.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Forward loop for broadcast * diff --git a/src/ipcpd/broadcast/main.c b/src/ipcpd/broadcast/main.c index 151b38c8..b3cbdc79 100644 --- a/src/ipcpd/broadcast/main.c +++ b/src/ipcpd/broadcast/main.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Broadcast IPC Process * diff --git a/src/ipcpd/common/comp.h b/src/ipcpd/common/comp.h index f3790d9c..e1d025b6 100644 --- a/src/ipcpd/common/comp.h +++ b/src/ipcpd/common/comp.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Components for the unicast/broadcast IPC process * diff --git a/src/ipcpd/common/connmgr.c b/src/ipcpd/common/connmgr.c index 1bb8c932..48ad79ba 100644 --- a/src/ipcpd/common/connmgr.c +++ b/src/ipcpd/common/connmgr.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Handles connections between components * diff --git a/src/ipcpd/common/connmgr.h b/src/ipcpd/common/connmgr.h index 0710dbbf..f48ecd1b 100644 --- a/src/ipcpd/common/connmgr.h +++ b/src/ipcpd/common/connmgr.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Handles the different AP connections * diff --git a/src/ipcpd/common/enroll.c b/src/ipcpd/common/enroll.c index 8e5384a5..959cca07 100644 --- a/src/ipcpd/common/enroll.c +++ b/src/ipcpd/common/enroll.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Enrollment Task * diff --git a/src/ipcpd/common/enroll.h b/src/ipcpd/common/enroll.h index f26c31a3..f56adfc8 100644 --- a/src/ipcpd/common/enroll.h +++ b/src/ipcpd/common/enroll.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Enrollment Task * diff --git a/src/ipcpd/config.h.in b/src/ipcpd/config.h.in index d2af6440..0b4252e5 100644 --- a/src/ipcpd/config.h.in +++ b/src/ipcpd/config.h.in @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process configuration * @@ -29,11 +29,9 @@ #define SOCKET_TIMEOUT @SOCKET_TIMEOUT@ #define CONNECT_TIMEOUT @CONNECT_TIMEOUT@ -#define SHM_BUFFER_SIZE @SHM_BUFFER_SIZE@ -#define SHM_RDRB_BLOCK_SIZE @SHM_RDRB_BLOCK_SIZE@ +#define SSM_POOL_BLOCK_SIZE @SSM_POOL_BLOCK_SIZE@ #define DU_BUFF_HEADSPACE @DU_BUFF_HEADSPACE@ #define DU_BUFF_TAILSPACE @DU_BUFF_TAILSPACE@ -#cmakedefine SHM_RDRB_MULTI_BLOCK #define IPCP_MIN_THREADS @IPCP_MIN_THREADS@ #define IPCP_ADD_THREADS @IPCP_ADD_THREADS@ @@ -47,11 +45,11 @@ #define QOS_PRIO_VOICE @IPCP_QOS_CUBE_VOICE_PRIO@ #define IPCP_SCHED_THR_MUL @IPCP_SCHED_THR_MUL@ #define PFT_SIZE @PFT_SIZE@ -#define DHT_ENROLL_SLACK @DHT_ENROLL_SLACK@ #define IPCP_UNICAST_MPL @IPCP_UNICAST_MPL@ #define CONNMGR_RCV_TIMEOUT @CONNMGR_RCV_TIMEOUT@ #cmakedefine DISABLE_CORE_LOCK +#cmakedefine BUILD_CONTAINER #cmakedefine IPCP_FLOW_STATS #cmakedefine IPCP_DEBUG_LOCAL #ifdef CONFIG_OUROBOROS_DEBUG @@ -73,10 +71,11 @@ #cmakedefine HAVE_BPF #cmakedefine HAVE_RAW_SOCKETS #cmakedefine IPCP_ETH_QDISC_BYPASS -#define IPCP_ETH_RD_THR @IPCP_ETH_RD_THR@ -#define IPCP_ETH_WR_THR @IPCP_ETH_WR_THR@ -#define IPCP_ETH_LO_MTU @IPCP_ETH_LO_MTU@ -#define IPCP_ETH_MPL @IPCP_ETH_MPL@ +#define IPCP_ETH_RD_THR @IPCP_ETH_RD_THR@ +#define IPCP_ETH_WR_THR @IPCP_ETH_WR_THR@ +#define IPCP_ETH_LO_MTU @IPCP_ETH_LO_MTU@ +#define IPCP_ETH_MGMT_FRAME_SIZE @IPCP_ETH_MGMT_FRAME_SIZE@ +#define IPCP_ETH_MPL @IPCP_ETH_MPL@ /* local */ #define IPCP_LOCAL_MPL @IPCP_LOCAL_MPL@ diff --git a/src/ipcpd/eth/CMakeLists.txt b/src/ipcpd/eth/CMakeLists.txt index 44299a59..5a36352d 100644 --- a/src/ipcpd/eth/CMakeLists.txt +++ b/src/ipcpd/eth/CMakeLists.txt @@ -1,134 +1,21 @@ -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) - -find_path(NETMAP_C_INCLUDE_DIR - net/netmap_user.h - HINTS /usr/include /usr/local/include) - -mark_as_advanced(NETMAP_C_INCLUDE_DIR) - -# Check for raw sockets -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(DISABLE_RAW_SOCKETS FALSE CACHE BOOL - "Disable raw socket support for Ethernet IPCPs") - if (NOT DISABLE_RAW_SOCKETS) - message(STATUS "Raw socket support for Ethernet IPCPs enabled") - set(HAVE_RAW_SOCKETS TRUE PARENT_SCOPE) - set(HAVE_RAW_SOCKETS TRUE) - set(HAVE_ETH TRUE) - else () - message(STATUS "Raw socket support for Ethernet IPCPs disabled by user") - unset(HAVE_RAW_SOCKETS PARENT_SCOPE) - unset(HAVE_RAW_SOCKETS) - endif () -endif () - -# Check for BPF -if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_path(BPF_C_INCLUDE_DIR - net/bpf.h - HINTS /usr/include /usr/local/include) - - mark_as_advanced(BPF_C_INCLUDE_DIR) - - if (BPF_C_INCLUDE_DIR) - set(DISABLE_BPF FALSE CACHE BOOL - "Disable Berkeley Packet Filter support for Ethernet IPCPs") - if (NOT DISABLE_BPF) - message(STATUS "Berkeley Packet Filter support " - "for Ethernet IPCPs enabled") - set(HAVE_BPF TRUE PARENT_SCOPE) - set(HAVE_BPF TRUE) - set(HAVE_ETH TRUE) - else () - message(STATUS "Berkeley Packet Filter support " - "for Ethernet IPCPs disabled by user") - unset(HAVE_BPF PARENT_SCOPE) - unset(HAVE_BPF) - endif () - endif () -endif () - -# Check for netmap exclusively -if (NOT HAVE_RAW_SOCKETS AND NOT HAVE_BPF AND NETMAP_C_INCLUDE_DIR) - set(DISABLE_NETMAP FALSE CACHE BOOL - "Disable netmap support for ETH IPCPs") - if (NOT DISABLE_NETMAP) - message(STATUS "Netmap support for Ethernet IPCPs enabled") - set(HAVE_NETMAP TRUE PARENT_SCOPE) - set(HAVE_ETH TRUE) - else () - message(STATUS "Netmap support for Ethernet IPCPs disabled by user") - unset(HAVE_NETMAP PARENT_SCOPE) - endif () -endif () - -if (HAVE_ETH) - message(STATUS "Supported raw packet API found, building eth-llc and eth-dix") - - set(IPCP_ETH_RD_THR 1 CACHE STRING - "Number of reader threads in Ethernet IPCP") - set(IPCP_ETH_WR_THR 1 CACHE STRING - "Number of writer threads in Ethernet IPCP") - set(IPCP_ETH_QDISC_BYPASS false CACHE BOOL - "Bypass the Qdisc in the kernel when using raw sockets") - set(IPCP_ETH_LO_MTU 1500 CACHE STRING - "Restrict Ethernet MTU over loopback interfaces") - set(IPCP_ETH_MPL 100 CACHE STRING - "Default maximum packet lifetime for the Ethernet IPCPs, in ms") - - set(ETH_LLC_SOURCES - # Add source files here - llc.c - ) - - set(ETH_DIX_SOURCES - # Add source files here - dix.c - ) - - set(IPCP_ETH_LLC_TARGET ipcpd-eth-llc CACHE INTERNAL "") - set(IPCP_ETH_DIX_TARGET ipcpd-eth-dix CACHE INTERNAL "") - - add_executable(ipcpd-eth-llc ${ETH_LLC_SOURCES} ${IPCP_SOURCES}) - add_executable(ipcpd-eth-dix ${ETH_DIX_SOURCES} ${IPCP_SOURCES}) - - if (HAVE_BPF AND NOT APPLE) - target_include_directories(ipcpd-eth-llc PUBLIC ${BPF_C_INCLUDE_DIR}) - target_include_directories(ipcpd-eth-dix PUBLIC ${BPF_C_INCLUDE_DIR}) - endif () - - if (HAVE_NETMAP AND NOT APPLE) - set_target_properties(ipcpd-eth-llc PROPERTIES - COMPILE_FLAGS "${CMAKE_C_FLAGS} -std=c99") - set_target_properties(ipcpd-eth-dix PROPERTIES - COMPILE_FLAGS "${CMAKE_C_FLAGS} -std=c99") - target_include_directories(ipcpd-eth-llc PUBLIC - ${NETMAP_C_INCLUDE_DIR}) - target_include_directories(ipcpd-eth-dix PUBLIC - ${NETMAP_C_INCLUDE_DIR}) - endif () - - target_link_libraries(ipcpd-eth-llc LINK_PUBLIC ouroboros-dev) - target_link_libraries(ipcpd-eth-dix LINK_PUBLIC ouroboros-dev) - - include(AddCompileFlags) - if (CMAKE_BUILD_TYPE MATCHES "Debug*") - add_compile_flags(ipcpd-eth-llc -DCONFIG_OUROBOROS_DEBUG) - add_compile_flags(ipcpd-eth-dix -DCONFIG_OUROBOROS_DEBUG) - endif () - - install(TARGETS ipcpd-eth-llc ipcpd-eth-dix RUNTIME DESTINATION - ${CMAKE_INSTALL_SBINDIR}) -endif () +# Ethernet IPCPs build configuration (LLC and DIX) +# HAVE_ETH detection is in cmake/dependencies.cmake + +add_executable(${IPCP_ETH_LLC_TARGET} llc.c ${IPCP_SOURCES}) +add_executable(${IPCP_ETH_DIX_TARGET} dix.c ${IPCP_SOURCES}) + +foreach(target ${IPCP_ETH_LLC_TARGET} ${IPCP_ETH_DIX_TARGET}) + target_include_directories(${target} PRIVATE ${IPCP_INCLUDE_DIRS}) + if(HAVE_BPF AND NOT APPLE) + target_include_directories(${target} PRIVATE ${BPF_C_INCLUDE_DIR}) + endif() + if(HAVE_NETMAP AND NOT APPLE) + target_compile_options(${target} PRIVATE -std=c99) + target_include_directories(${target} PRIVATE ${NETMAP_C_INCLUDE_DIR}) + endif() + target_link_libraries(${target} PRIVATE ouroboros-dev) + ouroboros_target_debug_definitions(${target}) +endforeach() + +install(TARGETS ${IPCP_ETH_LLC_TARGET} ${IPCP_ETH_DIX_TARGET} + RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) diff --git a/src/ipcpd/eth/dix.c b/src/ipcpd/eth/dix.c index 37b9896d..cf8253bd 100644 --- a/src/ipcpd/eth/dix.c +++ b/src/ipcpd/eth/dix.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC processes over Ethernet - DIX * diff --git a/src/ipcpd/eth/eth.c b/src/ipcpd/eth/eth.c index 0b6a91fb..4be7775e 100644 --- a/src/ipcpd/eth/eth.c +++ b/src/ipcpd/eth/eth.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC processes over Ethernet * @@ -52,6 +52,7 @@ #include <ouroboros/pthread.h> #include "ipcp.h" +#include "np1.h" #include "shim-data.h" #include <signal.h> @@ -138,7 +139,7 @@ #define NAME_QUERY_TIMEO 2000 /* ms */ #define MGMT_TIMEO 100 /* ms */ -#define MGMT_FRAME_SIZE 2048 +#define MGMT_FRAME_SIZE IPCP_ETH_MGMT_FRAME_SIZE #define FLOW_REQ 0 #define FLOW_REPLY 1 @@ -474,6 +475,8 @@ static int eth_ipcp_alloc(const uint8_t * dst_addr, if (buf == NULL) return -1; + memset(buf, 0, len + ETH_HEADER_TOT_SIZE + data->len); + msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE); msg->code = FLOW_REQ; #if defined(BUILD_ETH_DIX) @@ -526,6 +529,8 @@ static int eth_ipcp_alloc_resp(uint8_t * dst_addr, if (buf == NULL) return -1; + memset(buf, 0, sizeof(*msg) + ETH_HEADER_TOT_SIZE + data->len); + msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE); msg->code = FLOW_REPLY; @@ -664,6 +669,8 @@ static int eth_ipcp_name_query_req(const uint8_t * hash, if (buf == NULL) return -1; + memset(buf, 0, len + ETH_HEADER_TOT_SIZE); + msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE); msg->code = NAME_QUERY_REPLY; @@ -833,7 +840,7 @@ static void * eth_ipcp_packet_reader(void * o) #if defined(HAVE_NETMAP) struct nm_pkthdr hdr; #else - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; fd_set fds; int frame_len; #endif @@ -865,21 +872,21 @@ static void * eth_ipcp_packet_reader(void * o) if (select(eth_data.bpf + 1, &fds, NULL, NULL, NULL)) continue; assert(FD_ISSET(eth_data.bpf, &fds)); - if (ipcp_sdb_reserve(&sdb, BPF_LEN)) + if (ipcp_spb_reserve(&spb, BPF_LEN)) continue; - buf = shm_du_buff_head(sdb); + buf = ssm_pk_buff_head(spb); frame_len = read(eth_data.bpf, buf, BPF_BLEN); #elif defined(HAVE_RAW_SOCKETS) FD_SET(eth_data.s_fd, &fds); if (select(eth_data.s_fd + 1, &fds, NULL, NULL, NULL) < 0) continue; assert(FD_ISSET(eth_data.s_fd, &fds)); - if (ipcp_sdb_reserve(&sdb, ETH_MTU)) + if (ipcp_spb_reserve(&spb, ETH_MTU)) continue; - buf = shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE); + buf = ssm_pk_buff_head_alloc(spb, ETH_HEADER_TOT_SIZE); if (buf == NULL) { log_dbg("Failed to allocate header."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); continue; } frame_len = recv(eth_data.s_fd, buf, @@ -887,7 +894,7 @@ static void * eth_ipcp_packet_reader(void * o) #endif if (frame_len <= 0) { log_dbg("Failed to receive frame."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); continue; } #endif @@ -929,7 +936,13 @@ static void * eth_ipcp_packet_reader(void * o) if (ssap == MGMT_SAP && dsap == MGMT_SAP) { #endif - ipcp_sdb_release(sdb); /* No need for the N+1 buffer. */ + ipcp_spb_release(spb); /* No need for the N+1 buffer. */ + + if (length > MGMT_FRAME_SIZE) { + log_warn("Management frame size %u exceeds %u.", + length, MGMT_FRAME_SIZE); + goto fail_frame; + } frame = malloc(sizeof(*frame)); if (frame == NULL) { @@ -969,22 +982,22 @@ static void * eth_ipcp_packet_reader(void * o) pthread_rwlock_unlock(ð_data.flows_lock); #ifndef HAVE_NETMAP - shm_du_buff_head_release(sdb, ETH_HEADER_TOT_SIZE); - shm_du_buff_truncate(sdb, length); + ssm_pk_buff_head_release(spb, ETH_HEADER_TOT_SIZE); + ssm_pk_buff_truncate(spb, length); #else - if (ipcp_sdb_reserve(&sdb, length)) + if (ipcp_spb_reserve(&spb, length)) continue; - buf = shm_du_buff_head(sdb); + buf = ssm_pk_buff_head(spb); memcpy(buf, &e_frame->payload, length); #endif - if (np1_flow_write(fd, sdb) < 0) - ipcp_sdb_release(sdb); + if (np1_flow_write(fd, spb, NP1_GET_POOL(fd)) < 0) + ipcp_spb_release(spb); continue; fail_frame: #ifndef HAVE_NETMAP - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); #endif } } @@ -1000,7 +1013,7 @@ static void cleanup_writer(void * o) static void * eth_ipcp_packet_writer(void * o) { int fd; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; size_t len; #if defined(BUILD_ETH_DIX) uint16_t deid; @@ -1028,17 +1041,17 @@ static void * eth_ipcp_packet_writer(void * o) if (fqueue_type(fq) != FLOW_PKT) continue; - if (np1_flow_read(fd, &sdb)) { + if (np1_flow_read(fd, &spb, NP1_GET_POOL(fd))) { log_dbg("Bad read from fd %d.", fd); continue; } - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); - if (shm_du_buff_head_alloc(sdb, ETH_HEADER_TOT_SIZE) + if (ssm_pk_buff_head_alloc(spb, ETH_HEADER_TOT_SIZE) == NULL) { log_dbg("Failed to allocate header."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); continue; } @@ -1061,10 +1074,10 @@ static void * eth_ipcp_packet_writer(void * o) #elif defined(BUILD_ETH_LLC) dsap, ssap, #endif - shm_du_buff_head(sdb), + ssm_pk_buff_head(spb), len)) log_dbg("Failed to send frame."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); } } @@ -1330,14 +1343,7 @@ static int eth_set_mtu(struct ifreq * ifr) IPCP_ETH_LO_MTU); eth_data.mtu = IPCP_ETH_LO_MTU; } -#ifndef SHM_RDRB_MULTI_BLOCK - maxsz = SHM_RDRB_BLOCK_SIZE - 5 * sizeof(size_t) - - (DU_BUFF_HEADSPACE + DU_BUFF_TAILSPACE); - if ((size_t) eth_data.mtu > maxsz ) { - log_dbg("Layer MTU truncated to shm block size."); - eth_data.mtu = maxsz; - } -#endif + log_dbg("Layer MTU is %d.", eth_data.mtu); return 0; @@ -1491,9 +1497,6 @@ static int eth_ipcp_bootstrap(struct ipcp_config * conf) char ifn[IFNAMSIZ]; #endif /* HAVE_NETMAP */ -#ifndef SHM_RDRB_MULTI_BLOCK - size_t maxsz; -#endif assert(conf); assert(conf->type == THIS_TYPE); @@ -1650,6 +1653,8 @@ static int eth_ipcp_query(const uint8_t * hash) if (buf == NULL) return -1; + memset(buf, 0, len + ETH_HEADER_TOT_SIZE); + msg = (struct mgmt_msg *) (buf + ETH_HEADER_TOT_SIZE); msg->code = NAME_QUERY_REQ; diff --git a/src/ipcpd/eth/llc.c b/src/ipcpd/eth/llc.c index c900dcab..a772e86e 100644 --- a/src/ipcpd/eth/llc.c +++ b/src/ipcpd/eth/llc.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC processes over Ethernet - LLC * diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index ebb9b1c5..5ad2401f 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process main loop * @@ -52,6 +52,7 @@ #include <ouroboros/utils.h> #include "ipcp.h" +#include "np1.h" #include <signal.h> #include <string.h> @@ -131,6 +132,8 @@ struct { pthread_t acceptor; } ipcpd; +struct np1_state np1; + struct cmd { struct list_head next; @@ -205,7 +208,7 @@ static int ipcp_rib_read(const char * path, char * buf, size_t len) { - char * entry; + const char * entry; if (len < LAYER_NAME_SIZE + 2) /* trailing \n */ return 0; @@ -633,9 +636,11 @@ static void do_flow_alloc(pid_t pid, uint8_t * dst, qosspec_t qs, const buffer_t * data, + uid_t uid, ipcp_msg_t * ret_msg) { - int fd; + int fd; + struct ssm_pool * pool = NULL; log_info("Allocating flow %d for %d to " HASH_FMT32 ".", flow_id, pid, HASH_VAL32(dst)); @@ -662,6 +667,17 @@ static void do_flow_alloc(pid_t pid, return; } + if (uid != 0) { + pool = ssm_pool_open(uid); + if (pool == NULL) { + log_err("Failed to open PUP for uid %d.", uid); + ret_msg->result = -ENOMEM; + return; + } + } + + NP1_SET_POOL(fd, pool); + ret_msg->result = ipcpd.ops->ipcp_flow_alloc(fd, dst, qs, data); log_info("Finished allocating flow %d to " HASH_FMT32 ".", @@ -672,9 +688,11 @@ static void do_flow_alloc(pid_t pid, static void do_flow_join(pid_t pid, int flow_id, const uint8_t * dst, + uid_t uid, ipcp_msg_t * ret_msg) { - int fd; + int fd; + struct ssm_pool * pool = NULL; log_info("Joining layer " HASH_FMT32 ".", HASH_VAL32(dst)); @@ -699,6 +717,17 @@ static void do_flow_join(pid_t pid, return; } + if (uid != 0) { + pool = ssm_pool_open(uid); + if (pool == NULL) { + log_err("Failed to open PUP for uid %d.", uid); + ret_msg->result = -ENOMEM; + return; + } + } + + NP1_SET_POOL(fd, pool); + ret_msg->result = ipcpd.ops->ipcp_flow_join(fd, dst); log_info("Finished joining layer " HASH_FMT32 ".", HASH_VAL32(dst)); @@ -706,10 +735,12 @@ static void do_flow_join(pid_t pid, static void do_flow_alloc_resp(int resp, int flow_id, + uid_t uid, const buffer_t * data, ipcp_msg_t * ret_msg) { - int fd = -1; + int fd = -1; + struct ssm_pool * pool = NULL; log_info("Responding %d to alloc on flow_id %d.", resp, flow_id); @@ -737,6 +768,17 @@ static void do_flow_alloc_resp(int resp, return; } + if (uid != 0) { + pool = ssm_pool_open(uid); + if (pool == NULL) { + log_err("Failed to open PUP for uid %d.", uid); + ret_msg->result = -ENOMEM; + return; + } + } + + NP1_SET_POOL(fd, pool); + ret_msg->result = ipcpd.ops->ipcp_flow_alloc_resp(fd, resp, data); log_info("Finished responding %d to allocation request.", @@ -857,12 +899,12 @@ static void * mainloop(void * o) qs = qos_spec_msg_to_s(msg->qosspec); do_flow_alloc(msg->pid, msg->flow_id, msg->hash.data, qs, - &data, &ret_msg); + &data, msg->uid, &ret_msg); break; case IPCP_MSG_CODE__IPCP_FLOW_JOIN: assert(msg->hash.len == ipcp_dir_hash_len()); do_flow_join(msg->pid, msg->flow_id, - msg->hash.data, &ret_msg); + msg->hash.data, msg->uid, &ret_msg); break; case IPCP_MSG_CODE__IPCP_FLOW_ALLOC_RESP: assert(msg->pk.len > 0 ? msg->pk.data != NULL @@ -870,7 +912,7 @@ static void * mainloop(void * o) data.len = msg->pk.len; data.data = msg->pk.data; do_flow_alloc_resp(msg->response, msg->flow_id, - &data, &ret_msg); + msg->uid, &data, &ret_msg); break; case IPCP_MSG_CODE__IPCP_FLOW_DEALLOC: do_flow_dealloc(msg->flow_id, msg->timeo_sec, &ret_msg); @@ -1035,6 +1077,8 @@ int ipcp_init(int argc, ipcpd.alloc_id = -1; + memset(&np1, 0, sizeof(np1)); + pthread_condattr_destroy(&cattr); ipcp_set_state(IPCP_INIT); diff --git a/src/ipcpd/ipcp.h b/src/ipcpd/ipcp.h index e8c31a32..26a780a3 100644 --- a/src/ipcpd/ipcp.h +++ b/src/ipcpd/ipcp.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process structure * diff --git a/src/ipcpd/local/CMakeLists.txt b/src/ipcpd/local/CMakeLists.txt index f661e9ae..91f300a3 100644 --- a/src/ipcpd/local/CMakeLists.txt +++ b/src/ipcpd/local/CMakeLists.txt @@ -1,36 +1,17 @@ -get_filename_component(CURRENT_SOURCE_PARENT_DIR - ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CURRENT_BINARY_PARENT_DIR - ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +# Local IPCP build configuration -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_executable(${IPCP_LOCAL_TARGET} + main.c + ${IPCP_SOURCES} +) -include_directories(${CURRENT_SOURCE_PARENT_DIR}) -include_directories(${CURRENT_BINARY_PARENT_DIR}) +target_include_directories(${IPCP_LOCAL_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS}) +target_link_libraries(${IPCP_LOCAL_TARGET} PRIVATE ouroboros-dev) -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) +ouroboros_target_debug_definitions(${IPCP_LOCAL_TARGET}) -set(IPCP_LOCAL_TARGET ipcpd-local CACHE INTERNAL "") -set(IPCP_LOCAL_MPL 100 CACHE STRING - "Default maximum packet lifetime for the Ethernet IPCPs, in ms") +if(IPCP_LOCAL_POLLING) + target_compile_definitions(${IPCP_LOCAL_TARGET} PRIVATE CONFIG_IPCP_LOCAL_POLLING) +endif() -set(LOCAL_SOURCES - # Add source files here - ${CMAKE_CURRENT_SOURCE_DIR}/main.c) - -add_executable(ipcpd-local ${LOCAL_SOURCES} ${IPCP_SOURCES}) -target_link_libraries(ipcpd-local LINK_PUBLIC ouroboros-common ouroboros-dev) - -include(AddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES "Debug*") - add_compile_flags(ipcpd-local -DCONFIG_OUROBOROS_DEBUG) -endif () - -install(TARGETS ipcpd-local RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) - -# Enable once ipcp-local has tests -# if(BUILD_TESTS) -# add_subdirectory(tests) -# endif () +install(TARGETS ${IPCP_LOCAL_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) diff --git a/src/ipcpd/local/main.c b/src/ipcpd/local/main.c index ffa6dc5a..377a7df3 100644 --- a/src/ipcpd/local/main.c +++ b/src/ipcpd/local/main.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Local IPC process * @@ -40,6 +40,7 @@ #include <ouroboros/local-dev.h> #include "ipcp.h" +#include "np1.h" #include "shim-data.h" #include <string.h> @@ -103,34 +104,41 @@ static void local_data_fini(void){ static void * local_ipcp_packet_loop(void * o) { + int src_fd; + int dst_fd; + struct timespec * timeout; +#ifdef CONFIG_IPCP_LOCAL_POLLING + struct timespec ts_poll = {0, 0}; +#endif (void) o; ipcp_lock_to_core(); - while (true) { - int fd; - ssize_t idx; +#ifdef CONFIG_IPCP_LOCAL_POLLING + timeout = &ts_poll; /* Spin poll with zero timeout */ +#else + timeout = NULL; /* Block until event */ +#endif - fevent(local_data.flows, local_data.fq, NULL); + while (true) { + fevent(local_data.flows, local_data.fq, timeout); - while ((fd = fqueue_next(local_data.fq)) >= 0) { + while ((src_fd = fqueue_next(local_data.fq)) >= 0) { if (fqueue_type(local_data.fq) != FLOW_PKT) continue; - idx = local_flow_read(fd); - if (idx < 0) - continue; - - assert(idx < (SHM_BUFFER_SIZE)); - pthread_rwlock_rdlock(&local_data.lock); - fd = local_data.in_out[fd]; + dst_fd = local_data.in_out[src_fd]; pthread_rwlock_unlock(&local_data.lock); - if (fd != -1) - local_flow_write(fd, idx); + if (dst_fd == -1) + continue; + + local_flow_transfer(src_fd, dst_fd, + NP1_GET_POOL(src_fd), + NP1_GET_POOL(dst_fd)); } } diff --git a/src/ipcpd/np1.h b/src/ipcpd/np1.h new file mode 100644 index 00000000..b7792cb9 --- /dev/null +++ b/src/ipcpd/np1.h @@ -0,0 +1,41 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * N+1 flow pool tracking for IPCPs + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#ifndef OUROBOROS_IPCPD_NP1_H +#define OUROBOROS_IPCPD_NP1_H + +#include "config.h" + +#include <ouroboros/ssm_pool.h> + +#define NP1_LOAD(ptr) (__atomic_load_n((ptr), __ATOMIC_ACQUIRE)) +#define NP1_STORE(ptr, v) (__atomic_store_n((ptr), (v), __ATOMIC_RELEASE)) +#define NP1_GET_POOL(fd) (NP1_LOAD(&np1.pool[(fd)])) +#define NP1_SET_POOL(fd, p) (NP1_STORE(&np1.pool[(fd)], (p))) + +struct np1_state { + struct ssm_pool * pool[SYS_MAX_FLOWS]; +}; + +extern struct np1_state np1; + +#endif /* OUROBOROS_IPCPD_NP1_H */ diff --git a/src/ipcpd/shim-data.c b/src/ipcpd/shim-data.c index 8801213a..90a676da 100644 --- a/src/ipcpd/shim-data.c +++ b/src/ipcpd/shim-data.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process utilities * diff --git a/src/ipcpd/shim-data.h b/src/ipcpd/shim-data.h index ea4ce413..fbadb4d4 100644 --- a/src/ipcpd/shim-data.h +++ b/src/ipcpd/shim-data.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Utitilies for building IPC processes * diff --git a/src/ipcpd/udp/CMakeLists.txt b/src/ipcpd/udp/CMakeLists.txt index 27e32094..a98f0919 100644 --- a/src/ipcpd/udp/CMakeLists.txt +++ b/src/ipcpd/udp/CMakeLists.txt @@ -1,81 +1,14 @@ -get_filename_component(CURRENT_SOURCE_PARENT_DIR - ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CURRENT_BINARY_PARENT_DIR - ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +# UDP IPCPs build configuration (UDP4 and UDP6) +# DDNS detection is in cmake/dependencies/udp/ddns.cmake -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_executable(${IPCP_UDP4_TARGET} udp4.c ${IPCP_SOURCES}) +add_executable(${IPCP_UDP6_TARGET} udp6.c ${IPCP_SOURCES}) -include_directories(${CURRENT_SOURCE_PARENT_DIR}) -include_directories(${CURRENT_BINARY_PARENT_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -set(IPCP_UDP4_TARGET ipcpd-udp4 CACHE INTERNAL "") -set(IPCP_UDP6_TARGET ipcpd-udp6 CACHE INTERNAL "") - -set(UDP4_SOURCES - # Add source files here - udp4.c -) - -set(UDP6_SOURCES - # Add source files here - udp6.c -) - -add_executable(ipcpd-udp4 ${UDP4_SOURCES} ${IPCP_SOURCES}) -target_link_libraries(ipcpd-udp4 LINK_PUBLIC ouroboros-dev) - -add_executable(ipcpd-udp6 ${UDP6_SOURCES} ${IPCP_SOURCES}) -target_link_libraries(ipcpd-udp6 LINK_PUBLIC ouroboros-dev) - - -# Find the nsupdate executable -find_program(NSUPDATE_EXECUTABLE - NAMES nsupdate - DOC "The nsupdate tool that enables DDNS") - -# Find the nslookup executable -find_program(NSLOOKUP_EXECUTABLE - NAMES nslookup - DOC "The nslookup tool that resolves DNS names") - -mark_as_advanced(NSLOOKUP_EXECUTABLE NSUPDATE_EXECUTABLE) - -if (NSLOOKUP_EXECUTABLE AND NSUPDATE_EXECUTABLE) - set(DISABLE_DDNS FALSE CACHE BOOL "Disable DDNS support") - if (NOT DISABLE_DNS) - message(STATUS "DDNS support enabled") - set(HAVE_DDNS TRUE CACHE INTERNAL "") - else () - message(STATUS "DDNS support disabled by user") - unset(HAVE_DDNS CACHE) - endif () -else () - if (NSLOOKUP_EXECUTABLE) - message(STATUS "Install nsupdate to enable DDNS support") - elseif (NSUPDATE_EXECUTABLE) - message(STATUS "Install nslookup to enable DDNS support") - else () - message(STATUS "Install nslookup and nsupdate to enable DDNS support") - endif () -endif () - -set(IPCP_UDP_RD_THR 3 CACHE STRING - "Number of reader threads in UDP IPCPs") -set(IPCP_UDP_WR_THR 3 CACHE STRING - "Number of writer threads in UDP IPCPs") -set(IPCP_UDP_MPL 5000 CACHE STRING - "Default maximum packet lifetime for the UDP IPCPs, in ms") - -include(AddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES "Debug*") - add_compile_flags(ipcpd-udp4 -DCONFIG_OUROBOROS_DEBUG) - add_compile_flags(ipcpd-udp6 -DCONFIG_OUROBOROS_DEBUG) -endif () - -install(TARGETS ipcpd-udp4 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) -install(TARGETS ipcpd-udp6 RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) +foreach(target ${IPCP_UDP4_TARGET} ${IPCP_UDP6_TARGET}) + target_include_directories(${target} PRIVATE ${IPCP_INCLUDE_DIRS}) + target_link_libraries(${target} PRIVATE ouroboros-dev) + ouroboros_target_debug_definitions(${target}) +endforeach() +install(TARGETS ${IPCP_UDP4_TARGET} ${IPCP_UDP6_TARGET} + RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) diff --git a/src/ipcpd/udp/udp.c b/src/ipcpd/udp/udp.c index be8069a4..452bbc1a 100644 --- a/src/ipcpd/udp/udp.c +++ b/src/ipcpd/udp/udp.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process over UDP * @@ -34,6 +34,7 @@ #include <ouroboros/pthread.h> #include "ipcp.h" +#include "np1.h" #include "shim-data.h" #include <string.h> @@ -208,6 +209,8 @@ static int udp_ipcp_port_alloc(const struct __SOCKADDR * r_saddr, if (buf == NULL) return -1; + memset(buf, 0, len + data->len); + msg = (struct mgmt_msg *) buf; msg->eid = hton32(MGMT_EID); msg->code = FLOW_REQ; @@ -251,6 +254,8 @@ static int udp_ipcp_port_alloc_resp(const struct __SOCKADDR * r_saddr, if (msg == NULL) return -1; + memset(msg, 0, sizeof(*msg) + data->len); + msg->eid = hton32(MGMT_EID); msg->code = FLOW_REPLY; msg->s_eid = hton32(s_eid); @@ -439,7 +444,7 @@ static void * udp_ipcp_packet_reader(void * o) struct mgmt_frame * frame; struct __SOCKADDR r_saddr; socklen_t len; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; uint8_t * head; len = sizeof(r_saddr); @@ -483,13 +488,13 @@ static void * udp_ipcp_packet_reader(void * o) n-= sizeof(eid); - if (ipcp_sdb_reserve(&sdb, n)) + if (ipcp_spb_reserve(&spb, n)) continue; - head = shm_du_buff_head(sdb); + head = ssm_pk_buff_head(spb); memcpy(head, data, n); - if (np1_flow_write(eid, sdb) < 0) - ipcp_sdb_release(sdb); + if (np1_flow_write(eid, spb, NP1_GET_POOL(eid)) < 0) + ipcp_spb_release(spb); } return (void *) 0; @@ -500,9 +505,9 @@ static void cleanup_fqueue(void * fq) fqueue_destroy((fqueue_t *) fq); } -static void cleanup_sdb(void * sdb) +static void cleanup_spb(void * spb) { - ipcp_sdb_release((struct shm_du_buff *) sdb); + ipcp_spb_release((struct ssm_pk_buff *) spb); } static void * udp_ipcp_packet_writer(void * o) @@ -525,29 +530,29 @@ static void * udp_ipcp_packet_writer(void * o) int fd; fevent(udp_data.np1_flows, fq, NULL); while ((fd = fqueue_next(fq)) >= 0) { - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; uint8_t * buf; uint16_t len; if (fqueue_type(fq) != FLOW_PKT) continue; - if (np1_flow_read(fd, &sdb)) { + if (np1_flow_read(fd, &spb, NP1_GET_POOL(fd))) { log_dbg("Bad read from fd %d.", fd); continue; } - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); if (len > IPCP_UDP_MAX_PACKET_SIZE) { log_dbg("Packet length exceeds MTU."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); continue; } - buf = shm_du_buff_head_alloc(sdb, OUR_HEADER_LEN); + buf = ssm_pk_buff_head_alloc(spb, OUR_HEADER_LEN); if (buf == NULL) { log_dbg("Failed to allocate header."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); continue; } @@ -560,7 +565,7 @@ static void * udp_ipcp_packet_writer(void * o) memcpy(buf, &eid, sizeof(eid)); - pthread_cleanup_push(cleanup_sdb, sdb); + pthread_cleanup_push(cleanup_spb, spb); if (sendto(udp_data.s_fd, buf, len + OUR_HEADER_LEN, SENDTO_FLAGS, diff --git a/src/ipcpd/udp/udp4.c b/src/ipcpd/udp/udp4.c index 07d5f818..ff57bc09 100644 --- a/src/ipcpd/udp/udp4.c +++ b/src/ipcpd/udp/udp4.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process over UDP/IPv4 * diff --git a/src/ipcpd/udp/udp6.c b/src/ipcpd/udp/udp6.c index b7924a3f..2ceb95f0 100644 --- a/src/ipcpd/udp/udp6.c +++ b/src/ipcpd/udp/udp6.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * IPC process over UDP/IPv6 * diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt index a9155353..d3388112 100644 --- a/src/ipcpd/unicast/CMakeLists.txt +++ b/src/ipcpd/unicast/CMakeLists.txt @@ -1,42 +1,9 @@ -get_filename_component(CURRENT_SOURCE_PARENT_DIR - ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) -get_filename_component(CURRENT_BINARY_PARENT_DIR - ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +# Unicast IPCP build configuration -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +protobuf_generate_c(DHT_PROTO_SRCS DHT_PROTO_HDRS + "${CMAKE_CURRENT_SOURCE_DIR}/dir/dht.proto") -include_directories(${CURRENT_SOURCE_PARENT_DIR}) -include_directories(${CURRENT_BINARY_PARENT_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/include) -include_directories(${CMAKE_BINARY_DIR}/include) - -set(IPCP_UNICAST_TARGET ipcpd-unicast CACHE INTERNAL "") -set(IPCP_UNICAST_MPL 10000 CACHE STRING - "Default maximum packet lifetime for the unicast IPCP, in ms") -set(DEBUG_PROTO_DHT FALSE CACHE BOOL - "Add DHT protocol message output to debug logging") -set(DEBUG_PROTO_LS FALSE CACHE BOOL - "Add link state protocol message output to debug logging") - -protobuf_generate_c(DHT_PROTO_SRCS DHT_PROTO_HDRS dir/dht.proto) - -math(EXPR PFT_EXPR "1 << 12") -set(PFT_SIZE ${PFT_EXPR} CACHE STRING - "Size of the PDU forwarding table") -if (HAVE_FUSE) - set(IPCP_FLOW_STATS TRUE CACHE BOOL - "Enable flow statistics tracking in IPCP") - if (IPCP_FLOW_STATS) - message(STATUS "IPCP flow statistics enabled") - else () - message(STATUS "IPCP flow statistics disabled") - endif () -endif () - -set(IPCP_UNICAST_SOURCE_FILES - # Add source files here +set(UNICAST_SOURCES addr-auth.c ca.c connmgr.c @@ -47,7 +14,6 @@ set(IPCP_UNICAST_SOURCE_FILES pff.c routing.c psched.c - # Add policies last addr-auth/flat.c ca/mb-ecn.c ca/nop.c @@ -58,21 +24,26 @@ set(IPCP_UNICAST_SOURCE_FILES pff/pft.c routing/link-state.c routing/graph.c - ) +) + +add_executable(${IPCP_UNICAST_TARGET} + ${UNICAST_SOURCES} + ${IPCP_SOURCES} + ${COMMON_SOURCES} + ${DHT_PROTO_SRCS} +) -add_executable(ipcpd-unicast ${IPCP_UNICAST_SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES} - ${DHT_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS}) -target_link_libraries(ipcpd-unicast LINK_PUBLIC ouroboros-dev) +target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${IPCP_INCLUDE_DIRS}) +target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${IPCP_UNICAST_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(${IPCP_UNICAST_TARGET} PRIVATE ouroboros-dev) -include(AddCompileFlags) -if (CMAKE_BUILD_TYPE MATCHES "Debug*") - add_compile_flags(ipcpd-unicast -DCONFIG_OUROBOROS_DEBUG) -endif () +ouroboros_target_debug_definitions(${IPCP_UNICAST_TARGET}) -install(TARGETS ipcpd-unicast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) +install(TARGETS ${IPCP_UNICAST_TARGET} RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) if(BUILD_TESTS) + add_subdirectory(dir/tests) add_subdirectory(pff/tests) add_subdirectory(routing/tests) - add_subdirectory(dir/tests) -endif () +endif() diff --git a/src/ipcpd/unicast/addr-auth.c b/src/ipcpd/unicast/addr-auth.c index 908a4aa1..27671d09 100644 --- a/src/ipcpd/unicast/addr-auth.c +++ b/src/ipcpd/unicast/addr-auth.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Address authority * diff --git a/src/ipcpd/unicast/addr-auth.h b/src/ipcpd/unicast/addr-auth.h index 0d2cd4c0..65567dc3 100644 --- a/src/ipcpd/unicast/addr-auth.h +++ b/src/ipcpd/unicast/addr-auth.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Address authority * diff --git a/src/ipcpd/unicast/addr-auth/flat.c b/src/ipcpd/unicast/addr-auth/flat.c index 34ca1cef..cf832279 100644 --- a/src/ipcpd/unicast/addr-auth/flat.c +++ b/src/ipcpd/unicast/addr-auth/flat.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for flat addresses in a distributed way * diff --git a/src/ipcpd/unicast/addr-auth/flat.h b/src/ipcpd/unicast/addr-auth/flat.h index d4b672c7..b5c7e525 100644 --- a/src/ipcpd/unicast/addr-auth/flat.h +++ b/src/ipcpd/unicast/addr-auth/flat.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for flat addresses in a distributed way * diff --git a/src/ipcpd/unicast/addr-auth/ops.h b/src/ipcpd/unicast/addr-auth/ops.h index 06b24cec..f5c4c611 100644 --- a/src/ipcpd/unicast/addr-auth/ops.h +++ b/src/ipcpd/unicast/addr-auth/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Address authority policy ops * diff --git a/src/ipcpd/unicast/addr-auth/pol.h b/src/ipcpd/unicast/addr-auth/pol.h index 844308c6..a33f1dd6 100644 --- a/src/ipcpd/unicast/addr-auth/pol.h +++ b/src/ipcpd/unicast/addr-auth/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Address Authority policies * diff --git a/src/ipcpd/unicast/ca.c b/src/ipcpd/unicast/ca.c index 1fcc9bb2..a1751672 100644 --- a/src/ipcpd/unicast/ca.c +++ b/src/ipcpd/unicast/ca.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Congestion Avoidance * diff --git a/src/ipcpd/unicast/ca.h b/src/ipcpd/unicast/ca.h index ea803e17..47ea15a0 100644 --- a/src/ipcpd/unicast/ca.h +++ b/src/ipcpd/unicast/ca.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Congestion avoidance * diff --git a/src/ipcpd/unicast/ca/mb-ecn.c b/src/ipcpd/unicast/ca/mb-ecn.c index d9a204b0..b310c4fc 100644 --- a/src/ipcpd/unicast/ca/mb-ecn.c +++ b/src/ipcpd/unicast/ca/mb-ecn.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Multi-bit ECN Congestion Avoidance * diff --git a/src/ipcpd/unicast/ca/mb-ecn.h b/src/ipcpd/unicast/ca/mb-ecn.h index 9a2c8b49..1be27764 100644 --- a/src/ipcpd/unicast/ca/mb-ecn.h +++ b/src/ipcpd/unicast/ca/mb-ecn.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Multi-bit ECN Congestion Avoidance * diff --git a/src/ipcpd/unicast/ca/nop.c b/src/ipcpd/unicast/ca/nop.c index 617fc15b..e5cacf66 100644 --- a/src/ipcpd/unicast/ca/nop.c +++ b/src/ipcpd/unicast/ca/nop.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Dummy Congestion Avoidance * diff --git a/src/ipcpd/unicast/ca/nop.h b/src/ipcpd/unicast/ca/nop.h index 248b198d..8b892e61 100644 --- a/src/ipcpd/unicast/ca/nop.h +++ b/src/ipcpd/unicast/ca/nop.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Dummy Congestion Avoidance * diff --git a/src/ipcpd/unicast/ca/ops.h b/src/ipcpd/unicast/ca/ops.h index 3a7b7248..6d2ddf1d 100644 --- a/src/ipcpd/unicast/ca/ops.h +++ b/src/ipcpd/unicast/ca/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Congestion avoidance policy ops * diff --git a/src/ipcpd/unicast/ca/pol.h b/src/ipcpd/unicast/ca/pol.h index db0a1a11..bfb9cc2d 100644 --- a/src/ipcpd/unicast/ca/pol.h +++ b/src/ipcpd/unicast/ca/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Congestion avoidance policies * diff --git a/src/ipcpd/unicast/connmgr.c b/src/ipcpd/unicast/connmgr.c index 07568fb5..f60f6fca 100644 --- a/src/ipcpd/unicast/connmgr.c +++ b/src/ipcpd/unicast/connmgr.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Handles connections between components * diff --git a/src/ipcpd/unicast/dir.c b/src/ipcpd/unicast/dir.c index 2b305626..a31a562f 100644 --- a/src/ipcpd/unicast/dir.c +++ b/src/ipcpd/unicast/dir.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Directory Management * diff --git a/src/ipcpd/unicast/dir.h b/src/ipcpd/unicast/dir.h index dbfde19f..2be7b10f 100644 --- a/src/ipcpd/unicast/dir.h +++ b/src/ipcpd/unicast/dir.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Directory * diff --git a/src/ipcpd/unicast/dir/dht.c b/src/ipcpd/unicast/dir/dht.c index 6b06def9..8eeea800 100644 --- a/src/ipcpd/unicast/dir/dht.c +++ b/src/ipcpd/unicast/dir/dht.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Distributed Hash Table based on Kademlia * @@ -148,15 +148,8 @@ struct dht_entry { uint8_t * key; - struct { - struct list_head list; - size_t len; - } vals; /* We don't own these, only replicate */ - - struct { - struct list_head list; - size_t len; - } lvals; /* We own these, must be republished */ + struct llist vals; /* We don't own these, only replicate */ + struct llist lvals; /* We own these, must be republished */ }; struct contact { @@ -183,38 +176,24 @@ struct peer_entry { struct dht_req { struct list_head next; - uint8_t * key; - time_t t_exp; + uint8_t * key; + time_t t_exp; - struct { - struct list_head list; - size_t len; - } peers; - - struct { - struct list_head list; - size_t len; - } cache; + struct llist peers; + struct llist cache; }; struct bucket { - struct { - struct list_head list; - size_t len; - } contacts; + struct llist contacts; + struct llist alts; - struct { - struct list_head list; - size_t len; - } alts; + time_t t_refr; - time_t t_refr; + size_t depth; + uint8_t mask; - size_t depth; - uint8_t mask; - - struct bucket * parent; - struct bucket * children[1L << DHT_BETA]; + struct bucket * parent; + struct bucket * children[1L << DHT_BETA]; }; struct cmd { @@ -236,8 +215,8 @@ struct { struct { /* Kademlia parameters */ uint32_t alpha; /* Number of concurrent requests */ size_t k; /* Number of replicas to store */ - time_t t_expire; /* Expiry time for values (s) */ - time_t t_refresh; /* Refresh time for contacts (s) */ + time_t t_exp; /* Expiry time for values (s) */ + time_t t_refr; /* Refresh time for contacts (s) */ time_t t_repl; /* Replication time for values (s) */ }; @@ -261,8 +240,7 @@ struct { } contacts; struct { - struct list_head list; - size_t len; + struct llist ll; size_t vals; size_t lvals; } kv; @@ -271,10 +249,9 @@ struct { } db; struct { - struct list_head list; - size_t len; - pthread_cond_t cond; - pthread_mutex_t mtx; + struct llist ll; + pthread_cond_t cond; + pthread_mutex_t mtx; } reqs; struct { @@ -321,7 +298,7 @@ static int dht_rib_statfile(char * buf, pthread_rwlock_rdlock(&dht.db.lock); - keys = dht.db.kv.len; + keys = dht.db.kv.ll.len; lvals = dht.db.kv.lvals; vals = dht.db.kv.vals; @@ -335,7 +312,7 @@ static int dht_rib_statfile(char * buf, tmstr, ADDR_VAL32(&dht.addr), dht.alpha, dht.k, - dht.t_expire, dht.t_refresh, dht.t_repl, + dht.t_exp, dht.t_refr, dht.t_repl, keys, vals, lvals); return strlen(buf); @@ -350,14 +327,14 @@ static size_t dht_db_file_len(void) pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) { + if (llist_is_empty(&dht.db.kv.ll)) { pthread_rwlock_unlock(&dht.db.lock); sz += 14; /* No entries */ return sz; } sz += 39 * 3 + 1; /* tally + extra newline */ - sz += dht.db.kv.len * (25 + 19 + 23 + 1); + sz += dht.db.kv.ll.len * (25 + 19 + 23 + 1); vals = dht.db.kv.vals + dht.db.kv.lvals; @@ -382,7 +359,7 @@ static int dht_rib_dbfile(char * buf, pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) { + if (llist_is_empty(&dht.db.kv.ll)) { i += snprintf(buf, len, " No entries.\n"); pthread_rwlock_unlock(&dht.db.lock); return i; @@ -393,9 +370,9 @@ static int dht_rib_dbfile(char * buf, "Number of keys: %10zu\n" "Number of local values: %10zu\n" "Number of non-local values: %10zu\n\n", - dht.db.kv.len, dht.db.kv.vals, dht.db.kv.lvals); + dht.db.kv.ll.len, dht.db.kv.vals, dht.db.kv.lvals); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); struct list_head * h; @@ -403,7 +380,7 @@ static int dht_rib_dbfile(char * buf, KEY_VAL(e->key)); i += snprintf(buf + i, len - i, " Local entries:\n"); - list_for_each(h, &e->vals.list) { + llist_for_each(h, &e->vals) { struct val_entry * v; v = list_entry(h, struct val_entry, next); @@ -416,7 +393,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " " VAL_FMT - ", t_replicated=%.*s, t_expire=%.*s\n", + ", t_replicated=%.*s, t_exp=%.*s\n", VAL_VAL(v->val), RIB_TM_STRLEN, tmstr, RIB_TM_STRLEN, exstr); @@ -426,7 +403,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " Non-local entries:\n"); - list_for_each(h, &e->lvals.list) { + llist_for_each(h, &e->lvals) { struct val_entry * v; v= list_entry(h, struct val_entry, next); @@ -439,7 +416,7 @@ static int dht_rib_dbfile(char * buf, i += snprintf(buf + i, len - i, " " VAL_FMT - ", t_replicated=%.*s, t_expire=%.*s\n", + ", t_replicated=%.*s, t_exp=%.*s\n", VAL_VAL(v->val), RIB_TM_STRLEN, tmstr, RIB_TM_STRLEN, exstr); @@ -694,11 +671,8 @@ static struct dht_entry * dht_entry_create(const uint8_t * key) goto fail_entry; list_head_init(&e->next); - list_head_init(&e->vals.list); - list_head_init(&e->lvals.list); - - e->vals.len = 0; - e->lvals.len = 0; + llist_init(&e->vals); + llist_init(&e->lvals); e->key = dht_dup_key(key); if (e->key == NULL) @@ -718,25 +692,23 @@ static void dht_entry_destroy(struct dht_entry * e) assert(e != NULL); - list_for_each_safe(p, h, &e->vals.list) { + llist_for_each_safe(p, h, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); - list_del(&v->next); + llist_del(&v->next, &e->vals); val_entry_destroy(v); - --e->vals.len; --dht.db.kv.vals; } - list_for_each_safe(p, h, &e->lvals.list) { + llist_for_each_safe(p, h, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); - list_del(&v->next); + llist_del(&v->next, &e->lvals); val_entry_destroy(v); - --e->lvals.len; --dht.db.kv.lvals; } free(e->key); - assert(e->vals.len == 0 && e->lvals.len == 0); + assert(llist_is_empty(&e->vals) && llist_is_empty(&e->lvals)); free(e); } @@ -750,7 +722,7 @@ static struct val_entry * dht_entry_get_lval(const struct dht_entry * e, assert(val.data != NULL); assert(val.len > 0); - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (bufcmp(&v->val, &val) == 0) return v; @@ -768,7 +740,7 @@ static struct val_entry * dht_entry_get_val(const struct dht_entry * e, assert(val.data != NULL); assert(val.len > 0); - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (bufcmp(&v->val, &val) == 0) return v; @@ -805,8 +777,7 @@ static int dht_entry_update_val(struct dht_entry * e, if (v == NULL) return -ENOMEM; - list_add_tail(&v->next, &e->vals.list); - ++e->vals.len; + llist_add_tail(&v->next, &e->vals); ++dht.db.kv.vals; return 0; @@ -833,12 +804,11 @@ static int dht_entry_update_lval(struct dht_entry * e, v = dht_entry_get_lval(e, val); if (v == NULL) { log_dbg(KV_FMT " Adding lval.", KV_VAL(e->key, val)); - v = val_entry_create(val, now.tv_sec + dht.t_expire); + v = val_entry_create(val, now.tv_sec + dht.t_exp); if (v == NULL) return -ENOMEM; - list_add_tail(&v->next, &e->lvals.list); - ++e->lvals.len; + llist_add_tail(&v->next, &e->lvals); ++dht.db.kv.lvals; return 0; @@ -862,9 +832,8 @@ static int dht_entry_remove_lval(struct dht_entry * e, log_dbg(KV_FMT " Removing lval.", KV_VAL(e->key, val)); - list_del(&v->next); + llist_del(&v->next, &e->lvals); val_entry_destroy(v); - --e->lvals.len; --dht.db.kv.lvals; return 0; @@ -881,15 +850,14 @@ static void dht_entry_remove_expired_vals(struct dht_entry * e) clock_gettime(CLOCK_REALTIME_COARSE, &now); - list_for_each_safe(p, h, &e->vals.list) { + llist_for_each_safe(p, h, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (!IS_EXPIRED(v, &now)) continue; log_dbg(KV_FMT " Value expired." , KV_VAL(e->key, v->val)); - list_del(&v->next); + llist_del(&v->next, &e->vals); val_entry_destroy(v); - --e->vals.len; --dht.db.kv.vals; } } @@ -900,7 +868,7 @@ static struct dht_entry * __dht_kv_find_entry(const uint8_t * key) assert(key != NULL); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); if (!memcmp(key, e->key, dht.id.len)) return e; @@ -919,16 +887,15 @@ static void dht_kv_remove_expired_entries(void) pthread_rwlock_wrlock(&dht.db.lock); - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); dht_entry_remove_expired_vals(e); if (e->lvals.len > 0 || e->vals.len > 0) continue; log_dbg(KEY_FMT " Entry removed. ", KEY_VAL(e->key)); - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } pthread_rwlock_unlock(&dht.db.lock); @@ -987,15 +954,13 @@ static struct dht_req * dht_req_create(const uint8_t * key) req->t_exp = now.tv_sec + DHT_T_RESP; - list_head_init(&req->peers.list); - req->peers.len = 0; + llist_init(&req->peers); req->key = dht_dup_key(key); if (req->key == NULL) goto fail_dup_key; - list_head_init(&req->cache.list); - req->cache.len = 0; + llist_init(&req->cache); return req; @@ -1013,34 +978,32 @@ static void dht_req_destroy(struct dht_req * req) assert(req); assert(req->key); - list_for_each_safe(p, h, &req->peers.list) { + llist_for_each_safe(p, h, &req->peers) { struct peer_entry * e = list_entry(p, struct peer_entry, next); - list_del(&e->next); + llist_del(&e->next, &req->peers); free(e->id); free(e); - --req->peers.len; } - list_for_each_safe(p, h, &req->cache.list) { + llist_for_each_safe(p, h, &req->cache) { struct val_entry * e = list_entry(p, struct val_entry, next); - list_del(&e->next); + llist_del(&e->next, &req->cache); val_entry_destroy(e); - --req->cache.len; } free(req->key); - assert(req->peers.len == 0); + assert(llist_is_empty(&req->peers)); free(req); } -static struct peer_entry * dht_req_get_peer(struct dht_req * req, - struct peer_entry * e) +static struct peer_entry * dht_req_get_peer(struct dht_req * req, + const struct peer_entry * e) { struct list_head * p; - list_for_each(p, &req->peers.list) { + llist_for_each(p, &req->peers) { struct peer_entry * x = list_entry(p, struct peer_entry, next); if (x->addr == e->addr) return x; @@ -1050,8 +1013,8 @@ static struct peer_entry * dht_req_get_peer(struct dht_req * req, } #define IS_MAGIC(peer) ((peer)->cookie == dht.magic) -void dht_req_add_peer(struct dht_req * req, - struct peer_entry * e) +static int dht_req_add_peer(struct dht_req * req, + const struct peer_entry * e) { struct peer_entry * x; /* existing */ struct list_head * p; /* iterator */ @@ -1063,16 +1026,17 @@ void dht_req_add_peer(struct dht_req * req, /* * Dedupe messages to the same peer, unless - * 1) The previous request was FIND_NODE and now it's FIND_VALUE - * 2) We urgently need contacts from emergency peer (magic cookie) + * 1) The previous was FIND_NODE and now it's FIND_VALUE + * 2) We urgently need contacts (magic cookie) */ x = dht_req_get_peer(req, e); if (x != NULL && x->code >= e->code && !IS_MAGIC(e)) - goto skip; + return -1; /* Find how this contact ranks in distance to the key */ - list_for_each(p, &req->peers.list) { - struct peer_entry * y = list_entry(p, struct peer_entry, next); + llist_for_each(p, &req->peers) { + struct peer_entry * y; + y = list_entry(p, struct peer_entry, next); if (IS_CLOSER(y->id, e->id)) { pos++; continue; @@ -1080,36 +1044,32 @@ void dht_req_add_peer(struct dht_req * req, break; } - /* Add a new peer to this request if we need to */ - if (pos < dht.alpha || !IS_MAGIC(e)) { - x = malloc(sizeof(*x)); - if (x == NULL) { - log_err("Failed to malloc peer entry."); - goto skip; - } + if (pos >= dht.alpha && IS_MAGIC(e)) + return -1; - x->cookie = e->cookie; - x->addr = e->addr; - x->code = e->code; - x->t_sent = e->t_sent; - x->id = dht_dup_key(e->id); - if (x->id == NULL) { - log_err("Failed to dup peer ID."); - free(x); - goto skip; - } + x = malloc(sizeof(*x)); + if (x == NULL) { + log_err("Failed to malloc peer entry."); + return -1; + } - if (IS_MAGIC(e)) - list_add(&x->next, p); - else - list_add_tail(&x->next, p); - ++req->peers.len; - return; + x->cookie = e->cookie; + x->addr = e->addr; + x->code = e->code; + x->t_sent = e->t_sent; + x->id = dht_dup_key(e->id); + if (x->id == NULL) { + log_err("Failed to dup peer ID."); + free(x); + return -1; } - skip: - list_del(&e->next); - free(e->id); - free(e); + + if (IS_MAGIC(e)) + llist_add_at(&x->next, p, &req->peers); + else + llist_add_tail_at(&x->next, p, &req->peers); + + return 0; } static size_t dht_req_add_peers(struct dht_req * req, @@ -1123,8 +1083,13 @@ static size_t dht_req_add_peers(struct dht_req * req, assert(pl != NULL); list_for_each_safe(p, h, pl) { - struct peer_entry * e = list_entry(p, struct peer_entry, next); - dht_req_add_peer(req, e); + struct peer_entry * e; + e = list_entry(p, struct peer_entry, next); + if (dht_req_add_peer(req, e) < 0) { + list_del(&e->next); + free(e->id); + free(e); + } } return n; @@ -1137,7 +1102,7 @@ static bool dht_req_has_peer(struct dht_req * req, assert(req != NULL); - list_for_each(p, &req->peers.list) { + llist_for_each(p, &req->peers) { struct peer_entry * e = list_entry(p, struct peer_entry, next); if (e->cookie == cookie) return true; @@ -1209,7 +1174,7 @@ static struct dht_req * __dht_kv_req_get_req(const uint8_t * key) { struct list_head * p; - list_for_each(p, &dht.reqs.list) { + llist_for_each(p, &dht.reqs.ll) { struct dht_req * r = list_entry(p, struct dht_req, next); if (memcmp(r->key, key, dht.id.len) == 0) return r; @@ -1228,7 +1193,7 @@ static struct dht_req * __dht_kv_get_req_cache(const uint8_t * key) if (req == NULL) return NULL; - if (req->cache.len == 0) + if (llist_is_empty(&req->cache)) return NULL; return req; @@ -1244,8 +1209,7 @@ static void __dht_kv_req_remove(const uint8_t * key) if (req == NULL) return; - list_del(&req->next); - --dht.reqs.len; + llist_del(&req->next, &dht.reqs.ll); dht_req_destroy(req); } @@ -1301,9 +1265,9 @@ static int dht_kv_update_req(const uint8_t * key, req = __dht_kv_req_get_req(key); if (req == NULL) { - if (dht.reqs.len == DHT_MAX_REQS) { + if (dht.reqs.ll.len == DHT_MAX_REQS) { log_err(KEY_FMT " Max reqs reached (%zu).", - KEY_VAL(key), dht.reqs.len); + KEY_VAL(key), dht.reqs.ll.len); peer_list_destroy(pl); goto fail_req; } @@ -1312,8 +1276,7 @@ static int dht_kv_update_req(const uint8_t * key, log_err(KEY_FMT "Failed to create req.", KEY_VAL(key)); goto fail_req; } - list_add_tail(&req->next, &dht.reqs.list); - ++dht.reqs.len; + llist_add_tail(&req->next, &dht.reqs.ll); } if (req->cache.len > 0) /* Already have values */ @@ -1322,9 +1285,9 @@ static int dht_kv_update_req(const uint8_t * key, dht_req_add_peers(req, pl); req->t_exp = now.tv_sec + DHT_T_RESP; - if (dht.reqs.len > DHT_WARN_REQS) { + if (dht.reqs.ll.len > DHT_WARN_REQS) { log_warn("Number of outstanding requests (%zu) exceeds %u.", - dht.reqs.len, DHT_WARN_REQS); + dht.reqs.ll.len, DHT_WARN_REQS); } pthread_mutex_unlock(&dht.reqs.mtx); @@ -1368,8 +1331,7 @@ static int dht_kv_respond_req(uint8_t * key, continue; } - list_add_tail(&e->next, &req->cache.list); - ++req->cache.len; + llist_add_tail(&e->next, &req->cache); } pthread_cond_broadcast(&dht.reqs.cond); @@ -1434,7 +1396,7 @@ static ssize_t dht_kv_wait_req(const uint8_t * key, memset(*vals, 0, max * sizeof(**vals)); - list_for_each(p, &req->cache.list) { + llist_for_each(p, &req->cache) { struct val_entry * v; if (i == max) break; /* We have enough values */ @@ -1535,10 +1497,10 @@ static ssize_t dht_kv_contact_list(const uint8_t * key, goto fail_bucket; } - b->t_refr = t.tv_sec + dht.t_refresh; + b->t_refr = t.tv_sec + dht.t_refr; if (b->contacts.len == dht.k || b->parent == NULL) { - list_for_each(p, &b->contacts.list) { + llist_for_each(p, &b->contacts) { struct contact * c; struct contact * d; c = list_entry(p, struct contact, next); @@ -1554,7 +1516,7 @@ static ssize_t dht_kv_contact_list(const uint8_t * key, } else { struct bucket * d = b->parent; for (i = 0; i < (1L << DHT_BETA) && len < dht.k; ++i) { - list_for_each(p, &d->children[i]->contacts.list) { + llist_for_each(p, &d->children[i]->contacts) { struct contact * c; struct contact * d; c = list_entry(p, struct contact, next); @@ -1661,11 +1623,11 @@ static void __dht_kv_bucket_refresh_list(struct bucket * b, __dht_kv_bucket_refresh_list(b->children[i], t, r); } - if (b->contacts.len == 0) + if (llist_is_empty(&b->contacts)) return; - c = list_first_entry(&b->contacts.list, struct contact, next); - if (t > c->t_seen + dht.t_refresh) { + c = llist_first_entry(&b->contacts, struct contact, next); + if (t > c->t_seen + dht.t_refr) { d = contact_create(c->id, c->addr); if (d != NULL) list_add(&d->next, r); @@ -1682,14 +1644,12 @@ static struct bucket * bucket_create(void) if (b == NULL) return NULL; - list_head_init(&b->contacts.list); - b->contacts.len = 0; + llist_init(&b->contacts); - list_head_init(&b->alts.list); - b->alts.len = 0; + llist_init(&b->alts); clock_gettime(CLOCK_REALTIME_COARSE, &t); - b->t_refr = t.tv_sec + dht.t_refresh; + b->t_refr = t.tv_sec + dht.t_refr; for (i = 0; i < (1L << DHT_BETA); ++i) b->children[i] = NULL; @@ -1713,18 +1673,16 @@ static void bucket_destroy(struct bucket * b) if (b->children[i] != NULL) bucket_destroy(b->children[i]); - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { struct contact * c = list_entry(p, struct contact, next); - list_del(&c->next); + llist_del(&c->next, &b->contacts); contact_destroy(c); - --b->contacts.len; } - list_for_each_safe(p, h, &b->alts.list) { + llist_for_each_safe(p, h, &b->alts) { struct contact * c = list_entry(p, struct contact, next); - list_del(&c->next); + llist_del(&c->next, &b->alts); contact_destroy(c); - --b->alts.len; } free(b); @@ -1759,13 +1717,11 @@ static int move_contacts(struct bucket * b, assert(b != NULL); assert(c != NULL); - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { d = list_entry(p, struct contact, next); if (bucket_has_id(c, d->id)) { - list_del(&d->next); - --b->contacts.len; - list_add_tail(&d->next, &c->contacts.list); - ++c->contacts.len; + llist_del(&d->next, &b->contacts); + llist_add_tail(&d->next, &c->contacts); } } @@ -1779,8 +1735,8 @@ static int split_bucket(struct bucket * b) size_t b_len; assert(b); - assert(b->alts.len == 0); - assert(b->contacts.len != 0); + assert(llist_is_empty(&b->alts)); + assert(!llist_is_empty(&b->contacts)); assert(b->children[0] == NULL); b_len = b->contacts.len; @@ -1836,39 +1792,33 @@ static int dht_kv_update_contacts(const uint8_t * id, goto fail_update; } - list_for_each_safe(p, h, &b->contacts.list) { + llist_for_each_safe(p, h, &b->contacts) { struct contact * d = list_entry(p, struct contact, next); if (d->addr == addr) { - list_del(&d->next); + llist_del(&d->next, &b->contacts); contact_destroy(d); - --b->contacts.len; } } if (b->contacts.len == dht.k) { if (bucket_has_id(b, dht.id.data)) { - list_add_tail(&c->next, &b->contacts.list); - ++b->contacts.len; + llist_add_tail(&c->next, &b->contacts); if (split_bucket(b)) { - list_del(&c->next); + llist_del(&c->next, &b->contacts); contact_destroy(c); - --b->contacts.len; } } else if (b->alts.len == dht.k) { struct contact * d; - d = list_first_entry(&b->alts.list, + d = llist_first_entry(&b->alts, struct contact, next); - list_del(&d->next); + llist_del(&d->next, &b->alts); contact_destroy(d); - list_add_tail(&c->next, &b->alts.list); - ++b->alts.len; + llist_add_tail(&c->next, &b->alts); } else { - list_add_tail(&c->next, &b->alts.list); - ++b->alts.len; + llist_add_tail(&c->next, &b->alts); } } else { - list_add_tail(&c->next, &b->contacts.list); - ++b->contacts.len; + llist_add_tail(&c->next, &b->contacts); } pthread_rwlock_unlock(&dht.db.lock); @@ -2116,7 +2066,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key, i = 0; - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v; if (i == n) break; /* We have enough values */ @@ -2129,7 +2079,7 @@ static ssize_t dht_kv_retrieve(const uint8_t * key, memcpy((*vals)[i++].data, v->val.data, v->val.len); } - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v; if (i == n) break; /* We have enough values */ @@ -2266,7 +2216,7 @@ static int dht_send_msg(dht_msg_t * msg, uint64_t addr) { size_t len; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; if (msg == NULL) return 0; @@ -2279,21 +2229,21 @@ static int dht_send_msg(dht_msg_t * msg, goto fail_msg; } - if (ipcp_sdb_reserve(&sdb, len)) { - log_warn("%s failed to get sdb.", DHT_CODE(msg)); + if (ipcp_spb_reserve(&spb, len)) { + log_warn("%s failed to get spb.", DHT_CODE(msg)); goto fail_msg; } - dht_msg__pack(msg, shm_du_buff_head(sdb)); + dht_msg__pack(msg, ssm_pk_buff_head(spb)); - if (dt_write_packet(addr, QOS_CUBE_BE, dht.eid, sdb) < 0) { + if (dt_write_packet(addr, QOS_CUBE_BE, dht.eid, spb) < 0) { log_warn("%s write failed", DHT_CODE(msg)); goto fail_send; } return 0; fail_send: - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); fail_msg: return -1; } @@ -2584,15 +2534,14 @@ static void __add_dht_kv_entry(struct dht_entry * e) assert(e != NULL); - list_for_each(p, &dht.db.kv.list) { + llist_for_each(p, &dht.db.kv.ll) { struct dht_entry * d = list_entry(p, struct dht_entry, next); if (IS_CLOSER(d->key, e->key)) continue; break; } - list_add_tail(&e->next, p); - ++dht.db.kv.len; + llist_add_tail_at(&e->next, p, &dht.db.kv.ll); } /* incoming store message */ @@ -2629,9 +2578,8 @@ static int dht_kv_store(const uint8_t * key, return 0; fail_add: if (new) { - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } fail: pthread_rwlock_unlock(&dht.db.lock); @@ -2669,14 +2617,13 @@ static int dht_kv_publish(const uint8_t * key, pthread_rwlock_unlock(&dht.db.lock); - dht_kv_store_remote(key, val, now.tv_sec + dht.t_expire); + dht_kv_store_remote(key, val, now.tv_sec + dht.t_exp); return 0; fail_add: if (new) { - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - --dht.db.kv.len; } fail: pthread_rwlock_unlock(&dht.db.lock); @@ -2858,7 +2805,7 @@ static void do_dht_kv_store(const dht_store_msg_t * store) key = store->key.data; exp = store->exp; - if (dht_kv_store(store->key.data, val, store->exp) < 0) { + if (dht_kv_store(key, val, store->exp) < 0) { log_err(KV_FMT " Failed to store.", KV_VAL(key, val)); return; } @@ -3189,7 +3136,7 @@ static void * dht_handle_packet(void * o) } #ifndef __DHT_TEST__ static void dht_post_packet(void * comp, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct cmd * cmd; @@ -3201,17 +3148,17 @@ static void dht_post_packet(void * comp, goto fail_cmd; } - cmd->cbuf.data = malloc(shm_du_buff_len(sdb)); + cmd->cbuf.data = malloc(ssm_pk_buff_len(spb)); if (cmd->cbuf.data == NULL) { log_err("Command buffer malloc failed."); goto fail_buf; } - cmd->cbuf.len = shm_du_buff_len(sdb); + cmd->cbuf.len = ssm_pk_buff_len(spb); - memcpy(cmd->cbuf.data, shm_du_buff_head(sdb), cmd->cbuf.len); + memcpy(cmd->cbuf.data, ssm_pk_buff_head(spb), cmd->cbuf.len); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); pthread_mutex_lock(&dht.cmds.mtx); @@ -3226,7 +3173,7 @@ static void dht_post_packet(void * comp, fail_buf: free(cmd); fail_cmd: - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return; } #endif @@ -3449,15 +3396,14 @@ static void dht_kv_remove_expired_reqs(void) pthread_mutex_lock(&dht.reqs.mtx); - list_for_each_safe(p, h, &dht.reqs.list) { + llist_for_each_safe(p, h, &dht.reqs.ll) { struct dht_req * e; e = list_entry(p, struct dht_req, next); if (IS_EXPIRED(e, &now)) { log_dbg(KEY_FMT " Removing expired request.", KEY_VAL(e->key)); - list_del(&e->next); + llist_del(&e->next, &dht.reqs.ll); dht_req_destroy(e); - --dht.reqs.len; } } @@ -3489,7 +3435,7 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e, struct list_head * p; struct val_entry * n; - list_for_each(p, &e->vals.list) { + llist_for_each(p, &e->vals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (MUST_REPLICATE(v, now) && !IS_EXPIRED(v, now)) { n = val_entry_create(v->val, v->t_exp); @@ -3500,11 +3446,11 @@ static void dht_entry_get_repl_lists(const struct dht_entry * e, } } - list_for_each(p, &e->lvals.list) { + llist_for_each(p, &e->lvals) { struct val_entry * v = list_entry(p, struct val_entry, next); if (MUST_REPLICATE(v, now) && MUST_REPUBLISH(v, now)) { /* Add expire time here, to allow creating val_entry */ - n = val_entry_create(v->val, now->tv_sec + dht.t_expire); + n = val_entry_create(v->val, now->tv_sec + dht.t_exp); if (n == NULL) continue; @@ -3533,10 +3479,10 @@ static int dht_kv_next_values(uint8_t * key, pthread_rwlock_rdlock(&dht.db.lock); - if (dht.db.kv.len == 0) + if (llist_is_empty(&dht.db.kv.ll)) goto no_entries; - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { e = list_entry(p, struct dht_entry, next); if (IS_CLOSER(e->key, key)) continue; /* Already processed */ @@ -3578,7 +3524,7 @@ static void dht_kv_republish_value(const uint8_t * key, assert(MUST_REPLICATE(v, now)); if (MUST_REPUBLISH(v, now)) - assert(v->t_exp >= now->tv_sec + dht.t_expire); + assert(v->t_exp >= now->tv_sec + dht.t_exp); if (dht_kv_store_remote(key, v->val, v->t_exp) == 0) { log_dbg(KV_FMT " Republished.", KV_VAL(key, v->val)); @@ -3786,8 +3732,8 @@ static void * work(void * o) nanosleep(&now, NULL); } - intv = gcd(dht.t_expire, (dht.t_expire - DHT_N_REPUB * dht.t_repl)); - intv = gcd(intv, gcd(dht.t_repl, dht.t_refresh)) / 2; + intv = gcd(dht.t_exp, (dht.t_exp - DHT_N_REPUB * dht.t_repl)); + intv = gcd(intv, gcd(dht.t_repl, dht.t_refr)) / 2; intv = MAX(1, intv / n); log_dbg("DHT worker starting %ld seconds interval.", intv * n); @@ -3868,13 +3814,13 @@ int dht_init(struct dir_dht_config * conf) dht.id.len = DHT_TEST_KEY_LEN; dht.addr = DHT_TEST_ADDR; #endif - dht.t0 = now.tv_sec; - dht.alpha = conf->params.alpha; - dht.k = conf->params.k; - dht.t_expire = conf->params.t_expire; - dht.t_refresh = conf->params.t_refresh; - dht.t_repl = conf->params.t_replicate; - dht.peer = conf->peer; + dht.t0 = now.tv_sec; + dht.alpha = conf->params.alpha; + dht.k = conf->params.k; + dht.t_exp = conf->params.t_expire; + dht.t_refr = conf->params.t_refresh; + dht.t_repl = conf->params.t_replicate; + dht.peer = conf->peer; dht.magic = generate_cookie(); @@ -3899,8 +3845,7 @@ int dht_init(struct dir_dht_config * conf) goto fail_cmds_cond; } - list_head_init(&dht.reqs.list); - dht.reqs.len = 0; + llist_init(&dht.reqs.ll); if (pthread_mutex_init(&dht.reqs.mtx, NULL)) { log_err("Failed to initialize request mutex."); @@ -3922,8 +3867,7 @@ int dht_init(struct dir_dht_config * conf) goto fail_reqs_cond; } - list_head_init(&dht.db.kv.list); - dht.db.kv.len = 0; + llist_init(&dht.db.kv.ll); dht.db.kv.vals = 0; dht.db.kv.lvals = 0; @@ -3960,9 +3904,9 @@ int dht_init(struct dir_dht_config * conf) log_dbg(" address: " ADDR_FMT32 ".", ADDR_VAL32(&dht.addr)); log_dbg(" peer: " ADDR_FMT32 ".", ADDR_VAL32(&dht.peer)); log_dbg(" magic cookie: " HASH_FMT64 ".", HASH_VAL64(&dht.magic)); - log_info(" parameters: alpha=%u, k=%zu, t_expire=%ld, " - "t_refresh=%ld, t_replicate=%ld.", - dht.alpha, dht.k, dht.t_expire, dht.t_refresh, dht.t_repl); + log_info(" parameters: alpha=%u, k=%zu, t_exp=%ld, " + "t_refr=%ld, t_replicate=%ld.", + dht.alpha, dht.k, dht.t_exp, dht.t_refr, dht.t_repl); #endif dht.state = DHT_INIT; @@ -4015,11 +3959,10 @@ void dht_fini(void) pthread_mutex_lock(&dht.reqs.mtx); - list_for_each_safe(p, h, &dht.reqs.list) { + llist_for_each_safe(p, h, &dht.reqs.ll) { struct dht_req * r = list_entry(p, struct dht_req, next); - list_del(&r->next); + llist_del(&r->next, &dht.reqs.ll); dht_req_destroy(r); - dht.reqs.len--; } pthread_mutex_unlock(&dht.reqs.mtx); @@ -4029,11 +3972,10 @@ void dht_fini(void) pthread_rwlock_wrlock(&dht.db.lock); - list_for_each_safe(p, h, &dht.db.kv.list) { + llist_for_each_safe(p, h, &dht.db.kv.ll) { struct dht_entry * e = list_entry(p, struct dht_entry, next); - list_del(&e->next); + llist_del(&e->next, &dht.db.kv.ll); dht_entry_destroy(e); - dht.db.kv.len--; } if (dht.db.contacts.root != NULL) @@ -4043,10 +3985,10 @@ void dht_fini(void) pthread_rwlock_destroy(&dht.db.lock); - assert(dht.db.kv.len == 0); + assert(llist_is_empty(&dht.db.kv.ll)); assert(dht.db.kv.vals == 0); assert(dht.db.kv.lvals == 0); - assert(dht.reqs.len == 0); + assert(llist_is_empty(&dht.reqs.ll)); freebuf(dht.id); } diff --git a/src/ipcpd/unicast/dir/dht.h b/src/ipcpd/unicast/dir/dht.h index 852a5130..ed3bb9f0 100644 --- a/src/ipcpd/unicast/dir/dht.h +++ b/src/ipcpd/unicast/dir/dht.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Distributed Hash Table based on Kademlia * diff --git a/src/ipcpd/unicast/dir/dht.proto b/src/ipcpd/unicast/dir/dht.proto index ea74805f..02b6b341 100644 --- a/src/ipcpd/unicast/dir/dht.proto +++ b/src/ipcpd/unicast/dir/dht.proto @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * DHT protocol, based on Kademlia * diff --git a/src/ipcpd/unicast/dir/ops.h b/src/ipcpd/unicast/dir/ops.h index 8c6e5eb5..6c336ee0 100644 --- a/src/ipcpd/unicast/dir/ops.h +++ b/src/ipcpd/unicast/dir/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Directory policy ops * diff --git a/src/ipcpd/unicast/dir/pol.h b/src/ipcpd/unicast/dir/pol.h index eae4b2e7..8ccf4f95 100644 --- a/src/ipcpd/unicast/dir/pol.h +++ b/src/ipcpd/unicast/dir/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Directory policies * diff --git a/src/ipcpd/unicast/dir/tests/CMakeLists.txt b/src/ipcpd/unicast/dir/tests/CMakeLists.txt index 897f1ec2..eded823f 100644 --- a/src/ipcpd/unicast/dir/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/dir/tests/CMakeLists.txt @@ -3,38 +3,36 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR 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) +compute_test_prefix() + create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here dht_test.c - ) +) -protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ../dht.proto) +protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ${CURRENT_SOURCE_PARENT_DIR}/dht.proto) add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests} ${DHT_PROTO_SRCS}) -target_link_libraries(${PARENT_DIR}_test ouroboros-common) -add_dependencies(check ${PARENT_DIR}_test) +target_include_directories(${PARENT_DIR}_test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CURRENT_SOURCE_PARENT_DIR} + ${CURRENT_BINARY_PARENT_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include + ${CMAKE_SOURCE_DIR}/src/ipcpd + ${CMAKE_BINARY_DIR}/src/ipcpd + ${CMAKE_SOURCE_DIR}/src/ipcpd/unicast + ${CMAKE_BINARY_DIR}/src/ipcpd/unicast +) + +disable_test_logging_for_target(${PARENT_DIR}_test) -set(tests_to_run ${${PARENT_DIR}_tests}) -if(CMAKE_VERSION VERSION_LESS "3.29.0") - remove(tests_to_run test_suite.c) -else () - list(POP_FRONT tests_to_run) -endif() +target_link_libraries(${PARENT_DIR}_test ouroboros-common) +add_dependencies(build_tests ${PARENT_DIR}_test) -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) +ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/dir/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c index cb6b0f9f..1f7026b3 100644 --- a/src/ipcpd/unicast/dir/tests/dht_test.c +++ b/src/ipcpd/unicast/dir/tests/dht_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Unit tests of the DHT * @@ -27,7 +27,7 @@ #define _POSIX_C_SOURCE 200112L #endif -#include <ouroboros/test.h> +#include <test/test.h> #include <ouroboros/list.h> #include <ouroboros/utils.h> @@ -46,10 +46,9 @@ /* forward declare for use in the dht code */ /* Packet sink for DHT tests */ struct { - bool enabled; + bool enabled; - struct list_head list; - size_t len; + struct llist msgs; } sink; struct message { @@ -66,8 +65,6 @@ static int sink_send_msg(buffer_t * pkt, assert(pkt != NULL); assert(addr != 0); - assert(!list_is_empty(&sink.list) || sink.len == 0); - if (!sink.enabled) goto finish; @@ -83,9 +80,8 @@ static int sink_send_msg(buffer_t * pkt, m->dst = addr; - list_add_tail(&m->next, &sink.list); + llist_add_tail(&m->next, &sink.msgs); - ++sink.len; finish: freebuf(*pkt); @@ -103,8 +99,7 @@ static int sink_send_msg(buffer_t * pkt, static void sink_init(void) { - list_head_init(&sink.list); - sink.len = 0; + llist_init(&sink.msgs); sink.enabled = true; } @@ -113,22 +108,20 @@ static void sink_clear(void) struct list_head * p; struct list_head * h; - list_for_each_safe(p, h, &sink.list) { + llist_for_each_safe(p, h, &sink.msgs) { struct message * m = list_entry(p, struct message, next); - list_del(&m->next); + llist_del(&m->next, &sink.msgs); dht_msg__free_unpacked((dht_msg_t *) m->msg, NULL); free(m); - --sink.len; } - assert(list_is_empty(&sink.list)); + assert(llist_is_empty(&sink.msgs)); } static void sink_fini(void) { sink_clear(); - - assert(list_is_empty(&sink.list) || sink.len != 0); + sink.enabled = false; } static dht_msg_t * sink_read(void) @@ -136,16 +129,12 @@ static dht_msg_t * sink_read(void) struct message * m; dht_msg_t * msg; - assert(!list_is_empty(&sink.list) || sink.len == 0); - - if (list_is_empty(&sink.list)) + if (llist_is_empty(&sink.msgs)) return NULL; - m = list_first_entry(&sink.list, struct message, next); - - --sink.len; + m = llist_first_entry(&sink.msgs, struct message, next); - list_del(&m->next); + llist_del(&m->next, &sink.msgs); msg = m->msg; @@ -978,7 +967,7 @@ static int test_dht_kv_find_node_rsp_msg_contacts(void) } if ((size_t) n < dht.k) { - printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k); + printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k); goto fail_fill; } @@ -1204,7 +1193,7 @@ static int test_dht_kv_find_value_rsp_msg_contacts(void) } if ((size_t) n < dht.k) { - printf("Failed to get enough contacts (%zu < %zu).\n", n, dht.k); + printf("Failed to get all contacts (%zu < %zu).\n", n, dht.k); goto fail_fill; } @@ -1591,7 +1580,7 @@ static int test_dht_reg_unreg(void) goto fail_reg; } - if (sink.len != 0) { + if (!llist_is_empty(&sink.msgs)) { printf("Packet sent without contacts!"); goto fail_msg; } @@ -1642,7 +1631,7 @@ static int test_dht_reg_unreg_contacts(void) goto fail_reg; } - if (sink.len != dht.alpha) { + if (sink.msgs.len != dht.alpha) { printf("Packet sent to too few contacts!\n"); goto fail_msg; } @@ -1784,7 +1773,7 @@ static int test_dht_query(void) goto fail_get; } - if (sink.len != 0) { + if (!llist_is_empty(&sink.msgs)) { printf("Packet sent without contacts!"); goto fail_test; } diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c index e2679ffe..252477f4 100644 --- a/src/ipcpd/unicast/dt.c +++ b/src/ipcpd/unicast/dt.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Data Transfer Component * @@ -68,7 +68,7 @@ #endif struct comp_info { - void (* post_packet)(void * comp, struct shm_du_buff * sdb); + void (* post_packet)(void * comp, struct ssm_pk_buff * spb); void * comp; char * name; }; @@ -135,11 +135,11 @@ static void dt_pci_des(uint8_t * head, memcpy(&dt_pci->eid, head + dt_pci_info.eid_o, dt_pci_info.eid_size); } -static void dt_pci_shrink(struct shm_du_buff * sdb) +static void dt_pci_shrink(struct ssm_pk_buff * spb) { - assert(sdb); + assert(spb); - shm_du_buff_head_release(sdb, dt_pci_info.head_size); + ssm_pk_buff_head_release(spb, dt_pci_info.head_size); } struct { @@ -429,7 +429,7 @@ static void handle_event(void * self, static void packet_handler(int fd, qoscube_t qc, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct dt_pci dt_pci; int ret; @@ -437,7 +437,7 @@ static void packet_handler(int fd, uint8_t * head; size_t len; - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); #ifndef IPCP_FLOW_STATS (void) fd; @@ -451,13 +451,13 @@ static void packet_handler(int fd, #endif memset(&dt_pci, 0, sizeof(dt_pci)); - head = shm_du_buff_head(sdb); + head = ssm_pk_buff_head(spb); dt_pci_des(head, &dt_pci); if (dt_pci.dst_addr != dt.addr) { if (dt_pci.ttl == 0) { log_dbg("TTL was zero."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); #ifdef IPCP_FLOW_STATS pthread_mutex_lock(&dt.stat[fd].lock); @@ -474,7 +474,7 @@ static void packet_handler(int fd, if (ofd < 0) { log_dbg("No next hop for %" PRIu64 ".", dt_pci.dst_addr); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); #ifdef IPCP_FLOW_STATS pthread_mutex_lock(&dt.stat[fd].lock); @@ -488,12 +488,12 @@ static void packet_handler(int fd, (void) ca_calc_ecn(ofd, head + dt_pci_info.ecn_o, qc, len); - ret = ipcp_flow_write(ofd, sdb); + ret = ipcp_flow_write(ofd, spb); if (ret < 0) { log_dbg("Failed to write packet to fd %d.", ofd); if (ret == -EFLOWDOWN) notifier_event(NOTIFY_DT_FLOW_DOWN, &ofd); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); #ifdef IPCP_FLOW_STATS pthread_mutex_lock(&dt.stat[ofd].lock); @@ -513,17 +513,17 @@ static void packet_handler(int fd, pthread_mutex_unlock(&dt.stat[ofd].lock); #endif } else { - dt_pci_shrink(sdb); + dt_pci_shrink(spb); if (dt_pci.eid >= PROG_RES_FDS) { uint8_t ecn = *(head + dt_pci_info.ecn_o); - fa_np1_rcv(dt_pci.eid, ecn, sdb); + fa_np1_rcv(dt_pci.eid, ecn, spb); return; } if (dt.comps[dt_pci.eid].post_packet == NULL) { log_err("No registered component on eid %" PRIu64 ".", dt_pci.eid); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return; } #ifdef IPCP_FLOW_STATS @@ -541,7 +541,7 @@ static void packet_handler(int fd, pthread_mutex_unlock(&dt.stat[dt_pci.eid].lock); #endif dt.comps[dt_pci.eid].post_packet(dt.comps[dt_pci.eid].comp, - sdb); + spb); } } @@ -758,7 +758,7 @@ void dt_stop(void) } int dt_reg_comp(void * comp, - void (* func)(void * func, struct shm_du_buff *), + void (* func)(void * func, struct ssm_pk_buff *), char * name) { int eid; @@ -809,7 +809,7 @@ void dt_unreg_comp(int eid) int dt_write_packet(uint64_t dst_addr, qoscube_t qc, uint64_t eid, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct dt_pci dt_pci; int fd; @@ -817,12 +817,12 @@ int dt_write_packet(uint64_t dst_addr, uint8_t * head; size_t len; - assert(sdb); + assert(spb); assert(dst_addr != dt.addr); - len = shm_du_buff_len(sdb); - #ifdef IPCP_FLOW_STATS + len = ssm_pk_buff_len(spb); + if (eid < PROG_RES_FDS) { pthread_mutex_lock(&dt.stat[eid].lock); @@ -849,13 +849,13 @@ int dt_write_packet(uint64_t dst_addr, return -EPERM; } - head = shm_du_buff_head_alloc(sdb, dt_pci_info.head_size); + head = ssm_pk_buff_head_alloc(spb, dt_pci_info.head_size); if (head == NULL) { log_dbg("Failed to allocate DT header."); goto fail_write; } - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); dt_pci.dst_addr = dst_addr; dt_pci.qc = qc; @@ -866,7 +866,7 @@ int dt_write_packet(uint64_t dst_addr, dt_pci_ser(head, &dt_pci); - ret = ipcp_flow_write(fd, sdb); + ret = ipcp_flow_write(fd, spb); if (ret < 0) { log_dbg("Failed to write packet to fd %d.", fd); if (ret == -EFLOWDOWN) diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h index 2c5b7978..a484377d 100644 --- a/src/ipcpd/unicast/dt.h +++ b/src/ipcpd/unicast/dt.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Data Transfer component * @@ -25,7 +25,7 @@ #include <ouroboros/ipcp.h> #include <ouroboros/qoscube.h> -#include <ouroboros/shm_rdrbuff.h> +#include <ouroboros/ssm_pool.h> #define DT_COMP "Data Transfer" #define DT_PROTO "dtp" @@ -40,7 +40,7 @@ int dt_start(void); void dt_stop(void); int dt_reg_comp(void * comp, - void (* func)(void * comp, struct shm_du_buff * sdb), + void (* func)(void * comp, struct ssm_pk_buff * spb), char * name); void dt_unreg_comp(int eid); @@ -48,6 +48,6 @@ void dt_unreg_comp(int eid); int dt_write_packet(uint64_t dst_addr, qoscube_t qc, uint64_t eid, - struct shm_du_buff * sdb); + struct ssm_pk_buff * spb); #endif /* OUROBOROS_IPCPD_UNICAST_DT_H */ diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c index ac168bd9..ddf78e22 100644 --- a/src/ipcpd/unicast/fa.c +++ b/src/ipcpd/unicast/fa.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Flow allocator of the IPC Process * @@ -48,6 +48,7 @@ #include "ipcp.h" #include "dt.h" #include "ca.h" +#include "np1.h" #include <inttypes.h> #include <stdlib.h> @@ -85,7 +86,7 @@ struct fa_msg { struct cmd { struct list_head next; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; }; struct fa_flow { @@ -330,7 +331,7 @@ static uint64_t gen_eid(int fd) static void packet_handler(int fd, qoscube_t qc, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct fa_flow * flow; uint64_t r_addr; @@ -342,7 +343,7 @@ static void packet_handler(int fd, pthread_rwlock_wrlock(&fa.flows_lock); - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); #ifdef IPCP_FLOW_STATS ++flow->p_snd; @@ -357,8 +358,8 @@ static void packet_handler(int fd, ca_wnd_wait(wnd); - if (dt_write_packet(r_addr, qc, r_eid, sdb)) { - ipcp_sdb_release(sdb); + if (dt_write_packet(r_addr, qc, r_eid, spb)) { + ipcp_spb_release(spb); log_dbg("Failed to forward packet."); #ifdef IPCP_FLOW_STATS pthread_rwlock_wrlock(&fa.flows_lock); @@ -411,7 +412,7 @@ static void fa_flow_fini(struct fa_flow * flow) } static void fa_post_packet(void * comp, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct cmd * cmd; @@ -422,11 +423,11 @@ static void fa_post_packet(void * comp, cmd = malloc(sizeof(*cmd)); if (cmd == NULL) { log_err("Command failed. Out of memory."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return; } - cmd->sdb = sdb; + cmd->spb = spb; pthread_mutex_lock(&fa.mtx); @@ -454,16 +455,16 @@ static size_t fa_wait_for_fa_msg(struct fa_msg * msg) pthread_cleanup_pop(true); - len = shm_du_buff_len(cmd->sdb); + len = ssm_pk_buff_len(cmd->spb); if (len > MSGBUFSZ || len < sizeof(*msg)) { log_warn("Invalid flow allocation message (len: %zd).", len); free(cmd); return 0; /* No valid message */ } - memcpy(msg, shm_du_buff_head(cmd->sdb), len); + memcpy(msg, ssm_pk_buff_head(cmd->spb), len); - ipcp_sdb_release(cmd->sdb); + ipcp_spb_release(cmd->spb); free(cmd); @@ -687,13 +688,21 @@ void fa_fini(void) pthread_rwlock_destroy(&fa.flows_lock); } +static int np1_flow_read_fa(int fd, + struct ssm_pk_buff ** spb) +{ + return np1_flow_read(fd, spb, NP1_GET_POOL(fd)); +} + int fa_start(void) { +#ifndef BUILD_CONTAINER struct sched_param par; int pol; int max; +#endif - fa.psched = psched_create(packet_handler, np1_flow_read); + fa.psched = psched_create(packet_handler, np1_flow_read_fa); if (fa.psched == NULL) { log_err("Failed to start packet scheduler."); goto fail_psched; @@ -704,6 +713,7 @@ int fa_start(void) goto fail_thread; } +#ifndef BUILD_CONTAINER if (pthread_getschedparam(fa.worker, &pol, &par)) { log_err("Failed to get worker thread scheduling parameters."); goto fail_sched; @@ -721,12 +731,15 @@ int fa_start(void) log_err("Failed to set scheduler priority to maximum."); goto fail_sched; } +#endif return 0; +#ifndef BUILD_CONTAINER fail_sched: pthread_cancel(fa.worker); pthread_join(fa.worker, NULL); +#endif fail_thread: psched_destroy(fa.psched); fail_psched: @@ -747,7 +760,7 @@ int fa_alloc(int fd, const buffer_t * data) { struct fa_msg * msg; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; struct fa_flow * flow; uint64_t addr; qoscube_t qc = QOS_CUBE_BE; @@ -760,10 +773,10 @@ int fa_alloc(int fd, len = sizeof(*msg) + ipcp_dir_hash_len(); - if (ipcp_sdb_reserve(&sdb, len + data->len)) + if (ipcp_spb_reserve(&spb, len + data->len)) return -1; - msg = (struct fa_msg *) shm_du_buff_head(sdb); + msg = (struct fa_msg *) ssm_pk_buff_head(spb); memset(msg, 0, sizeof(*msg)); eid = gen_eid(fd); @@ -782,11 +795,11 @@ int fa_alloc(int fd, memcpy(msg + 1, dst, ipcp_dir_hash_len()); if (data->len > 0) - memcpy(shm_du_buff_head(sdb) + len, data->data, data->len); + memcpy(ssm_pk_buff_head(spb) + len, data->data, data->len); - if (dt_write_packet(addr, qc, fa.eid, sdb)) { + if (dt_write_packet(addr, qc, fa.eid, spb)) { log_err("Failed to send flow allocation request packet."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return -1; } @@ -808,7 +821,7 @@ int fa_alloc_resp(int fd, const buffer_t * data) { struct fa_msg * msg; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; struct fa_flow * flow; qoscube_t qc = QOS_CUBE_BE; @@ -819,13 +832,13 @@ int fa_alloc_resp(int fd, goto fail_alloc_resp; } - if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + data->len)) { - log_err("Failed to reserve sdb (%zu bytes).", + if (ipcp_spb_reserve(&spb, sizeof(*msg) + data->len)) { + log_err("Failed to reserve spb (%zu bytes).", sizeof(*msg) + data->len); goto fail_reserve; } - msg = (struct fa_msg *) shm_du_buff_head(sdb); + msg = (struct fa_msg *) ssm_pk_buff_head(spb); memset(msg, 0, sizeof(*msg)); msg->code = FLOW_REPLY; @@ -840,7 +853,7 @@ int fa_alloc_resp(int fd, pthread_rwlock_unlock(&fa.flows_lock); - if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) { + if (dt_write_packet(flow->r_addr, qc, fa.eid, spb)) { log_err("Failed to send flow allocation response packet."); goto fail_packet; } @@ -856,7 +869,7 @@ int fa_alloc_resp(int fd, return 0; fail_packet: - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); fail_reserve: pthread_rwlock_wrlock(&fa.flows_lock); fa_flow_fini(flow); @@ -887,17 +900,17 @@ static int fa_update_remote(int fd, uint16_t ece) { struct fa_msg * msg; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; qoscube_t qc = QOS_CUBE_BE; struct fa_flow * flow; uint64_t r_addr; - if (ipcp_sdb_reserve(&sdb, sizeof(*msg))) { - log_err("Failed to reserve sdb (%zu bytes).", sizeof(*msg)); + if (ipcp_spb_reserve(&spb, sizeof(*msg))) { + log_err("Failed to reserve spb (%zu bytes).", sizeof(*msg)); return -1; } - msg = (struct fa_msg *) shm_du_buff_head(sdb); + msg = (struct fa_msg *) ssm_pk_buff_head(spb); memset(msg, 0, sizeof(*msg)); @@ -916,9 +929,9 @@ static int fa_update_remote(int fd, pthread_rwlock_unlock(&fa.flows_lock); - if (dt_write_packet(r_addr, qc, fa.eid, sdb)) { + if (dt_write_packet(r_addr, qc, fa.eid, spb)) { log_err("Failed to send flow update packet."); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return -1; } @@ -927,7 +940,7 @@ static int fa_update_remote(int fd, void fa_np1_rcv(uint64_t eid, uint8_t ecn, - struct shm_du_buff * sdb) + struct ssm_pk_buff * spb) { struct fa_flow * flow; bool update; @@ -935,7 +948,7 @@ void fa_np1_rcv(uint64_t eid, int fd; size_t len; - len = shm_du_buff_len(sdb); + len = ssm_pk_buff_len(spb); pthread_rwlock_wrlock(&fa.flows_lock); @@ -943,7 +956,7 @@ void fa_np1_rcv(uint64_t eid, if (fd < 0) { pthread_rwlock_unlock(&fa.flows_lock); log_dbg("Received packet for unknown EID %" PRIu64 ".", eid); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); return; } @@ -957,9 +970,9 @@ void fa_np1_rcv(uint64_t eid, pthread_rwlock_unlock(&fa.flows_lock); - if (ipcp_flow_write(fd, sdb) < 0) { + if (np1_flow_write(fd, spb, NP1_GET_POOL(fd)) < 0) { log_dbg("Failed to write to flow %d.", fd); - ipcp_sdb_release(sdb); + ipcp_spb_release(spb); #ifdef IPCP_FLOW_STATS pthread_rwlock_wrlock(&fa.flows_lock); ++flow->p_rcv_f; diff --git a/src/ipcpd/unicast/fa.h b/src/ipcpd/unicast/fa.h index 1e716966..0c19dc25 100644 --- a/src/ipcpd/unicast/fa.h +++ b/src/ipcpd/unicast/fa.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Flow allocator of the IPC Process * @@ -47,6 +47,6 @@ int fa_dealloc(int fd); void fa_np1_rcv(uint64_t eid, uint8_t ecn, - struct shm_du_buff * sdb); + struct ssm_pk_buff * spb); #endif /* OUROBOROS_IPCPD_UNICAST_FA_H */ diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c index 7989d3e1..583a04ff 100644 --- a/src/ipcpd/unicast/main.c +++ b/src/ipcpd/unicast/main.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Unicast IPC Process * diff --git a/src/ipcpd/unicast/pff.c b/src/ipcpd/unicast/pff.c index 9b2aa2b4..c8c3126f 100644 --- a/src/ipcpd/unicast/pff.c +++ b/src/ipcpd/unicast/pff.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * PDU Forwarding Function * diff --git a/src/ipcpd/unicast/pff.h b/src/ipcpd/unicast/pff.h index f44e5531..2eb42ce6 100644 --- a/src/ipcpd/unicast/pff.h +++ b/src/ipcpd/unicast/pff.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * PDU Forwarding Function * diff --git a/src/ipcpd/unicast/pff/alternate.c b/src/ipcpd/unicast/pff/alternate.c index 85e85914..be1c35c0 100644 --- a/src/ipcpd/unicast/pff/alternate.c +++ b/src/ipcpd/unicast/pff/alternate.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for PFF with alternate next hops * diff --git a/src/ipcpd/unicast/pff/alternate.h b/src/ipcpd/unicast/pff/alternate.h index 96207e74..ae3758dc 100644 --- a/src/ipcpd/unicast/pff/alternate.h +++ b/src/ipcpd/unicast/pff/alternate.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for PFF with alternate next hops * diff --git a/src/ipcpd/unicast/pff/multipath.c b/src/ipcpd/unicast/pff/multipath.c index cbab0f5f..c636e789 100644 --- a/src/ipcpd/unicast/pff/multipath.c +++ b/src/ipcpd/unicast/pff/multipath.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for PFF supporting multipath routing * diff --git a/src/ipcpd/unicast/pff/multipath.h b/src/ipcpd/unicast/pff/multipath.h index 0eb03476..5329f7fc 100644 --- a/src/ipcpd/unicast/pff/multipath.h +++ b/src/ipcpd/unicast/pff/multipath.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Policy for PFF supporting multipath routing * diff --git a/src/ipcpd/unicast/pff/ops.h b/src/ipcpd/unicast/pff/ops.h index 16a31273..e4cabd11 100644 --- a/src/ipcpd/unicast/pff/ops.h +++ b/src/ipcpd/unicast/pff/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Pff policy ops * diff --git a/src/ipcpd/unicast/pff/pft.c b/src/ipcpd/unicast/pff/pft.c index 8c436113..a0d70799 100644 --- a/src/ipcpd/unicast/pff/pft.c +++ b/src/ipcpd/unicast/pff/pft.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Packet forwarding table (PFT) with chaining on collisions * diff --git a/src/ipcpd/unicast/pff/pft.h b/src/ipcpd/unicast/pff/pft.h index 711dabcb..3bb9cff7 100644 --- a/src/ipcpd/unicast/pff/pft.h +++ b/src/ipcpd/unicast/pff/pft.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Packet forwarding table (PFT) with chaining on collisions * diff --git a/src/ipcpd/unicast/pff/pol.h b/src/ipcpd/unicast/pff/pol.h index 245b03c4..e31c2794 100644 --- a/src/ipcpd/unicast/pff/pol.h +++ b/src/ipcpd/unicast/pff/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * PDU Forwarding Function policies * diff --git a/src/ipcpd/unicast/pff/simple.c b/src/ipcpd/unicast/pff/simple.c index 5f95e3ce..be542bdb 100644 --- a/src/ipcpd/unicast/pff/simple.c +++ b/src/ipcpd/unicast/pff/simple.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Simple PDU Forwarding Function * diff --git a/src/ipcpd/unicast/pff/simple.h b/src/ipcpd/unicast/pff/simple.h index 0966a186..1046e4c4 100644 --- a/src/ipcpd/unicast/pff/simple.h +++ b/src/ipcpd/unicast/pff/simple.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Simple policy for PFF * diff --git a/src/ipcpd/unicast/pff/tests/CMakeLists.txt b/src/ipcpd/unicast/pff/tests/CMakeLists.txt index 99c32e7a..8c0e3d51 100644 --- a/src/ipcpd/unicast/pff/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/pff/tests/CMakeLists.txt @@ -3,36 +3,32 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR 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) +compute_test_prefix() + create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here pft_test.c ) add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests}) -target_link_libraries(${PARENT_DIR}_test ouroboros-common) -add_dependencies(check ${PARENT_DIR}_test) +target_include_directories(${PARENT_DIR}_test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CURRENT_SOURCE_PARENT_DIR} + ${CURRENT_BINARY_PARENT_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include + ${CMAKE_SOURCE_DIR}/src/ipcpd + ${CMAKE_BINARY_DIR}/src/ipcpd +) + +disable_test_logging_for_target(${PARENT_DIR}_test) +target_link_libraries(${PARENT_DIR}_test PRIVATE ouroboros-common) -set(tests_to_run ${${PARENT_DIR}_tests}) -if(CMAKE_VERSION VERSION_LESS "3.29.0") - remove(tests_to_run test_suite.c) -else () - list(POP_FRONT tests_to_run) -endif() +add_dependencies(build_tests ${PARENT_DIR}_test) -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) +ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/pff/tests/pft_test.c b/src/ipcpd/unicast/pff/tests/pft_test.c index 18287fb8..4962c241 100644 --- a/src/ipcpd/unicast/pff/tests/pft_test.c +++ b/src/ipcpd/unicast/pff/tests/pft_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Test of the hash table * diff --git a/src/ipcpd/unicast/psched.c b/src/ipcpd/unicast/psched.c index 7e12148b..21e23617 100644 --- a/src/ipcpd/unicast/psched.c +++ b/src/ipcpd/unicast/psched.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Packet scheduler component * @@ -41,11 +41,13 @@ #include <stdlib.h> #include <string.h> +#ifndef BUILD_CONTAINER static int qos_prio [] = { QOS_PRIO_BE, QOS_PRIO_VIDEO, QOS_PRIO_VOICE, }; +#endif struct psched { fset_t * set[QOS_CUBE_MAX]; @@ -67,7 +69,7 @@ static void cleanup_reader(void * o) static void * packet_reader(void * o) { struct psched * sched; - struct shm_du_buff * sdb; + struct ssm_pk_buff * spb; int fd; fqueue_t * fq; qoscube_t qc; @@ -102,10 +104,10 @@ static void * packet_reader(void * o) notifier_event(NOTIFY_DT_FLOW_UP, &fd); break; case FLOW_PKT: - if (sched->read(fd, &sdb) < 0) + if (sched->read(fd, &spb) < 0) continue; - sched->callback(fd, qc, sdb); + sched->callback(fd, qc, spb); break; default: break; @@ -168,6 +170,7 @@ struct psched * psched_create(next_packet_fn_t callback, } } +#ifndef BUILD_CONTAINER for (i = 0; i < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++i) { struct sched_param par; int pol = SCHED_RR; @@ -185,14 +188,17 @@ struct psched * psched_create(next_packet_fn_t callback, if (pthread_setschedparam(psched->readers[i], pol, &par)) goto fail_sched; } +#endif return psched; +#ifndef BUILD_CONTAINER fail_sched: for (j = 0; j < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++j) pthread_cancel(psched->readers[j]); for (j = 0; j < QOS_CUBE_MAX * IPCP_SCHED_THR_MUL; ++j) pthread_join(psched->readers[j], NULL); +#endif fail_infos: for (j = 0; j < QOS_CUBE_MAX; ++j) fset_destroy(psched->set[j]); diff --git a/src/ipcpd/unicast/psched.h b/src/ipcpd/unicast/psched.h index 831f8084..d83bb793 100644 --- a/src/ipcpd/unicast/psched.h +++ b/src/ipcpd/unicast/psched.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Packet scheduler component * @@ -28,10 +28,10 @@ typedef void (* next_packet_fn_t)(int fd, qoscube_t qc, - struct shm_du_buff * sdb); + struct ssm_pk_buff * spb); typedef int (* read_fn_t)(int fd, - struct shm_du_buff ** sdb); + struct ssm_pk_buff ** spb); struct psched * psched_create(next_packet_fn_t callback, read_fn_t read); diff --git a/src/ipcpd/unicast/routing.c b/src/ipcpd/unicast/routing.c index 2ad7b234..1a4e4372 100644 --- a/src/ipcpd/unicast/routing.c +++ b/src/ipcpd/unicast/routing.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing component of the IPCP * diff --git a/src/ipcpd/unicast/routing.h b/src/ipcpd/unicast/routing.h index e14960b5..8d721095 100644 --- a/src/ipcpd/unicast/routing.h +++ b/src/ipcpd/unicast/routing.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing component of the IPCP * diff --git a/src/ipcpd/unicast/routing/graph.c b/src/ipcpd/unicast/routing/graph.c index 32442dad..0226c762 100644 --- a/src/ipcpd/unicast/routing/graph.c +++ b/src/ipcpd/unicast/routing/graph.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Undirected graph structure * @@ -57,10 +57,7 @@ struct edge { }; struct graph { - struct { - struct list_head list; - size_t len; - } vertices; + struct llist vertices; pthread_mutex_t lock; }; @@ -88,7 +85,7 @@ static struct vertex * find_vertex_by_addr(struct graph * graph, assert(graph); - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); if (e->addr == addr) return e; @@ -142,7 +139,7 @@ static struct vertex * add_vertex(struct graph * graph, vertex->addr = addr; /* Keep them ordered on address. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > addr) break; @@ -151,7 +148,7 @@ static struct vertex * add_vertex(struct graph * graph, vertex->index = i; - list_add_tail(&vertex->next, p); + llist_add_tail_at(&vertex->next, p, &graph->vertices); /* Increase the index of the vertices to the right. */ list_for_each(p, &vertex->next) { @@ -160,37 +157,41 @@ static struct vertex * add_vertex(struct graph * graph, v->index++; } - ++graph->vertices.len; - return vertex; } +static void free_edges(struct list_head * edges) +{ + struct list_head * p; + struct list_head * h; + + list_for_each_safe(p, h, edges) { + struct edge * e = list_entry(p, struct edge, next); + list_del(&e->next); + free(e); + } +} + static void del_vertex(struct graph * graph, struct vertex * vertex) { struct list_head * p; - struct list_head * h; assert(graph != NULL); assert(vertex != NULL); - list_del(&vertex->next); + llist_del(&vertex->next, &graph->vertices); /* Decrease the index of the vertices to the right. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { struct vertex * v = list_entry(p, struct vertex, next); if (v->addr > vertex->addr) v->index--; } - list_for_each_safe(p, h, &vertex->edges) { - struct edge * e = list_entry(p, struct edge, next); - del_edge(e); - } + free_edges(&vertex->edges); free(vertex); - - --graph->vertices.len; } struct graph * graph_create(void) @@ -206,8 +207,7 @@ struct graph * graph_create(void) return NULL; } - graph->vertices.len = 0; - list_head_init(&graph->vertices.list); + llist_init(&graph->vertices); return graph; } @@ -221,7 +221,7 @@ void graph_destroy(struct graph * graph) pthread_mutex_lock(&graph->lock); - list_for_each_safe(p, n, &graph->vertices.list) { + llist_for_each_safe(p, n, &graph->vertices) { struct vertex * e = list_entry(p, struct vertex, next); del_vertex(graph, e); } @@ -230,7 +230,7 @@ void graph_destroy(struct graph * graph) pthread_mutex_destroy(&graph->lock); - assert(graph->vertices.len == 0); + assert(llist_is_empty(&graph->vertices)); free(graph); } @@ -371,7 +371,7 @@ static int get_min_vertex(struct graph * graph, *v = NULL; - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { if (!used[i] && dist[i] < min) { min = dist[i]; index = i; @@ -420,7 +420,7 @@ static int dijkstra(struct graph * graph, memset(*nhops, 0, sizeof(**nhops) * graph->vertices.len); memset(*dist, 0, sizeof(**dist) * graph->vertices.len); - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); (*dist)[i++] = (v->addr == src) ? 0 : INT_MAX; } @@ -526,7 +526,7 @@ static int graph_routing_table_simple(struct graph * graph, list_head_init(table); /* Now construct the routing table from the nhops. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); /* This is the src */ @@ -624,7 +624,7 @@ static int graph_routing_table_lfa(struct graph * graph, addrs[j] = -1; } - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr != s_addr) @@ -650,7 +650,7 @@ static int graph_routing_table_lfa(struct graph * graph, } /* Loop though all nodes to see if we have a LFA for them. */ - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); if (v->addr == s_addr) @@ -695,7 +695,6 @@ static int graph_routing_table_ecmp(struct graph * graph, { struct vertex ** nhops; struct list_head * p; - struct list_head * h; size_t i; struct vertex * v; struct vertex * src_v; @@ -735,16 +734,15 @@ static int graph_routing_table_ecmp(struct graph * graph, free(nhops); - list_for_each(h, &graph->vertices.list) { - v = list_entry(h, struct vertex, next); - if (tmp_dist[v->index] + 1 == (*dist)[v->index]) { + for (i = 0; i < graph->vertices.len; ++i) { + if (tmp_dist[i] + 1 == (*dist)[i]) { n = malloc(sizeof(*n)); if (n == NULL) { free(tmp_dist); goto fail_src_v; } n->nhop = e->nb->addr; - list_add_tail(&n->next, &forwarding[v->index]); + list_add_tail(&n->next, &forwarding[i]); } } @@ -753,38 +751,34 @@ static int graph_routing_table_ecmp(struct graph * graph, list_head_init(table); i = 0; - list_for_each(p, &graph->vertices.list) { + llist_for_each(p, &graph->vertices) { v = list_entry(p, struct vertex, next); - if (v->addr == s_addr) { + if (v->addr == s_addr || list_is_empty(&forwarding[i])) { ++i; continue; } t = malloc(sizeof(*t)); if (t == NULL) - goto fail_t; + goto fail_malloc; t->dst = v->addr; list_head_init(&t->nhops); - if (&forwarding[i] != forwarding[i].nxt) { - t->nhops.nxt = forwarding[i].nxt; - t->nhops.prv = forwarding[i].prv; - forwarding[i].prv->nxt = &t->nhops; - forwarding[i].nxt->prv = &t->nhops; - } + t->nhops.nxt = forwarding[i].nxt; + t->nhops.prv = forwarding[i].prv; + forwarding[i].prv->nxt = &t->nhops; + forwarding[i].nxt->prv = &t->nhops; list_add(&t->next, table); ++i; } - free(*dist); - *dist = NULL; free(forwarding); return 0; - fail_t: + fail_malloc: free_routing_table(table); fail_src_v: free(*dist); diff --git a/src/ipcpd/unicast/routing/graph.h b/src/ipcpd/unicast/routing/graph.h index 8190cc6c..f3766771 100644 --- a/src/ipcpd/unicast/routing/graph.h +++ b/src/ipcpd/unicast/routing/graph.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Undirected graph structure * diff --git a/src/ipcpd/unicast/routing/link-state.c b/src/ipcpd/unicast/routing/link-state.c index e5edf539..051dd98d 100644 --- a/src/ipcpd/unicast/routing/link-state.c +++ b/src/ipcpd/unicast/routing/link-state.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Link state routing policy * @@ -56,7 +56,7 @@ #include <string.h> #define LS_ENTRY_SIZE 104 -#define LSDB "lsdb" +#define lsdb "lsdb" #ifndef CLOCK_REALTIME_COARSE #define CLOCK_REALTIME_COARSE CLOCK_REALTIME @@ -121,16 +121,8 @@ struct { struct graph * graph; struct { - struct { - struct list_head list; - size_t len; - } nbs; - - struct { - struct list_head list; - size_t len; - } db; - + struct llist nbs; + struct llist db; pthread_rwlock_t lock; }; @@ -189,7 +181,7 @@ static struct adjacency * get_adj(const char * path) assert(path); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); if (strcmp(entry, path) == 0) @@ -245,7 +237,7 @@ static int lsdb_rib_read(const char * path, pthread_rwlock_rdlock(&ls.lock); - if (ls.db.len + ls.nbs.len == 0) + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) goto fail; a = get_adj(entry); @@ -274,7 +266,7 @@ static int lsdb_rib_readdir(char *** buf) pthread_rwlock_rdlock(&ls.lock); - if (ls.db.len + ls.nbs.len == 0) { + if (llist_is_empty(&ls.db) && llist_is_empty(&ls.nbs)) { *buf = NULL; goto no_entries; } @@ -284,7 +276,7 @@ static int lsdb_rib_readdir(char *** buf) if (*buf == NULL) goto fail_entries; - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); char * str = (nb->type == NB_DT ? ".dt " : ".mgmt "); sprintf(entry, "%s" ADDR_FMT32 , str, ADDR_VAL32(&nb->addr)); @@ -295,7 +287,7 @@ static int lsdb_rib_readdir(char *** buf) strcpy((*buf)[idx++], entry); } - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); sprintf(entry, LINK_FMT, LINK_VAL(a->src, a->dst)); (*buf)[idx] = malloc(strlen(entry) + 1); @@ -333,7 +325,7 @@ static int lsdb_add_nb(uint64_t addr, pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * el = list_entry(p, struct nb, next); if (addr > el->addr) break; @@ -360,9 +352,7 @@ static int lsdb_add_nb(uint64_t addr, nb->fd = fd; nb->type = type; - list_add_tail(&nb->next, p); - - ++ls.nbs.len; + llist_add_tail_at(&nb->next, p, &ls.nbs); log_dbg("Type %s neighbor " ADDR_FMT32 " added.", nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); @@ -380,13 +370,12 @@ static int lsdb_del_nb(uint64_t addr, pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.nbs.list) { + llist_for_each_safe(p, h, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->addr != addr || nb->fd != fd) continue; - list_del(&nb->next); - --ls.nbs.len; + llist_del(&nb->next, &ls.nbs); pthread_rwlock_unlock(&ls.lock); log_dbg("Type %s neighbor " ADDR_FMT32 " deleted.", nb->type == NB_DT ? "dt" : "mgmt", ADDR_VAL32(&addr)); @@ -406,7 +395,7 @@ static int nbr_to_fd(uint64_t addr) pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->addr == addr && nb->type == NB_DT) { fd = nb->fd; @@ -494,7 +483,7 @@ static int lsdb_add_link(uint64_t src, pthread_rwlock_wrlock(&ls.lock); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { if (a->seqno < seqno) { @@ -521,9 +510,7 @@ static int lsdb_add_link(uint64_t src, adj->seqno = seqno; adj->stamp = now.tv_sec; - list_add_tail(&adj->next, p); - - ls.db.len++; + llist_add_tail_at(&adj->next, p, &ls.db); if (graph_update_edge(ls.graph, src, dst, *qs)) log_warn("Failed to add edge to graph."); @@ -543,15 +530,13 @@ static int lsdb_del_link(uint64_t src, pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); if (a->dst == dst && a->src == src) { - list_del(&a->next); + llist_del(&a->next, &ls.db); if (graph_del_edge(ls.graph, src, dst)) log_warn("Failed to delete edge from graph."); - ls.db.len--; - pthread_rwlock_unlock(&ls.lock); set_pff_modified(false); free(a); @@ -599,7 +584,7 @@ static void send_lsm(uint64_t src, lsm.s_addr = hton64(src); lsm.seqno = hton64(seqno); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->type != NB_MGMT) continue; @@ -628,7 +613,7 @@ static void lsdb_replicate(int fd) /* Lock the lsdb, copy the lsms and send outside of lock. */ pthread_rwlock_rdlock(&ls.lock); - list_for_each(p, &ls.db.list) { + llist_for_each(p, &ls.db) { struct adjacency * adj; struct adjacency * cpy; adj = list_entry(p, struct adjacency, next); @@ -675,11 +660,11 @@ static void * lsupdate(void * o) pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * adj; adj = list_entry(p, struct adjacency, next); if (now.tv_sec > adj->stamp + ls.conf.t_timeo) { - list_del(&adj->next); + llist_del(&adj->next, &ls.db); log_dbg(LINK_FMT " timed out.", LINK_VAL(adj->src, adj->dst)); if (graph_del_edge(ls.graph, adj->src, @@ -746,7 +731,7 @@ static void forward_lsm(uint8_t * buf, pthread_cleanup_push(__cleanup_rwlock_unlock, &ls.lock); - list_for_each(p, &ls.nbs.list) { + llist_for_each(p, &ls.nbs) { struct nb * nb = list_entry(p, struct nb, next); if (nb->type != NB_MGMT || nb->fd == in_fd) continue; @@ -874,19 +859,19 @@ static void handle_event(void * self, pthread_cleanup_pop(true); if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_DT)) - log_dbg("Failed to add neighbor to LSDB."); + log_dbg("Failed to add neighbor to lsdb."); if (lsdb_add_link(ls.addr, c->conn_info.addr, 0, &qs)) - log_dbg("Failed to add new adjacency to LSDB."); + log_dbg("Failed to add new adjacency to lsdb."); break; case NOTIFY_DT_CONN_DEL: flow_event(c->flow_info.fd, false); if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd)) - log_dbg("Failed to delete neighbor from LSDB."); + log_dbg("Failed to delete neighbor from lsdb."); if (lsdb_del_link(ls.addr, c->conn_info.addr)) - log_dbg("Local link was not in LSDB."); + log_dbg("Local link was not in lsdb."); break; case NOTIFY_DT_CONN_QOS: log_dbg("QoS changes currently unsupported."); @@ -902,14 +887,14 @@ static void handle_event(void * self, fccntl(c->flow_info.fd, FLOWSFLAGS, flags | FLOWFRNOPART); fset_add(ls.mgmt_set, c->flow_info.fd); if (lsdb_add_nb(c->conn_info.addr, c->flow_info.fd, NB_MGMT)) - log_warn("Failed to add mgmt neighbor to LSDB."); + log_warn("Failed to add mgmt neighbor to lsdb."); /* replicate the entire lsdb */ lsdb_replicate(c->flow_info.fd); break; case NOTIFY_MGMT_CONN_DEL: fset_del(ls.mgmt_set, c->flow_info.fd); if (lsdb_del_nb(c->conn_info.addr, c->flow_info.fd)) - log_warn("Failed to delete mgmt neighbor from LSDB."); + log_warn("Failed to delete mgmt neighbor from lsdb."); break; default: break; @@ -1090,16 +1075,13 @@ int link_state_init(struct ls_config * conf, goto fail_fset_create; } - list_head_init(&ls.db.list); - list_head_init(&ls.nbs.list); + llist_init(&ls.db); + llist_init(&ls.nbs); list_head_init(&ls.instances.list); - if (rib_reg(LSDB, &r_ops)) + if (rib_reg(lsdb, &r_ops)) goto fail_rib_reg; - ls.db.len = 0; - ls.nbs.len = 0; - return 0; fail_rib_reg: @@ -1121,7 +1103,7 @@ void link_state_fini(void) struct list_head * p; struct list_head * h; - rib_unreg(LSDB); + rib_unreg(lsdb); fset_destroy(ls.mgmt_set); @@ -1131,9 +1113,9 @@ void link_state_fini(void) pthread_rwlock_wrlock(&ls.lock); - list_for_each_safe(p, h, &ls.db.list) { + llist_for_each_safe(p, h, &ls.db) { struct adjacency * a = list_entry(p, struct adjacency, next); - list_del(&a->next); + llist_del(&a->next, &ls.db); free(a); } diff --git a/src/ipcpd/unicast/routing/link-state.h b/src/ipcpd/unicast/routing/link-state.h index 69eb6781..38e19065 100644 --- a/src/ipcpd/unicast/routing/link-state.h +++ b/src/ipcpd/unicast/routing/link-state.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Link state routing policy * diff --git a/src/ipcpd/unicast/routing/ops.h b/src/ipcpd/unicast/routing/ops.h index 4bf75c80..b19c5176 100644 --- a/src/ipcpd/unicast/routing/ops.h +++ b/src/ipcpd/unicast/routing/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing policy ops * diff --git a/src/ipcpd/unicast/routing/pol.h b/src/ipcpd/unicast/routing/pol.h index b6a6f150..545f5df2 100644 --- a/src/ipcpd/unicast/routing/pol.h +++ b/src/ipcpd/unicast/routing/pol.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Routing policies * diff --git a/src/ipcpd/unicast/routing/tests/CMakeLists.txt b/src/ipcpd/unicast/routing/tests/CMakeLists.txt index b5011474..be2de72c 100644 --- a/src/ipcpd/unicast/routing/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/routing/tests/CMakeLists.txt @@ -3,36 +3,32 @@ get_filename_component(CURRENT_SOURCE_PARENT_DIR 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) +compute_test_prefix() + create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here graph_test.c ) add_executable(${PARENT_DIR}_test ${${PARENT_DIR}_tests}) -target_link_libraries(${PARENT_DIR}_test ouroboros-common) -add_dependencies(check ${PARENT_DIR}_test) +target_include_directories(${PARENT_DIR}_test PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CURRENT_SOURCE_PARENT_DIR} + ${CURRENT_BINARY_PARENT_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_BINARY_DIR}/include + ${CMAKE_SOURCE_DIR}/src/ipcpd + ${CMAKE_BINARY_DIR}/src/ipcpd +) + +disable_test_logging_for_target(${PARENT_DIR}_test) +target_link_libraries(${PARENT_DIR}_test PRIVATE ouroboros-common) -set(tests_to_run ${${PARENT_DIR}_tests}) -if(CMAKE_VERSION VERSION_LESS "3.29.0") - remove(tests_to_run test_suite.c) -else () - list(POP_FRONT tests_to_run) -endif() +add_dependencies(build_tests ${PARENT_DIR}_test) -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) +ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/routing/tests/graph_test.c b/src/ipcpd/unicast/routing/tests/graph_test.c index d805640c..40a744ff 100644 --- a/src/ipcpd/unicast/routing/tests/graph_test.c +++ b/src/ipcpd/unicast/routing/tests/graph_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2024 + * Ouroboros - Copyright (C) 2016 - 2026 * * Test of the graph structure * |
