diff options
Diffstat (limited to 'src/ipcpd/unicast')
-rw-r--r-- | src/ipcpd/unicast/CMakeLists.txt | 36 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth.c (renamed from src/ipcpd/unicast/addr_auth.c) | 9 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth.h (renamed from src/ipcpd/unicast/addr_auth.h) | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth/flat.c (renamed from src/ipcpd/unicast/pol/flat.c) | 28 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth/flat.h (renamed from src/ipcpd/unicast/pol/flat.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth/ops.h (renamed from src/ipcpd/unicast/pol-addr-auth-ops.h) | 10 | ||||
-rw-r--r-- | src/ipcpd/unicast/addr-auth/pol.h | 23 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca.c | 8 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca.h | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/mb-ecn.c (renamed from src/ipcpd/unicast/pol/ca-mb-ecn.c) | 10 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/mb-ecn.h (renamed from src/ipcpd/unicast/pol/ca-mb-ecn.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/nop.c (renamed from src/ipcpd/unicast/pol/ca-nop.c) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/nop.h (renamed from src/ipcpd/unicast/pol/ca-nop.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/ops.h (renamed from src/ipcpd/unicast/pol-ca-ops.h) | 10 | ||||
-rw-r--r-- | src/ipcpd/unicast/ca/pol.h | 24 | ||||
-rw-r--r-- | src/ipcpd/unicast/connmgr.c | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir.c | 55 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir.h | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/dht.c (renamed from src/ipcpd/unicast/dht.c) | 207 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/dht.h (renamed from src/ipcpd/unicast/dht.h) | 34 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/dht.proto (renamed from src/ipcpd/unicast/kademlia.proto) | 14 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/ops.h | 46 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/pol.h | 23 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/tests/CMakeLists.txt (renamed from src/ipcpd/unicast/tests/CMakeLists.txt) | 5 | ||||
-rw-r--r-- | src/ipcpd/unicast/dir/tests/dht_test.c (renamed from src/ipcpd/unicast/tests/dht_test.c) | 23 | ||||
-rw-r--r-- | src/ipcpd/unicast/dt.c | 77 | ||||
-rw-r--r-- | src/ipcpd/unicast/dt.h | 8 | ||||
-rw-r--r-- | src/ipcpd/unicast/enroll.c | 3 | ||||
-rw-r--r-- | src/ipcpd/unicast/fa.c | 377 | ||||
-rw-r--r-- | src/ipcpd/unicast/fa.h | 18 | ||||
-rw-r--r-- | src/ipcpd/unicast/main.c | 149 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff.c | 15 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff.h | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/alternate.c (renamed from src/ipcpd/unicast/pol/alternate_pff.c) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/alternate.h (renamed from src/ipcpd/unicast/pol/alternate_pff.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/multipath.c (renamed from src/ipcpd/unicast/pol/multipath_pff.c) | 34 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/multipath.h (renamed from src/ipcpd/unicast/pol/multipath_pff.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/ops.h (renamed from src/ipcpd/unicast/pol-pff-ops.h) | 10 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/pft.c (renamed from src/ipcpd/unicast/pol/pft.c) | 16 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/pft.h (renamed from src/ipcpd/unicast/pol/pft.h) | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/pol.h | 25 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/simple.c (renamed from src/ipcpd/unicast/pol/simple_pff.c) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/simple.h (renamed from src/ipcpd/unicast/pol/simple_pff.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/tests/CMakeLists.txt | 34 | ||||
-rw-r--r-- | src/ipcpd/unicast/pff/tests/pft_test.c (renamed from src/ipcpd/unicast/pol/tests/pft_test.c) | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/psched.c | 9 | ||||
-rw-r--r-- | src/ipcpd/unicast/psched.h | 8 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing.c | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing.h | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/graph.c (renamed from src/ipcpd/unicast/pol/graph.c) | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/graph.h (renamed from src/ipcpd/unicast/pol/graph.h) | 2 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/link-state.c (renamed from src/ipcpd/unicast/pol/link_state.c) | 8 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/link-state.h (renamed from src/ipcpd/unicast/pol/link_state.h) | 6 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/ops.h (renamed from src/ipcpd/unicast/pol-routing-ops.h) | 10 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/pol.h | 23 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/tests/CMakeLists.txt (renamed from src/ipcpd/unicast/pol/tests/CMakeLists.txt) | 1 | ||||
-rw-r--r-- | src/ipcpd/unicast/routing/tests/graph_test.c (renamed from src/ipcpd/unicast/pol/tests/graph_test.c) | 2 |
57 files changed, 843 insertions, 635 deletions
diff --git a/src/ipcpd/unicast/CMakeLists.txt b/src/ipcpd/unicast/CMakeLists.txt index 07f12540..ca742871 100644 --- a/src/ipcpd/unicast/CMakeLists.txt +++ b/src/ipcpd/unicast/CMakeLists.txt @@ -13,8 +13,10 @@ include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/include) set(IPCP_UNICAST_TARGET ipcpd-unicast CACHE INTERNAL "") +set(IPCP_UNICAST_MPL 60 CACHE STRING + "Default maximum packet lifetime for the unicast IPCP, in seconds") -protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS kademlia.proto) +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 @@ -31,32 +33,31 @@ endif () set(SOURCE_FILES # Add source files here - addr_auth.c + addr-auth.c ca.c connmgr.c - dht.c dir.c dt.c - enroll.c fa.c main.c pff.c routing.c psched.c # Add policies last - pol/pft.c - pol/flat.c - pol/link_state.c - pol/graph.c - pol/simple_pff.c - pol/alternate_pff.c - pol/multipath_pff.c - pol/ca-mb-ecn.c - pol/ca-nop.c + addr-auth/flat.c + ca/mb-ecn.c + ca/nop.c + dir/dht.c + pff/simple.c + pff/alternate.c + pff/multipath.c + pff/pft.c + routing/link-state.c + routing/graph.c ) -add_executable(ipcpd-unicast ${SOURCE_FILES} ${IPCP_SOURCES} - ${KAD_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS}) +add_executable(ipcpd-unicast ${SOURCE_FILES} ${IPCP_SOURCES} ${COMMON_SOURCES} + ${DHT_PROTO_SRCS} ${LAYER_CONFIG_PROTO_SRCS}) target_link_libraries(ipcpd-unicast LINK_PUBLIC ouroboros-dev) include(AddCompileFlags) @@ -66,8 +67,9 @@ endif () install(TARGETS ipcpd-unicast RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}) -add_subdirectory(pol/tests) +add_subdirectory(pff/tests) +add_subdirectory(routing/tests) if (NOT GNU) - add_subdirectory(tests) + add_subdirectory(dir/tests) endif () diff --git a/src/ipcpd/unicast/addr_auth.c b/src/ipcpd/unicast/addr-auth.c index e508d0cb..908a4aa1 100644 --- a/src/ipcpd/unicast/addr_auth.c +++ b/src/ipcpd/unicast/addr-auth.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Address authority * @@ -24,13 +24,12 @@ #include <ouroboros/logs.h> -#include "addr_auth.h" -#include "pol-addr-auth-ops.h" -#include "pol/flat.h" +#include "addr-auth.h" +#include "addr-auth/pol.h" #include <stdlib.h> -struct pol_addr_auth_ops * ops; +struct addr_auth_ops * ops; int addr_auth_init(enum pol_addr_auth type, const void * info) diff --git a/src/ipcpd/unicast/addr_auth.h b/src/ipcpd/unicast/addr-auth.h index d26d3eb7..e119dff3 100644 --- a/src/ipcpd/unicast/addr_auth.h +++ b/src/ipcpd/unicast/addr-auth.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Address authority * diff --git a/src/ipcpd/unicast/pol/flat.c b/src/ipcpd/unicast/addr-auth/flat.c index f869f761..c4562935 100644 --- a/src/ipcpd/unicast/pol/flat.c +++ b/src/ipcpd/unicast/addr-auth/flat.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for flat addresses in a distributed way * @@ -29,19 +29,11 @@ #define OUROBOROS_PREFIX "flat-addr-auth" #include <ouroboros/logs.h> -#include <ouroboros/errno.h> -#include <ouroboros/time_utils.h> -#include <ouroboros/utils.h> +#include <ouroboros/random.h> #include "ipcp.h" #include "flat.h" -#include <time.h> -#include <stdlib.h> -#include <math.h> -#include <string.h> -#include <assert.h> - #define NAME_LEN 8 struct { @@ -50,7 +42,7 @@ struct { #define INVALID_ADDRESS 0 -struct pol_addr_auth_ops flat_ops = { +struct addr_auth_ops flat_ops = { .init = flat_init, .fini = flat_fini, .address = flat_address @@ -75,13 +67,13 @@ int flat_fini(void) uint64_t flat_address(void) { - struct timespec t; - uint32_t addr; - - clock_gettime(CLOCK_REALTIME, &t); - srand(t.tv_nsec); - - addr = (rand() % (RAND_MAX - 1) + 1) & 0xFFFFFFFF; + uint32_t addr = INVALID_ADDRESS; +#if defined (CONFIG_OUROBOROS_DEBUG) && defined (IPCP_DEBUG_LOCAL) + addr = getpid(); +#else + while (addr == INVALID_ADDRESS) + random_buffer(&addr,sizeof(addr)); +#endif return addr; } diff --git a/src/ipcpd/unicast/pol/flat.h b/src/ipcpd/unicast/addr-auth/flat.h index 21f7721a..d4b672c7 100644 --- a/src/ipcpd/unicast/pol/flat.h +++ b/src/ipcpd/unicast/addr-auth/flat.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for flat addresses in a distributed way * @@ -23,7 +23,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_FLAT_H #define OUROBOROS_IPCPD_UNICAST_FLAT_H -#include "pol-addr-auth-ops.h" +#include "ops.h" int flat_init(const void * info); @@ -31,6 +31,6 @@ int flat_fini(void); uint64_t flat_address(void); -extern struct pol_addr_auth_ops flat_ops; +extern struct addr_auth_ops flat_ops; #endif /* OUROBOROS_IPCPD_UNICAST_FLAT_H */ diff --git a/src/ipcpd/unicast/pol-addr-auth-ops.h b/src/ipcpd/unicast/addr-auth/ops.h index 395a5675..06b24cec 100644 --- a/src/ipcpd/unicast/pol-addr-auth-ops.h +++ b/src/ipcpd/unicast/addr-auth/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Address authority policy ops * @@ -20,10 +20,10 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H -#define OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H +#ifndef OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H +#define OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H -struct pol_addr_auth_ops { +struct addr_auth_ops { int (* init)(const void * info); int (* fini)(void); @@ -31,4 +31,4 @@ struct pol_addr_auth_ops { uint64_t (* address)(void); }; -#endif /* OUROBOROS_IPCPD_UNICAST_POL_ADDR_AUTH_OPS_H */ +#endif /* OUROBOROS_IPCPD_UNICAST_ADDR_AUTH_OPS_H */ diff --git a/src/ipcpd/unicast/addr-auth/pol.h b/src/ipcpd/unicast/addr-auth/pol.h new file mode 100644 index 00000000..844308c6 --- /dev/null +++ b/src/ipcpd/unicast/addr-auth/pol.h @@ -0,0 +1,23 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Address Authority policies + * + * 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/. + */ + +#include "flat.h" diff --git a/src/ipcpd/unicast/ca.c b/src/ipcpd/unicast/ca.c index ddeb2849..287eaf41 100644 --- a/src/ipcpd/unicast/ca.c +++ b/src/ipcpd/unicast/ca.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Congestion Avoidance * @@ -25,12 +25,10 @@ #include <ouroboros/logs.h> #include "ca.h" -#include "pol-ca-ops.h" -#include "pol/ca-mb-ecn.h" -#include "pol/ca-nop.h" +#include "ca/pol.h" struct { - struct pol_ca_ops * ops; + struct ca_ops * ops; } ca; int ca_init(enum pol_cong_avoid pol) diff --git a/src/ipcpd/unicast/ca.h b/src/ipcpd/unicast/ca.h index 8b221790..ea803e17 100644 --- a/src/ipcpd/unicast/ca.h +++ b/src/ipcpd/unicast/ca.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Congestion avoidance * diff --git a/src/ipcpd/unicast/pol/ca-mb-ecn.c b/src/ipcpd/unicast/ca/mb-ecn.c index 7a88718f..d9a204b0 100644 --- a/src/ipcpd/unicast/pol/ca-mb-ecn.c +++ b/src/ipcpd/unicast/ca/mb-ecn.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Multi-bit ECN Congestion Avoidance * @@ -29,9 +29,9 @@ #include "config.h" #include <ouroboros/ipcp-dev.h> -#include <ouroboros/time_utils.h> +#include <ouroboros/time.h> -#include "ca-mb-ecn.h" +#include "mb-ecn.h" #include <inttypes.h> #include <stdlib.h> @@ -65,7 +65,7 @@ struct mb_ecn_ctx { size_t tx_slot; }; -struct pol_ca_ops mb_ecn_ca_ops = { +struct ca_ops mb_ecn_ca_ops = { .ctx_create = mb_ecn_ctx_create, .ctx_destroy = mb_ecn_ctx_destroy, .ctx_update_snd = mb_ecn_ctx_update_snd, @@ -187,7 +187,7 @@ ca_wnd_t mb_ecn_ctx_update_snd(void * _ctx, void mb_ecn_wnd_wait(ca_wnd_t wnd) { if (wnd.wait > 0) { - struct timespec s = {0, 0}; + struct timespec s = TIMESPEC_INIT_S(0); if (wnd.wait > BILLION) /* Don't care throttling < 1s */ s.tv_sec = 1; else diff --git a/src/ipcpd/unicast/pol/ca-mb-ecn.h b/src/ipcpd/unicast/ca/mb-ecn.h index a90ae3e2..9a2c8b49 100644 --- a/src/ipcpd/unicast/pol/ca-mb-ecn.h +++ b/src/ipcpd/unicast/ca/mb-ecn.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Multi-bit ECN Congestion Avoidance * @@ -23,7 +23,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H #define OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H -#include "pol-ca-ops.h" +#include "ops.h" void * mb_ecn_ctx_create(void); @@ -51,6 +51,6 @@ ssize_t mb_ecn_print_stats(void * ctx, char * buf, size_t len); -extern struct pol_ca_ops mb_ecn_ca_ops; +extern struct ca_ops mb_ecn_ca_ops; #endif /* OUROBOROS_IPCPD_UNICAST_CA_MB_ECN_H */ diff --git a/src/ipcpd/unicast/pol/ca-nop.c b/src/ipcpd/unicast/ca/nop.c index db908c5c..617fc15b 100644 --- a/src/ipcpd/unicast/pol/ca-nop.c +++ b/src/ipcpd/unicast/ca/nop.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Dummy Congestion Avoidance * @@ -20,11 +20,11 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#include "ca-nop.h" +#include "nop.h" #include <string.h> -struct pol_ca_ops nop_ca_ops = { +struct ca_ops nop_ca_ops = { .ctx_create = nop_ctx_create, .ctx_destroy = nop_ctx_destroy, .ctx_update_snd = nop_ctx_update_snd, diff --git a/src/ipcpd/unicast/pol/ca-nop.h b/src/ipcpd/unicast/ca/nop.h index 7b9d318f..248b198d 100644 --- a/src/ipcpd/unicast/pol/ca-nop.h +++ b/src/ipcpd/unicast/ca/nop.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Dummy Congestion Avoidance * @@ -23,7 +23,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_CA_NOP_H #define OUROBOROS_IPCPD_UNICAST_CA_NOP_H -#include "pol-ca-ops.h" +#include "ops.h" void * nop_ctx_create(void); @@ -47,6 +47,6 @@ int nop_calc_ecn(int fd, qoscube_t qc, size_t len); -extern struct pol_ca_ops nop_ca_ops; +extern struct ca_ops nop_ca_ops; #endif /* OUROBOROS_IPCPD_UNICAST_CA_NOP_H */ diff --git a/src/ipcpd/unicast/pol-ca-ops.h b/src/ipcpd/unicast/ca/ops.h index 88f6cf61..3a7b7248 100644 --- a/src/ipcpd/unicast/pol-ca-ops.h +++ b/src/ipcpd/unicast/ca/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Congestion avoidance policy ops * @@ -20,12 +20,12 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H -#define OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H +#ifndef OUROBOROS_IPCPD_UNICAST_CA_OPS_H +#define OUROBOROS_IPCPD_UNICAST_CA_OPS_H #include "ca.h" -struct pol_ca_ops { +struct ca_ops { void * (* ctx_create)(void); void (* ctx_destroy)(void * ctx); @@ -55,4 +55,4 @@ struct pol_ca_ops { }; -#endif /* OUROBOROS_IPCPD_UNICAST_POL_CA_OPS_H */ +#endif /* OUROBOROS_IPCPD_UNICAST_CA_OPS_H */ diff --git a/src/ipcpd/unicast/ca/pol.h b/src/ipcpd/unicast/ca/pol.h new file mode 100644 index 00000000..db0a1a11 --- /dev/null +++ b/src/ipcpd/unicast/ca/pol.h @@ -0,0 +1,24 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Congestion avoidance policies + * + * 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/. + */ + +#include "mb-ecn.h" +#include "nop.h" diff --git a/src/ipcpd/unicast/connmgr.c b/src/ipcpd/unicast/connmgr.c index 904deff8..11c5d5b6 100644 --- a/src/ipcpd/unicast/connmgr.c +++ b/src/ipcpd/unicast/connmgr.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Handles connections between components * diff --git a/src/ipcpd/unicast/dir.c b/src/ipcpd/unicast/dir.c index a30908b8..e0cb09fc 100644 --- a/src/ipcpd/unicast/dir.c +++ b/src/ipcpd/unicast/dir.c @@ -1,7 +1,7 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * - * Directory + * Directory Management * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -34,8 +34,7 @@ #include <ouroboros/utils.h> #include "dir.h" -#include "dht.h" -#include "ipcp.h" +#include "dir/pol.h" #include <stdlib.h> #include <string.h> @@ -43,60 +42,52 @@ #include <inttypes.h> #include <limits.h> -#define KAD_B (hash_len(ipcpi.dir_hash_algo) * CHAR_BIT) - -struct ipcp icpci; -struct dht * dht; +struct { + struct dir_ops * ops; + void * dir; +} dirmgr; int dir_init(void) { - dht = dht_create(ipcpi.dt_addr); - if (dht == NULL) + dirmgr.ops = &dht_dir_ops; + + dirmgr.dir = dirmgr.ops->create(); + if (dirmgr.dir == NULL) { + dirmgr.ops = NULL; return -ENOMEM; + } return 0; } void dir_fini(void) { - dht_destroy(dht); + dirmgr.ops->destroy(dirmgr.dir); + dirmgr.ops = NULL; + dirmgr.dir = NULL; } -int dir_bootstrap(void) { - log_dbg("Bootstrapping directory."); - - /* TODO: get parameters for bootstrap from IRM tool. */ - if (dht_bootstrap(dht, KAD_B, 86400)) { - dht_destroy(dht); - return -ENOMEM; - } - - log_info("Directory bootstrapped."); - - return 0; +int dir_bootstrap(void) +{ + return dirmgr.ops->bootstrap(dirmgr.dir); } int dir_reg(const uint8_t * hash) { - return dht_reg(dht, hash); + return dirmgr.ops->reg(dirmgr.dir, hash); } int dir_unreg(const uint8_t * hash) { - return dht_unreg(dht, hash); + return dirmgr.ops->unreg(dirmgr.dir, hash); } uint64_t dir_query(const uint8_t * hash) { - return dht_query(dht, hash); + return dirmgr.ops->query(dirmgr.dir, hash); } int dir_wait_running(void) { - if (dht_wait_running(dht)) { - log_warn("Directory did not bootstrap."); - return -1; - } - - return 0; + return dirmgr.ops->wait_running(dirmgr.dir); } diff --git a/src/ipcpd/unicast/dir.h b/src/ipcpd/unicast/dir.h index 8aa79638..b261ea2c 100644 --- a/src/ipcpd/unicast/dir.h +++ b/src/ipcpd/unicast/dir.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Directory * diff --git a/src/ipcpd/unicast/dht.c b/src/ipcpd/unicast/dir/dht.c index 2b668f9f..08a5a5a9 100644 --- a/src/ipcpd/unicast/dht.c +++ b/src/ipcpd/unicast/dir/dht.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Distributed Hash Table based on Kademlia * @@ -31,6 +31,7 @@ #define DHT "dht" #define OUROBOROS_PREFIX DHT +#include <ouroboros/endian.h> #include <ouroboros/hash.h> #include <ouroboros/ipcp-dev.h> #include <ouroboros/bitmap.h> @@ -39,7 +40,7 @@ #include <ouroboros/list.h> #include <ouroboros/notifier.h> #include <ouroboros/random.h> -#include <ouroboros/time_utils.h> +#include <ouroboros/time.h> #include <ouroboros/tpm.h> #include <ouroboros/utils.h> #include <ouroboros/pthread.h> @@ -47,6 +48,8 @@ #include "common/connmgr.h" #include "dht.h" #include "dt.h" +#include "ipcp.h" +#include "ops.h" #include <stdlib.h> #include <string.h> @@ -54,9 +57,9 @@ #include <inttypes.h> #include <limits.h> -#include "kademlia.pb-c.h" -typedef KadMsg kad_msg_t; -typedef KadContactMsg kad_contact_msg_t; +#include "dht.pb-c.h" +typedef DhtMsg dht_msg_t; +typedef DhtContactMsg dht_contact_msg_t; #ifndef CLOCK_REALTIME_COARSE #define CLOCK_REALTIME_COARSE CLOCK_REALTIME @@ -208,6 +211,16 @@ struct cmd { struct shm_du_buff * sdb; }; +struct dir_ops dht_dir_ops = { + .create = dht_create, + .destroy = dht_destroy, + .bootstrap = dht_bootstrap, + .reg = dht_reg, + .unreg = dht_unreg, + .query = dht_query, + .wait_running = dht_wait_running +}; + struct dht { size_t alpha; size_t b; @@ -302,9 +315,12 @@ static int dht_set_state(struct dht * dht, return 0; } -int dht_wait_running(struct dht * dht) +int dht_wait_running(void * dir) { - int ret = 0; + struct dht * dht; + int ret = 0; + + dht = (struct dht *) dir; pthread_mutex_lock(&dht->mtx); @@ -338,7 +354,7 @@ static uint8_t * create_id(size_t len) } static void kad_req_create(struct dht * dht, - kad_msg_t * msg, + dht_msg_t * msg, uint64_t addr) { struct kad_req * req; @@ -346,14 +362,14 @@ static void kad_req_create(struct dht * dht, struct timespec t; size_t b; + clock_gettime(CLOCK_REALTIME_COARSE, &t); + req = malloc(sizeof(*req)); if (req == NULL) - return; + goto fail_malloc; list_head_init(&req->next); - clock_gettime(CLOCK_REALTIME_COARSE, &t); - req->t_exp = t.tv_sec + KAD_T_RESP; req->addr = addr; req->state = REQ_INIT; @@ -367,30 +383,22 @@ static void kad_req_create(struct dht * dht, if (msg->has_key) { req->key = dht_dup_key(msg->key.data, b); - if (req->key == NULL) { - free(req); - return; - } + if (req->key == NULL) + goto fail_dup_key; } - if (pthread_mutex_init(&req->lock, NULL)) { - free(req->key); - free(req); - return; - } + if (pthread_mutex_init(&req->lock, NULL)) + goto fail_mutex; - pthread_condattr_init(&cattr); + + if (pthread_condattr_init(&cattr)) + goto fail_condattr; #ifndef __APPLE__ pthread_condattr_setclock(&cattr, PTHREAD_COND_CLOCK); #endif - if (pthread_cond_init(&req->cond, &cattr)) { - pthread_condattr_destroy(&cattr); - pthread_mutex_destroy(&req->lock); - free(req->key); - free(req); - return; - } + if (pthread_cond_init(&req->cond, &cattr)) + goto fail_cond_init; pthread_condattr_destroy(&cattr); @@ -399,6 +407,19 @@ static void kad_req_create(struct dht * dht, list_add(&req->next, &dht->requests); pthread_rwlock_unlock(&dht->lock); + + return; + + fail_cond_init: + pthread_condattr_destroy(&cattr); + fail_condattr: + pthread_mutex_destroy(&req->lock); + fail_mutex: + free(req->key); + fail_dup_key: + free(req); + fail_malloc: + return; } static void cancel_req_destroy(void * o) @@ -428,7 +449,7 @@ static void kad_req_destroy(struct kad_req * req) return; case REQ_PENDING: req->state = REQ_DESTROY; - pthread_cond_signal(&req->cond); + pthread_cond_broadcast(&req->cond); break; case REQ_INIT: case REQ_DONE: @@ -451,12 +472,14 @@ static void kad_req_destroy(struct kad_req * req) static int kad_req_wait(struct kad_req * req, time_t t) { - struct timespec timeo = {t, 0}; + struct timespec timeo = TIMESPEC_INIT_S(0); struct timespec abs; int ret = 0; assert(req); + timeo.tv_sec = t; + clock_gettime(PTHREAD_COND_CLOCK, &abs); ts_add(&abs, &timeo, &abs); @@ -772,7 +795,7 @@ static void lookup_destroy(struct lookup * lu) static void lookup_update(struct dht * dht, struct lookup * lu, - kad_msg_t * msg) + dht_msg_t * msg) { struct list_head * p = NULL; struct list_head * h; @@ -974,7 +997,7 @@ static void cancel_lookup_wait(void * o) static enum lookup_state lookup_wait(struct lookup * lu) { - struct timespec timeo = {KAD_T_RESP, 0}; + struct timespec timeo = TIMESPEC_INIT_S(KAD_T_RESP); struct timespec abs; enum lookup_state state; int ret = 0; @@ -1006,7 +1029,7 @@ static enum lookup_state lookup_wait(struct lookup * lu) } static struct kad_req * dht_find_request(struct dht * dht, - kad_msg_t * msg) + dht_msg_t * msg) { struct list_head * p; @@ -1254,7 +1277,7 @@ static void bucket_refresh(struct dht * dht, struct contact * d; c = list_first_entry(&b->contacts, struct contact, next); d = contact_create(c->id, dht->b, c->addr); - if (c != NULL) + if (d != NULL) list_add(&d->next, r); return; } @@ -1443,7 +1466,7 @@ static int dht_update_bucket(struct dht * dht, } static int send_msg(struct dht * dht, - kad_msg_t * msg, + dht_msg_t * msg, uint64_t addr) { #ifndef __DHT_TEST__ @@ -1476,7 +1499,7 @@ static int send_msg(struct dht * dht, pthread_rwlock_unlock(&dht->lock); #ifndef __DHT_TEST__ - len = kad_msg__get_packed_size(msg); + len = dht_msg__get_packed_size(msg); if (len == 0) goto fail_msg; @@ -1484,7 +1507,7 @@ static int send_msg(struct dht * dht, if (ipcp_sdb_reserve(&sdb, len)) goto fail_msg; - kad_msg__pack(msg, shm_du_buff_head(sdb)); + dht_msg__pack(msg, shm_du_buff_head(sdb)); if (dt_write_packet(addr, QOS_CUBE_BE, dht->eid, sdb) == 0) break; @@ -1531,7 +1554,7 @@ static struct dht_entry * dht_find_entry(struct dht * dht, } static int kad_add(struct dht * dht, - const kad_contact_msg_t * contacts, + const dht_contact_msg_t * contacts, ssize_t n, time_t exp) { @@ -1570,7 +1593,7 @@ static int kad_add(struct dht * dht, } static int wait_resp(struct dht * dht, - kad_msg_t * msg, + dht_msg_t * msg, time_t timeo) { struct kad_req * req; @@ -1597,9 +1620,9 @@ static int kad_store(struct dht * dht, uint64_t r_addr, time_t ttl) { - kad_msg_t msg = KAD_MSG__INIT; - kad_contact_msg_t cmsg = KAD_CONTACT_MSG__INIT; - kad_contact_msg_t * cmsgp[1]; + dht_msg_t msg = DHT_MSG__INIT; + dht_contact_msg_t cmsg = DHT_CONTACT_MSG__INIT; + dht_contact_msg_t * cmsgp[1]; cmsg.id.data = (uint8_t *) key; cmsg.addr = addr; @@ -1629,7 +1652,7 @@ static ssize_t kad_find(struct dht * dht, const uint64_t * addrs, enum kad_code code) { - kad_msg_t msg = KAD_MSG__INIT; + dht_msg_t msg = DHT_MSG__INIT; ssize_t sent = 0; assert(dht); @@ -1769,7 +1792,7 @@ static void kad_publish(struct dht * dht, while (n-- > 0) { if (addrs[n] == dht->addr) { - kad_contact_msg_t msg = KAD_CONTACT_MSG__INIT; + dht_contact_msg_t msg = DHT_CONTACT_MSG__INIT; msg.id.data = (uint8_t *) key; msg.id.len = dht->b; msg.addr = addr; @@ -1788,7 +1811,7 @@ static void kad_publish(struct dht * dht, static int kad_join(struct dht * dht, uint64_t addr) { - kad_msg_t msg = KAD_MSG__INIT; + dht_msg_t msg = DHT_MSG__INIT; msg.code = KAD_JOIN; @@ -1868,18 +1891,13 @@ static int dht_del(struct dht * dht, { struct dht_entry * e; - pthread_rwlock_wrlock(&dht->lock); - e = dht_find_entry(dht, key); if (e == NULL) { - pthread_rwlock_unlock(&dht->lock); return -EPERM; } dht_entry_del_addr(e, addr); - pthread_rwlock_unlock(&dht->lock); - return 0; } @@ -1921,14 +1939,14 @@ static buffer_t dht_retrieve(struct dht * dht, fail: pthread_rwlock_unlock(&dht->lock); - buf.len = 0; - + buf.len = 0; + buf.data = NULL; return buf; } static ssize_t dht_get_contacts(struct dht * dht, const uint8_t * key, - kad_contact_msg_t *** msgs) + dht_contact_msg_t *** msgs) { struct list_head l; struct list_head * p; @@ -1965,7 +1983,7 @@ static ssize_t dht_get_contacts(struct dht * dht, return 0; } - kad_contact_msg__init((*msgs)[i]); + dht_contact_msg__init((*msgs)[i]); (*msgs)[i]->id.data = c->id; (*msgs)[i]->id.len = dht->b; @@ -2102,7 +2120,7 @@ static void * work(void * o) static int kad_handle_join_resp(struct dht * dht, struct kad_req * req, - kad_msg_t * msg) + dht_msg_t * msg) { assert(dht); assert(req); @@ -2162,7 +2180,7 @@ static int kad_handle_join_resp(struct dht * dht, static int kad_handle_find_resp(struct dht * dht, struct kad_req * req, - kad_msg_t * msg) + dht_msg_t * msg) { struct lookup * lu; @@ -2186,7 +2204,7 @@ static int kad_handle_find_resp(struct dht * dht, } static void kad_handle_response(struct dht * dht, - kad_msg_t * msg) + dht_msg_t * msg) { struct kad_req * req; @@ -2224,15 +2242,23 @@ static void kad_handle_response(struct dht * dht, kad_req_destroy(req); } -int dht_bootstrap(struct dht * dht, - size_t b, - time_t t_expire) +int dht_bootstrap(void * dir) { + struct dht * dht; + + dht = (struct dht *) dir; + assert(dht); pthread_rwlock_wrlock(&dht->lock); - dht->id = create_id(b); +#ifndef __DHT_TEST__ + dht->b = hash_len(ipcpi.dir_hash_algo); +#else + dht->b = DHT_TEST_KEY_LEN; +#endif + + dht->id = create_id(dht->b); if (dht->id == NULL) goto fail_id; @@ -2243,9 +2269,8 @@ int dht_bootstrap(struct dht * dht, dht->buckets->depth = 0; dht->buckets->mask = 0; - dht->b = b / CHAR_BIT; - dht->t_expire = MAX(2, t_expire); - dht->t_repub = MAX(1, t_expire - 10); + dht->t_expire = 86400; /* 1 day */ + dht->t_repub = dht->t_expire - 10; dht->k = KAD_K; if (pthread_create(&dht->worker, NULL, work, dht)) @@ -2284,13 +2309,16 @@ static struct ref_entry * ref_entry_get(struct dht * dht, return NULL; } -int dht_reg(struct dht * dht, +int dht_reg(void * dir, const uint8_t * key) { + struct dht * dht; struct ref_entry * e; uint64_t addr; time_t t_expire; + dht = (struct dht *) dir; + assert(dht); assert(key); assert(dht->addr != 0); @@ -2324,12 +2352,15 @@ int dht_reg(struct dht * dht, return 0; } -int dht_unreg(struct dht * dht, +int dht_unreg(void * dir, const uint8_t * key) { + struct dht * dht; struct list_head * p; struct list_head * h; + dht = (struct dht *) dir; + assert(dht); assert(key); @@ -2353,14 +2384,19 @@ int dht_unreg(struct dht * dht, return 0; } -uint64_t dht_query(struct dht * dht, +uint64_t dht_query(void * dir, const uint8_t * key) { + struct dht * dht; struct dht_entry * e; struct lookup * lu; uint64_t addrs[KAD_K]; size_t n; + dht = (struct dht *) dir; + + assert(dht); + addrs[0] = 0; if (dht_wait_running(dht)) @@ -2406,9 +2442,9 @@ static void * dht_handle_packet(void * o) assert(dht); while (true) { - kad_msg_t * msg; - kad_contact_msg_t ** cmsgs; - kad_msg_t resp_msg = KAD_MSG__INIT; + dht_msg_t * msg; + dht_contact_msg_t ** cmsgs; + dht_msg_t resp_msg = DHT_MSG__INIT; uint64_t addr; buffer_t buf; size_t i; @@ -2428,9 +2464,9 @@ static void * dht_handle_packet(void * o) pthread_cleanup_pop(true); - i = shm_du_buff_tail(cmd->sdb) - shm_du_buff_head(cmd->sdb); + i = shm_du_buff_len(cmd->sdb); - msg = kad_msg__unpack(NULL, i, shm_du_buff_head(cmd->sdb)); + msg = dht_msg__unpack(NULL, i, shm_du_buff_head(cmd->sdb)); #ifndef __DHT_TEST__ ipcp_sdb_release(cmd->sdb); #endif @@ -2442,7 +2478,7 @@ static void * dht_handle_packet(void * o) } if (msg->code != KAD_RESPONSE && dht_wait_running(dht)) { - kad_msg__free_unpacked(msg, NULL); + dht_msg__free_unpacked(msg, NULL); log_dbg("Got a request message when not running."); continue; } @@ -2455,13 +2491,13 @@ static void * dht_handle_packet(void * o) pthread_rwlock_unlock(&dht->lock); if (msg->has_key && msg->key.len != b) { - kad_msg__free_unpacked(msg, NULL); + dht_msg__free_unpacked(msg, NULL); log_warn("Bad key in message."); continue; } if (msg->has_s_id && !msg->has_b && msg->s_id.len != b) { - kad_msg__free_unpacked(msg, NULL); + dht_msg__free_unpacked(msg, NULL); log_warn("Bad source ID in message of type %d.", msg->code); continue; @@ -2562,7 +2598,7 @@ static void * dht_handle_packet(void * o) log_warn("Failed to send response."); finish: - kad_msg__free_unpacked(msg, NULL); + dht_msg__free_unpacked(msg, NULL); if (resp_msg.n_addrs > 0) free(resp_msg.addrs); @@ -2573,7 +2609,7 @@ static void * dht_handle_packet(void * o) } for (i = 0; i < resp_msg.n_contacts; ++i) - kad_contact_msg__free_unpacked(resp_msg.contacts[i], + dht_contact_msg__free_unpacked(resp_msg.contacts[i], NULL); free(resp_msg.contacts); @@ -2613,11 +2649,13 @@ static void dht_post_packet(void * comp, pthread_mutex_unlock(&dht->mtx); } -void dht_destroy(struct dht * dht) +void dht_destroy(void * dir) { + struct dht * dht; struct list_head * p; struct list_head * h; + dht = (struct dht *) dir; if (dht == NULL) return; @@ -2728,7 +2766,7 @@ static void handle_event(void * self, pthread_t thr; struct join_info * inf; struct conn * c = (struct conn *) o; - struct timespec slack = {0, DHT_ENROLL_SLACK * MILLION}; + struct timespec slack = TIMESPEC_INIT_MS(DHT_ENROLL_SLACK); /* Give the pff some time to update for the new link. */ nanosleep(&slack, NULL); @@ -2770,7 +2808,7 @@ static void handle_event(void * self, } } -struct dht * dht_create(uint64_t addr) +void * dht_create(void) { struct dht * dht; @@ -2800,9 +2838,9 @@ struct dht * dht_create(uint64_t addr) goto fail_bmp; dht->b = 0; - dht->addr = addr; dht->id = NULL; #ifndef __DHT_TEST__ + dht->addr = ipcpi.dt_addr; dht->tpm = tpm_create(2, 1, dht_handle_packet, dht); if (dht->tpm == NULL) goto fail_tpm_create; @@ -2814,7 +2852,8 @@ struct dht * dht_create(uint64_t addr) if ((int) dht->eid < 0) goto fail_tpm_start; - notifier_reg(handle_event, dht); + if (notifier_reg(handle_event, dht)) + goto fail_notifier_reg; #else (void) handle_event; (void) dht_handle_packet; @@ -2822,8 +2861,10 @@ struct dht * dht_create(uint64_t addr) #endif dht->state = DHT_INIT; - return dht; + return (void *) dht; #ifndef __DHT_TEST__ + fail_notifier_reg: + tpm_stop(dht->tpm); fail_tpm_start: tpm_destroy(dht->tpm); fail_tpm_create: diff --git a/src/ipcpd/unicast/dht.h b/src/ipcpd/unicast/dir/dht.h index df394714..311c6b23 100644 --- a/src/ipcpd/unicast/dht.h +++ b/src/ipcpd/unicast/dir/dht.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Distributed Hash Table based on Kademlia * @@ -20,33 +20,33 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_IPCPD_UNICAST_DHT_H -#define OUROBOROS_IPCPD_UNICAST_DHT_H +#ifndef OUROBOROS_IPCPD_UNICAST_DIR_DHT_H +#define OUROBOROS_IPCPD_UNICAST_DIR_DHT_H #include <ouroboros/ipcp-dev.h> +#include "ops.h" + #include <stdint.h> #include <sys/types.h> -struct dht; +void * dht_create(void); -struct dht * dht_create(uint64_t addr); +void dht_destroy(void * dir); -int dht_bootstrap(struct dht * dht, - size_t b, - time_t t_expire); +int dht_bootstrap(void * dir); -void dht_destroy(struct dht * dht); +int dht_reg(void * dir, + const uint8_t * key); -int dht_reg(struct dht * dht, - const uint8_t * key); +int dht_unreg(void * dir, + const uint8_t * key); -int dht_unreg(struct dht * dht, - const uint8_t * key); +uint64_t dht_query(void * dir, + const uint8_t * key); -uint64_t dht_query(struct dht * dht, - const uint8_t * key); +int dht_wait_running(void * dir); -int dht_wait_running(struct dht * dht); +extern struct dir_ops dht_dir_ops; -#endif /* OUROBOROS_IPCPD_UNICAST_DHT_H */ +#endif /* OUROBOROS_IPCPD_UNICAST_DIR_DHT_H */ diff --git a/src/ipcpd/unicast/kademlia.proto b/src/ipcpd/unicast/dir/dht.proto index 58f5e787..4c5b06db 100644 --- a/src/ipcpd/unicast/kademlia.proto +++ b/src/ipcpd/unicast/dir/dht.proto @@ -1,7 +1,7 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * - * KAD protocol + * DHT protocol, based on Kademlia * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -22,19 +22,19 @@ syntax = "proto2"; -message kad_contact_msg { +message dht_contact_msg { required bytes id = 1; required uint64 addr = 2; -}; +} -message kad_msg { +message dht_msg { required uint32 code = 1; required uint32 cookie = 2; required uint64 s_addr = 3; optional bytes s_id = 4; optional bytes key = 5; repeated uint64 addrs = 6; - repeated kad_contact_msg contacts = 7; + repeated dht_contact_msg contacts = 7; // enrolment parameters optional uint32 alpha = 8; optional uint32 b = 9; @@ -42,4 +42,4 @@ message kad_msg { optional uint32 t_expire = 11; optional uint32 t_refresh = 12; optional uint32 t_replicate = 13; -};
\ No newline at end of file +} diff --git a/src/ipcpd/unicast/dir/ops.h b/src/ipcpd/unicast/dir/ops.h new file mode 100644 index 00000000..6ff61ce6 --- /dev/null +++ b/src/ipcpd/unicast/dir/ops.h @@ -0,0 +1,46 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Directory policy ops + * + * 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_UNICAST_DIR_OPS_H +#define OUROBOROS_IPCPD_UNICAST_DIR_OPS_H + + +struct dir_ops { + void * (* create)(void); + + void (* destroy)(void * dir); + + int (* bootstrap)(void * dir); + + int (* reg)(void * dir, + const uint8_t * hash); + + int (* unreg)(void * dir, + const uint8_t * hash); + + uint64_t (* query)(void * dir, + const uint8_t * hash); + + int (* wait_running)(void * dir); +}; + +#endif /* OUROBOROS_IPCPD_UNICAST_DIR_OPS_H */ diff --git a/src/ipcpd/unicast/dir/pol.h b/src/ipcpd/unicast/dir/pol.h new file mode 100644 index 00000000..eae4b2e7 --- /dev/null +++ b/src/ipcpd/unicast/dir/pol.h @@ -0,0 +1,23 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Directory policies + * + * 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/. + */ + +#include "dht.h" diff --git a/src/ipcpd/unicast/tests/CMakeLists.txt b/src/ipcpd/unicast/dir/tests/CMakeLists.txt index 482711d5..c850e41d 100644 --- a/src/ipcpd/unicast/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/dir/tests/CMakeLists.txt @@ -20,10 +20,9 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c dht_test.c ) -protobuf_generate_c(KAD_PROTO_SRCS KAD_PROTO_HDRS ../kademlia.proto) - +protobuf_generate_c(DHT_PROTO_SRCS KAD_PROTO_HDRS ../dht.proto) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests} - ${KAD_PROTO_SRCS}) + ${DHT_PROTO_SRCS}) target_link_libraries(${PARENT_DIR}_test ouroboros-common) add_dependencies(check ${PARENT_DIR}_test) diff --git a/src/ipcpd/unicast/tests/dht_test.c b/src/ipcpd/unicast/dir/tests/dht_test.c index 552af75c..bea2c3e7 100644 --- a/src/ipcpd/unicast/tests/dht_test.c +++ b/src/ipcpd/unicast/dir/tests/dht_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Unit tests of the DHT * @@ -21,6 +21,7 @@ */ #define __DHT_TEST__ +#define DHT_TEST_KEY_LEN 32 #include "dht.c" @@ -29,23 +30,19 @@ #include <stdlib.h> #include <stdio.h> -#define KEY_LEN 32 - -#define EXP 86400 -#define CONTACTS 1000 +#define CONTACTS 1000 int dht_test(int argc, char ** argv) { struct dht * dht; - uint64_t addr = 0x0D1F; - uint8_t key[KEY_LEN]; + uint8_t key[DHT_TEST_KEY_LEN]; size_t i; (void) argc; (void) argv; - dht = dht_create(addr); + dht = dht_create(); if (dht == NULL) { printf("Failed to create dht.\n"); return -1; @@ -53,13 +50,13 @@ int dht_test(int argc, dht_destroy(dht); - dht = dht_create(addr); + dht = dht_create(); if (dht == NULL) { printf("Failed to re-create dht.\n"); return -1; } - if (dht_bootstrap(dht, KEY_LEN, EXP)) { + if (dht_bootstrap(dht)) { printf("Failed to bootstrap dht.\n"); dht_destroy(dht); return -1; @@ -67,13 +64,13 @@ int dht_test(int argc, dht_destroy(dht); - dht = dht_create(addr); + dht = dht_create(); if (dht == NULL) { printf("Failed to re-create dht.\n"); return -1; } - if (dht_bootstrap(dht, KEY_LEN, EXP)) { + if (dht_bootstrap(dht)) { printf("Failed to bootstrap dht.\n"); dht_destroy(dht); return -1; @@ -82,7 +79,7 @@ int dht_test(int argc, for (i = 0; i < CONTACTS; ++i) { uint64_t addr; random_buffer(&addr, sizeof(addr)); - random_buffer(key, KEY_LEN); + random_buffer(key, DHT_TEST_KEY_LEN); pthread_rwlock_wrlock(&dht->lock); if (dht_update_bucket(dht, key, addr)) { pthread_rwlock_unlock(&dht->lock); diff --git a/src/ipcpd/unicast/dt.c b/src/ipcpd/unicast/dt.c index 0f504daa..2bb5ed2f 100644 --- a/src/ipcpd/unicast/dt.c +++ b/src/ipcpd/unicast/dt.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Data Transfer Component * @@ -312,7 +312,7 @@ static int dt_rib_readdir(char *** buf) if ((*buf)[idx] == NULL) { while (idx-- > 0) free((*buf)[idx]); - free(buf); + free(*buf); pthread_mutex_unlock(&dt.stat[i].lock); pthread_rwlock_unlock(&dt.lock); return -ENOMEM; @@ -399,6 +399,7 @@ static void handle_event(void * self, const void * o) { struct conn * c; + int fd; (void) self; @@ -406,19 +407,20 @@ static void handle_event(void * self, switch (event) { case NOTIFY_DT_CONN_ADD: + fd = c->flow_info.fd; #ifdef IPCP_FLOW_STATS - stat_used(c->flow_info.fd, c->conn_info.addr); + stat_used(fd, c->conn_info.addr); #endif - psched_add(dt.psched, c->flow_info.fd); - log_dbg("Added fd %d to packet scheduler.", c->flow_info.fd); + psched_add(dt.psched, fd); + log_dbg("Added fd %d to packet scheduler.", fd); break; case NOTIFY_DT_CONN_DEL: + fd = c->flow_info.fd; #ifdef IPCP_FLOW_STATS - stat_used(c->flow_info.fd, INVALID_ADDR); + stat_used(fd, INVALID_ADDR); #endif - psched_del(dt.psched, c->flow_info.fd); - log_dbg("Removed fd %d from " - "packet scheduler.", c->flow_info.fd); + psched_del(dt.psched, fd); + log_dbg("Removed fd %d from packet scheduler.", fd); break; default: break; @@ -435,7 +437,7 @@ static void packet_handler(int fd, uint8_t * head; size_t len; - len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); + len = shm_du_buff_len(sdb); #ifndef IPCP_FLOW_STATS (void) fd; @@ -563,10 +565,7 @@ static void * dt_conn_handle(void * o) return 0; } -int dt_init(enum pol_routing pr, - uint8_t addr_size, - uint8_t eid_size, - uint8_t max_ttl) +int dt_init(struct dt_config cfg) { int i; int j; @@ -582,14 +581,14 @@ int dt_init(enum pol_routing pr, info.pref_syntax = PROTO_FIXED; info.addr = ipcpi.dt_addr; - if (eid_size != 8) { /* only support 64 bits from now */ + if (cfg.eid_size != 8) { /* only support 64 bits from now */ log_warn("Invalid EID size. Only 64 bit is supported."); - eid_size = 8; + cfg.eid_size = 8; } - dt_pci_info.addr_size = addr_size; - dt_pci_info.eid_size = eid_size; - dt_pci_info.max_ttl = max_ttl; + dt_pci_info.addr_size = cfg.addr_size; + dt_pci_info.eid_size = cfg.eid_size; + dt_pci_info.max_ttl = cfg.max_ttl; dt_pci_info.qc_o = dt_pci_info.addr_size; dt_pci_info.ttl_o = dt_pci_info.qc_o + QOS_LEN; @@ -597,17 +596,12 @@ int dt_init(enum pol_routing pr, dt_pci_info.eid_o = dt_pci_info.ecn_o + ECN_LEN; dt_pci_info.head_size = dt_pci_info.eid_o + dt_pci_info.eid_size; - if (notifier_reg(handle_event, NULL)) { - log_err("Failed to register with notifier."); - goto fail_notifier_reg; - } - if (connmgr_comp_init(COMPID_DT, &info)) { log_err("Failed to register with connmgr."); goto fail_connmgr_comp_init; } - pp = routing_init(pr); + pp = routing_init(cfg.routing_type); if (pp < 0) { log_err("Failed to init routing."); goto fail_routing; @@ -645,6 +639,7 @@ int dt_init(enum pol_routing pr, for (i = 0; i < PROG_MAX_FLOWS; ++i) if (pthread_mutex_init(&dt.stat[i].lock, NULL)) { + log_err("Failed to init mutex for flow %d.", i); for (j = 0; j < i; ++j) pthread_mutex_destroy(&dt.stat[j].lock); goto fail_stat_lock; @@ -653,8 +648,10 @@ int dt_init(enum pol_routing pr, dt.n_flows = 0; #endif sprintf(dtstr, "%s.%" PRIu64, DT, ipcpi.dt_addr); - if (rib_reg(dtstr, &r_ops)) + if (rib_reg(dtstr, &r_ops)) { + log_err("Failed to register RIB."); goto fail_rib_reg; + } return 0; @@ -678,8 +675,6 @@ int dt_init(enum pol_routing pr, fail_routing: connmgr_comp_fini(COMPID_DT); fail_connmgr_comp_init: - notifier_unreg(&handle_event); - fail_notifier_reg: return -1; } @@ -707,16 +702,19 @@ void dt_fini(void) routing_fini(); connmgr_comp_fini(COMPID_DT); - - notifier_unreg(&handle_event); } int dt_start(void) { - dt.psched = psched_create(packet_handler); + dt.psched = psched_create(packet_handler, ipcp_flow_read); if (dt.psched == NULL) { log_err("Failed to create N-1 packet scheduler."); - return -1; + goto fail_psched; + } + + if (notifier_reg(handle_event, NULL)) { + log_err("Failed to register with notifier."); + goto fail_notifier_reg; } if (pthread_create(&dt.listener, NULL, dt_conn_handle, NULL)) { @@ -726,12 +724,21 @@ int dt_start(void) } return 0; + + fail_notifier_reg: + psched_destroy(dt.psched); + fail_psched: + return -1; + } void dt_stop(void) { pthread_cancel(dt.listener); pthread_join(dt.listener, NULL); + + notifier_unreg(&handle_event); + psched_destroy(dt.psched); } @@ -747,7 +754,7 @@ int dt_reg_comp(void * comp, eid = bmp_allocate(dt.res_fds); if (!bmp_is_id_valid(dt.res_fds, eid)) { - log_warn("Reserved EIDs depleted."); + log_err("Cannot allocate EID."); pthread_rwlock_unlock(&dt.lock); return -EBADF; } @@ -781,7 +788,7 @@ int dt_write_packet(uint64_t dst_addr, assert(sdb); assert(dst_addr != ipcpi.dt_addr); - len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); + len = shm_du_buff_len(sdb); #ifdef IPCP_FLOW_STATS if (eid < PROG_RES_FDS) { @@ -815,7 +822,7 @@ int dt_write_packet(uint64_t dst_addr, goto fail_write; } - len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); + len = shm_du_buff_len(sdb); dt_pci.dst_addr = dst_addr; dt_pci.qc = qc; diff --git a/src/ipcpd/unicast/dt.h b/src/ipcpd/unicast/dt.h index e1abbe28..7198a013 100644 --- a/src/ipcpd/unicast/dt.h +++ b/src/ipcpd/unicast/dt.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Data Transfer component * @@ -31,11 +31,7 @@ #define DT_PROTO "dtp" #define INVALID_ADDR 0 -int dt_init(enum pol_routing pr, - uint8_t addr_size, - uint8_t eid_size, - uint8_t max_ttl -); +int dt_init(struct dt_config cfg); void dt_fini(void); diff --git a/src/ipcpd/unicast/enroll.c b/src/ipcpd/unicast/enroll.c deleted file mode 100644 index 500a3895..00000000 --- a/src/ipcpd/unicast/enroll.c +++ /dev/null @@ -1,3 +0,0 @@ -#define BUILD_IPCP_UNICAST - -#include "common/enroll.c" diff --git a/src/ipcpd/unicast/fa.c b/src/ipcpd/unicast/fa.c index 6e6d52f0..3631fd7b 100644 --- a/src/ipcpd/unicast/fa.c +++ b/src/ipcpd/unicast/fa.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Flow allocator of the IPC Process * @@ -31,6 +31,7 @@ #define FA "flow-allocator" #define OUROBOROS_PREFIX FA +#include <ouroboros/endian.h> #include <ouroboros/logs.h> #include <ouroboros/fqueue.h> #include <ouroboros/errno.h> @@ -55,7 +56,7 @@ #define CLOCK_REALTIME_COARSE CLOCK_REALTIME #endif -#define TIMEOUT 10000 /* nanoseconds */ +#define TIMEOUT 10 * MILLION /* nanoseconds */ #define FLOW_REQ 0 #define FLOW_REPLY 1 @@ -72,14 +73,15 @@ struct fa_msg { int8_t response; uint16_t ece; /* QoS parameters from spec, aligned */ - uint8_t availability; - uint8_t in_order; uint32_t delay; uint64_t bandwidth; uint32_t loss; uint32_t ber; uint32_t max_gap; + uint32_t timeout; uint16_t cypher_s; + uint8_t availability; + uint8_t in_order; } __attribute__((packed)); struct cmd { @@ -143,7 +145,7 @@ static int fa_rib_read(const char * path, fd = atoi(entry); - if (fd < 0 || fd > PROG_MAX_FLOWS) + if (fd < 0 || fd >= PROG_MAX_FLOWS) return -1; if (len < 1536) @@ -238,7 +240,7 @@ static int fa_rib_readdir(char *** buf) if ((*buf)[idx] == NULL) { while (idx-- > 0) free((*buf)[idx]); - free(buf); + free(*buf); pthread_rwlock_unlock(&fa.flows_lock); return -ENOMEM; } @@ -303,7 +305,7 @@ static int eid_to_fd(uint64_t eid) fd = eid & 0xFFFFFFFF; - if (fd < 0 || fd > PROG_MAX_FLOWS) + if (fd < 0 || fd >= PROG_MAX_FLOWS) return -1; flow = &fa.flows[fd]; @@ -340,7 +342,7 @@ static void packet_handler(int fd, pthread_rwlock_wrlock(&fa.flows_lock); - len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); + len = shm_du_buff_len(sdb); #ifdef IPCP_FLOW_STATS ++flow->p_snd; @@ -357,7 +359,7 @@ static void packet_handler(int fd, if (dt_write_packet(r_addr, qc, r_eid, sdb)) { ipcp_sdb_release(sdb); - log_warn("Failed to forward packet."); + log_dbg("Failed to forward packet."); #ifdef IPCP_FLOW_STATS pthread_rwlock_wrlock(&fa.flows_lock); ++flow->p_snd_f; @@ -435,167 +437,190 @@ static void fa_post_packet(void * comp, pthread_mutex_unlock(&fa.mtx); } -static void * fa_handle_packet(void * o) +static size_t fa_wait_for_fa_msg(struct fa_msg * msg) { - struct timespec ts = {0, TIMEOUT * 1000}; - - (void) o; + struct cmd * cmd; + size_t len; - while (true) { - struct timespec abstime; - int fd; - uint8_t buf[MSGBUFSZ]; - struct fa_msg * msg; - qosspec_t qs; - struct cmd * cmd; - size_t len; - size_t msg_len; - struct fa_flow * flow; + pthread_mutex_lock(&fa.mtx); - pthread_mutex_lock(&fa.mtx); + pthread_cleanup_push(__cleanup_mutex_unlock, &fa.mtx); - pthread_cleanup_push(__cleanup_mutex_unlock, &fa.mtx); + while (list_is_empty(&fa.cmds)) + pthread_cond_wait(&fa.cond, &fa.mtx); - while (list_is_empty(&fa.cmds)) - pthread_cond_wait(&fa.cond, &fa.mtx); + cmd = list_last_entry(&fa.cmds, struct cmd, next); + list_del(&cmd->next); - cmd = list_last_entry(&fa.cmds, struct cmd, next); - list_del(&cmd->next); + pthread_cleanup_pop(true); - pthread_cleanup_pop(true); + len = shm_du_buff_len(cmd->sdb); + if (len > MSGBUFSZ || len < sizeof(*msg)) { + log_warn("Invalid flow allocation message (len: %zd).", len); + free(cmd); + return 0; /* No valid message */ + } - len = shm_du_buff_tail(cmd->sdb) - shm_du_buff_head(cmd->sdb); + memcpy(msg, shm_du_buff_head(cmd->sdb), len); - if (len > MSGBUFSZ) { - log_err("Message over buffer size."); - free(cmd); - continue; - } + ipcp_sdb_release(cmd->sdb); - msg = (struct fa_msg *) buf; + free(cmd); - /* Depending on the message call the function in ipcp-dev.h */ + return len; +} - memcpy(msg, shm_du_buff_head(cmd->sdb), len); +static int fa_handle_flow_req(struct fa_msg * msg, + size_t len) +{ + size_t msg_len; + int fd; + qosspec_t qs; + struct fa_flow * flow; + uint8_t * dst; + buffer_t data; /* Piggbacked data on flow alloc request. */ - ipcp_sdb_release(cmd->sdb); + msg_len = sizeof(*msg) + ipcp_dir_hash_len(); + if (len < msg_len) { + log_err("Invalid flow allocation request"); + return -EPERM; + } - free(cmd); + dst = (uint8_t *)(msg + 1); + data.data = (uint8_t *) msg + msg_len; + data.len = len - msg_len; + + qs.delay = ntoh32(msg->delay); + qs.bandwidth = ntoh64(msg->bandwidth); + qs.availability = msg->availability; + qs.loss = ntoh32(msg->loss); + qs.ber = ntoh32(msg->ber); + qs.in_order = msg->in_order; + qs.max_gap = ntoh32(msg->max_gap); + qs.cypher_s = ntoh16(msg->cypher_s); + qs.timeout = ntoh32(msg->timeout); + + fd = ipcp_wait_flow_req_arr(dst, qs, IPCP_UNICAST_MPL, &data); + if (fd < 0) + return fd; - switch (msg->code) { - case FLOW_REQ: - msg_len = sizeof(*msg) + ipcp_dir_hash_len(); + flow = &fa.flows[fd]; - assert(len >= msg_len); + pthread_rwlock_wrlock(&fa.flows_lock); - clock_gettime(PTHREAD_COND_CLOCK, &abstime); + fa_flow_init(flow); - pthread_mutex_lock(&ipcpi.alloc_lock); + flow->s_eid = gen_eid(fd); + flow->r_eid = ntoh64(msg->s_eid); + flow->r_addr = ntoh64(msg->s_addr); - while (ipcpi.alloc_id != -1 && - ipcp_get_state() == IPCP_OPERATIONAL) { - ts_add(&abstime, &ts, &abstime); - pthread_cond_timedwait(&ipcpi.alloc_cond, - &ipcpi.alloc_lock, - &abstime); - } + pthread_rwlock_unlock(&fa.flows_lock); - if (ipcp_get_state() != IPCP_OPERATIONAL) { - pthread_mutex_unlock(&ipcpi.alloc_lock); - log_dbg("Won't allocate over non-operational" - "IPCP."); - continue; - } + return fd; +} - assert(ipcpi.alloc_id == -1); +static int fa_handle_flow_reply(struct fa_msg * msg, + size_t len) +{ + int fd; + struct fa_flow * flow; + buffer_t data; /* Piggbacked data on flow alloc request. */ + time_t mpl = IPCP_UNICAST_MPL; - qs.delay = ntoh32(msg->delay); - qs.bandwidth = ntoh64(msg->bandwidth); - qs.availability = msg->availability; - qs.loss = ntoh32(msg->loss); - qs.ber = ntoh32(msg->ber); - qs.in_order = msg->in_order; - qs.max_gap = ntoh32(msg->max_gap); - qs.cypher_s = ntoh16(msg->cypher_s); + assert(len >= sizeof(*msg)); - fd = ipcp_flow_req_arr((uint8_t *) (msg + 1), - ipcp_dir_hash_len(), - qs, - buf + msg_len, - len - msg_len); - if (fd < 0) { - pthread_mutex_unlock(&ipcpi.alloc_lock); - log_err("Failed to get fd for flow."); - continue; - } + data.data = (uint8_t *) msg + sizeof(*msg); + data.len = len - sizeof(*msg); - flow = &fa.flows[fd]; + pthread_rwlock_wrlock(&fa.flows_lock); - pthread_rwlock_wrlock(&fa.flows_lock); + fd = eid_to_fd(ntoh64(msg->r_eid)); + if (fd < 0) { + pthread_rwlock_unlock(&fa.flows_lock); + log_err("Flow reply for unknown EID %" PRIu64 ".", + ntoh64(msg->r_eid)); + return -ENOTALLOC; + } - fa_flow_init(flow); + flow = &fa.flows[fd]; - flow->s_eid = gen_eid(fd); - flow->r_eid = ntoh64(msg->s_eid); - flow->r_addr = ntoh64(msg->s_addr); + flow->r_eid = ntoh64(msg->s_eid); - pthread_rwlock_unlock(&fa.flows_lock); + if (msg->response < 0) + fa_flow_fini(flow); + else + psched_add(fa.psched, fd); - ipcpi.alloc_id = fd; - pthread_cond_broadcast(&ipcpi.alloc_cond); + pthread_rwlock_unlock(&fa.flows_lock); - pthread_mutex_unlock(&ipcpi.alloc_lock); + if (ipcp_flow_alloc_reply(fd, msg->response, mpl, &data) < 0) { + log_err("Failed to reply for flow allocation on fd %d.", fd); + return -EIRMD; + } - break; - case FLOW_REPLY: - assert(len >= sizeof(*msg)); + return 0; +} - pthread_rwlock_wrlock(&fa.flows_lock); +static int fa_handle_flow_update(struct fa_msg * msg, + size_t len) +{ + struct fa_flow * flow; + int fd; - fd = eid_to_fd(ntoh64(msg->r_eid)); - if (fd < 0) { - pthread_rwlock_unlock(&fa.flows_lock); - break; - } + (void) len; + assert(len >= sizeof(*msg)); - flow = &fa.flows[fd]; + pthread_rwlock_wrlock(&fa.flows_lock); - flow->r_eid = ntoh64(msg->s_eid); + fd = eid_to_fd(ntoh64(msg->r_eid)); + if (fd < 0) { + pthread_rwlock_unlock(&fa.flows_lock); + log_err("Flow update for unknown EID %" PRIu64 ".", + ntoh64(msg->r_eid)); + return -EPERM; + } - if (msg->response < 0) - fa_flow_fini(flow); - else - psched_add(fa.psched, fd); + flow = &fa.flows[fd]; +#ifdef IPCP_FLOW_STATS + flow->u_rcv++; +#endif + ca_ctx_update_ece(flow->ctx, ntoh16(msg->ece)); - pthread_rwlock_unlock(&fa.flows_lock); + pthread_rwlock_unlock(&fa.flows_lock); - ipcp_flow_alloc_reply(fd, - msg->response, - buf + sizeof(*msg), - len - sizeof(*msg)); - break; - case FLOW_UPDATE: - assert(len >= sizeof(*msg)); + return 0; +} - pthread_rwlock_wrlock(&fa.flows_lock); +static void * fa_handle_packet(void * o) +{ + (void) o; - fd = eid_to_fd(ntoh64(msg->r_eid)); - if (fd < 0) { - pthread_rwlock_unlock(&fa.flows_lock); - break; - } + while (true) { + uint8_t buf[MSGBUFSZ]; + struct fa_msg * msg; + size_t len; - flow = &fa.flows[fd]; -#ifdef IPCP_FLOW_STATS - flow->u_rcv++; -#endif - ca_ctx_update_ece(flow->ctx, ntoh16(msg->ece)); + msg = (struct fa_msg *) buf; - pthread_rwlock_unlock(&fa.flows_lock); + len = fa_wait_for_fa_msg(msg); + if (len == 0) + continue; + switch (msg->code) { + case FLOW_REQ: + if (fa_handle_flow_req(msg, len) < 0) + log_err("Error handling flow alloc request."); + break; + case FLOW_REPLY: + if (fa_handle_flow_reply(msg, len) < 0) + log_err("Error handling flow reply."); + break; + case FLOW_UPDATE: + if (fa_handle_flow_update(msg, len) < 0) + log_err("Error handling flow update."); break; default: - log_err("Got an unknown flow allocation message."); + log_warn("Recieved unknown flow allocation message."); break; } } @@ -644,7 +669,7 @@ int fa_init(void) fail_mtx: pthread_rwlock_destroy(&fa.flows_lock); fail_rwlock: - log_err("Failed to initialize flow allocator."); + return -1; } @@ -663,7 +688,7 @@ int fa_start(void) int pol; int max; - fa.psched = psched_create(packet_handler); + fa.psched = psched_create(packet_handler, np1_flow_read); if (fa.psched == NULL) { log_err("Failed to start packet scheduler."); goto fail_psched; @@ -700,7 +725,6 @@ int fa_start(void) fail_thread: psched_destroy(fa.psched); fail_psched: - log_err("Failed to start flow allocator."); return -1; } @@ -712,11 +736,10 @@ void fa_stop(void) psched_destroy(fa.psched); } -int fa_alloc(int fd, - const uint8_t * dst, - qosspec_t qs, - const void * data, - size_t dlen) +int fa_alloc(int fd, + const uint8_t * dst, + qosspec_t qs, + const buffer_t * data) { struct fa_msg * msg; struct shm_du_buff * sdb; @@ -732,7 +755,7 @@ int fa_alloc(int fd, len = sizeof(*msg) + ipcp_dir_hash_len(); - if (ipcp_sdb_reserve(&sdb, len + dlen)) + if (ipcp_sdb_reserve(&sdb, len + data->len)) return -1; msg = (struct fa_msg *) shm_du_buff_head(sdb); @@ -751,11 +774,14 @@ int fa_alloc(int fd, msg->in_order = qs.in_order; msg->max_gap = hton32(qs.max_gap); msg->cypher_s = hton16(qs.cypher_s); + msg->timeout = hton32(qs.timeout); memcpy(msg + 1, dst, ipcp_dir_hash_len()); - memcpy(shm_du_buff_head(sdb) + len, data, dlen); + if (data->len > 0) + memcpy(shm_du_buff_head(sdb) + len, data->data, data->len); if (dt_write_packet(addr, qc, fa.eid, sdb)) { + log_err("Failed to send flow allocation request packet."); ipcp_sdb_release(sdb); return -1; } @@ -773,75 +799,66 @@ int fa_alloc(int fd, return 0; } -int fa_alloc_resp(int fd, - int response, - const void * data, - size_t len) +int fa_alloc_resp(int fd, + int response, + const buffer_t * data) { - struct timespec ts = {0, TIMEOUT * 1000}; - struct timespec abstime; struct fa_msg * msg; struct shm_du_buff * sdb; struct fa_flow * flow; qoscube_t qc = QOS_CUBE_BE; - clock_gettime(PTHREAD_COND_CLOCK, &abstime); - flow = &fa.flows[fd]; - pthread_mutex_lock(&ipcpi.alloc_lock); - - while (ipcpi.alloc_id != fd && ipcp_get_state() == IPCP_OPERATIONAL) { - ts_add(&abstime, &ts, &abstime); - pthread_cond_timedwait(&ipcpi.alloc_cond, - &ipcpi.alloc_lock, - &abstime); + if (ipcp_wait_flow_resp(fd) < 0) { + log_err("Failed to wait for flow response."); + goto fail_alloc_resp; } - if (ipcp_get_state() != IPCP_OPERATIONAL) { - pthread_mutex_unlock(&ipcpi.alloc_lock); - return -1; - } - - ipcpi.alloc_id = -1; - pthread_cond_broadcast(&ipcpi.alloc_cond); - - pthread_mutex_unlock(&ipcpi.alloc_lock); - - if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + len)) { - fa_flow_fini(flow); - return -1; + if (ipcp_sdb_reserve(&sdb, sizeof(*msg) + data->len)) { + log_err("Failed to reserve sdb (%zu bytes).", + sizeof(*msg) + data->len); + goto fail_reserve; } msg = (struct fa_msg *) shm_du_buff_head(sdb); memset(msg, 0, sizeof(*msg)); - pthread_rwlock_wrlock(&fa.flows_lock); - msg->code = FLOW_REPLY; + msg->response = response; + if (data->len > 0) + memcpy(msg + 1, data->data, data->len); + + pthread_rwlock_rdlock(&fa.flows_lock); + msg->r_eid = hton64(flow->r_eid); msg->s_eid = hton64(flow->s_eid); - msg->response = response; - memcpy(msg + 1, data, len); + pthread_rwlock_unlock(&fa.flows_lock); + + if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) { + log_err("Failed to send flow allocation response packet."); + goto fail_packet; + } if (response < 0) { + pthread_rwlock_rdlock(&fa.flows_lock); fa_flow_fini(flow); - ipcp_sdb_release(sdb); + pthread_rwlock_unlock(&fa.flows_lock); } else { psched_add(fa.psched, fd); } - if (dt_write_packet(flow->r_addr, qc, fa.eid, sdb)) { - fa_flow_fini(flow); - pthread_rwlock_unlock(&fa.flows_lock); - ipcp_sdb_release(sdb); - return -1; - } + return 0; + fail_packet: + ipcp_sdb_release(sdb); + fail_reserve: + pthread_rwlock_wrlock(&fa.flows_lock); + fa_flow_fini(flow); pthread_rwlock_unlock(&fa.flows_lock); - - return 0; + fail_alloc_resp: + return -1; } int fa_dealloc(int fd) @@ -857,7 +874,7 @@ int fa_dealloc(int fd) pthread_rwlock_unlock(&fa.flows_lock); - flow_dealloc(fd); + ipcp_flow_dealloc(fd); return 0; } @@ -872,6 +889,7 @@ static int fa_update_remote(int fd, uint64_t r_addr; if (ipcp_sdb_reserve(&sdb, sizeof(*msg))) { + log_err("Failed to reserve sdb (%zu bytes).", sizeof(*msg)); return -1; } @@ -895,6 +913,7 @@ static int fa_update_remote(int fd, if (dt_write_packet(r_addr, qc, fa.eid, sdb)) { + log_err("Failed to send flow update packet."); ipcp_sdb_release(sdb); return -1; } @@ -912,13 +931,14 @@ void fa_np1_rcv(uint64_t eid, int fd; size_t len; - len = shm_du_buff_tail(sdb) - shm_du_buff_head(sdb); + len = shm_du_buff_len(sdb); pthread_rwlock_wrlock(&fa.flows_lock); fd = eid_to_fd(eid); if (fd < 0) { pthread_rwlock_unlock(&fa.flows_lock); + log_dbg("Received packet for unknown EID %" PRIu64 ".", eid); ipcp_sdb_release(sdb); return; } @@ -934,6 +954,7 @@ void fa_np1_rcv(uint64_t eid, pthread_rwlock_unlock(&fa.flows_lock); if (ipcp_flow_write(fd, sdb) < 0) { + log_dbg("Failed to write to flow %d.", fd); ipcp_sdb_release(sdb); #ifdef IPCP_FLOW_STATS pthread_rwlock_wrlock(&fa.flows_lock); diff --git a/src/ipcpd/unicast/fa.h b/src/ipcpd/unicast/fa.h index 376fdb20..1e716966 100644 --- a/src/ipcpd/unicast/fa.h +++ b/src/ipcpd/unicast/fa.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Flow allocator of the IPC Process * @@ -34,16 +34,14 @@ int fa_start(void); void fa_stop(void); -int fa_alloc(int fd, - const uint8_t * dst, - qosspec_t qs, - const void * data, - size_t len); +int fa_alloc(int fd, + const uint8_t * dst, + qosspec_t qs, + const buffer_t * data); -int fa_alloc_resp(int fd, - int response, - const void * data, - size_t len); +int fa_alloc_resp(int fd, + int response, + const buffer_t * data); int fa_dealloc(int fd); diff --git a/src/ipcpd/unicast/main.c b/src/ipcpd/unicast/main.c index 018dd1c6..e6cb2994 100644 --- a/src/ipcpd/unicast/main.c +++ b/src/ipcpd/unicast/main.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Unicast IPC Process * @@ -32,16 +32,16 @@ #define THIS_TYPE IPCP_UNICAST #include <ouroboros/errno.h> -#include <ouroboros/hash.h> #include <ouroboros/ipcp-dev.h> #include <ouroboros/logs.h> #include <ouroboros/notifier.h> +#include <ouroboros/random.h> #include <ouroboros/rib.h> -#include <ouroboros/time_utils.h> +#include <ouroboros/time.h> #include "common/connmgr.h" #include "common/enroll.h" -#include "addr_auth.h" +#include "addr-auth.h" #include "ca.h" #include "dir.h" #include "dt.h" @@ -59,18 +59,13 @@ struct ipcp ipcpi; static int initialize_components(const struct ipcp_config * conf) { - ipcpi.layer_name = strdup(conf->layer_info.layer_name); - if (ipcpi.layer_name == NULL) { - log_err("Failed to set layer name."); - goto fail_layer_name; - } - - ipcpi.dir_hash_algo = conf->layer_info.dir_hash_algo; + strcpy(ipcpi.layer_name, conf->layer_info.name); + ipcpi.dir_hash_algo = (enum hash_algo) conf->layer_info.dir_hash_algo; assert(ipcp_dir_hash_len() != 0); - if (addr_auth_init(conf->addr_auth_type, - &conf->addr_size)) { + if (addr_auth_init(conf->unicast.addr_auth_type, + &conf->unicast.dt.addr_size)) { log_err("Failed to init address authority."); goto fail_addr_auth; } @@ -81,17 +76,14 @@ static int initialize_components(const struct ipcp_config * conf) goto fail_addr_auth; } - log_dbg("IPCP got address %" PRIu64 ".", ipcpi.dt_addr); + log_info("IPCP got address %" PRIu64 ".", ipcpi.dt_addr); - if (ca_init(conf->cong_avoid)) { + if (ca_init(conf->unicast.cong_avoid)) { log_err("Failed to initialize congestion avoidance."); goto fail_ca; } - if (dt_init(conf->routing_type, - conf->addr_size, - conf->eid_size, - conf->max_ttl)) { + if (dt_init(conf->unicast.dt)) { log_err("Failed to initialize data transfer component."); goto fail_dt; } @@ -119,8 +111,6 @@ static int initialize_components(const struct ipcp_config * conf) fail_ca: addr_auth_fini(); fail_addr_auth: - free(ipcpi.layer_name); - fail_layer_name: return -1; } @@ -135,27 +125,26 @@ static void finalize_components(void) ca_fini(); addr_auth_fini(); - - free(ipcpi.layer_name); } static int start_components(void) { - assert(ipcp_get_state() == IPCP_INIT); - - ipcp_set_state(IPCP_OPERATIONAL); + if (dt_start() < 0) { + log_err("Failed to start data transfer."); + goto fail_dt_start; + } - if (fa_start()) { + if (fa_start() < 0) { log_err("Failed to start flow allocator."); goto fail_fa_start; } - if (enroll_start()) { + if (enroll_start() < 0) { log_err("Failed to start enrollment."); goto fail_enroll_start; } - if (connmgr_start()) { + if (connmgr_start() < 0) { log_err("Failed to start AP connection manager."); goto fail_connmgr_start; } @@ -167,21 +156,22 @@ static int start_components(void) fail_enroll_start: fa_stop(); fail_fa_start: + dt_stop(); + fail_dt_start: ipcp_set_state(IPCP_INIT); return -1; } static void stop_components(void) { - assert(ipcp_get_state() == IPCP_OPERATIONAL || - ipcp_get_state() == IPCP_SHUTDOWN); - connmgr_stop(); enroll_stop(); fa_stop(); + dt_stop(); + ipcp_set_state(IPCP_INIT); } @@ -189,7 +179,6 @@ static int bootstrap_components(void) { if (dir_bootstrap()) { log_err("Failed to bootstrap directory."); - dt_stop(); return -1; } @@ -200,53 +189,54 @@ static int unicast_ipcp_enroll(const char * dst, struct layer_info * info) { struct conn conn; + uint8_t id[ENROLL_ID_LEN]; - if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn)) { - log_err("Failed to get connection."); - goto fail_er_flow; + if (random_buffer(id, ENROLL_ID_LEN) < 0) { + log_err("Failed to generate enrollment ID."); + goto fail_id; } - /* Get boot state from peer. */ - if (enroll_boot(&conn)) { - log_err("Failed to get boot information."); - goto fail_enroll_boot; + log_info_id(id, "Requesting enrollment."); + + if (connmgr_alloc(COMPID_ENROLL, dst, NULL, &conn) < 0) { + log_err_id(id, "Failed to get connection."); + goto fail_id; } - if (initialize_components(enroll_get_conf())) { - log_err("Failed to initialize IPCP components."); + /* Get boot state from peer. */ + if (enroll_boot(&conn, id) < 0) { + log_err_id(id, "Failed to get boot information."); goto fail_enroll_boot; } - if (dt_start()) { - log_err("Failed to initialize IPCP components."); - goto fail_dt_start; + if (initialize_components(enroll_get_conf()) < 0) { + log_err_id(id, "Failed to initialize components."); + goto fail_enroll_boot; } - if (start_components()) { - log_err("Failed to start components."); + if (start_components() < 0) { + log_err_id(id, "Failed to start components."); goto fail_start_comp; } - if (enroll_done(&conn, 0)) - log_warn("Failed to confirm enrollment with peer."); + if (enroll_ack(&conn, id, 0) < 0) + log_err_id(id, "Failed to confirm enrollment."); - if (connmgr_dealloc(COMPID_ENROLL, &conn)) - log_warn("Failed to deallocate enrollment flow."); + if (connmgr_dealloc(COMPID_ENROLL, &conn) < 0) + log_warn_id(id, "Failed to dealloc enrollment flow."); - log_info("Enrolled with %s.", dst); + log_info_id(id, "Enrolled with %s.", dst); - info->dir_hash_algo = ipcpi.dir_hash_algo; - strcpy(info->layer_name, ipcpi.layer_name); + info->dir_hash_algo = (enum pol_dir_hash) ipcpi.dir_hash_algo; + strcpy(info->name, ipcpi.layer_name); return 0; fail_start_comp: - dt_stop(); - fail_dt_start: finalize_components(); fail_enroll_boot: connmgr_dealloc(COMPID_ENROLL, &conn); - fail_er_flow: + fail_id: return -1; } @@ -257,35 +247,26 @@ static int unicast_ipcp_bootstrap(const struct ipcp_config * conf) enroll_bootstrap(conf); - if (initialize_components(conf)) { + if (initialize_components(conf) < 0) { log_err("Failed to init IPCP components."); goto fail_init; } - if (dt_start()) { - log_err("Failed to initialize IPCP components."); - goto fail_dt_start; - }; - - if (start_components()) { + if (start_components() < 0) { log_err("Failed to init IPCP components."); goto fail_start; } - if (bootstrap_components()) { + if (bootstrap_components() < 0) { log_err("Failed to bootstrap IPCP components."); goto fail_bootstrap; } - log_dbg("Bootstrapped in layer %s.", conf->layer_info.layer_name); - return 0; fail_bootstrap: stop_components(); fail_start: - dt_stop(); - fail_dt_start: finalize_components(); fail_init: return -1; @@ -318,40 +299,35 @@ int main(int argc, goto fail_init; } - if (notifier_init()) { + if (notifier_init() < 0) { log_err("Failed to initialize notifier component."); goto fail_notifier_init; } - if (connmgr_init()) { + if (connmgr_init() < 0) { log_err("Failed to initialize connection manager."); goto fail_connmgr_init; } - if (enroll_init()) { + if (enroll_init() < 0) { log_err("Failed to initialize enrollment component."); goto fail_enroll_init; } - if (ipcp_boot() < 0) { - log_err("Failed to boot IPCP."); - goto fail_boot; - } - - if (ipcp_create_r(0)) { - log_err("Failed to notify IRMd we are initialized."); - ipcp_set_state(IPCP_NULL); - goto fail_create_r; + if (ipcp_start() < 0) { + log_err("Failed to start IPCP."); + goto fail_start; } - ipcp_shutdown(); + ipcp_sigwait(); if (ipcp_get_state() == IPCP_SHUTDOWN) { - dt_stop(); stop_components(); finalize_components(); } + ipcp_stop(); + enroll_fini(); connmgr_fini(); @@ -362,17 +338,14 @@ int main(int argc, exit(EXIT_SUCCESS); - fail_create_r: - ipcp_shutdown(); - fail_boot: + fail_start: enroll_fini(); fail_enroll_init: connmgr_fini(); fail_connmgr_init: notifier_fini(); fail_notifier_init: - ipcp_fini(); + ipcp_fini(); fail_init: - ipcp_create_r(-1); exit(EXIT_FAILURE); } diff --git a/src/ipcpd/unicast/pff.c b/src/ipcpd/unicast/pff.c index 03682184..9b2aa2b4 100644 --- a/src/ipcpd/unicast/pff.c +++ b/src/ipcpd/unicast/pff.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * PDU Forwarding Function * @@ -26,14 +26,11 @@ #include <ouroboros/logs.h> #include "pff.h" -#include "pol-pff-ops.h" -#include "pol/alternate_pff.h" -#include "pol/multipath_pff.h" -#include "pol/simple_pff.h" +#include "pff/pol.h" struct pff { - struct pol_pff_ops * ops; - struct pff_i * pff_i; + struct pff_ops * ops; + struct pff_i * pff_i; }; struct pff * pff_create(enum pol_pff pol) @@ -62,8 +59,10 @@ struct pff * pff_create(enum pol_pff pol) } pff->pff_i = pff->ops->create(); - if (pff->pff_i == NULL) + if (pff->pff_i == NULL) { + log_err("Failed to create PFF instance."); goto err; + } return pff; err: diff --git a/src/ipcpd/unicast/pff.h b/src/ipcpd/unicast/pff.h index 3ac9d5fb..f44e5531 100644 --- a/src/ipcpd/unicast/pff.h +++ b/src/ipcpd/unicast/pff.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * PDU Forwarding Function * diff --git a/src/ipcpd/unicast/pol/alternate_pff.c b/src/ipcpd/unicast/pff/alternate.c index 18d3dfed..85e85914 100644 --- a/src/ipcpd/unicast/pol/alternate_pff.c +++ b/src/ipcpd/unicast/pff/alternate.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for PFF with alternate next hops * @@ -28,7 +28,7 @@ #include <ouroboros/list.h> #include "pft.h" -#include "alternate_pff.h" +#include "alternate.h" #include <string.h> #include <assert.h> @@ -54,7 +54,7 @@ struct pff_i { pthread_rwlock_t lock; }; -struct pol_pff_ops alternate_pff_ops = { +struct pff_ops alternate_pff_ops = { .create = alternate_pff_create, .destroy = alternate_pff_destroy, .lock = alternate_pff_lock, diff --git a/src/ipcpd/unicast/pol/alternate_pff.h b/src/ipcpd/unicast/pff/alternate.h index 9c7cc08f..96207e74 100644 --- a/src/ipcpd/unicast/pol/alternate_pff.h +++ b/src/ipcpd/unicast/pff/alternate.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for PFF with alternate next hops * @@ -23,7 +23,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H #define OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H -#include "pol-pff-ops.h" +#include "ops.h" struct pff_i * alternate_pff_create(void); @@ -56,6 +56,6 @@ int alternate_flow_state_change(struct pff_i * pff_i, int fd, bool up); -extern struct pol_pff_ops alternate_pff_ops; +extern struct pff_ops alternate_pff_ops; #endif /* OUROBOROS_IPCPD_UNICAST_ALTERNATE_PFF_H */ diff --git a/src/ipcpd/unicast/pol/multipath_pff.c b/src/ipcpd/unicast/pff/multipath.c index 0d759ec4..cbab0f5f 100644 --- a/src/ipcpd/unicast/pol/multipath_pff.c +++ b/src/ipcpd/unicast/pff/multipath.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for PFF supporting multipath routing * @@ -28,7 +28,7 @@ #include <ouroboros/errno.h> #include "pft.h" -#include "multipath_pff.h" +#include "multipath.h" #include <string.h> #include <assert.h> @@ -39,7 +39,7 @@ struct pff_i { pthread_rwlock_t lock; }; -struct pol_pff_ops multipath_pff_ops = { +struct pff_ops multipath_pff_ops = { .create = multipath_pff_create, .destroy = multipath_pff_destroy, .lock = multipath_pff_lock, @@ -58,21 +58,23 @@ struct pff_i * multipath_pff_create(void) tmp = malloc(sizeof(*tmp)); if (tmp == NULL) - return NULL; + goto fail_malloc; - if (pthread_rwlock_init(&tmp->lock, NULL)) { - free(tmp); - return NULL; - } + if (pthread_rwlock_init(&tmp->lock, NULL)) + goto fail_rwlock; tmp->pft = pft_create(PFT_SIZE, false); - if (tmp->pft == NULL) { - pthread_rwlock_destroy(&tmp->lock); - free(tmp); - return NULL; - } + if (tmp->pft == NULL) + goto fail_pft; return tmp; + + fail_pft: + pthread_rwlock_destroy(&tmp->lock); + fail_rwlock: + free(tmp); + fail_malloc: + return NULL; } void multipath_pff_destroy(struct pff_i * pff_i) @@ -80,8 +82,8 @@ void multipath_pff_destroy(struct pff_i * pff_i) assert(pff_i); pft_destroy(pff_i->pft); - pthread_rwlock_destroy(&pff_i->lock); + free(pff_i); } @@ -177,7 +179,7 @@ int multipath_pff_nhop(struct pff_i * pff_i, assert(pff_i); - pthread_rwlock_rdlock(&pff_i->lock); + pthread_rwlock_wrlock(&pff_i->lock); if (pft_lookup(pff_i->pft, addr, &fds, &len)) { pthread_rwlock_unlock(&pff_i->lock); @@ -189,7 +191,7 @@ int multipath_pff_nhop(struct pff_i * pff_i, assert(len > 0); /* Rotate fds left. */ - memcpy(fds, fds + 1, (len - 1) * sizeof(*fds)); + memmove(fds, fds + 1, (len - 1) * sizeof(*fds)); fds[len - 1] = fd; pthread_rwlock_unlock(&pff_i->lock); diff --git a/src/ipcpd/unicast/pol/multipath_pff.h b/src/ipcpd/unicast/pff/multipath.h index 8168995e..0eb03476 100644 --- a/src/ipcpd/unicast/pol/multipath_pff.h +++ b/src/ipcpd/unicast/pff/multipath.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Policy for PFF supporting multipath routing * @@ -24,7 +24,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H #define OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H -#include "pol-pff-ops.h" +#include "ops.h" struct pff_i * multipath_pff_create(void); @@ -53,6 +53,6 @@ void multipath_pff_flush(struct pff_i * pff_i); int multipath_pff_nhop(struct pff_i * pff_i, uint64_t addr); -extern struct pol_pff_ops multipath_pff_ops; +extern struct pff_ops multipath_pff_ops; #endif /* OUROBOROS_IPCPD_UNICAST_MULTIPATH_PFF_H */ diff --git a/src/ipcpd/unicast/pol-pff-ops.h b/src/ipcpd/unicast/pff/ops.h index 85615a1f..16a31273 100644 --- a/src/ipcpd/unicast/pol-pff-ops.h +++ b/src/ipcpd/unicast/pff/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Pff policy ops * @@ -20,14 +20,14 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H -#define OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H +#ifndef OUROBOROS_IPCPD_UNICAST_PFF_OPS_H +#define OUROBOROS_IPCPD_UNICAST_PFF_OPS_H #include <stdbool.h> struct pff_i; -struct pol_pff_ops { +struct pff_ops { struct pff_i * (* create)(void); void (* destroy)(struct pff_i * pff_i); @@ -60,4 +60,4 @@ struct pol_pff_ops { bool up); }; -#endif /* OUROBOROS_IPCPD_UNICAST_POL_PFF_OPS_H */ +#endif /* OUROBOROS_IPCPD_UNICAST_PFF_OPS_H */ diff --git a/src/ipcpd/unicast/pol/pft.c b/src/ipcpd/unicast/pff/pft.c index e42b4a98..8c436113 100644 --- a/src/ipcpd/unicast/pol/pft.c +++ b/src/ipcpd/unicast/pff/pft.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Packet forwarding table (PFT) with chaining on collisions * @@ -115,19 +115,11 @@ void pft_flush(struct pft * pft) static uint64_t hash(uint64_t key) { - void * res; - uint64_t ret; - uint8_t keys[4]; + uint64_t res[2]; - memcpy(keys, &key, 4); + mem_hash(HASH_MD5, res, (uint8_t *) &key, sizeof(key)); - mem_hash(HASH_MD5, &res, keys, 4); - - ret = (* (uint64_t *) res); - - free(res); - - return ret; + return res[0]; } static uint64_t calc_key(struct pft * pft, diff --git a/src/ipcpd/unicast/pol/pft.h b/src/ipcpd/unicast/pff/pft.h index 011ad414..711dabcb 100644 --- a/src/ipcpd/unicast/pol/pft.h +++ b/src/ipcpd/unicast/pff/pft.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Packet forwarding table (PFT) with chaining on collisions * diff --git a/src/ipcpd/unicast/pff/pol.h b/src/ipcpd/unicast/pff/pol.h new file mode 100644 index 00000000..245b03c4 --- /dev/null +++ b/src/ipcpd/unicast/pff/pol.h @@ -0,0 +1,25 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * PDU Forwarding Function policies + * + * 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/. + */ + +#include "alternate.h" +#include "multipath.h" +#include "simple.h" diff --git a/src/ipcpd/unicast/pol/simple_pff.c b/src/ipcpd/unicast/pff/simple.c index 13944aed..5f95e3ce 100644 --- a/src/ipcpd/unicast/pol/simple_pff.c +++ b/src/ipcpd/unicast/pff/simple.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Simple PDU Forwarding Function * @@ -27,7 +27,7 @@ #include <ouroboros/errno.h> #include "pft.h" -#include "simple_pff.h" +#include "simple.h" #include <assert.h> #include <pthread.h> @@ -37,7 +37,7 @@ struct pff_i { pthread_rwlock_t lock; }; -struct pol_pff_ops simple_pff_ops = { +struct pff_ops simple_pff_ops = { .create = simple_pff_create, .destroy = simple_pff_destroy, .lock = simple_pff_lock, diff --git a/src/ipcpd/unicast/pol/simple_pff.h b/src/ipcpd/unicast/pff/simple.h index 2b22c130..0966a186 100644 --- a/src/ipcpd/unicast/pol/simple_pff.h +++ b/src/ipcpd/unicast/pff/simple.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Simple policy for PFF * @@ -23,7 +23,7 @@ #ifndef OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H #define OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H -#include "pol-pff-ops.h" +#include "ops.h" struct pff_i * simple_pff_create(void); @@ -52,6 +52,6 @@ void simple_pff_flush(struct pff_i * pff_i); int simple_pff_nhop(struct pff_i * pff_i, uint64_t addr); -extern struct pol_pff_ops simple_pff_ops; +extern struct pff_ops simple_pff_ops; #endif /* OUROBOROS_IPCPD_UNICAST_SIMPLE_PFF_H */ diff --git a/src/ipcpd/unicast/pff/tests/CMakeLists.txt b/src/ipcpd/unicast/pff/tests/CMakeLists.txt new file mode 100644 index 00000000..e7082372 --- /dev/null +++ b/src/ipcpd/unicast/pff/tests/CMakeLists.txt @@ -0,0 +1,34 @@ +get_filename_component(CURRENT_SOURCE_PARENT_DIR + ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(CURRENT_BINARY_PARENT_DIR + ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +include_directories(${CURRENT_SOURCE_PARENT_DIR}) +include_directories(${CURRENT_BINARY_PARENT_DIR}) + +include_directories(${CMAKE_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) + +get_filename_component(PARENT_PATH ${CMAKE_CURRENT_SOURCE_DIR} DIRECTORY) +get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) + +create_test_sourcelist(${PARENT_DIR}_tests test_suite.c + # Add new tests here + pft_test.c + ) + +add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) +target_link_libraries(${PARENT_DIR}_test ouroboros-common) + +add_dependencies(check ${PARENT_DIR}_test) + +set(tests_to_run ${${PARENT_DIR}_tests}) +remove(tests_to_run test_suite.c) + +foreach (test ${tests_to_run}) + get_filename_component(test_name ${test} NAME_WE) + add_test(${test_name} ${C_TEST_PATH}/${PARENT_DIR}_test ${test_name}) +endforeach (test) diff --git a/src/ipcpd/unicast/pol/tests/pft_test.c b/src/ipcpd/unicast/pff/tests/pft_test.c index c48267eb..18287fb8 100644 --- a/src/ipcpd/unicast/pol/tests/pft_test.c +++ b/src/ipcpd/unicast/pff/tests/pft_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the hash table * diff --git a/src/ipcpd/unicast/psched.c b/src/ipcpd/unicast/psched.c index 33ac5afe..7e12148b 100644 --- a/src/ipcpd/unicast/psched.c +++ b/src/ipcpd/unicast/psched.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Packet scheduler component * @@ -50,6 +50,7 @@ static int qos_prio [] = { struct psched { fset_t * set[QOS_CUBE_MAX]; next_packet_fn_t callback; + read_fn_t read; pthread_t readers[QOS_CUBE_MAX * IPCP_SCHED_THR_MUL]; }; @@ -101,7 +102,7 @@ static void * packet_reader(void * o) notifier_event(NOTIFY_DT_FLOW_UP, &fd); break; case FLOW_PKT: - if (ipcp_flow_read(fd, &sdb)) + if (sched->read(fd, &sdb) < 0) continue; sched->callback(fd, qc, sdb); @@ -117,7 +118,8 @@ static void * packet_reader(void * o) return (void *) 0; } -struct psched * psched_create(next_packet_fn_t callback) +struct psched * psched_create(next_packet_fn_t callback, + read_fn_t read) { struct psched * psched; struct sched_info * infos[QOS_CUBE_MAX * IPCP_SCHED_THR_MUL]; @@ -131,6 +133,7 @@ struct psched * psched_create(next_packet_fn_t callback) goto fail_malloc; psched->callback = callback; + psched->read = read; for (i = 0; i < QOS_CUBE_MAX; ++i) { psched->set[i] = fset_create(); diff --git a/src/ipcpd/unicast/psched.h b/src/ipcpd/unicast/psched.h index 1f22b34b..831f8084 100644 --- a/src/ipcpd/unicast/psched.h +++ b/src/ipcpd/unicast/psched.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Packet scheduler component * @@ -30,7 +30,11 @@ typedef void (* next_packet_fn_t)(int fd, qoscube_t qc, struct shm_du_buff * sdb); -struct psched * psched_create(next_packet_fn_t callback); +typedef int (* read_fn_t)(int fd, + struct shm_du_buff ** sdb); + +struct psched * psched_create(next_packet_fn_t callback, + read_fn_t read); void psched_destroy(struct psched * psched); diff --git a/src/ipcpd/unicast/routing.c b/src/ipcpd/unicast/routing.c index 1b13ae0e..f5417c24 100644 --- a/src/ipcpd/unicast/routing.c +++ b/src/ipcpd/unicast/routing.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Routing component of the IPCP * @@ -26,9 +26,9 @@ #include "pff.h" #include "routing.h" -#include "pol/link_state.h" +#include "routing/pol.h" -struct pol_routing_ops * r_ops; +struct routing_ops * r_ops; int routing_init(enum pol_routing pr) { diff --git a/src/ipcpd/unicast/routing.h b/src/ipcpd/unicast/routing.h index 2eaaeb68..d5d833ae 100644 --- a/src/ipcpd/unicast/routing.h +++ b/src/ipcpd/unicast/routing.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Routing component of the IPCP * diff --git a/src/ipcpd/unicast/pol/graph.c b/src/ipcpd/unicast/routing/graph.c index 6ea5c507..32f3e6fb 100644 --- a/src/ipcpd/unicast/pol/graph.c +++ b/src/ipcpd/unicast/routing/graph.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Undirected graph structure * diff --git a/src/ipcpd/unicast/pol/graph.h b/src/ipcpd/unicast/routing/graph.h index 632cc5a0..8190cc6c 100644 --- a/src/ipcpd/unicast/pol/graph.h +++ b/src/ipcpd/unicast/routing/graph.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Undirected graph structure * diff --git a/src/ipcpd/unicast/pol/link_state.c b/src/ipcpd/unicast/routing/link-state.c index 08d39372..57c0c7cb 100644 --- a/src/ipcpd/unicast/pol/link_state.c +++ b/src/ipcpd/unicast/routing/link-state.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Link state routing policy * @@ -46,7 +46,7 @@ #include "common/connmgr.h" #include "graph.h" #include "ipcp.h" -#include "link_state.h" +#include "link-state.h" #include "pff.h" #include <assert.h> @@ -127,7 +127,7 @@ struct { enum routing_algo routing_algo; } ls; -struct pol_routing_ops link_state_ops = { +struct routing_ops link_state_ops = { .init = link_state_init, .fini = link_state_fini, .routing_i_create = link_state_routing_i_create, @@ -273,7 +273,7 @@ static int lsdb_rib_readdir(char *** buf) if ((*buf)[idx] == NULL) { while (idx-- > 0) free((*buf)[idx]); - free(buf); + free(*buf); pthread_rwlock_unlock(&ls.db_lock); return -ENOMEM; } diff --git a/src/ipcpd/unicast/pol/link_state.h b/src/ipcpd/unicast/routing/link-state.h index 05b0ae5d..d77d72df 100644 --- a/src/ipcpd/unicast/pol/link_state.h +++ b/src/ipcpd/unicast/routing/link-state.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Link state routing policy * @@ -26,7 +26,7 @@ #define LS_COMP "Management" #define LS_PROTO "LSP" -#include "pol-routing-ops.h" +#include "ops.h" int link_state_init(enum pol_routing pr); @@ -36,6 +36,6 @@ struct routing_i * link_state_routing_i_create(struct pff * pff); void link_state_routing_i_destroy(struct routing_i * instance); -extern struct pol_routing_ops link_state_ops; +extern struct routing_ops link_state_ops; #endif /* OUROBOROS_IPCPD_UNICAST_POL_LINK_STATE_H */ diff --git a/src/ipcpd/unicast/pol-routing-ops.h b/src/ipcpd/unicast/routing/ops.h index cea88582..8a79b7ec 100644 --- a/src/ipcpd/unicast/pol-routing-ops.h +++ b/src/ipcpd/unicast/routing/ops.h @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Routing policy ops * @@ -20,12 +20,12 @@ * Foundation, Inc., http://www.fsf.org/about/contact/. */ -#ifndef OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H -#define OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H +#ifndef OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H +#define OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H #include "pff.h" -struct pol_routing_ops { +struct routing_ops { int (* init)(enum pol_routing pr); void (* fini)(void); @@ -35,4 +35,4 @@ struct pol_routing_ops { void (* routing_i_destroy)(struct routing_i * instance); }; -#endif /* OUROBOROS_IPCPD_UNICAST_POL_ROUTING_OPS_H */ +#endif /* OUROBOROS_IPCPD_UNICAST_ROUTING_OPS_H */ diff --git a/src/ipcpd/unicast/routing/pol.h b/src/ipcpd/unicast/routing/pol.h new file mode 100644 index 00000000..b6a6f150 --- /dev/null +++ b/src/ipcpd/unicast/routing/pol.h @@ -0,0 +1,23 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2024 + * + * Routing policies + * + * 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/. + */ + +#include "link-state.h" diff --git a/src/ipcpd/unicast/pol/tests/CMakeLists.txt b/src/ipcpd/unicast/routing/tests/CMakeLists.txt index 34d80e8d..d0652533 100644 --- a/src/ipcpd/unicast/pol/tests/CMakeLists.txt +++ b/src/ipcpd/unicast/routing/tests/CMakeLists.txt @@ -18,7 +18,6 @@ get_filename_component(PARENT_DIR ${PARENT_PATH} NAME) create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here graph_test.c - pft_test.c ) add_executable(${PARENT_DIR}_test EXCLUDE_FROM_ALL ${${PARENT_DIR}_tests}) diff --git a/src/ipcpd/unicast/pol/tests/graph_test.c b/src/ipcpd/unicast/routing/tests/graph_test.c index 217c7eab..d805640c 100644 --- a/src/ipcpd/unicast/pol/tests/graph_test.c +++ b/src/ipcpd/unicast/routing/tests/graph_test.c @@ -1,5 +1,5 @@ /* - * Ouroboros - Copyright (C) 2016 - 2021 + * Ouroboros - Copyright (C) 2016 - 2024 * * Test of the graph structure * |