Browse Source

refactor: переименование route_node/route_bgp в topo_node/topo_bgp

Файлы: route_node.* route_node_lmdb.* route_bgp.* -> topo_node.* topo_node_lmdb.* topo_bgp.*

Структуры:
- ROUTE_BGP -> TOPO_BGP, ROUTE_BGP_CONN_ITEM -> TOPO_BGP_CONN_ITEM
- NODEINFO -> TOPO_NODE, NODEINFO_Q -> TOPO_NODEQ, NODEINFO_PATH -> TOPO_NODEPATH
- NODEINFO_ROUTES -> TOPO_NODESUBNETS, NODE_CONNECTIVITY -> TOPO_CONNECTIVITY
- wire: NODEINFO_MSG -> TOPOMSG_NODE, NODEINFO_IPV4_* -> TOPOMSG_*4 и т.д.
- memory: NI_IPV4_* -> TOPO_*4, NI_IPV6_* -> TOPO_*6
- ROUTE_SUBCMD_* -> TOPO_SUBCMD_*, ETCP_ID_ROUTE_ENTRY -> ETCP_ID_TOPO_ENTRY

Функции:
- route_bgp_* -> topo_bgp_*
- nodeinfo_* -> topo_node_*
- route_node_* -> topo_node_*
- route_node_lmdb_* -> topo_node_lmdb_*

Смысл: отделение механизма формирования топологии узлов от IP-роутинга.
chatgui
Evgeny 3 months ago
parent
commit
3c3d9a65d9
  1. 2
      build_direct.sh
  2. 24
      compile_commands.json
  3. 4
      cross-build-win.sh
  4. 12
      src/Makefile.am
  5. 122
      src/conn_mgr.c
  6. 6
      src/conn_mgr.h
  7. 20
      src/control_server.c
  8. 4
      src/control_server.h
  9. 6
      src/db_sync.c
  10. 6
      src/etcp.c
  11. 4
      src/etcp_api.h
  12. 20
      src/etcp_connect.c
  13. 18
      src/etcp_connections.c
  14. 42
      src/etcp_router.c
  15. 6
      src/msg_transport.c
  16. 10
      src/route6_lib.c
  17. 6
      src/route6_lib.h
  18. 30
      src/route_connectivity.c
  19. 6
      src/route_connectivity.h
  20. 18
      src/route_lib.c
  21. 8
      src/route_lib.h
  22. 23
      src/route_node_lmdb.h
  23. 48
      src/route_ping.c
  24. 28
      src/route_ping.h
  25. 4
      src/routing.c
  26. 427
      src/topo_bgp.c
  27. 90
      src/topo_bgp.h
  28. 335
      src/topo_node.c
  29. 130
      src/topo_node.h
  30. 14
      src/topo_node_lmdb.c
  31. 23
      src/topo_node_lmdb.h
  32. 10
      src/utun_instance.c
  33. 4
      src/utun_instance.h
  34. 2
      tests/test_bgp_route_exchange.c
  35. 16
      tests/test_bgp_triangle.c
  36. 10
      tests/test_conn_mgr.c
  37. 30
      tests/test_etcp_connect.c
  38. 2
      tests/test_etcp_router.c
  39. 28
      tests/test_etcp_router_reconnect.c
  40. 12
      tests/test_etcp_router_unit.c
  41. 30
      tests/test_ipv6_sockets.c
  42. 32
      tests/test_nat_detection.c
  43. 6
      tests/test_nat_transport.c
  44. 54
      tests/test_route6_lib.c
  45. 36
      tests/test_route_lib.c
  46. 10
      tests/test_route_ping.c
  47. 6
      tests/test_stcp_traffic.c
  48. 6
      tools/chatgui/libutun/CMakeLists.txt
  49. 6
      tools/chatgui/transport/chat_core.c
  50. 4
      tools/etcpmon/etcpmon_protocol.h

2
build_direct.sh

@ -70,7 +70,7 @@ echo "Building utun.exe..."
cd src cd src
EXE_NEEDS_REBUILD=0 EXE_NEEDS_REBUILD=0
CORE_SOURCES="utun.c utun_instance.c config_parser.c config_updater.c route_lib.c route_bgp.c routing.c tun_if.c tun_route.c etcp.c etcp_connections.c etcp_loadbalancer.c secure_channel.c crc32.c pkt_normalizer.c etcp_api.c tun_windows.c" CORE_SOURCES="utun.c utun_instance.c config_parser.c config_updater.c route_lib.c topo_bgp.c routing.c tun_if.c tun_route.c etcp.c etcp_connections.c etcp_loadbalancer.c secure_channel.c crc32.c pkt_normalizer.c etcp_api.c tun_windows.c"
for src in $CORE_SOURCES; do for src in $CORE_SOURCES; do
if [ -f "$src" ]; then if [ -f "$src" ]; then

24
compile_commands.json

@ -500,12 +500,12 @@
"-O2", "-O2",
"-c", "-c",
"-o", "-o",
"libutun_a-route_bgp.o", "libutun_a-topo_bgp.o",
"route_bgp.c" "topo_bgp.c"
], ],
"directory": "/home/vnc1/proj/utun3/src", "directory": "/home/vnc1/proj/utun3/src",
"file": "/home/vnc1/proj/utun3/src/route_bgp.c", "file": "/home/vnc1/proj/utun3/src/topo_bgp.c",
"output": "/home/vnc1/proj/utun3/src/libutun_a-route_bgp.o" "output": "/home/vnc1/proj/utun3/src/libutun_a-topo_bgp.o"
}, },
{ {
"arguments": [ "arguments": [
@ -540,12 +540,12 @@
"-O2", "-O2",
"-c", "-c",
"-o", "-o",
"libutun_a-route_node.o", "libutun_a-topo_node.o",
"route_node.c" "topo_node.c"
], ],
"directory": "/home/vnc1/proj/utun3/src", "directory": "/home/vnc1/proj/utun3/src",
"file": "/home/vnc1/proj/utun3/src/route_node.c", "file": "/home/vnc1/proj/utun3/src/topo_node.c",
"output": "/home/vnc1/proj/utun3/src/libutun_a-route_node.o" "output": "/home/vnc1/proj/utun3/src/libutun_a-topo_node.o"
}, },
{ {
"arguments": [ "arguments": [
@ -560,12 +560,12 @@
"-O2", "-O2",
"-c", "-c",
"-o", "-o",
"libutun_a-route_node_lmdb.o", "libutun_a-topo_node_lmdb.o",
"route_node_lmdb.c" "topo_node_lmdb.c"
], ],
"directory": "/home/vnc1/proj/utun3/src", "directory": "/home/vnc1/proj/utun3/src",
"file": "/home/vnc1/proj/utun3/src/route_node_lmdb.c", "file": "/home/vnc1/proj/utun3/src/topo_node_lmdb.c",
"output": "/home/vnc1/proj/utun3/src/libutun_a-route_node_lmdb.o" "output": "/home/vnc1/proj/utun3/src/libutun_a-topo_node_lmdb.o"
}, },
{ {
"arguments": [ "arguments": [

4
cross-build-win.sh

@ -194,8 +194,8 @@ mkdir -p "$SRC_OBJDIR"
# Все .c файлы из src/Makefile.am (utun_CORE_SOURCES) # Все .c файлы из src/Makefile.am (utun_CORE_SOURCES)
SRC_SOURCES=( SRC_SOURCES=(
utun.c utun_instance.c config_parser.c config_updater.c utun.c utun_instance.c config_parser.c config_updater.c
route_lib.c route6_lib.c route_bgp.c route_ping.c route_lib.c route6_lib.c topo_bgp.c route_ping.c
route_node.c route_node_lmdb.c route_connectivity.c conn_mgr.c topo_node.c topo_node_lmdb.c route_connectivity.c conn_mgr.c
routing.c tun_if.c tun_route.c tun_linux.c tun_freebsd.c tun_windows.c routing.c tun_if.c tun_route.c tun_linux.c tun_freebsd.c tun_windows.c
etcp.c etcp_connections.c etcp_bbr.c etcp_loadbalancer.c etcp.c etcp_connections.c etcp_bbr.c etcp_loadbalancer.c
etcp_debug.c etcp_dump.c secure_channel.c crc32.c etcp_debug.c etcp_dump.c secure_channel.c crc32.c

12
src/Makefile.am

@ -9,10 +9,10 @@ utun_CORE_SOURCES = \
config_updater.c \ config_updater.c \
route_lib.c \ route_lib.c \
route6_lib.c \ route6_lib.c \
route_bgp.c \ topo_bgp.c \
route_ping.c \ route_ping.c \
route_node.c \ topo_node.c \
route_node_lmdb.c \ topo_node_lmdb.c \
route_connectivity.c \ route_connectivity.c \
conn_mgr.c \ conn_mgr.c \
db_sync.c \ db_sync.c \
@ -62,10 +62,10 @@ libutun_a_SOURCES = \
config_updater.c \ config_updater.c \
route_lib.c \ route_lib.c \
route6_lib.c \ route6_lib.c \
route_bgp.c \ topo_bgp.c \
route_ping.c \ route_ping.c \
route_node.c \ topo_node.c \
route_node_lmdb.c \ topo_node_lmdb.c \
route_connectivity.c \ route_connectivity.c \
conn_mgr.c \ conn_mgr.c \
db_sync.c \ db_sync.c \

122
src/conn_mgr.c

@ -17,8 +17,8 @@
#include "etcp_router.h" #include "etcp_router.h"
#include "config_parser.h" #include "config_parser.h"
#include "secure_channel.h" #include "secure_channel.h"
#include "route_node.h" #include "topo_node.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_ping.h" #include "route_ping.h"
#include "route_connectivity.h" #include "route_connectivity.h"
#include "conn_mgr.h" #include "conn_mgr.h"
@ -32,13 +32,13 @@ static void cm_idle_timer_cb(void* arg);
static void cm_deliver_result(struct CONN_MGR_ENTRY* entry, int result); static void cm_deliver_result(struct CONN_MGR_ENTRY* entry, int result);
static void cm_bg_ping_timer_cb(void* arg); static void cm_bg_ping_timer_cb(void* arg);
static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_config_type, uint8_t target_nat_type); static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_config_type, uint8_t target_nat_type);
static uint16_t cm_get_node_min_rtt(struct NODEINFO_Q* nq); static uint16_t cm_get_node_min_rtt(struct TOPO_NODEQ* nq);
static int cm_has_direct_ip(struct NODEINFO_Q* nq); static int cm_has_direct_ip(struct TOPO_NODEQ* nq);
static int cm_has_local_addr(struct NODEINFO_Q* nq); static int cm_has_local_addr(struct TOPO_NODEQ* nq);
static void cm_entry_destroy(struct CONN_MGR_ENTRY* entry); static void cm_entry_destroy(struct CONN_MGR_ENTRY* entry);
static void cm_exchange_probe_retry_cb(void* arg); static void cm_exchange_probe_retry_cb(void* arg);
static uint64_t cm_get_node_max_probe_time(struct NODEINFO_Q* nq); static uint64_t cm_get_node_max_probe_time(struct TOPO_NODEQ* nq);
static int cm_is_rtt_fresh(struct NODEINFO_Q* nq, uint64_t now_tb); static int cm_is_rtt_fresh(struct TOPO_NODEQ* nq, uint64_t now_tb);
static void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry); static void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry);
static void cm_handle_direct_req(struct ETCP_CONN* conn, const uint8_t* data, size_t len); static void cm_handle_direct_req(struct ETCP_CONN* conn, const uint8_t* data, size_t len);
@ -157,9 +157,9 @@ static void cm_deliver_result(struct CONN_MGR_ENTRY* entry, int result) {
} }
static void cm_update_nodeinfo(struct CONN_MGR_ENTRY* entry) { static void cm_update_nodeinfo(struct CONN_MGR_ENTRY* entry) {
struct ROUTE_BGP* bgp = entry->mgr->instance->bgp; struct TOPO_BGP* bgp = entry->mgr->instance->bgp;
if (!bgp) return; if (!bgp) return;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, entry->node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, entry->node_id);
if (!nq) return; if (!nq) return;
nq->conn_mgr_type = entry->conn_type; nq->conn_mgr_type = entry->conn_type;
memcpy(nq->conn_mgr_intermediaries, entry->intermediaries, sizeof(entry->intermediaries)); memcpy(nq->conn_mgr_intermediaries, entry->intermediaries, sizeof(entry->intermediaries));
@ -167,7 +167,7 @@ static void cm_update_nodeinfo(struct CONN_MGR_ENTRY* entry) {
} }
static void cm_clear_nodeinfo(struct CONN_MGR* mgr, uint64_t node_id) { static void cm_clear_nodeinfo(struct CONN_MGR* mgr, uint64_t node_id) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(mgr->instance->bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, node_id);
if (!nq) return; if (!nq) return;
nq->conn_mgr_type = CONN_TYPE_NONE; nq->conn_mgr_type = CONN_TYPE_NONE;
nq->conn_mgr_intermediariy_count = 0; nq->conn_mgr_intermediariy_count = 0;
@ -176,9 +176,9 @@ static void cm_clear_nodeinfo(struct CONN_MGR* mgr, uint64_t node_id) {
int conn_mgr_connect_node(struct CONN_MGR* mgr, uint64_t node_id, uint32_t idle_timeout_ms, int conn_mgr_connect_node(struct CONN_MGR* mgr, uint64_t node_id, uint32_t idle_timeout_ms,
conn_mgr_connect_callback_t cb, void* cb_arg) { conn_mgr_connect_callback_t cb, void* cb_arg) {
if (!mgr) return CONN_MGR_ERR_INTERNAL; if (!mgr) return CONN_MGR_ERR_INTERNAL;
struct ROUTE_BGP* bgp = mgr->instance->bgp; struct TOPO_BGP* bgp = mgr->instance->bgp;
if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr_connect: BGP not initialized"); return CONN_MGR_ERR_INTERNAL; } if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr_connect: BGP not initialized"); return CONN_MGR_ERR_INTERNAL; }
struct NODEINFO_Q* target = nodeinfo_find_by_id(bgp, node_id); struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, node_id);
if (!target) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr_connect: node 0x%016llx not found", (unsigned long long)node_id); return CONN_MGR_ERR_NOT_FOUND; } if (!target) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr_connect: node 0x%016llx not found", (unsigned long long)node_id); return CONN_MGR_ERR_NOT_FOUND; }
struct CONN_MGR_ENTRY* entry = cm_find_entry(mgr, node_id); struct CONN_MGR_ENTRY* entry = cm_find_entry(mgr, node_id);
if (entry && entry->state == CONN_MGR_STATE_CONNECTED) { if (entry && entry->state == CONN_MGR_STATE_CONNECTED) {
@ -191,7 +191,7 @@ int conn_mgr_connect_node(struct CONN_MGR* mgr, uint64_t node_id, uint32_t idle_
if (cn) { cn->cb = cb; cn->arg = cb_arg; cn->next = entry->cb_list; entry->cb_list = cn; } if (cn) { cn->cb = cb; cn->arg = cb_arg; cn->next = entry->cb_list; entry->cb_list = cn; }
return CONN_MGR_OK; return CONN_MGR_OK;
} }
struct ETCP_CONN* existing = route_bgp_find_conn_for_node(bgp, node_id); struct ETCP_CONN* existing = topo_bgp_find_conn_for_node(bgp, node_id);
if (existing && existing->peer_node_id == node_id && existing->links) { if (existing && existing->peer_node_id == node_id && existing->links) {
struct ETCP_LINK* l = existing->links; struct ETCP_LINK* l = existing->links;
while (l) { if (l->link_status && l->initialized) break; l = l->next; } while (l) { if (l->link_status && l->initialized) break; l = l->next; }
@ -270,20 +270,20 @@ int conn_mgr_get_status(struct CONN_MGR* mgr, uint64_t node_id, uint8_t* out_sta
} }
int conn_mgr_add_alien_node(struct CONN_MGR* mgr, const uint8_t* nodeinfo_data, size_t len) { int conn_mgr_add_alien_node(struct CONN_MGR* mgr, const uint8_t* nodeinfo_data, size_t len) {
if (!mgr || !nodeinfo_data || len < sizeof(struct NODEINFO)) return CONN_MGR_ERR_INTERNAL; if (!mgr || !nodeinfo_data || len < sizeof(struct TOPO_NODE)) return CONN_MGR_ERR_INTERNAL;
struct ROUTE_BGP* bgp = mgr->instance->bgp; struct TOPO_BGP* bgp = mgr->instance->bgp;
if (!bgp) return CONN_MGR_ERR_INTERNAL; if (!bgp) return CONN_MGR_ERR_INTERNAL;
const struct NODEINFO* src = (const struct NODEINFO*)nodeinfo_data; const struct TOPO_NODE* src = (const struct TOPO_NODE*)nodeinfo_data;
uint64_t node_id = src->node_id; uint64_t node_id = src->node_id;
struct NODEINFO_Q* existing = nodeinfo_find_by_id(bgp, node_id); struct TOPO_NODEQ* existing = topo_node_find_by_id(bgp, node_id);
if (existing) { DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: alien node 0x%016llx already exists, ignoring", (unsigned long long)node_id); return CONN_MGR_OK; } if (existing) { DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: alien node 0x%016llx already exists, ignoring", (unsigned long long)node_id); return CONN_MGR_OK; }
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) return CONN_MGR_ERR_INTERNAL; if (!ni) return CONN_MGR_ERR_INTERNAL;
memcpy(ni, nodeinfo_data, len < sizeof(*ni) ? len : sizeof(*ni)); memcpy(ni, nodeinfo_data, len < sizeof(*ni) ? len : sizeof(*ni));
ni->ref_count = 1; ni->ref_count = 1;
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)queue_entry_new(sizeof(struct NODEINFO_Q)); struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)queue_entry_new(sizeof(struct TOPO_NODEQ));
if (!nq) { u_free(ni); return CONN_MGR_ERR_INTERNAL; } if (!nq) { u_free(ni); return CONN_MGR_ERR_INTERNAL; }
nq->node = ni; nodeinfo_ref(ni); nq->node = ni; topo_node_ref(ni);
nq->hash_node_id = ni->node_id; nq->hash_node_id = ni->node_id;
nq->alien = 1; nq->dirty = 0; nq->last_ver = ni->ver; nq->alien = 1; nq->dirty = 0; nq->last_ver = ni->ver;
nq->connectivity.ping_req_time = 0; nq->connectivity.ping_req_time = 0;
@ -363,7 +363,7 @@ static int cm_nat_compatible(struct ETCP_SOCKET* our, uint8_t target_config_type
return 0; return 0;
} }
static uint16_t cm_get_node_min_rtt(struct NODEINFO_Q* nq) { static uint16_t cm_get_node_min_rtt(struct TOPO_NODEQ* nq) {
uint16_t rtt = 0xFFFF; uint16_t rtt = 0xFFFF;
if (nq->connectivity.interface_status == PROBE_RESULT_REACHABLE && nq->connectivity.interface_min_rtt < rtt) if (nq->connectivity.interface_status == PROBE_RESULT_REACHABLE && nq->connectivity.interface_min_rtt < rtt)
rtt = nq->connectivity.interface_min_rtt; rtt = nq->connectivity.interface_min_rtt;
@ -374,23 +374,23 @@ static uint16_t cm_get_node_min_rtt(struct NODEINFO_Q* nq) {
return rtt; return rtt;
} }
static uint64_t cm_get_node_max_probe_time(struct NODEINFO_Q* nq) { static uint64_t cm_get_node_max_probe_time(struct TOPO_NODEQ* nq) {
uint64_t t = nq->connectivity.interface_probe_time; uint64_t t = nq->connectivity.interface_probe_time;
if (nq->connectivity.nat_probe_time > t) t = nq->connectivity.nat_probe_time; if (nq->connectivity.nat_probe_time > t) t = nq->connectivity.nat_probe_time;
if (nq->connectivity.real_probe_time > t) t = nq->connectivity.real_probe_time; if (nq->connectivity.real_probe_time > t) t = nq->connectivity.real_probe_time;
return t; return t;
} }
static int cm_is_rtt_fresh(struct NODEINFO_Q* nq, uint64_t now_tb) { static int cm_is_rtt_fresh(struct TOPO_NODEQ* nq, uint64_t now_tb) {
uint64_t last = cm_get_node_max_probe_time(nq); uint64_t last = cm_get_node_max_probe_time(nq);
return (last > 0 && (now_tb - last) < (uint64_t)(CONN_MGR_CANDIDATE_CACHE_MS * 10)); return (last > 0 && (now_tb - last) < (uint64_t)(CONN_MGR_CANDIDATE_CACHE_MS * 10));
} }
static int cm_has_direct_ip(struct NODEINFO_Q* nq) { static int cm_has_direct_ip(struct TOPO_NODEQ* nq) {
if (!nq || !nq->node) return 0; if (!nq || !nq->node) return 0;
for (const struct NI_IPV4_ADDR* a = nq->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = nq->node->v4_addrs; a; a = a->next) {
if (a->type == ADDR_TYPE_REAL || a->type == ADDR_TYPE_NAT) { if (a->type == TOPO_ADDR_REAL || a->type == TOPO_ADDR_NAT) {
for (const struct NI_IPV4_SOCKET_META* m = nq->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = nq->node->v4_sock_meta; m; m = m->next) {
if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PUBLIC || m->config_type == CFG_SERVER_TYPE_UNKNOWN if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PUBLIC || m->config_type == CFG_SERVER_TYPE_UNKNOWN
|| m->nat_type == NAT_VERIFIED_EIM || m->nat_type == NAT_VERIFIED_DIRECT)) || m->nat_type == NAT_VERIFIED_EIM || m->nat_type == NAT_VERIFIED_DIRECT))
return 1; return 1;
@ -400,11 +400,11 @@ static int cm_has_direct_ip(struct NODEINFO_Q* nq) {
return 0; return 0;
} }
static int cm_has_local_addr(struct NODEINFO_Q* nq) { static int cm_has_local_addr(struct TOPO_NODEQ* nq) {
if (!nq || !nq->node) return 0; if (!nq || !nq->node) return 0;
for (const struct NI_IPV4_ADDR* a = nq->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = nq->node->v4_addrs; a; a = a->next) {
if (a->type == ADDR_TYPE_INTERFACE) { if (a->type == TOPO_ADDR_INTERFACE) {
for (const struct NI_IPV4_SOCKET_META* m = nq->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = nq->node->v4_sock_meta; m; m = m->next) {
if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PRIVATE || m->config_type == CFG_SERVER_TYPE_LOCAL)) if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PRIVATE || m->config_type == CFG_SERVER_TYPE_LOCAL))
return 1; return 1;
} }
@ -426,12 +426,12 @@ struct cm_ping_ctx {
}; };
static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) { static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) {
struct ROUTE_BGP* bgp = entry->mgr->instance->bgp; struct TOPO_BGP* bgp = entry->mgr->instance->bgp;
struct NODEINFO_Q* target = nodeinfo_find_by_id(bgp, entry->node_id); struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id);
if (!target || !target->node) { entry->local_scan_state = CM_TRY_FAILED; return; } if (!target || !target->node) { entry->local_scan_state = CM_TRY_FAILED; return; }
for (const struct NI_IPV4_ADDR* a = target->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = target->node->v4_addrs; a; a = a->next) {
if (a->type != ADDR_TYPE_INTERFACE) continue; if (a->type != TOPO_ADDR_INTERFACE) continue;
for (const struct NI_IPV4_SOCKET_META* m = target->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = target->node->v4_sock_meta; m; m = m->next) {
if (m->id != a->socket_id || (m->config_type != CFG_SERVER_TYPE_PRIVATE && m->config_type != CFG_SERVER_TYPE_LOCAL)) continue; if (m->id != a->socket_id || (m->config_type != CFG_SERVER_TYPE_PRIVATE && m->config_type != CFG_SERVER_TYPE_LOCAL)) continue;
struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets; struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets;
while (s) { while (s) {
@ -454,14 +454,14 @@ static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) {
static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) { static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) {
if (entry->main_connect_state == CM_TRY_OK) return; if (entry->main_connect_state == CM_TRY_OK) return;
if (entry->local_scan_state == CM_TRY_OK) return; if (entry->local_scan_state == CM_TRY_OK) return;
struct ROUTE_BGP* bgp = entry->mgr->instance->bgp; struct TOPO_BGP* bgp = entry->mgr->instance->bgp;
struct NODEINFO_Q* target = nodeinfo_find_by_id(bgp, entry->node_id); struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id);
if (!target || !target->node) { cm_deliver_result(entry, CONN_MGR_ERR_NOT_FOUND); return; } if (!target || !target->node) { cm_deliver_result(entry, CONN_MGR_ERR_NOT_FOUND); return; }
uint8_t priority_order[] = { ADDR_TYPE_REAL, ADDR_TYPE_NAT, ADDR_TYPE_INTERFACE }; uint8_t priority_order[] = { TOPO_ADDR_REAL, TOPO_ADDR_NAT, TOPO_ADDR_INTERFACE };
for (int pri = 0; pri < 3; pri++) { for (int pri = 0; pri < 3; pri++) {
for (const struct NI_IPV4_ADDR* a = target->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = target->node->v4_addrs; a; a = a->next) {
if (a->type != priority_order[pri]) continue; if (a->type != priority_order[pri]) continue;
for (const struct NI_IPV4_SOCKET_META* m = target->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = target->node->v4_sock_meta; m; m = m->next) {
if (m->id != a->socket_id) continue; if (m->id != a->socket_id) continue;
struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets; struct ETCP_SOCKET* s = entry->mgr->instance->etcp_sockets;
while (s) { while (s) {
@ -493,8 +493,8 @@ static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) {
static void cm_direct_timeout_cb(void* arg) { static void cm_direct_timeout_cb(void* arg) {
struct CONN_MGR_ENTRY* entry = (struct CONN_MGR_ENTRY*)arg; struct CONN_MGR_ENTRY* entry = (struct CONN_MGR_ENTRY*)arg;
entry->main.timer = NULL; entry->main.timer = NULL;
struct ROUTE_BGP* bgp = entry->mgr->instance->bgp; struct TOPO_BGP* bgp = entry->mgr->instance->bgp;
struct NODEINFO_Q* target = nodeinfo_find_by_id(bgp, entry->node_id); struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id);
int has_our = cm_has_direct_ip(bgp->local_node); int has_our = cm_has_direct_ip(bgp->local_node);
int has_target = target ? cm_has_direct_ip(target) : 0; int has_target = target ? cm_has_direct_ip(target) : 0;
if (entry->local_scan_state != CM_TRY_OK) { if (entry->local_scan_state != CM_TRY_OK) {
@ -542,7 +542,7 @@ static void cm_ping_cb(int success, uint16_t rtt, void* arg, uint64_t nonce,
ctx->attempt++; ctx->attempt++;
if (ctx->attempt < CONN_MGR_LOCAL_SCAN_ATTEMPTS && ctx->phase == 0) { if (ctx->attempt < CONN_MGR_LOCAL_SCAN_ATTEMPTS && ctx->phase == 0) {
etcp_send_ping_to_socket(entry->mgr->instance, ctx->sock, etcp_send_ping_to_socket(entry->mgr->instance, ctx->sock,
nodeinfo_find_by_id(entry->mgr->instance->bgp, entry->node_id)->node->public_key, topo_node_find_by_id(entry->mgr->instance->bgp, entry->node_id)->node->public_key,
&ctx->addr, CONN_MGR_LOCAL_SCAN_TIMEOUT_MS, cm_ping_cb, ctx, NULL, 0); &ctx->addr, CONN_MGR_LOCAL_SCAN_TIMEOUT_MS, cm_ping_cb, ctx, NULL, 0);
return; return;
} }
@ -553,16 +553,16 @@ static void cm_ping_cb(int success, uint16_t rtt, void* arg, uint64_t nonce,
} }
static void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry) { static void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry) {
struct ROUTE_BGP* bgp = entry->mgr->instance->bgp; struct TOPO_BGP* bgp = entry->mgr->instance->bgp;
struct NODEINFO_Q* local = bgp->local_node; struct TOPO_NODEQ* local = bgp->local_node;
if (!local || !local->node) { cm_deliver_result(entry, CONN_MGR_ERR_INTERNAL); return; } if (!local || !local->node) { cm_deliver_result(entry, CONN_MGR_ERR_INTERNAL); return; }
uint32_t req_id = ++entry->mgr->next_request_id; uint32_t req_id = ++entry->mgr->next_request_id;
entry->main.request_id = req_id; entry->main.phase = 2; entry->main.request_id = req_id; entry->main.phase = 2;
uint8_t direct_count = 0; uint8_t direct_count = 0;
struct { uint8_t type; uint8_t ip[4]; uint16_t port; uint8_t socket_id; } out_addrs[8]; struct { uint8_t type; uint8_t ip[4]; uint16_t port; uint8_t socket_id; } out_addrs[8];
for (const struct NI_IPV4_ADDR* a = local->node->v4_addrs; a && direct_count < 8; a = a->next) { for (const struct TOPO_ADDR4* a = local->node->v4_addrs; a && direct_count < 8; a = a->next) {
if (a->type != ADDR_TYPE_REAL && a->type != ADDR_TYPE_NAT) continue; if (a->type != TOPO_ADDR_REAL && a->type != TOPO_ADDR_NAT) continue;
for (const struct NI_IPV4_SOCKET_META* m = local->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = local->node->v4_sock_meta; m; m = m->next) {
if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PUBLIC || m->config_type == CFG_SERVER_TYPE_UNKNOWN if (m->id == a->socket_id && (m->config_type == CFG_SERVER_TYPE_PUBLIC || m->config_type == CFG_SERVER_TYPE_UNKNOWN
|| m->nat_type == NAT_VERIFIED_EIM || m->nat_type == NAT_VERIFIED_DIRECT)) { || m->nat_type == NAT_VERIFIED_EIM || m->nat_type == NAT_VERIFIED_DIRECT)) {
out_addrs[direct_count].type = a->type; memcpy(out_addrs[direct_count].ip, a->addr, 4); out_addrs[direct_count].type = a->type; memcpy(out_addrs[direct_count].ip, a->addr, 4);
@ -686,7 +686,7 @@ static void cm_compute_intermediaries(struct CONN_MGR_ENTRY* entry, struct CONN_
} }
for (uint8_t i = 0; i < resp->my_count && count < 8; i++) { for (uint8_t i = 0; i < resp->my_count && count < 8; i++) {
uint64_t id = resp->my_candidates[i].node_id; uint64_t id = resp->my_candidates[i].node_id;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(entry->mgr->instance->bgp, id); struct TOPO_NODEQ* nq = topo_node_find_by_id(entry->mgr->instance->bgp, id);
uint16_t our_rtt = nq ? cm_get_node_min_rtt(nq) : 0; uint16_t our_rtt = nq ? cm_get_node_min_rtt(nq) : 0;
if (our_rtt == 0xFFFF) our_rtt = 0; if (our_rtt == 0xFFFF) our_rtt = 0;
all[count].node_id = id; all[count].node_id = id;
@ -712,7 +712,7 @@ static void cm_compute_intermediaries(struct CONN_MGR_ENTRY* entry, struct CONN_
for (uint8_t i = 0; i < sel; i++) { for (uint8_t i = 0; i < sel; i++) {
pkt.selected[i].node_id = all[i].node_id; pkt.selected[i].node_id = all[i].node_id;
pkt.selected[i].rtt = 0; pkt.selected[i].rtt = 0;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(entry->mgr->instance->bgp, all[i].node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(entry->mgr->instance->bgp, all[i].node_id);
if (nq) pkt.selected[i].rtt = cm_get_node_min_rtt(nq); if (nq) pkt.selected[i].rtt = cm_get_node_min_rtt(nq);
} }
struct ll_entry* qe = queue_entry_new(sizeof(pkt)); struct ll_entry* qe = queue_entry_new(sizeof(pkt));
@ -733,7 +733,7 @@ static void cm_exchange_probe_retry_cb(void* arg) {
uint8_t need_probe = 0; uint8_t need_probe = 0;
uint64_t now_tb = get_time_tb(); uint64_t now_tb = get_time_tb();
for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) { for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id);
if (!nq || !cm_is_rtt_fresh(nq, now_tb)) { need_probe++; break; } if (!nq || !cm_is_rtt_fresh(nq, now_tb)) { need_probe++; break; }
} }
if (need_probe == 0) { if (need_probe == 0) {
@ -763,7 +763,7 @@ static void cm_handle_interm_exchange_resp(struct CONN_MGR* mgr, const uint8_t*
uint8_t need_probe = 0; uint8_t need_probe = 0;
uint64_t now_tb = get_time_tb(); uint64_t now_tb = get_time_tb();
for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) { for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id);
if (!nq || !cm_is_rtt_fresh(nq, now_tb)) { need_probe++; route_connectivity_probe_node(mgr->instance, nq); } if (!nq || !cm_is_rtt_fresh(nq, now_tb)) { need_probe++; route_connectivity_probe_node(mgr->instance, nq); }
} }
if (need_probe == 0) { ep->probes_done = 1; cm_compute_intermediaries(ep->entry, &ep->cached_resp); if (need_probe == 0) { ep->probes_done = 1; cm_compute_intermediaries(ep->entry, &ep->cached_resp);
@ -852,7 +852,7 @@ static void cm_handle_direct_req(struct ETCP_CONN* conn, const uint8_t* data, si
memset(&sa, 0, sizeof(sa)); memcpy(&sa, &sin, sizeof(sin)); memset(&sa, 0, sizeof(sa)); memcpy(&sa, &sin, sizeof(sin));
struct ETCP_CONN* new_conn = etcp_connection_create(conn->instance, NULL); struct ETCP_CONN* new_conn = etcp_connection_create(conn->instance, NULL);
if (new_conn) { if (new_conn) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(conn->instance->bgp, src_node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(conn->instance->bgp, src_node_id);
if (nq) sc_set_peer_public_key(&new_conn->crypto_ctx, nq->node->public_key, 0); if (nq) sc_set_peer_public_key(&new_conn->crypto_ctx, nq->node->public_key, 0);
struct cm_reverse_pending* rp = u_calloc(1, sizeof(struct cm_reverse_pending)); struct cm_reverse_pending* rp = u_calloc(1, sizeof(struct cm_reverse_pending));
if (rp) { rp->request_id = req->request_id; rp->entry = NULL; rp->next = mgr->reverse_pending; if (rp) { rp->request_id = req->request_id; rp->entry = NULL; rp->next = mgr->reverse_pending;
@ -873,7 +873,7 @@ static void cm_handle_interm_exchange_req(struct ETCP_CONN* conn,
uint64_t now_tb = get_time_tb(); uint64_t now_tb = get_time_tb();
for (uint8_t i = 0; i < req->candidate_count && i < 4; i++) { for (uint8_t i = 0; i < req->candidate_count && i < 4; i++) {
uint64_t cand_id = req->candidates[i].node_id; uint64_t cand_id = req->candidates[i].node_id;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(mgr->instance->bgp, cand_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, cand_id);
if (nq && cm_is_rtt_fresh(nq, now_tb)) continue; if (nq && cm_is_rtt_fresh(nq, now_tb)) continue;
route_connectivity_probe_node(mgr->instance, nq); route_connectivity_probe_node(mgr->instance, nq);
} }
@ -888,7 +888,7 @@ static void cm_handle_interm_exchange_req(struct ETCP_CONN* conn,
resp.your_count = req->candidate_count > 4 ? 4 : req->candidate_count; resp.your_count = req->candidate_count > 4 ? 4 : req->candidate_count;
for (uint8_t i = 0; i < resp.your_count; i++) { for (uint8_t i = 0; i < resp.your_count; i++) {
resp.your_candidates[i].node_id = req->candidates[i].node_id; resp.your_candidates[i].node_id = req->candidates[i].node_id;
struct NODEINFO_Q* nq2 = nodeinfo_find_by_id(mgr->instance->bgp, req->candidates[i].node_id); struct TOPO_NODEQ* nq2 = topo_node_find_by_id(mgr->instance->bgp, req->candidates[i].node_id);
uint16_t rtt = nq2 ? cm_get_node_min_rtt(nq2) : 0; uint16_t rtt = nq2 ? cm_get_node_min_rtt(nq2) : 0;
resp.your_candidates[i].rtt = rtt; resp.your_candidates[i].rtt = rtt;
} }
@ -913,7 +913,7 @@ static void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) {
static void cm_bg_ping_timer_cb(void* arg) { static void cm_bg_ping_timer_cb(void* arg) {
struct CONN_MGR* mgr = (struct CONN_MGR*)arg; struct CONN_MGR* mgr = (struct CONN_MGR*)arg;
struct ROUTE_BGP* bgp = mgr->instance->bgp; struct TOPO_BGP* bgp = mgr->instance->bgp;
if (!bgp || !bgp->nodes) { if (!bgp || !bgp->nodes) {
mgr->bg_ping_timer = uasync_set_timeout(mgr->instance->ua, CONN_MGR_BG_PING_INTERVAL_TB, mgr, cm_bg_ping_timer_cb, "conn_mgr_bg_ping"); mgr->bg_ping_timer = uasync_set_timeout(mgr->instance->ua, CONN_MGR_BG_PING_INTERVAL_TB, mgr, cm_bg_ping_timer_cb, "conn_mgr_bg_ping");
return; return;
@ -939,10 +939,10 @@ static void cm_bg_ping_timer_cb(void* arg) {
e = bgp->nodes->head; e = bgp->nodes->head;
while (e && cursor < mgr->bg_ping_cursor) { cursor++; e = e->next; } while (e && cursor < mgr->bg_ping_cursor) { cursor++; e = e->next; }
if (e) { if (e) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
uint64_t node_id = nq->node->node_id; uint64_t node_id = nq->node->node_id;
if (node_id != mgr->instance->node_id) { if (node_id != mgr->instance->node_id) {
struct ETCP_CONN* dconn = route_bgp_find_conn_for_node(bgp, node_id); struct ETCP_CONN* dconn = topo_bgp_find_conn_for_node(bgp, node_id);
int has_active = 0; int has_active = 0;
if (dconn && dconn->links) { if (dconn && dconn->links) {
struct ETCP_LINK* l = dconn->links; struct ETCP_LINK* l = dconn->links;
@ -963,7 +963,7 @@ static void cm_candidate_ping_timer_cb(void* arg) {
uint64_t now_tb = get_time_tb(); uint64_t now_tb = get_time_tb();
for (uint8_t i = 0; i < mgr->best_candidate_count; i++) { for (uint8_t i = 0; i < mgr->best_candidate_count; i++) {
uint64_t cand_id = mgr->best_candidates[i].node_id; uint64_t cand_id = mgr->best_candidates[i].node_id;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(mgr->instance->bgp, cand_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, cand_id);
if (!nq) { if (!nq) {
memmove(&mgr->best_candidates[i], &mgr->best_candidates[i+1], (mgr->best_candidate_count - i - 1) * sizeof(mgr->best_candidates[0])); memmove(&mgr->best_candidates[i], &mgr->best_candidates[i+1], (mgr->best_candidate_count - i - 1) * sizeof(mgr->best_candidates[0]));
mgr->best_candidate_count--; i--; continue; mgr->best_candidate_count--; i--; continue;
@ -974,7 +974,7 @@ static void cm_candidate_ping_timer_cb(void* arg) {
memmove(&mgr->best_candidates[i], &mgr->best_candidates[i+1], (mgr->best_candidate_count - i - 1) * sizeof(mgr->best_candidates[0])); memmove(&mgr->best_candidates[i], &mgr->best_candidates[i+1], (mgr->best_candidate_count - i - 1) * sizeof(mgr->best_candidates[0]));
mgr->best_candidate_count--; i--; continue; mgr->best_candidate_count--; i--; continue;
} }
struct ETCP_CONN* dconn = route_bgp_find_conn_for_node(mgr->instance->bgp, cand_id); struct ETCP_CONN* dconn = topo_bgp_find_conn_for_node(mgr->instance->bgp, cand_id);
int has_active = 0; int has_active = 0;
if (dconn && dconn->links) { if (dconn && dconn->links) {
struct ETCP_LINK* l = dconn->links; struct ETCP_LINK* l = dconn->links;

6
src/conn_mgr.h

@ -11,12 +11,12 @@ extern "C" {
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
#include "etcp_api.h" #include "etcp_api.h"
#include "etcp_router.h" #include "etcp_router.h"
#include "route_node.h" #include "topo_node.h"
struct UTUN_INSTANCE; struct UTUN_INSTANCE;
struct ETCP_CONN; struct ETCP_CONN;
struct NODEINFO_Q; struct TOPO_NODEQ;
struct ROUTE_BGP; struct TOPO_BGP;
/** /**
* @file conn_mgr.h * @file conn_mgr.h

20
src/control_server.c

@ -10,9 +10,9 @@
#include "etcp_connections.h" #include "etcp_connections.h"
#include "tun_if.h" #include "tun_if.h"
#include "route_lib.h" #include "route_lib.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "etcp_router.h" #include "etcp_router.h"
#include "route_node.h" #include "topo_node.h"
#include "pkt_normalizer.h" #include "pkt_normalizer.h"
#include "../tools/etcpmon/etcpmon_protocol.h" #include "../tools/etcpmon/etcpmon_protocol.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -100,7 +100,7 @@ static void send_debug_config(struct control_server* server, struct control_clie
static void send_error(struct control_client* client, uint8_t error_code, const char* msg, uint8_t seq_id); static void send_error(struct control_client* client, uint8_t error_code, const char* msg, uint8_t seq_id);
static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id); static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id);
static void send_single_node_info(struct control_server* server, struct control_client* client, struct NODEINFO_Q* nq); static void send_single_node_info(struct control_server* server, struct control_client* client, struct TOPO_NODEQ* nq);
static int control_client_send(struct control_server* server, struct control_client* client, uint8_t* dgram, uint16_t len); static int control_client_send(struct control_server* server, struct control_client* client, uint8_t* dgram, uint16_t len);
static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instance, uint64_t peer_id); static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instance, uint64_t peer_id);
@ -784,13 +784,13 @@ static void handle_client_data(struct control_server* server, struct control_cli
struct etcpmon_cmd_action* cmd = (struct etcpmon_cmd_action*)payload; struct etcpmon_cmd_action* cmd = (struct etcpmon_cmd_action*)payload;
if (strncmp(cmd->action, "nat", 3) == 0) { if (strncmp(cmd->action, "nat", 3) == 0) {
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nat' received, requesting NAT check for all links"); DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nat' received, requesting NAT check for all links");
route_bgp_request_nat_check_all(server->instance->bgp); topo_bgp_request_nat_check_all(server->instance->bgp);
} else if (strncmp(cmd->action, "nodes", 5) == 0) { } else if (strncmp(cmd->action, "nodes", 5) == 0) {
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nodes' received, dumping all BGP nodes"); DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nodes' received, dumping all BGP nodes");
uint16_t text_max = (ETCPMON_MAX_MSG_SIZE > 1024) ? ETCPMON_MAX_MSG_SIZE - 512 : 1024; uint16_t text_max = (ETCPMON_MAX_MSG_SIZE > 1024) ? ETCPMON_MAX_MSG_SIZE - 512 : 1024;
char* text = (char*)u_malloc(text_max); char* text = (char*)u_malloc(text_max);
if (text) { if (text) {
int text_len = route_node_format_all(server->instance->bgp, text, text_max); int text_len = topo_node_format_all(server->instance->bgp, text, text_max);
if (text_len < 0) text_len = 0; if (text_len < 0) text_len = 0;
text[text_len] = '\0'; text[text_len] = '\0';
uint16_t rsp_size = ETCPMON_ACTION_RESULT_SIZE(text_len); uint16_t rsp_size = ETCPMON_ACTION_RESULT_SIZE(text_len);
@ -1385,10 +1385,10 @@ static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instan
* Node Info Helpers (send_single_node_info, send_node_list, notify_change) * Node Info Helpers (send_single_node_info, send_node_list, notify_change)
* ============================================================================ */ * ============================================================================ */
static void send_single_node_info(struct control_server* server, struct control_client* client, struct NODEINFO_Q* nq) { static void send_single_node_info(struct control_server* server, struct control_client* client, struct TOPO_NODEQ* nq) {
if (!server || !nq || !nq->node) return; if (!server || !nq || !nq->node) return;
uint8_t buf[8192]; uint8_t buf[8192];
int ser_len = nodeinfo_serialize(server->instance->bgp, nq, buf + 2, sizeof(buf) - 2); int ser_len = topo_node_serialize(server->instance->bgp, nq, buf + 2, sizeof(buf) - 2);
if (ser_len < 0) { DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to serialize node info"); return; } if (ser_len < 0) { DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Failed to serialize node info"); return; }
buf[0] = CTRL_BGP_CMD; buf[1] = CTRL_BGP_SUBCMD; buf[0] = CTRL_BGP_CMD; buf[1] = CTRL_BGP_SUBCMD;
size_t data_size = 2 + (size_t)ser_len; size_t data_size = 2 + (size_t)ser_len;
@ -1405,7 +1405,7 @@ static void send_single_node_info(struct control_server* server, struct control_
} }
static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id) { static void control_server_send_node_list(struct control_server* server, struct control_client* client, uint8_t seq_id) {
struct ROUTE_BGP* bgp = server->instance->bgp; struct TOPO_BGP* bgp = server->instance->bgp;
if (!bgp) { send_error(client, ETCPMON_ERR_SERVER_BUSY, "BGP not available", seq_id); return; } if (!bgp) { send_error(client, ETCPMON_ERR_SERVER_BUSY, "BGP not available", seq_id); return; }
/* Send local node first */ /* Send local node first */
@ -1414,7 +1414,7 @@ static void control_server_send_node_list(struct control_server* server, struct
/* Send all known remote nodes */ /* Send all known remote nodes */
struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL;
while (e) { while (e) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
send_single_node_info(server, client, nq); send_single_node_info(server, client, nq);
e = e->next; e = e->next;
} }
@ -1429,7 +1429,7 @@ static void control_server_send_node_list(struct control_server* server, struct
DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Sent node list to client (seq=%d)", seq_id); DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Sent node list to client (seq=%d)", seq_id);
} }
void control_server_notify_node_change(struct control_server* server, struct NODEINFO_Q* node) { void control_server_notify_node_change(struct control_server* server, struct TOPO_NODEQ* node) {
if (!server || !node) return; if (!server || !node) return;
struct control_client* client = server->clients; struct control_client* client = server->clients;
while (client) { while (client) {

4
src/control_server.h

@ -19,7 +19,7 @@ extern "C" {
/* Forward declarations */ /* Forward declarations */
struct UTUN_INSTANCE; struct UTUN_INSTANCE;
struct UASYNC; struct UASYNC;
struct NODEINFO_Q; struct TOPO_NODEQ;
struct ll_queue; struct ll_queue;
/* Forward declaration */ /* Forward declaration */
@ -117,7 +117,7 @@ void control_server_process_updates(struct control_server* server);
*/ */
uint32_t control_server_get_client_count(const struct control_server* server); uint32_t control_server_get_client_count(const struct control_server* server);
void control_server_notify_node_change(struct control_server* server, struct NODEINFO_Q* node); void control_server_notify_node_change(struct control_server* server, struct TOPO_NODEQ* node);
void control_server_notify_node_removed(struct control_server* server, uint64_t node_id); void control_server_notify_node_removed(struct control_server* server, uint64_t node_id);
#ifdef __cplusplus #ifdef __cplusplus

6
src/db_sync.c

@ -5,7 +5,7 @@
#include "etcp.h" #include "etcp.h"
#include "etcp_router.h" #include "etcp_router.h"
#include "utun_instance.h" #include "utun_instance.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -778,13 +778,13 @@ static void db_sync_initiate_sync(struct DB_SYNC* db, uint64_t peer_node_id) {
static void db_sync_peer_check_cb(void* arg) { static void db_sync_peer_check_cb(void* arg) {
struct DB_SYNC* db = (struct DB_SYNC*)arg; struct DB_SYNC* db = (struct DB_SYNC*)arg;
if (!db || !db->enabled) return; if (!db || !db->enabled) return;
struct ROUTE_BGP* bgp = db->inst->bgp; struct TOPO_BGP* bgp = db->inst->bgp;
if (!bgp) { db->peer_check_timer = uasync_set_timeout(db->inst->ua, DB_SYNC_PEER_CHECK_INTERVAL * 10000u, db, db_sync_peer_check_cb, "db_sync_peer"); return; } if (!bgp) { db->peer_check_timer = uasync_set_timeout(db->inst->ua, DB_SYNC_PEER_CHECK_INTERVAL * 10000u, db, db_sync_peer_check_cb, "db_sync_peer"); return; }
// Check all known peers with active connections // Check all known peers with active connections
struct ll_entry* e = bgp->senders_list->head; struct ll_entry* e = bgp->senders_list->head;
while (e) { while (e) {
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data;
if (item->conn && item->conn->peer_node_id != 0 && item->conn->links_up) { if (item->conn && item->conn->peer_node_id != 0 && item->conn->links_up) {
uint64_t pid = item->conn->peer_node_id; uint64_t pid = item->conn->peer_node_id;
if (pid != db->inst->node_id) { if (pid != db->inst->node_id) {

6
src/etcp.c

@ -5,7 +5,7 @@
#include "etcp_loadbalancer.h" #include "etcp_loadbalancer.h"
#include "etcp_router.h" #include "etcp_router.h"
#include "routing.h" #include "routing.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_ping.h" #include "route_ping.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -96,7 +96,7 @@ static void feed_dgram_to_asm(struct ETCP_CONN* etcp, struct PKTNORM* pn,
if (pkt_len == 0 || pkt_len > 16384 || *asm_len < 2 + pkt_len) break; if (pkt_len == 0 || pkt_len > 16384 || *asm_len < 2 + pkt_len) break;
const uint8_t* pkt_data = *asm_buf + 2; const uint8_t* pkt_data = *asm_buf + 2;
if (pkt_data[0] != ETCP_ID_ROUTE_ENTRY) { if (pkt_data[0] != ETCP_ID_TOPO_ENTRY) {
struct ll_entry* e = ll_alloc_lldgram(pkt_len); struct ll_entry* e = ll_alloc_lldgram(pkt_len);
if (e) { if (e) {
memcpy(e->dgram, pkt_data, pkt_len); memcpy(e->dgram, pkt_data, pkt_len);
@ -303,7 +303,7 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
routing_del_conn(etcp); routing_del_conn(etcp);
// NOTE: route_bgp_remove_conn is already called via down_cbk in etcp_on_down() above // NOTE: topo_bgp_remove_conn is already called via down_cbk in etcp_on_down() above
// DO NOT call it again here to avoid double-processing and ref_count corruption // DO NOT call it again here to avoid double-processing and ref_count corruption
// Очистить транзитные очереди (до pn_deinit/stcp_link_close — waiter'ы на normalizer->input/tx_queue) // Очистить транзитные очереди (до pn_deinit/stcp_link_close — waiter'ы на normalizer->input/tx_queue)

4
src/etcp_api.h

@ -71,7 +71,7 @@ typedef void (*etcp_recv_fn)(struct ETCP_CONN* conn, struct ll_entry* entry);
// Forward declaration // Forward declaration
struct ETCP_CONN; struct ETCP_CONN;
struct UTUN_INSTANCE; struct UTUN_INSTANCE;
struct NODEINFO_Q; struct TOPO_NODEQ;
typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg); typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg);
// ---- Background connection initialization ---- // ---- Background connection initialization ----
@ -81,7 +81,7 @@ typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg);
typedef void (*etcp_connect_callback_t)(void* arg, struct ETCP_CONN* conn, int type); typedef void (*etcp_connect_callback_t)(void* arg, struct ETCP_CONN* conn, int type);
int etcp_connect(struct UTUN_INSTANCE* instance, struct NODEINFO_Q* node, int etcp_connect(struct UTUN_INSTANCE* instance, struct TOPO_NODEQ* node,
etcp_connect_callback_t cb, void* arg, uint8_t flags); etcp_connect_callback_t cb, void* arg, uint8_t flags);
/** /**

20
src/etcp_connect.c

@ -1,7 +1,7 @@
#include "etcp_api.h" #include "etcp_api.h"
#include "etcp.h" #include "etcp.h"
#include "utun_instance.h" #include "utun_instance.h"
#include "route_node.h" #include "topo_node.h"
#include "stcp_link.h" #include "stcp_link.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
@ -69,19 +69,19 @@ static void connect_cancel(struct ETCP_CONNECT* ctx) {
u_free(ctx); u_free(ctx);
} }
static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct NODEINFO_Q* node) { static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct TOPO_NODEQ* node) {
if (!node || !node->node) return; if (!node || !node->node) return;
for (const struct NI_IPV4_ADDR* a = node->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = node->node->v4_addrs; a; a = a->next) {
if (a->port == 0) continue; if (a->port == 0) continue;
{ int zero = 1; for (int j = 0; j < 4; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue; } { int zero = 1; for (int j = 0; j < 4; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue; }
struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET;
memcpy(&sin.sin_addr.s_addr, a->addr, 4); sin.sin_port = htons(a->port); memcpy(&sin.sin_addr.s_addr, a->addr, 4); sin.sin_port = htons(a->port);
struct sockaddr_storage sa; memcpy(&sa, &sin, sizeof(sin)); struct sockaddr_storage sa; memcpy(&sa, &sin, sizeof(sin));
if (!(a->protocol & NODE_PROTO_TCP)) { if (!(a->protocol & TOPO_PROTO_TCP)) {
struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; struct ETCP_SOCKET* s = ctx->instance->etcp_sockets;
while (s) { if (s->local_addr.ss_family == AF_INET) etcp_link_new(ctx->conn, s, &sa, 0); s = s->next; } while (s) { if (s->local_addr.ss_family == AF_INET) etcp_link_new(ctx->conn, s, &sa, 0); s = s->next; }
} }
if ((a->protocol & NODE_PROTO_TCP) && !ctx->tcp_link) { if ((a->protocol & TOPO_PROTO_TCP) && !ctx->tcp_link) {
struct stcp_link_config tcp_cfg = {.ua = ctx->instance->ua, .my_keys = &ctx->instance->my_keys, .inst = ctx->instance, struct stcp_link_config tcp_cfg = {.ua = ctx->instance->ua, .my_keys = &ctx->instance->my_keys, .inst = ctx->instance,
.peer_pubkey = ctx->conn->crypto_ctx.peer_public_key, .peer_pubkey_mode = 0, .peer_pubkey = ctx->conn->crypto_ctx.peer_public_key, .peer_pubkey_mode = 0,
.remote_addr = &sa, .remote_port = a->port}; .remote_addr = &sa, .remote_port = a->port};
@ -91,19 +91,19 @@ static void connect_create_links_v4(struct ETCP_CONNECT* ctx, struct NODEINFO_Q*
} }
} }
static void connect_create_links_v6(struct ETCP_CONNECT* ctx, struct NODEINFO_Q* node) { static void connect_create_links_v6(struct ETCP_CONNECT* ctx, struct TOPO_NODEQ* node) {
if (!node || !node->node) return; if (!node || !node->node) return;
for (const struct NI_IPV6_ADDR* a = node->node->v6_addrs; a; a = a->next) { for (const struct TOPO_ADDR6* a = node->node->v6_addrs; a; a = a->next) {
if (a->port == 0) continue; if (a->port == 0) continue;
int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue; int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } if (zero) continue;
struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port); memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port);
struct sockaddr_storage sa; memcpy(&sa, &sin6, sizeof(sin6)); struct sockaddr_storage sa; memcpy(&sa, &sin6, sizeof(sin6));
if (!(a->protocol & NODE_PROTO_TCP)) { if (!(a->protocol & TOPO_PROTO_TCP)) {
struct ETCP_SOCKET* s = ctx->instance->etcp_sockets; struct ETCP_SOCKET* s = ctx->instance->etcp_sockets;
while (s) { if (s->local_addr.ss_family == AF_INET6) etcp_link_new(ctx->conn, s, &sa, 0); s = s->next; } while (s) { if (s->local_addr.ss_family == AF_INET6) etcp_link_new(ctx->conn, s, &sa, 0); s = s->next; }
} }
if ((a->protocol & NODE_PROTO_TCP) && !ctx->tcp_link) { if ((a->protocol & TOPO_PROTO_TCP) && !ctx->tcp_link) {
struct stcp_link_config tcp_cfg = {.ua = ctx->instance->ua, .my_keys = &ctx->instance->my_keys, .inst = ctx->instance, struct stcp_link_config tcp_cfg = {.ua = ctx->instance->ua, .my_keys = &ctx->instance->my_keys, .inst = ctx->instance,
.peer_pubkey = ctx->conn->crypto_ctx.peer_public_key, .peer_pubkey_mode = 0, .peer_pubkey = ctx->conn->crypto_ctx.peer_public_key, .peer_pubkey_mode = 0,
.remote_addr = &sa, .remote_port = a->port}; .remote_addr = &sa, .remote_port = a->port};
@ -205,7 +205,7 @@ static void connect_ready_cb(struct ETCP_CONN* conn, void* arg) {
connect_settle_timeout_cb, "etcp_connect_settle"); connect_settle_timeout_cb, "etcp_connect_settle");
} }
int etcp_connect(struct UTUN_INSTANCE* inst, struct NODEINFO_Q* node, int etcp_connect(struct UTUN_INSTANCE* inst, struct TOPO_NODEQ* node,
etcp_connect_callback_t cb, void* arg, uint8_t flags) { etcp_connect_callback_t cb, void* arg, uint8_t flags) {
if (!inst || !node || !cb) return -1; if (!inst || !node || !cb) return -1;
uint64_t node_id = node->node->node_id; uint64_t node_id = node->node->node_id;

18
src/etcp_connections.c

@ -17,8 +17,8 @@
#include "crc32.h" #include "crc32.h"
#include "etcp.h" #include "etcp.h"
#include "stcp_link.h" #include "stcp_link.h"
#include "route_node.h" #include "topo_node.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_ping.h" #include "route_ping.h"
#include "../lib/memory_pool.h" #include "../lib/memory_pool.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -1289,7 +1289,7 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
link->nat_type = NAT_TYPE_DIRECT; link->nat_type = NAT_TYPE_DIRECT;
link->nat_check_status = NAT_CHECK_EIM; link->nat_check_status = NAT_CHECK_EIM;
if (link->etcp->instance->bgp) { if (link->etcp->instance->bgp) {
route_bgp_send_nat_info(link->etcp, link->remote_socket_id, topo_bgp_send_nat_info(link->etcp, link->remote_socket_id,
link->nat_ip, link->nat_port, NAT_TYPE_DIRECT); link->nat_ip, link->nat_port, NAT_TYPE_DIRECT);
} }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "DIRECT IP: %s:%u for %s", DEBUG_INFO(DEBUG_CATEGORY_BGP, "DIRECT IP: %s:%u for %s",
@ -1311,15 +1311,15 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
nat_sin->sin_addr.s_addr = my_ip; nat_sin->sin_addr.s_addr = my_ip;
nat_sin->sin_port = ((struct sockaddr_in*)&e_sock->interface_addr)->sin_port; nat_sin->sin_port = ((struct sockaddr_in*)&e_sock->interface_addr)->sin_port;
if (link->etcp->instance->bgp) { if (link->etcp->instance->bgp) {
route_bgp_update_my_nodeinfo(link->etcp->instance->bgp->instance, link->etcp->instance->bgp); topo_bgp_update_my_nodeinfo(link->etcp->instance->bgp->instance, link->etcp->instance->bgp);
struct ROUTE_BGP* bgp = link->etcp->instance->bgp; struct TOPO_BGP* bgp = link->etcp->instance->bgp;
if (bgp->local_node && bgp->senders_list) { if (bgp->local_node && bgp->senders_list) {
bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1; bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1;
bgp->local_node->dirty = 1; bgp->local_node->dirty = 1;
struct ll_entry* se = bgp->senders_list->head; struct ll_entry* se = bgp->senders_list->head;
while (se) { while (se) {
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)se->data;
if (item && item->conn) route_bgp_send_nodeinfo(bgp->local_node, item->conn); if (item && item->conn) topo_bgp_send_nodeinfo(bgp->local_node, item->conn);
se = se->next; se = se->next;
} }
} }
@ -1369,7 +1369,7 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
loadbalancer_link_ready(link); loadbalancer_link_ready(link);
// Restart NAT check after link is up (e.g. after address change or reinit) // Restart NAT check after link is up (e.g. after address change or reinit)
if (link->etcp->instance->bgp) { if (link->etcp->instance->bgp) {
if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) route_bgp_start_link_nat_check(link->etcp->instance->bgp, link); if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_bgp_start_link_nat_check(link->etcp->instance->bgp, link);
} }
} }
@ -1839,7 +1839,7 @@ ec_fr:
} }
// Initialize only sockets (servers for incoming connections) // Initialize only sockets (servers for incoming connections)
// Called before route_bgp_init() to populate etcp_sockets for nodeinfo // Called before topo_bgp_init() to populate etcp_sockets for nodeinfo
// Returns: 0 = all OK, 1 = partial success (some sockets failed), -1 = fatal error (no sockets) // Returns: 0 = all OK, 1 = partial success (some sockets failed), -1 = fatal error (no sockets)
int init_sockets(struct UTUN_INSTANCE* instance) { int init_sockets(struct UTUN_INSTANCE* instance) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");

42
src/etcp_router.c

@ -14,7 +14,7 @@ in ---> {Q} -> [src, etcp] --> ... --> [dst,etcp] -> {asm_q} -> {buf q} ---> out
#include "etcp_router.h" #include "etcp_router.h"
#include "etcp.h" #include "etcp.h"
#include "utun_instance.h" #include "utun_instance.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -178,17 +178,17 @@ static int router_send_one_flags(struct ETCP_ROUTER_CONN* rconn, const uint8_t*
if (pl_len > 0) memcpy(dgram + SVC_ROUTE_HDR_SIZE, payload, pl_len); if (pl_len > 0) memcpy(dgram + SVC_ROUTE_HDR_SIZE, payload, pl_len);
struct ETCP_CONN* conn = NULL; struct ETCP_CONN* conn = NULL;
struct ROUTE_BGP* bgp = inst->bgp; struct TOPO_BGP* bgp = inst->bgp;
if (bgp) { if (bgp) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, rconn->remote_node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, rconn->remote_node_id);
if (nq && nq->conn_mgr_type == CONN_TYPE_INDIRECT && nq->conn_mgr_intermediariy_count > 0) { if (nq && nq->conn_mgr_type == CONN_TYPE_INDIRECT && nq->conn_mgr_intermediariy_count > 0) {
for (uint8_t i = 0; i < nq->conn_mgr_intermediariy_count; i++) { for (uint8_t i = 0; i < nq->conn_mgr_intermediariy_count; i++) {
conn = route_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]); conn = topo_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]);
if (conn) break; if (conn) break;
} }
} }
} }
if (!conn) conn = route_bgp_find_conn_for_node(bgp, rconn->remote_node_id); if (!conn) conn = topo_bgp_find_conn_for_node(bgp, rconn->remote_node_id);
if (!conn) { if (!conn) {
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_send_one: no route to %016llx svc_id=%u", DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_send_one: no route to %016llx svc_id=%u",
(unsigned long long)rconn->remote_node_id, rconn->svc_id); (unsigned long long)rconn->remote_node_id, rconn->svc_id);
@ -259,7 +259,7 @@ static int router_send_one_flags(struct ETCP_ROUTER_CONN* rconn, const uint8_t*
// Отправка без conn (RST для неизвестного src) // Отправка без conn (RST для неизвестного src)
static void router_send_to(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t svc_id, uint8_t flag_bits) { static void router_send_to(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t svc_id, uint8_t flag_bits) {
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, dst); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, dst);
if (!conn) return; if (!conn) return;
struct SVC_ROUTE_HDR* hdr = (struct SVC_ROUTE_HDR*)u_malloc(SVC_ROUTE_HDR_SIZE); struct SVC_ROUTE_HDR* hdr = (struct SVC_ROUTE_HDR*)u_malloc(SVC_ROUTE_HDR_SIZE);
if (!hdr) return; if (!hdr) return;
@ -314,7 +314,7 @@ static void router_close_and_notify(struct ETCP_ROUTER_CONN* rconn) {
rconn->closed = 1; rconn->closed = 1;
router_send_close_to_service(rconn); router_send_close_to_service(rconn);
// Отправляем CLOSE удалённой стороне // Отправляем CLOSE удалённой стороне
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id);
if (conn) router_send_one_flags(rconn, NULL, 0, ROUTER_FLAG_CLOSE, 0); if (conn) router_send_one_flags(rconn, NULL, 0, ROUTER_FLAG_CLOSE, 0);
// Таймеры // Таймеры
if (rconn->ack_timer) { uasync_cancel_timeout(inst->ua, rconn->ack_timer); rconn->ack_timer = NULL; } if (rconn->ack_timer) { uasync_cancel_timeout(inst->ua, rconn->ack_timer); rconn->ack_timer = NULL; }
@ -389,7 +389,7 @@ static void router_no_route_retry_cb(void* arg) {
struct ETCP_ROUTER_CONN* rconn = (struct ETCP_ROUTER_CONN*)arg; struct ETCP_ROUTER_CONN* rconn = (struct ETCP_ROUTER_CONN*)arg;
if (rconn->closed) return; if (rconn->closed) return;
rconn->no_route_timer = NULL; rconn->no_route_timer = NULL;
struct ETCP_CONN* c = route_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id); struct ETCP_CONN* c = topo_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id);
if (c) { if (c) {
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router: route appeared for %016llx svc_id=%u, draining send_q=%d", DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router: route appeared for %016llx svc_id=%u, draining send_q=%d",
(unsigned long long)rconn->remote_node_id, rconn->svc_id, queue_entry_count(rconn->send_q)); (unsigned long long)rconn->remote_node_id, rconn->svc_id, queue_entry_count(rconn->send_q));
@ -420,17 +420,17 @@ static void router_retransmit_one(struct ETCP_ROUTER_CONN* rconn, struct ROUTER_
hdr->timestamp = get_current_timestamp(); hdr->timestamp = get_current_timestamp();
struct ETCP_CONN* conn = NULL; struct ETCP_CONN* conn = NULL;
struct ROUTE_BGP* bgp = inst->bgp; struct TOPO_BGP* bgp = inst->bgp;
if (bgp) { if (bgp) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, rconn->remote_node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, rconn->remote_node_id);
if (nq && nq->conn_mgr_type == CONN_TYPE_INDIRECT && nq->conn_mgr_intermediariy_count > 0) { if (nq && nq->conn_mgr_type == CONN_TYPE_INDIRECT && nq->conn_mgr_intermediariy_count > 0) {
for (uint8_t i = 0; i < nq->conn_mgr_intermediariy_count; i++) { for (uint8_t i = 0; i < nq->conn_mgr_intermediariy_count; i++) {
conn = route_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]); conn = topo_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]);
if (conn) break; if (conn) break;
} }
} }
} }
if (!conn) conn = route_bgp_find_conn_for_node(bgp, rconn->remote_node_id); if (!conn) conn = topo_bgp_find_conn_for_node(bgp, rconn->remote_node_id);
if (!conn) { if (!conn) {
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_retransmit: no route to %016llx svc_id=%u", DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_retransmit: no route to %016llx svc_id=%u",
(unsigned long long)rconn->remote_node_id, rconn->svc_id); (unsigned long long)rconn->remote_node_id, rconn->svc_id);
@ -618,7 +618,7 @@ static void router_ack_do_send(struct ETCP_ROUTER_CONN* rconn) {
static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) { static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
struct UTUN_INSTANCE* inst = rconn->inst; struct UTUN_INSTANCE* inst = rconn->inst;
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id);
if (!conn) { if (!conn) {
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_ack: no route to %016llx svc_id=%u", DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_ack: no route to %016llx svc_id=%u",
(unsigned long long)rconn->remote_node_id, rconn->svc_id); (unsigned long long)rconn->remote_node_id, rconn->svc_id);
@ -768,7 +768,7 @@ static void router_incoming_q_cb(struct ll_queue* q, void* arg) {
queue_data_put_with_index(rconn->recv_q, rq); queue_data_put_with_index(rconn->recv_q, rq);
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id);
if (seq == rconn->rx_seq) router_try_assembly(rconn, conn); if (seq == rconn->rx_seq) router_try_assembly(rconn, conn);
router_schedule_ack(rconn); router_schedule_ack(rconn);
queue_resume_callback(q); queue_resume_callback(q);
@ -788,8 +788,8 @@ static int router_verify_signature(struct UTUN_INSTANCE* inst, struct ll_entry*
} }
size_t actual_payload = *pl_len - SC_SIGN_SIZE; size_t actual_payload = *pl_len - SC_SIGN_SIZE;
uint8_t* sig = (uint8_t*)entry->dgram + SVC_ROUTE_HDR_SIZE + actual_payload; uint8_t* sig = (uint8_t*)entry->dgram + SVC_ROUTE_HDR_SIZE + actual_payload;
struct ROUTE_BGP* bgp = inst->bgp; struct TOPO_BGP* bgp = inst->bgp;
struct NODEINFO_Q* nq = bgp ? nodeinfo_find_by_id(bgp, hdr->src_node_id) : NULL; struct TOPO_NODEQ* nq = bgp ? topo_node_find_by_id(bgp, hdr->src_node_id) : NULL;
if (!nq) { if (!nq) {
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router: SIGNED packet from unknown node %016llx — dropping", DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router: SIGNED packet from unknown node %016llx — dropping",
(unsigned long long)hdr->src_node_id); (unsigned long long)hdr->src_node_id);
@ -875,7 +875,7 @@ static void router_handle_ack(struct UTUN_INSTANCE* inst, struct ETCP_ROUTER_CON
static void router_forward_transit(struct UTUN_INSTANCE* inst, struct ll_entry* entry, static void router_forward_transit(struct UTUN_INSTANCE* inst, struct ll_entry* entry,
struct SVC_ROUTE_HDR* hdr) { struct SVC_ROUTE_HDR* hdr) {
struct ETCP_CONN* next = route_bgp_find_conn_for_node(inst->bgp, hdr->dst_node_id); struct ETCP_CONN* next = topo_bgp_find_conn_for_node(inst->bgp, hdr->dst_node_id);
if (!next) { if (!next) {
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router: no route to %016llx svc_id=%u, dropping", DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router: no route to %016llx svc_id=%u, dropping",
(unsigned long long)hdr->dst_node_id, hdr->svc_id); (unsigned long long)hdr->dst_node_id, hdr->svc_id);
@ -1088,7 +1088,7 @@ int etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t dst_node_id, struct ll_
return 0; return 0;
} }
struct ETCP_CONN* etcp_conn = route_bgp_find_conn_for_node(inst->bgp, dst_node_id); struct ETCP_CONN* etcp_conn = topo_bgp_find_conn_for_node(inst->bgp, dst_node_id);
if (!etcp_conn) { if (!etcp_conn) {
struct ETCP_ROUTER_CONN* rconn = etcp_router_conn_get(inst, dst_node_id, svc_id); struct ETCP_ROUTER_CONN* rconn = etcp_router_conn_get(inst, dst_node_id, svc_id);
if (!rconn) { queue_dgram_free(entry); queue_entry_free(entry); return -1; } if (!rconn) { queue_dgram_free(entry); queue_entry_free(entry); return -1; }
@ -1120,7 +1120,7 @@ int etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t dst_node_id, struct ll_
int etcp_router_input_q_count(struct UTUN_INSTANCE* inst, uint64_t node_id) { int etcp_router_input_q_count(struct UTUN_INSTANCE* inst, uint64_t node_id) {
if (!inst || !inst->bgp) return -1; if (!inst || !inst->bgp) return -1;
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, node_id);
if (!conn || !conn->normalizer || !conn->normalizer->input) return -1; if (!conn || !conn->normalizer || !conn->normalizer->input) return -1;
return queue_entry_count(conn->normalizer->input); return queue_entry_count(conn->normalizer->input);
} }
@ -1129,7 +1129,7 @@ void etcp_router_waiter_register(struct UTUN_INSTANCE* inst, uint64_t peer_node_
struct queue_waiter_handle* h, struct queue_waiter_handle* h,
queue_threshold_callback_fn callback, void* arg) { queue_threshold_callback_fn callback, void* arg) {
if (!inst || !inst->bgp || !h) return; if (!inst || !inst->bgp || !h) return;
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, peer_node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, peer_node_id);
if (!conn || !conn->normalizer || !conn->normalizer->input) return; if (!conn || !conn->normalizer || !conn->normalizer->input) return;
queue_waiter_wait(conn->normalizer->input, h, callback, arg); queue_waiter_wait(conn->normalizer->input, h, callback, arg);
} }
@ -1137,7 +1137,7 @@ void etcp_router_waiter_register(struct UTUN_INSTANCE* inst, uint64_t peer_node_
void etcp_router_waiter_cancel(struct UTUN_INSTANCE* inst, uint64_t peer_node_id, void etcp_router_waiter_cancel(struct UTUN_INSTANCE* inst, uint64_t peer_node_id,
struct queue_waiter_handle* h) { struct queue_waiter_handle* h) {
if (!inst || !inst->bgp || !h) return; if (!inst || !inst->bgp || !h) return;
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, peer_node_id); struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, peer_node_id);
if (!conn || !conn->normalizer || !conn->normalizer->input) return; if (!conn || !conn->normalizer || !conn->normalizer->input) return;
queue_waiter_cancel(conn->normalizer->input, h); queue_waiter_cancel(conn->normalizer->input, h);
} }

6
src/msg_transport.c

@ -10,7 +10,7 @@
#include "etcp_router.h" #include "etcp_router.h"
#include "etcp.h" #include "etcp.h"
#include "secure_channel.h" #include "secure_channel.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
@ -457,12 +457,12 @@ static void handle_client_data(struct msg_transport* t, struct msg_client* clien
case MSG_CTL_GET_PEER_INFO: { case MSG_CTL_GET_PEER_INFO: {
uint64_t peer_id = hdr->id; uint64_t peer_id = hdr->id;
struct ROUTE_BGP* bgp = t->instance->bgp; struct TOPO_BGP* bgp = t->instance->bgp;
if (!bgp) { if (!bgp) {
send_error(client, MSG_ERR_PEER_NOT_FOUND, "BGP not initialized"); send_error(client, MSG_ERR_PEER_NOT_FOUND, "BGP not initialized");
break; break;
} }
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, peer_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, peer_id);
if (!nq) { if (!nq) {
send_error(client, MSG_ERR_PEER_NOT_FOUND, "peer not found"); send_error(client, MSG_ERR_PEER_NOT_FOUND, "peer not found");
DEBUG_WARN(DEBUG_CATEGORY_MSGTRANSPORT, "GET_PEER_INFO: peer=%016llx not found", DEBUG_WARN(DEBUG_CATEGORY_MSGTRANSPORT, "GET_PEER_INFO: peer=%016llx not found",

10
src/route6_lib.c

@ -3,7 +3,7 @@
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
#include "../lib/radix.h" #include "../lib/radix.h"
#include "route_node.h" #include "topo_node.h"
#include "route6_lib.h" #include "route6_lib.h"
#define HASH_SIZE 256 #define HASH_SIZE 256
@ -63,9 +63,9 @@ void route6_table_destroy(struct ROUTE6_TABLE *table) {
u_free(table); u_free(table);
} }
bool route6_insert(struct ROUTE6_TABLE *table, struct NODEINFO_Q *node) { bool route6_insert(struct ROUTE6_TABLE *table, struct TOPO_NODEQ *node) {
if (!table || !node || !node->routes || !node->routes->v6_subnets) return false; if (!table || !node || !node->subnets || !node->subnets->v6_subnets) return false;
for (const struct NI_IPV6_SUBNET* s = node->routes->v6_subnets; s; s = s->next) { for (const struct TOPO_SUBNET6* s = node->subnets->v6_subnets; s; s = s->next) {
struct ll_entry *entry = queue_entry_new(ROUTE6_DATA_SIZE); struct ll_entry *entry = queue_entry_new(ROUTE6_DATA_SIZE);
if (!entry) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route6_insert: queue_entry_new failed"); return false; } if (!entry) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route6_insert: queue_entry_new failed"); return false; }
struct ROUTE6_DATA *rd = (struct ROUTE6_DATA *)entry->data; struct ROUTE6_DATA *rd = (struct ROUTE6_DATA *)entry->data;
@ -81,7 +81,7 @@ bool route6_insert(struct ROUTE6_TABLE *table, struct NODEINFO_Q *node) {
return true; return true;
} }
void route6_delete(struct ROUTE6_TABLE *table, struct NODEINFO_Q *node) { void route6_delete(struct ROUTE6_TABLE *table, struct TOPO_NODEQ *node) {
if (!table || !node) return; if (!table || !node) return;
uint64_t node_id = node->node->node_id; uint64_t node_id = node->node->node_id;
struct ll_entry *entry = queue_find_data_by_index(table->queue, &node_id); struct ll_entry *entry = queue_find_data_by_index(table->queue, &node_id);

6
src/route6_lib.h

@ -48,7 +48,7 @@ FDxx/8 - опциональные ipv6 подсети узлов /64 (если
struct ROUTE6_DATA { struct ROUTE6_DATA {
struct radix_node rn_nodes[2]; // scratch-буфер для rn_addroute struct radix_node rn_nodes[2]; // scratch-буфер для rn_addroute
struct NODEINFO_Q *v_node_info; // узел-владелец struct TOPO_NODEQ *v_node_info; // узел-владелец
uint64_t node_id; // ключ для hash-поиска в ll_queue uint64_t node_id; // ключ для hash-поиска в ll_queue
uint8_t prefix_length; // 0..128 uint8_t prefix_length; // 0..128
uint8_t key[17]; // sockaddr-like: {len=17, addr[16]} uint8_t key[17]; // sockaddr-like: {len=17, addr[16]}
@ -66,8 +66,8 @@ struct ROUTE6_TABLE {
struct ROUTE6_TABLE *route6_table_create(struct UASYNC *ua); struct ROUTE6_TABLE *route6_table_create(struct UASYNC *ua);
void route6_table_destroy(struct ROUTE6_TABLE *table); void route6_table_destroy(struct ROUTE6_TABLE *table);
bool route6_insert(struct ROUTE6_TABLE *table, struct NODEINFO_Q *node); bool route6_insert(struct ROUTE6_TABLE *table, struct TOPO_NODEQ *node);
void route6_delete(struct ROUTE6_TABLE *table, struct NODEINFO_Q *node); void route6_delete(struct ROUTE6_TABLE *table, struct TOPO_NODEQ *node);
const struct ROUTE6_DATA *route6_lookup(struct ROUTE6_TABLE *table, const uint8_t addr[16]); const struct ROUTE6_DATA *route6_lookup(struct ROUTE6_TABLE *table, const uint8_t addr[16]);

30
src/route_connectivity.c

@ -13,8 +13,8 @@
#include "utun_instance.h" #include "utun_instance.h"
#include "etcp.h" #include "etcp.h"
#include "etcp_connections.h" #include "etcp_connections.h"
#include "route_node.h" #include "topo_node.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_connectivity.h" #include "route_connectivity.h"
#define CONN_MAX_SOCKET_CANDIDATES 8 #define CONN_MAX_SOCKET_CANDIDATES 8
@ -22,7 +22,7 @@
struct conn_probe_ctx { struct conn_probe_ctx {
struct conn_probe_ctx* next; /* linked list in nq->connectivity.probe_list */ struct conn_probe_ctx* next; /* linked list in nq->connectivity.probe_list */
struct UTUN_INSTANCE* instance; struct UTUN_INSTANCE* instance;
struct NODEINFO_Q* nq; struct TOPO_NODEQ* nq;
uint8_t addr_type; // ADDR_TYPE_* uint8_t addr_type; // ADDR_TYPE_*
struct sockaddr_storage target_addr; struct sockaddr_storage target_addr;
uint8_t peer_pubkey[SC_PUBKEY_SIZE]; uint8_t peer_pubkey[SC_PUBKEY_SIZE];
@ -68,7 +68,7 @@ static int sock_addr_cmp(const struct sockaddr_storage* a, const struct sockaddr
} }
// проверяет что два адреса (NODEINFO_IPV4_ADDR) не дубликаты по IP+port // проверяет что два адреса (NODEINFO_IPV4_ADDR) не дубликаты по IP+port
static int addr_eq(const struct NODEINFO_IPV4_ADDR* a, uint32_t ip, uint16_t port) { static int addr_eq(const struct TOPO_ADDR4* a, uint32_t ip, uint16_t port) {
uint32_t a_ip; memcpy(&a_ip, a->addr, 4); uint32_t a_ip; memcpy(&a_ip, a->addr, 4);
return a_ip == ip && a->port == port; return a_ip == ip && a->port == port;
} }
@ -123,7 +123,7 @@ static int conn_match_candidate_sockets(struct UTUN_INSTANCE* instance,
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
uint32_t if_ip = if_sin->sin_addr.s_addr; uint32_t if_ip = if_sin->sin_addr.s_addr;
if (addr_type == ADDR_TYPE_INTERFACE) { if (addr_type == TOPO_ADDR_INTERFACE) {
// предпочитаем PRIVATE/LOCAL сокеты в той же /24 подсети // предпочитаем PRIVATE/LOCAL сокеты в той же /24 подсети
if ((e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) if ((e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL)
&& (if_ip & 0x00FFFFFF) == (target_ip & 0x00FFFFFF)) && (if_ip & 0x00FFFFFF) == (target_ip & 0x00FFFFFF))
@ -150,7 +150,7 @@ static int conn_match_candidate_sockets(struct UTUN_INSTANCE* instance,
int dup = 0; int dup = 0;
for (int i = 0; i < found; i++) if (out_sockets[i] == e_sock) { dup = 1; break; } for (int i = 0; i < found; i++) if (out_sockets[i] == e_sock) { dup = 1; break; }
if (!dup) { if (!dup) {
if (addr_type == ADDR_TYPE_INTERFACE) { if (addr_type == TOPO_ADDR_INTERFACE) {
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL)
out_sockets[found++] = e_sock; out_sockets[found++] = e_sock;
} else { } else {
@ -251,22 +251,22 @@ static void conn_probe_single_cb(int success, uint16_t rtt, void* arg,
static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) { static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) {
if (!ctx) return; if (!ctx) return;
if (ctx->nq) { if (ctx->nq) {
struct NODE_CONNECTIVITY* c = &ctx->nq->connectivity; struct TOPO_CONNECTIVITY* c = &ctx->nq->connectivity;
struct conn_probe_ctx** p = (struct conn_probe_ctx**)&c->probe_list; struct conn_probe_ctx** p = (struct conn_probe_ctx**)&c->probe_list;
while (*p) { if (*p == ctx) { *p = ctx->next; break; } p = &(*p)->next; } while (*p) { if (*p == ctx) { *p = ctx->next; break; } p = &(*p)->next; }
switch (ctx->addr_type) { switch (ctx->addr_type) {
case ADDR_TYPE_INTERFACE: case TOPO_ADDR_INTERFACE:
c->interface_status = ok ? PROBE_RESULT_REACHABLE : (c->interface_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->interface_status); c->interface_status = ok ? PROBE_RESULT_REACHABLE : (c->interface_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->interface_status);
if (ok && ctx->best_across_sockets < c->interface_min_rtt) c->interface_min_rtt = ctx->best_across_sockets; if (ok && ctx->best_across_sockets < c->interface_min_rtt) c->interface_min_rtt = ctx->best_across_sockets;
c->interface_probe_time = get_time_tb(); c->interface_probe_time = get_time_tb();
break; break;
case ADDR_TYPE_NAT: case TOPO_ADDR_NAT:
c->nat_status = ok ? PROBE_RESULT_REACHABLE : (c->nat_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->nat_status); c->nat_status = ok ? PROBE_RESULT_REACHABLE : (c->nat_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->nat_status);
if (ok && ctx->best_across_sockets < c->nat_min_rtt) c->nat_min_rtt = ctx->best_across_sockets; if (ok && ctx->best_across_sockets < c->nat_min_rtt) c->nat_min_rtt = ctx->best_across_sockets;
c->nat_probe_time = get_time_tb(); c->nat_probe_time = get_time_tb();
break; break;
case ADDR_TYPE_REAL: case TOPO_ADDR_REAL:
c->real_status = ok ? PROBE_RESULT_REACHABLE : (c->real_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->real_status); c->real_status = ok ? PROBE_RESULT_REACHABLE : (c->real_status == PROBE_RESULT_UNKNOWN ? PROBE_RESULT_UNREACHABLE : c->real_status);
if (ok && ctx->best_across_sockets < c->real_min_rtt) c->real_min_rtt = ctx->best_across_sockets; if (ok && ctx->best_across_sockets < c->real_min_rtt) c->real_min_rtt = ctx->best_across_sockets;
c->real_probe_time = get_time_tb(); c->real_probe_time = get_time_tb();
@ -287,7 +287,7 @@ static void conn_probe_finish(struct conn_probe_ctx* ctx, int ok) {
// ---- public API ---- // ---- public API ----
void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEINFO_Q* nq) { void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_NODEQ* nq) {
if (!instance || !nq) return; if (!instance || !nq) return;
if (nq->node->node_id == instance->node_id) return; // не пингуем себя if (nq->node->node_id == instance->node_id) return; // не пингуем себя
if (nq->connectivity.probe_status == PROBE_STATUS_IN_PROGRESS) { if (nq->connectivity.probe_status == PROBE_STATUS_IN_PROGRESS) {
@ -310,7 +310,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEIN
// ---- IPv4 addresses ---- // ---- IPv4 addresses ----
if (nq->node && nq->node->v4_addrs) { if (nq->node && nq->node->v4_addrs) {
uint32_t seen_ips[16]; uint16_t seen_ports[16]; int seen_count = 0; uint32_t seen_ips[16]; uint16_t seen_ports[16]; int seen_count = 0;
for (const struct NI_IPV4_ADDR* a = nq->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = nq->node->v4_addrs; a; a = a->next) {
uint32_t ip; memcpy(&ip, a->addr, 4); uint16_t port = a->port; uint32_t ip; memcpy(&ip, a->addr, 4); uint16_t port = a->port;
if (ip == 0 || port == 0) continue; if (ip == 0 || port == 0) continue;
int dup = 0; for (int j = 0; j < seen_count; j++) { if (seen_ips[j] == ip && seen_ports[j] == port) { dup = 1; break; } } int dup = 0; for (int j = 0; j < seen_count; j++) { if (seen_ips[j] == ip && seen_ports[j] == port) { dup = 1; break; } }
@ -338,7 +338,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEIN
// ---- IPv6 addresses ---- // ---- IPv6 addresses ----
if (nq->node && nq->node->v6_addrs) { if (nq->node && nq->node->v6_addrs) {
uint8_t seen_ip6s[16][16]; uint16_t seen_ports6[16]; int seen6_count = 0; uint8_t seen_ip6s[16][16]; uint16_t seen_ports6[16]; int seen6_count = 0;
for (const struct NI_IPV6_ADDR* a6 = nq->node->v6_addrs; a6; a6 = a6->next) { for (const struct TOPO_ADDR6* a6 = nq->node->v6_addrs; a6; a6 = a6->next) {
if (a6->port == 0) continue; if (a6->port == 0) continue;
int zero = 1; for (int z = 0; z < 16; z++) if (a6->addr[z] != 0) { zero = 0; break; } if (zero) continue; int zero = 1; for (int z = 0; z < 16; z++) if (a6->addr[z] != 0) { zero = 0; break; } if (zero) continue;
int dup = 0; for (int j = 0; j < seen6_count; j++) { if (memcmp(seen_ip6s[j], a6->addr, 16) == 0 && seen_ports6[j] == a6->port) { dup = 1; break; } } int dup = 0; for (int j = 0; j < seen6_count; j++) { if (memcmp(seen_ip6s[j], a6->addr, 16) == 0 && seen_ports6[j] == a6->port) { dup = 1; break; } }
@ -376,7 +376,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct NODEIN
} }
} }
void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct NODEINFO_Q* nq) { void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct TOPO_NODEQ* nq) {
if (!instance || !nq) return; if (!instance || !nq) return;
nq->connectivity.probe_status = PROBE_STATUS_NONE; nq->connectivity.probe_status = PROBE_STATUS_NONE;
nq->connectivity.pending_count = 0; nq->connectivity.pending_count = 0;
@ -391,7 +391,7 @@ void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance) {
int count = 0; int count = 0;
struct ll_entry* e = instance->bgp->nodes->head; struct ll_entry* e = instance->bgp->nodes->head;
while (e) { while (e) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
nq->connectivity.probe_status = PROBE_STATUS_NONE; nq->connectivity.probe_status = PROBE_STATUS_NONE;
nq->connectivity.pending_count = 0; nq->connectivity.pending_count = 0;
e = e->next; e = e->next;

6
src/route_connectivity.h

@ -7,17 +7,17 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include "route_node.h" #include "topo_node.h"
struct UTUN_INSTANCE; struct UTUN_INSTANCE;
// Запускает зондирование связности ко всем адресам удалённого узла // Запускает зондирование связности ко всем адресам удалённого узла
void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, void route_connectivity_probe_node(struct UTUN_INSTANCE* instance,
struct NODEINFO_Q* nq); struct TOPO_NODEQ* nq);
// Отменяет все pending пробы для узла (при удалении / withdraw) // Отменяет все pending пробы для узла (при удалении / withdraw)
void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance,
struct NODEINFO_Q* nq); struct TOPO_NODEQ* nq);
// Отменяет все pending пробы для всех узлов (при destroy) // Отменяет все pending пробы для всех узлов (при destroy)
void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance); void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance);

18
src/route_lib.c

@ -5,7 +5,7 @@
#include "../lib/mem.h" #include "../lib/mem.h"
#include "../lib/platform_compat.h" #include "../lib/platform_compat.h"
#include "utun_instance.h" #include "utun_instance.h"
#include "route_node.h" #include "topo_node.h"
#include "route_lib.h" #include "route_lib.h"
#include "etcp_debug.h" #include "etcp_debug.h"
@ -136,7 +136,7 @@ void route_table_destroy(struct ROUTE_TABLE *table) {
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_table_destroy: count=%zu", table->count); DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "route_table_destroy: count=%zu", table->count);
// v_node_info — внешний объект (NODEINFO_Q), память им не управляем // v_node_info — внешний объект (TOPO_NODEQ), память им не управляем
u_free(table->dynamic_subnets); u_free(table->dynamic_subnets);
u_free(table->local_subnets); u_free(table->local_subnets);
u_free(table->entries); u_free(table->entries);
@ -145,19 +145,19 @@ void route_table_destroy(struct ROUTE_TABLE *table) {
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing table destroyed"); DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "Routing table destroyed");
} }
bool route_insert(struct ROUTE_TABLE *table, struct NODEINFO_Q *node) { bool route_insert(struct ROUTE_TABLE *table, struct TOPO_NODEQ *node) {
if (!table || !node) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_insert: invalid arguments"); return false; } if (!table || !node) { DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "route_insert: invalid arguments"); return false; }
if (!node->routes || !node->routes->v4_subnets) { if (!node->subnets || !node->subnets->v4_subnets) {
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: node has no v4 subnets"); DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: node has no v4 subnets");
return false; return false;
} }
const struct NI_IPV4_SUBNET* sub = node->routes->v4_subnets; const struct TOPO_SUBNET4* sub = node->subnets->v4_subnets;
int cnt = 0; for (const struct NI_IPV4_SUBNET* s = sub; s; s = s->next) cnt++; int cnt = 0; for (const struct TOPO_SUBNET4* s = sub; s; s = s->next) cnt++;
if (cnt == 0) { DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: 0 subnets"); return false; } if (cnt == 0) { DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: 0 subnets"); return false; }
size_t count = (size_t)cnt; size_t count = (size_t)cnt;
for (const struct NI_IPV4_SUBNET* s = sub; s; s = s->next) { for (const struct TOPO_SUBNET4* s = sub; s; s = s->next) {
uint32_t network; memcpy(&network, s->addr, 4); network = ntohl(network); uint32_t network; memcpy(&network, s->addr, 4); network = ntohl(network);
if (check_route_overlap_in_table(network, s->prefix_length, table->entries, table->count)) { if (check_route_overlap_in_table(network, s->prefix_length, table->entries, table->count)) {
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: overlap detected for %s/%d", ip_to_string(network).a, s->prefix_length); DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_insert: overlap detected for %s/%d", ip_to_string(network).a, s->prefix_length);
@ -173,7 +173,7 @@ bool route_insert(struct ROUTE_TABLE *table, struct NODEINFO_Q *node) {
table->entries = new_entries; table->capacity = new_cap; table->entries = new_entries; table->capacity = new_cap;
} }
for (const struct NI_IPV4_SUBNET* s = sub; s; s = s->next) { for (const struct TOPO_SUBNET4* s = sub; s; s = s->next) {
uint32_t network; memcpy(&network, s->addr, 4); network = ntohl(network); uint32_t network; memcpy(&network, s->addr, 4); network = ntohl(network);
int pos = binary_search_insert_pos(table->entries, table->count, network, s->prefix_length); int pos = binary_search_insert_pos(table->entries, table->count, network, s->prefix_length);
if (pos < (int)table->count) memmove(&table->entries[pos + 1], &table->entries[pos], (table->count - pos) * sizeof(struct ROUTE_ENTRY)); if (pos < (int)table->count) memmove(&table->entries[pos + 1], &table->entries[pos], (table->count - pos) * sizeof(struct ROUTE_ENTRY));
@ -188,7 +188,7 @@ bool route_insert(struct ROUTE_TABLE *table, struct NODEINFO_Q *node) {
return true; return true;
} }
void route_delete(struct ROUTE_TABLE *table, struct NODEINFO_Q *node) { void route_delete(struct ROUTE_TABLE *table, struct TOPO_NODEQ *node) {
if (!table || !node) return; if (!table || !node) return;
DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_delete: removing all routes for node=%016llx", (unsigned long long)node->node->node_id); DEBUG_INFO(DEBUG_CATEGORY_ROUTING, "route_delete: removing all routes for node=%016llx", (unsigned long long)node->node->node_id);
size_t i = 0, removed = 0; size_t i = 0, removed = 0;

8
src/route_lib.h

@ -15,7 +15,7 @@ extern "C" {
struct ETCP_CONNECTIONS; struct ETCP_CONNECTIONS;
struct ROUTE_TABLE; struct ROUTE_TABLE;
struct ROUTE_ENTRY; struct ROUTE_ENTRY;
struct NODEINFO_Q; struct TOPO_NODEQ;
/** /**
* @brief Флаги узла * @brief Флаги узла
@ -34,7 +34,7 @@ typedef enum {
struct ROUTE_ENTRY { struct ROUTE_ENTRY {
uint32_t network; // Сетевой адрес (big-endian) uint32_t network; // Сетевой адрес (big-endian)
uint8_t prefix_length; // Длина префикса подсети uint8_t prefix_length; // Длина префикса подсети
struct NODEINFO_Q* v_node_info; // узел владелец этих маршрутов. null если - локальный маршрут. struct TOPO_NODEQ* v_node_info; // узел владелец этих маршрутов. null если - локальный маршрут.
}; };
/** /**
@ -79,7 +79,7 @@ void route_table_destroy(struct ROUTE_TABLE *table);
* *
* @return true если вставка/обновление успешно * @return true если вставка/обновление успешно
*/ */
bool route_insert(struct ROUTE_TABLE *table, struct NODEINFO_Q *node); bool route_insert(struct ROUTE_TABLE *table, struct TOPO_NODEQ *node);
/** /**
* @brief Удаляет все записи из таблицы маршрутизации для указанного узла * @brief Удаляет все записи из таблицы маршрутизации для указанного узла
@ -87,7 +87,7 @@ bool route_insert(struct ROUTE_TABLE *table, struct NODEINFO_Q *node);
* @param table Указатель на таблицу маршрутизации * @param table Указатель на таблицу маршрутизации
* @param node узел, все маршруты которого нужно удалить * @param node узел, все маршруты которого нужно удалить
*/ */
void route_delete(struct ROUTE_TABLE *table, struct NODEINFO_Q *node); void route_delete(struct ROUTE_TABLE *table, struct TOPO_NODEQ *node);
/** /**
* @brief Выполняет поиск маршрута для заданного IP-адреса * @brief Выполняет поиск маршрута для заданного IP-адреса

23
src/route_node_lmdb.h

@ -1,23 +0,0 @@
#ifndef ROUTE_NODE_LMDB_H
#define ROUTE_NODE_LMDB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "route_node.h"
struct ROUTE_BGP;
int route_node_lmdb_init(struct ROUTE_BGP* bgp, const char* db_path);
void route_node_lmdb_destroy(struct ROUTE_BGP* bgp);
int route_node_lmdb_put(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq);
int route_node_lmdb_del(struct ROUTE_BGP* bgp, uint64_t node_id);
#ifdef __cplusplus
}
#endif
#endif

48
src/route_ping.c

@ -14,8 +14,8 @@
#include "etcp_api.h" #include "etcp_api.h"
#include "etcp.h" #include "etcp.h"
#include "etcp_connections.h" #include "etcp_connections.h"
#include "route_node.h" #include "topo_node.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_ping.h" #include "route_ping.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -36,7 +36,7 @@ struct route_ping_series_ctx {
struct route_ping_pending { struct route_ping_pending {
struct route_ping_pending* next; struct route_ping_pending* next;
struct ROUTE_BGP* bgp; struct TOPO_BGP* bgp;
uint32_t request_id; uint32_t request_id;
route_ping_callback_t callback; route_ping_callback_t callback;
void* arg; void* arg;
@ -54,7 +54,7 @@ static void route_ping_pending_timeout(void* arg) {
u_free(p); u_free(p);
return; return;
} }
struct ROUTE_BGP* bgp = p->bgp; struct TOPO_BGP* bgp = p->bgp;
struct route_ping_pending** cur = &bgp->ping_pending; struct route_ping_pending** cur = &bgp->ping_pending;
while (*cur) { while (*cur) {
if (*cur == p) { if (*cur == p) {
@ -70,12 +70,12 @@ static void route_ping_pending_timeout(void* arg) {
} }
// прошел ответ "серия пигнов на удаленном узле завершена" // прошел ответ "серия пигнов на удаленном узле завершена"
void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { void route_ping_handle_resp(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) {
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_PING_RESPONSE)) { if (!bgp || !from_conn || !data || len < sizeof(struct TOPO_PING_RESP)) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args");
return; return;
} }
const struct BGP_PING_RESPONSE* resp = (const struct BGP_PING_RESPONSE*)data; const struct TOPO_PING_RESP* resp = (const struct TOPO_PING_RESP*)data;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%08x sent=%u ok=%u avg_rtt=%u", DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%08x sent=%u ok=%u avg_rtt=%u",
from_conn->log_name, (unsigned)resp->request_id, from_conn->log_name, (unsigned)resp->request_id,
(unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt); (unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt);
@ -102,7 +102,7 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn,
(unsigned)resp->request_id); (unsigned)resp->request_id);
} }
void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn) return; if (!bgp || !conn) return;
if (!bgp->ping_pending) { if (!bgp->ping_pending) {
@ -148,7 +148,7 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) {
// ======================================================================== // ========================================================================
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn,
uint32_t target_ip, uint16_t target_port, uint32_t target_ip, uint16_t target_port,
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms, uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg, uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg,
@ -157,14 +157,14 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args");
return -1; return -1;
} }
size_t pkt_size = pubkey ? sizeof(struct BGP_PING_REQUEST) : offsetof(struct BGP_PING_REQUEST, pubkey); size_t pkt_size = pubkey ? sizeof(struct TOPO_PING_REQ) : offsetof(struct TOPO_PING_REQ, pubkey);
struct BGP_PING_REQUEST* req_pkt = u_calloc(1, pkt_size); struct TOPO_PING_REQ* req_pkt = u_calloc(1, pkt_size);
if (!req_pkt) { if (!req_pkt) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed");
return -2; return -2;
} }
req_pkt->cmd = ETCP_ID_ROUTE_ENTRY; req_pkt->cmd = ETCP_ID_TOPO_ENTRY;
req_pkt->subcmd = ROUTE_SUBCMD_PING_REQ; req_pkt->subcmd = TOPO_SUBCMD_PING_REQ;
uint32_t new_req_id = bgp->next_ping_req_id++; uint32_t new_req_id = bgp->next_ping_req_id++;
req_pkt->request_id = new_req_id; req_pkt->request_id = new_req_id;
req_pkt->count = count; req_pkt->count = count;
@ -228,10 +228,10 @@ static void route_ping_series_finish(struct route_ping_series_ctx* ctx) {
: (uint16_t)(ctx->timeout_ms * 10); /* таймаут как "плохо" */ : (uint16_t)(ctx->timeout_ms * 10); /* таймаут как "плохо" */
/* Отправляем ответ по BGP */ /* Отправляем ответ по BGP */
struct BGP_PING_RESPONSE* resp = u_calloc(1, sizeof(struct BGP_PING_RESPONSE)); struct TOPO_PING_RESP* resp = u_calloc(1, sizeof(struct TOPO_PING_RESP));
if (resp) { if (resp) {
resp->cmd = ETCP_ID_ROUTE_ENTRY; resp->cmd = ETCP_ID_TOPO_ENTRY;
resp->subcmd = ROUTE_SUBCMD_PING_RESP; resp->subcmd = TOPO_SUBCMD_PING_RESP;
resp->request_id = ctx->request_id; resp->request_id = ctx->request_id;
resp->count_sent = ctx->count_sent; resp->count_sent = ctx->count_sent;
resp->count_ok = ctx->count_ok; resp->count_ok = ctx->count_ok;
@ -240,7 +240,7 @@ static void route_ping_series_finish(struct route_ping_series_ctx* ctx) {
struct ll_entry* e = queue_entry_new(0); struct ll_entry* e = queue_entry_new(0);
if (e) { if (e) {
e->dgram = (uint8_t*)resp; e->dgram = (uint8_t*)resp;
e->len = sizeof(struct BGP_PING_RESPONSE); e->len = sizeof(struct TOPO_PING_RESP);
etcp_send(ctx->reply_conn, e); etcp_send(ctx->reply_conn, e);
DEBUG_INFO(DEBUG_CATEGORY_BGP, DEBUG_INFO(DEBUG_CATEGORY_BGP,
"PING series done %s request_id=%08x sent=%u ok=%u avg_rtt=%u", "PING series done %s request_id=%08x sent=%u ok=%u avg_rtt=%u",
@ -303,16 +303,16 @@ static void route_ping_single_cb(int success,
} }
// Обработчик PING_REQ (нам запросили "пропингуй узел и верни результат") // Обработчик PING_REQ (нам запросили "пропингуй узел и верни результат")
void route_ping_handle_req(struct ROUTE_BGP* bgp, void route_ping_handle_req(struct TOPO_BGP* bgp,
struct ETCP_CONN* from_conn, struct ETCP_CONN* from_conn,
const uint8_t* data, const uint8_t* data,
size_t len) { size_t len) {
if (!bgp || !from_conn || !data || len < offsetof(struct BGP_PING_REQUEST, pubkey)) { if (!bgp || !from_conn || !data || len < offsetof(struct TOPO_PING_REQ, pubkey)) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "ping req: bad args len=%zu", len); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "ping req: bad args len=%zu", len);
return; return;
} }
const struct BGP_PING_REQUEST* req_pkt = (const struct BGP_PING_REQUEST*)data; const struct TOPO_PING_REQ* req_pkt = (const struct TOPO_PING_REQ*)data;
/* Создаём контекст серии */ /* Создаём контекст серии */
struct route_ping_series_ctx* ctx = u_calloc(1, sizeof(struct route_ping_series_ctx)); struct route_ping_series_ctx* ctx = u_calloc(1, sizeof(struct route_ping_series_ctx));
@ -327,10 +327,10 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
ctx->timeout_ms = req_pkt->timeout_ms; ctx->timeout_ms = req_pkt->timeout_ms;
{ {
struct NODEINFO_Q* req_nq = nodeinfo_find_by_id(bgp, from_conn->peer_node_id); struct TOPO_NODEQ* req_nq = topo_node_find_by_id(bgp, from_conn->peer_node_id);
if (req_nq) req_nq->connectivity.ping_req_time = get_time_tb(); if (req_nq) req_nq->connectivity.ping_req_time = get_time_tb();
} }
if (len >= sizeof(struct BGP_PING_REQUEST)) { if (len >= sizeof(struct TOPO_PING_REQ)) {
memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE); memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE);
} }
@ -343,9 +343,9 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
/* Если target не указан — можно разрешить из nodeinfo */ /* Если target не указан — можно разрешить из nodeinfo */
/* /*
if (sin->sin_addr.s_addr == 0 && sin->sin_port == 0) { if (sin->sin_addr.s_addr == 0 && sin->sin_port == 0) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, req_pkt->node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, req_pkt->node_id);
if (nq) { if (nq) {
const struct NODEINFO_IPV4_ADDR* addrs; const struct TOPOMSG_ADDR4* addrs;
int count = get_node_v4_addrs(nq, &addrs); int count = get_node_v4_addrs(nq, &addrs);
if (count > 0) { if (count > 0) {
memcpy(&sin->sin_addr.s_addr, addrs[0].addr, 4); memcpy(&sin->sin_addr.s_addr, addrs[0].addr, 4);

28
src/route_ping.h

@ -8,14 +8,14 @@ extern "C" {
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include "route_bgp.h" #include "topo_bgp.h"
#define ROUTE_SUBCMD_PING_REQ 0x07 #define TOPO_SUBCMD_PING_REQ 0x07
#define ROUTE_SUBCMD_PING_RESP 0x08 #define TOPO_SUBCMD_PING_RESP 0x08
struct BGP_PING_REQUEST { struct TOPO_PING_REQ {
uint8_t cmd; // ETCP_ID_ROUTE_ENTRY uint8_t cmd; // ETCP_ID_TOPO_ENTRY
uint8_t subcmd; // ROUTE_SUBCMD_PING_REQ uint8_t subcmd; // TOPO_SUBCMD_PING_REQ
uint16_t reserved; // padding для выравнивания request_id uint16_t reserved; // padding для выравнивания request_id
uint32_t request_id; // для корреляции uint32_t request_id; // для корреляции
uint8_t count; // число пингов uint8_t count; // число пингов
@ -27,9 +27,9 @@ struct BGP_PING_REQUEST {
uint8_t pubkey[SC_PUBKEY_SIZE]; // pubkey for encryption if target not in nodes uint8_t pubkey[SC_PUBKEY_SIZE]; // pubkey for encryption if target not in nodes
} __attribute__((packed)); } __attribute__((packed));
struct BGP_PING_RESPONSE { struct TOPO_PING_RESP {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; // ROUTE_SUBCMD_PING_RESP uint8_t subcmd; // TOPO_SUBCMD_PING_RESP
uint16_t reserved; // padding для выравнивания uint16_t reserved; // padding для выравнивания
uint32_t request_id; uint32_t request_id;
uint8_t count_sent; uint8_t count_sent;
@ -42,21 +42,21 @@ typedef void (*route_ping_callback_t)(int success, uint16_t avg_rtt, uint8_t cou
// Отправить запрос пинга по произвольному IP:port (используется для NAT-детекции) // Отправить запрос пинга по произвольному IP:port (используется для NAT-детекции)
// Если target_ip == 0, используется node_id из списка известных узлов // Если target_ip == 0, используется node_id из списка известных узлов
// Если pubkey != NULL, он передается в пакете (для пинга без локального nodeinfo) // Если pubkey != NULL, он передается в пакете (для пинга без локального nodeinfo)
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn,
uint32_t target_ip, uint16_t target_port, uint32_t target_ip, uint16_t target_port,
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms, uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg, uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg,
const uint8_t* pubkey); const uint8_t* pubkey);
// Очистить список ожидающих запросов (при уничтожении BGP) // Очистить список ожидающих запросов (при уничтожении BGP)
void route_ping_destroy_pending(struct ROUTE_BGP* bgp); void route_ping_destroy_pending(struct TOPO_BGP* bgp);
// Отменить pending запросы для указанного соединения (при удалении conn) // Отменить pending запросы для указанного соединения (при удалении conn)
void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn);
// Обработчики, вызываемые из route_bgp_receive_cbk // Обработчики, вызываемые из topo_bgp_receive_cbk
void route_ping_handle_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); void route_ping_handle_req(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); void route_ping_handle_resp(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
#ifdef __cplusplus #ifdef __cplusplus

4
src/routing.c

@ -2,7 +2,7 @@
#include "../lib/platform_compat.h" #include "../lib/platform_compat.h"
#include "routing.h" #include "routing.h"
#include "route_lib.h" #include "route_lib.h"
#include "route_node.h" #include "topo_node.h"
#include "tun_if.h" #include "tun_if.h"
#include "packet_dump.h" #include "packet_dump.h"
#include "etcp.h" #include "etcp.h"
@ -138,7 +138,7 @@ void route_pkt(struct UTUN_INSTANCE* instance, struct ll_entry* entry, uint64_t
return; return;
} }
struct NODEINFO_Q* nq = route->v_node_info; struct TOPO_NODEQ* nq = route->v_node_info;
if (!nq || !nq->node || nq->hop_count == 0) { if (!nq || !nq->node || nq->hop_count == 0) {
DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "Local route to %s", ip_to_str(&addr, AF_INET).str); DEBUG_TRACE(DEBUG_CATEGORY_ROUTING, "Local route to %s", ip_to_str(&addr, AF_INET).str);
} else { } else {

427
src/route_bgp.c → src/topo_bgp.c

@ -1,6 +1,6 @@
/** /**
* @file route_bgp.c * @file topo_bgp.c
* @brief BGP-like обмен маршрутами * @brief BGP-like обмен топологией узлов
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -15,10 +15,10 @@
#include "etcp_connections.h" #include "etcp_connections.h"
#include "etcp_debug.h" #include "etcp_debug.h"
#include "config_parser.h" #include "config_parser.h"
#include "route_node.h" #include "topo_node.h"
#include "route_node_lmdb.h" #include "topo_node_lmdb.h"
#include "route_lib.h" #include "route_lib.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_ping.h" #include "route_ping.h"
#include "route_connectivity.h" #include "route_connectivity.h"
#include "control_server.h" #include "control_server.h"
@ -28,64 +28,64 @@
// Вспомогательные функции // Вспомогательные функции
// ============================================================================ // ============================================================================
static void route_bgp_send_table_request(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { static void topo_bgp_send_table_request(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn) return; if (!bgp || !conn) return;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending table request to %s", conn->log_name); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending table request to %s", conn->log_name);
struct BGP_ROUTE_REQUEST* req = u_calloc(1, sizeof(struct BGP_ROUTE_REQUEST)); struct TOPOMSG_TABLE_REQ* req = u_calloc(1, sizeof(struct TOPOMSG_TABLE_REQ));
if (!req) return; if (!req) return;
req->cmd = ETCP_ID_ROUTE_ENTRY; req->cmd = ETCP_ID_TOPO_ENTRY;
req->subcmd = ROUTE_SUBCMD_REQUEST_TABLE; req->subcmd = TOPO_SUBCMD_REQUEST_TABLE;
struct ll_entry* e = queue_entry_new(0); struct ll_entry* e = queue_entry_new(0);
if (!e) { u_free(req); return; } if (!e) { u_free(req); return; }
e->dgram = (uint8_t*)req; e->len = sizeof(struct BGP_ROUTE_REQUEST); e->dgram = (uint8_t*)req; e->len = sizeof(struct TOPOMSG_TABLE_REQ);
if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); } if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); }
} }
static void route_bgp_send_table_complete(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { static void topo_bgp_send_table_complete(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn) return; if (!bgp || !conn) return;
struct BGP_ROUTE_REQUEST* req = u_calloc(1, sizeof(struct BGP_ROUTE_REQUEST)); struct TOPOMSG_TABLE_REQ* req = u_calloc(1, sizeof(struct TOPOMSG_TABLE_REQ));
if (!req) return; if (!req) return;
req->cmd = ETCP_ID_ROUTE_ENTRY; req->cmd = ETCP_ID_TOPO_ENTRY;
req->subcmd = ROUTE_SUBCMD_TABLE_COMPLETE; req->subcmd = TOPO_SUBCMD_TABLE_COMPLETE;
struct ll_entry* e = queue_entry_new(0); struct ll_entry* e = queue_entry_new(0);
if (!e) { u_free(req); return; } if (!e) { u_free(req); return; }
e->dgram = (uint8_t*)req; e->len = sizeof(struct BGP_ROUTE_REQUEST); e->dgram = (uint8_t*)req; e->len = sizeof(struct TOPOMSG_TABLE_REQ);
if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); } if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); }
} }
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); static void topo_bgp_add_to_senders(struct TOPO_BGP* bgp, struct ETCP_CONN* conn);
static bool route_bgp_should_send_to(const struct NODEINFO_Q* nq, uint64_t target_id); static bool topo_bgp_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id);
static void route_bgp_send_full_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); static void topo_bgp_send_full_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn);
static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn); static void topo_bgp_handle_request_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn);
static void nodeinfo_dump_log(const uint8_t* data, size_t len) { static void nodeinfo_dump_log(const uint8_t* data, size_t len) {
if (!data || len < sizeof(struct BGP_NODEINFO_PACKET)) return; if (!data || len < sizeof(struct TOPOMSG_NODEINFO_PKT)) return;
struct BGP_NODEINFO_PACKET* pkt = (struct BGP_NODEINFO_PACKET*)data; struct TOPOMSG_NODEINFO_PKT* pkt = (struct TOPOMSG_NODEINFO_PKT*)data;
struct NODEINFO_MSG* ni = &pkt->node; struct TOPOMSG_NODE* ni = &pkt->node;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NODEINFO nid=%016llx ver=%u v4s=%u v4a=%u hops=%u", DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NODEINFO nid=%016llx ver=%u v4s=%u v4a=%u hops=%u",
(unsigned long long)ni->node_id, ni->ver, (unsigned long long)ni->node_id, ni->ver,
ni->local_v4_sockets, ni->local_v4_addrs, ni->hop_count); ni->local_v4_sockets, ni->local_v4_addrs, ni->hop_count);
} }
static char* nodeinfo_format(const uint8_t* data, size_t len) { static char* nodeinfo_format(const uint8_t* data, size_t len) {
if (!data || len < sizeof(struct BGP_NODEINFO_PACKET)) return NULL; if (!data || len < sizeof(struct TOPOMSG_NODEINFO_PKT)) return NULL;
struct BGP_NODEINFO_PACKET* pkt = (struct BGP_NODEINFO_PACKET*)data; struct TOPOMSG_NODEINFO_PKT* pkt = (struct TOPOMSG_NODEINFO_PKT*)data;
struct NODEINFO_MSG* ni = &pkt->node; struct TOPOMSG_NODE* ni = &pkt->node;
uint64_t node_id = ni->node_id; uint64_t node_id = ni->node_id;
const uint8_t* dyn = data + sizeof(struct BGP_NODEINFO_PACKET); const uint8_t* dyn = data + sizeof(struct TOPOMSG_NODEINFO_PKT);
size_t off = 0; size_t off = 0;
char name_buf[64] = {0}; char name_buf[64] = {0};
size_t nl = ni->node_name_len; size_t nl = ni->node_name_len;
if (nl > 0 && nl < 63 && off + nl < len - sizeof(struct BGP_NODEINFO_PACKET)) { if (nl > 0 && nl < 63 && off + nl < len - sizeof(struct TOPOMSG_NODEINFO_PKT)) {
memcpy(name_buf, dyn + off, nl); off += nl; memcpy(name_buf, dyn + off, nl); off += nl;
} }
off += ni->local_v4_sockets * sizeof(struct NODEINFO_IPV4_SOCKET_META); off += ni->local_v4_sockets * sizeof(struct TOPOMSG_SOCKMETA4);
off += ni->local_v4_addrs * sizeof(struct NODEINFO_IPV4_ADDR); off += ni->local_v4_addrs * sizeof(struct TOPOMSG_ADDR4);
off += ni->local_v6_sockets * sizeof(struct NODEINFO_IPV6_SOCKET_META); off += ni->local_v6_sockets * sizeof(struct TOPOMSG_SOCKMETA6);
off += ni->local_v6_addrs * sizeof(struct NODEINFO_IPV6_ADDR); off += ni->local_v6_addrs * sizeof(struct TOPOMSG_ADDR6);
char subs_buf[512] = {0}; char subs_buf[512] = {0};
if (ni->local_v4_subnets > 0) { if (ni->local_v4_subnets > 0) {
const struct NODEINFO_IPV4_SUBNET* subs = (const struct NODEINFO_IPV4_SUBNET*)(dyn + off); const struct TOPOMSG_SUBNET4* subs = (const struct TOPOMSG_SUBNET4*)(dyn + off);
size_t sl = 0; size_t sl = 0;
for (uint8_t i = 0; i < ni->local_v4_subnets && sl < 400; i++) { for (uint8_t i = 0; i < ni->local_v4_subnets && sl < 400; i++) {
uint32_t addr = (subs[i].addr[0]<<24)|(subs[i].addr[1]<<16)|(subs[i].addr[2]<<8)|subs[i].addr[3]; uint32_t addr = (subs[i].addr[0]<<24)|(subs[i].addr[1]<<16)|(subs[i].addr[2]<<8)|subs[i].addr[3];
@ -101,14 +101,14 @@ static char* nodeinfo_format(const uint8_t* data, size_t len) {
static const char* bgp_subcmd_name(uint8_t subcmd) { static const char* bgp_subcmd_name(uint8_t subcmd) {
switch (subcmd) { switch (subcmd) {
case ROUTE_SUBCMD_NODEINFO: return "NODEINFO"; case TOPO_SUBCMD_NODEINFO: return "NODEINFO";
case ROUTE_SUBCMD_REQUEST_TABLE: return "REQ_TABLE"; case TOPO_SUBCMD_REQUEST_TABLE: return "REQ_TABLE";
case ROUTE_SUBCMD_WITHDRAW: return "WITHDRAW"; case TOPO_SUBCMD_WITHDRAW: return "WITHDRAW";
case ROUTE_SUBCMD_PING_REQ: return "PING_REQ"; case TOPO_SUBCMD_PING_REQ: return "PING_REQ";
case ROUTE_SUBCMD_PING_RESP: return "PING_RESP"; case TOPO_SUBCMD_PING_RESP: return "PING_RESP";
case ROUTE_SUBCMD_NAT_INFO: return "NAT_INFO"; case TOPO_SUBCMD_NAT_INFO: return "NAT_INFO";
case ROUTE_SUBCMD_NAT_CHECK_REQ: return "NAT_CHECK_REQ"; case TOPO_SUBCMD_NAT_CHECK_REQ: return "NAT_CHECK_REQ";
case ROUTE_SUBCMD_TABLE_COMPLETE: return "TABLE_COMPLETE"; case TOPO_SUBCMD_TABLE_COMPLETE: return "TABLE_COMPLETE";
default: return "?"; default: return "?";
} }
} }
@ -118,15 +118,15 @@ static const char* bgp_subcmd_name(uint8_t subcmd) {
// Broadcast / Withdraw // Broadcast / Withdraw
// ============================================================================ // ============================================================================
static void route_bgp_broadcast_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id, uint64_t wd_source, struct ETCP_CONN* exclude) { static void topo_bgp_broadcast_withdraw(struct TOPO_BGP* bgp, uint64_t node_id, uint64_t wd_source, struct ETCP_CONN* exclude) {
if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "bgp is NULL"); return; } if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "bgp is NULL"); return; }
struct BGP_WITHDRAW_PACKET* pkt = u_calloc(1, sizeof(struct BGP_WITHDRAW_PACKET)); struct TOPOMSG_WITHDRAW_PKT* pkt = u_calloc(1, sizeof(struct TOPOMSG_WITHDRAW_PKT));
if (!pkt) return; if (!pkt) return;
pkt->cmd = ETCP_ID_ROUTE_ENTRY; pkt->subcmd = ROUTE_SUBCMD_WITHDRAW; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_WITHDRAW;
pkt->node_id = node_id; pkt->wd_source = wd_source; pkt->node_id = node_id; pkt->wd_source = wd_source;
struct ll_entry* e = bgp->senders_list ? bgp->senders_list->head : NULL; struct ll_entry* e = bgp->senders_list ? bgp->senders_list->head : NULL;
while (e) { while (e) {
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data;
if (item && item->conn && item->conn != exclude) { if (item && item->conn && item->conn != exclude) {
struct ll_entry* copy = queue_entry_new(0); struct ll_entry* copy = queue_entry_new(0);
if (copy) { copy->dgram = u_malloc(sizeof(*pkt)); if (copy->dgram) memcpy(copy->dgram, pkt, sizeof(*pkt)); copy->len = sizeof(*pkt); etcp_send(item->conn, copy); } if (copy) { copy->dgram = u_malloc(sizeof(*pkt)); if (copy->dgram) memcpy(copy->dgram, pkt, sizeof(*pkt)); copy->len = sizeof(*pkt); etcp_send(item->conn, copy); }
@ -141,27 +141,27 @@ static void route_bgp_broadcast_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id
// Приём пакетов // Приём пакетов
// ============================================================================ // ============================================================================
static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); static void topo_bgp_handle_nat_info(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); static void topo_bgp_handle_nat_check_req(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len);
static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* entry) { static void topo_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* entry) {
if (!from_conn || !entry || entry->len < 2) { if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return; } if (!from_conn || !entry || entry->len < 2) { if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return; }
struct UTUN_INSTANCE* instance = from_conn->instance; struct UTUN_INSTANCE* instance = from_conn->instance;
if (!instance || !instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_receive_cbk: invalid instance/bgp"); queue_dgram_free(entry); queue_entry_free(entry); return; } if (!instance || !instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_receive_cbk: invalid instance/bgp"); queue_dgram_free(entry); queue_entry_free(entry); return; }
struct ROUTE_BGP* bgp = instance->bgp; struct TOPO_BGP* bgp = instance->bgp;
uint8_t* data = entry->dgram; uint8_t cmd = data[0]; uint8_t subcmd = data[1]; uint8_t* data = entry->dgram; uint8_t cmd = data[0]; uint8_t subcmd = data[1];
if (cmd != ETCP_ID_ROUTE_ENTRY) { queue_dgram_free(entry); queue_entry_free(entry); return; } if (cmd != ETCP_ID_TOPO_ENTRY) { queue_dgram_free(entry); queue_entry_free(entry); return; }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP recv %s from %s len=%zu", bgp_subcmd_name(subcmd), from_conn->log_name, entry->len); DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP recv %s from %s len=%zu", bgp_subcmd_name(subcmd), from_conn->log_name, entry->len);
if (subcmd == ROUTE_SUBCMD_NODEINFO) { nodeinfo_dump_log(data, entry->len); route_bgp_process_nodeinfo(bgp, from_conn, data, entry->len); } if (subcmd == TOPO_SUBCMD_NODEINFO) { nodeinfo_dump_log(data, entry->len); topo_bgp_process_nodeinfo(bgp, from_conn, data, entry->len); }
else if (subcmd == ROUTE_SUBCMD_WITHDRAW) route_bgp_process_withdraw(bgp, from_conn, data, entry->len); else if (subcmd == TOPO_SUBCMD_WITHDRAW) topo_bgp_process_withdraw(bgp, from_conn, data, entry->len);
else if (subcmd == ROUTE_SUBCMD_REQUEST_TABLE) route_bgp_handle_request_table(bgp, from_conn); else if (subcmd == TOPO_SUBCMD_REQUEST_TABLE) topo_bgp_handle_request_table(bgp, from_conn);
else if (subcmd == ROUTE_SUBCMD_PING_REQ) route_ping_handle_req(bgp, from_conn, data, entry->len); else if (subcmd == TOPO_SUBCMD_PING_REQ) route_ping_handle_req(bgp, from_conn, data, entry->len);
else if (subcmd == ROUTE_SUBCMD_PING_RESP) route_ping_handle_resp(bgp, from_conn, data, entry->len); else if (subcmd == TOPO_SUBCMD_PING_RESP) route_ping_handle_resp(bgp, from_conn, data, entry->len);
else if (subcmd == ROUTE_SUBCMD_NAT_INFO) route_bgp_handle_nat_info(bgp, from_conn, data, entry->len); else if (subcmd == TOPO_SUBCMD_NAT_INFO) topo_bgp_handle_nat_info(bgp, from_conn, data, entry->len);
else if (subcmd == ROUTE_SUBCMD_NAT_CHECK_REQ) route_bgp_handle_nat_check_req(bgp, from_conn, data, entry->len); else if (subcmd == TOPO_SUBCMD_NAT_CHECK_REQ) topo_bgp_handle_nat_check_req(bgp, from_conn, data, entry->len);
else if (subcmd == ROUTE_SUBCMD_TABLE_COMPLETE) { etcp_set_routing_exchange_state(from_conn, 3); DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP initial sync complete with %s", from_conn->log_name); } else if (subcmd == TOPO_SUBCMD_TABLE_COMPLETE) { etcp_set_routing_exchange_state(from_conn, 3); DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP initial sync complete with %s", from_conn->log_name); }
queue_dgram_free(entry); queue_entry_free(entry); queue_dgram_free(entry); queue_entry_free(entry);
} }
@ -171,22 +171,22 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
// Init / Destroy / New / Remove conn // Init / Destroy / New / Remove conn
// ============================================================================ // ============================================================================
static void route_bgp_on_conn_up(struct ETCP_CONN* conn, void* arg) { static void topo_bgp_on_conn_up(struct ETCP_CONN* conn, void* arg) {
(void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer UP: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); route_bgp_new_conn(conn); } (void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer UP: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); topo_bgp_new_conn(conn); }
} }
static void route_bgp_on_conn_down(struct ETCP_CONN* conn, void* arg) { static void topo_bgp_on_conn_down(struct ETCP_CONN* conn, void* arg) {
(void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer DOWN: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); route_bgp_remove_conn(conn); } (void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer DOWN: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); topo_bgp_remove_conn(conn); }
} }
static void route_bgp_etcp_conn_cbk(struct ETCP_CONN* conn, void* arg) { static void topo_bgp_etcp_conn_cbk(struct ETCP_CONN* conn, void* arg) {
(void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP set callbacks: %s", conn->log_name); etcp_conn_add_up_cbk(conn, route_bgp_on_conn_up, conn->instance->bgp); etcp_conn_add_down_cbk(conn, route_bgp_on_conn_down, conn->instance->bgp); } (void)arg; if (conn && conn->instance && conn->instance->bgp) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP set callbacks: %s", conn->log_name); etcp_conn_add_up_cbk(conn, topo_bgp_on_conn_up, conn->instance->bgp); etcp_conn_add_down_cbk(conn, topo_bgp_on_conn_down, conn->instance->bgp); }
} }
struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance) { struct TOPO_BGP* topo_bgp_init(struct UTUN_INSTANCE* instance) {
if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_init: instance is NULL"); return NULL; } if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: instance is NULL"); return NULL; }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_init: node_id=%016llx", (unsigned long long)instance->node_id); DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_init: node_id=%016llx", (unsigned long long)instance->node_id);
struct ROUTE_BGP* bgp = u_calloc(1, sizeof(struct ROUTE_BGP)); struct TOPO_BGP* bgp = u_calloc(1, sizeof(struct TOPO_BGP));
if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_init: alloc failed"); return NULL; } if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: alloc failed"); return NULL; }
bgp->instance = instance; bgp->instance = instance;
bgp->ping_pending = NULL; bgp->next_ping_req_id = 1; bgp->ping_pending = NULL; bgp->next_ping_req_id = 1;
bgp->nodeinfo_env = NULL; bgp->nodeinfo_dbi = 0; bgp->nodeinfo_env = NULL; bgp->nodeinfo_dbi = 0;
@ -194,46 +194,46 @@ struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance) {
sc_derive_ed25519_pubkey(instance->my_keys.private_key, bgp->ed25519_public_key); sc_derive_ed25519_pubkey(instance->my_keys.private_key, bgp->ed25519_public_key);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Ed25519 pubkey derived from X25519 private key"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Ed25519 pubkey derived from X25519 private key");
if (instance->config && instance->config->global.db_path[0]) route_node_lmdb_init(bgp, instance->config->global.db_path); if (instance->config && instance->config->global.db_path[0]) topo_node_lmdb_init(bgp, instance->config->global.db_path);
bgp->nodes = queue_new(instance->ua, BGP_NODES_HASH_SIZE, offsetof(struct NODEINFO_Q, hash_node_id) - sizeof(struct ll_entry), 8, "bgp_nodes"); bgp->nodes = queue_new(instance->ua, BGP_NODES_HASH_SIZE, offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "bgp_nodes");
if (!bgp->nodes) { u_free(bgp); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_init: nodes queue creation failed"); return NULL; } if (!bgp->nodes) { u_free(bgp); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: nodes queue creation failed"); return NULL; }
bgp->senders_list = queue_new(instance->ua, 0, 0, 0, "BGP_senders"); bgp->senders_list = queue_new(instance->ua, 0, 0, 0, "BGP_senders");
if (!bgp->senders_list) { queue_free(bgp->nodes); u_free(bgp); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_init: senders_list queue creation failed"); return NULL; } if (!bgp->senders_list) { queue_free(bgp->nodes); u_free(bgp); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: senders_list queue creation failed"); return NULL; }
bgp->v4_sock_meta_pool = memory_pool_init(sizeof(struct NI_IPV4_SOCKET_META), "ni_v4sock"); bgp->v4_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA4), "to_v4sock");
bgp->v4_addr_pool = memory_pool_init(sizeof(struct NI_IPV4_ADDR), "ni_v4addr"); bgp->v4_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR4), "to_v4addr");
bgp->v6_sock_meta_pool = memory_pool_init(sizeof(struct NI_IPV6_SOCKET_META), "ni_v6sock"); bgp->v6_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA6), "to_v6sock");
bgp->v6_addr_pool = memory_pool_init(sizeof(struct NI_IPV6_ADDR), "ni_v6addr"); bgp->v6_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR6), "to_v6addr");
bgp->v4_subnet_pool = memory_pool_init(sizeof(struct NI_IPV4_SUBNET), "ni_v4sub"); bgp->v4_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET4), "to_v4sub");
bgp->v6_subnet_pool = memory_pool_init(sizeof(struct NI_IPV6_SUBNET), "ni_v6sub"); bgp->v6_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET6), "to_v6sub");
bgp->local_node = NULL; bgp->local_node = NULL;
route_bgp_update_my_nodeinfo(instance, bgp); topo_bgp_update_my_nodeinfo(instance, bgp);
etcp_bind(instance, ETCP_ID_ROUTE_ENTRY, route_bgp_receive_cbk); etcp_bind(instance, ETCP_ID_TOPO_ENTRY, topo_bgp_receive_cbk);
etcp_add_new_conn_cbk(instance, route_bgp_etcp_conn_cbk, NULL); etcp_add_new_conn_cbk(instance, topo_bgp_etcp_conn_cbk, NULL);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized (NODEINFO based routing)"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "TOPO BGP module initialized");
return bgp; return bgp;
} }
void route_bgp_destroy(struct UTUN_INSTANCE* instance) { void topo_bgp_destroy(struct UTUN_INSTANCE* instance) {
if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_destroy: instance is NULL"); return; } if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: instance is NULL"); return; }
if (!instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_destroy: bgp is NULL"); return; } if (!instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: bgp is NULL"); return; }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_destroy: node_id=%016llx", (unsigned long long)instance->node_id); DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: node_id=%016llx", (unsigned long long)instance->node_id);
etcp_unbind(instance, ETCP_ID_ROUTE_ENTRY); etcp_unbind(instance, ETCP_ID_TOPO_ENTRY);
route_connectivity_cancel_all(instance); route_connectivity_cancel_all(instance);
struct ll_entry* e; struct ll_entry* e;
while ((e = queue_data_get(instance->bgp->senders_list)) != NULL) queue_entry_free(e); while ((e = queue_data_get(instance->bgp->senders_list)) != NULL) queue_entry_free(e);
queue_free(instance->bgp->senders_list); queue_free(instance->bgp->senders_list);
if (instance->bgp->local_node) { nodeinfo_free_lists(instance->bgp, instance->bgp->local_node); u_free(instance->bgp->local_node); } if (instance->bgp->local_node) { topo_node_free_lists(instance->bgp, instance->bgp->local_node); u_free(instance->bgp->local_node); }
route_node_lmdb_destroy(instance->bgp); topo_node_lmdb_destroy(instance->bgp);
if (instance->bgp->nodes) queue_free(instance->bgp->nodes); if (instance->bgp->nodes) queue_free(instance->bgp->nodes);
@ -247,36 +247,36 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance) {
u_free(instance->bgp); instance->bgp = NULL; u_free(instance->bgp); instance->bgp = NULL;
} }
void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow) { if (!bgp) return; bgp->allow_nat_check_local = allow ? 1 : 0; } void topo_bgp_set_nat_check_local(struct TOPO_BGP* bgp, int allow) { if (!bgp) return; bgp->allow_nat_check_local = allow ? 1 : 0; }
void route_bgp_new_conn(struct ETCP_CONN* conn) { void topo_bgp_new_conn(struct ETCP_CONN* conn) {
if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn is NULL"); return; } if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn is NULL"); return; }
if (!conn->instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn->instance is NULL"); return; } if (!conn->instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn->instance is NULL"); return; }
if (!conn->instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn->instance->bgp is NULL"); return; } if (!conn->instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn->instance->bgp is NULL"); return; }
if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn->instance->rt is NULL"); return; } if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn->instance->rt is NULL"); return; }
struct ROUTE_BGP* bgp = conn->instance->bgp; struct TOPO_BGP* bgp = conn->instance->bgp;
struct NODEINFO_Q* peer_nq = nodeinfo_find_by_id(bgp, conn->peer_node_id); struct TOPO_NODEQ* peer_nq = topo_node_find_by_id(bgp, conn->peer_node_id);
route_bgp_add_to_senders(bgp, conn); topo_bgp_add_to_senders(bgp, conn);
if (peer_nq && peer_nq->alien) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: peer 0x%016llx is alien, skipping route exchange", (unsigned long long)conn->peer_node_id); return; } if (peer_nq && peer_nq->alien) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: peer 0x%016llx is alien, skipping route exchange", (unsigned long long)conn->peer_node_id); return; }
struct ETCP_CONN* c = conn->instance->connections; struct ETCP_CONN* c = conn->instance->connections;
while (c) { struct ETCP_LINK* l = c->links; while (l) { if (l->initialized && l->conn && l->nat_check_status < NAT_CHECK_IN_PROGRESS) route_bgp_start_link_nat_check(bgp, l); l = l->next; } c = c->next; } while (c) { struct ETCP_LINK* l = c->links; while (l) { if (l->initialized && l->conn && l->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_bgp_start_link_nat_check(bgp, l); l = l->next; } c = c->next; }
route_bgp_send_table_request(bgp, conn); topo_bgp_send_table_request(bgp, conn);
} }
void route_bgp_remove_conn(struct ETCP_CONN* conn) { void topo_bgp_remove_conn(struct ETCP_CONN* conn) {
if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: conn is NULL"); return; } if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_remove_conn: conn is NULL"); return; }
if (!conn->instance || !conn->instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: invalid instance/bgp"); return; } if (!conn->instance || !conn->instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_remove_conn: invalid instance/bgp"); return; }
struct ROUTE_BGP* bgp = conn->instance->bgp; struct TOPO_BGP* bgp = conn->instance->bgp;
bool found_in_list = false; bool found_in_list = false;
struct ll_entry* e = bgp->senders_list->head; struct ll_entry* e = bgp->senders_list->head;
while (e) { struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; if (item->conn == conn) { found_in_list = true; break; } e = e->next; } while (e) { struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data; if (item->conn == conn) { found_in_list = true; break; } e = e->next; }
if (!found_in_list) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: conn already removed or not in list, skipping"); return; } if (!found_in_list) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "topo_bgp_remove_conn: conn already removed or not in list, skipping"); return; }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "route_bgp_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id); DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id);
route_ping_cancel_for_conn(bgp, conn); route_ping_cancel_for_conn(bgp, conn);
struct ETCP_LINK* lnk = conn->links; while (lnk) { if (lnk->nat_check_status == NAT_CHECK_IN_PROGRESS) lnk->nat_check_status = NAT_CHECK_NONE; lnk = lnk->next; } struct ETCP_LINK* lnk = conn->links; while (lnk) { if (lnk->nat_check_status == NAT_CHECK_IN_PROGRESS) lnk->nat_check_status = NAT_CHECK_NONE; lnk = lnk->next; }
@ -286,46 +286,46 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
struct ll_entry* node_entry = bgp->nodes ? bgp->nodes->head : NULL; struct ll_entry* node_entry = bgp->nodes ? bgp->nodes->head : NULL;
while (node_entry) { while (node_entry) {
struct ll_entry* next = node_entry->next; struct ll_entry* next = node_entry->next;
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)node_entry; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)node_entry;
if (route_bgp_remove_path(nq, conn) == 1) { if (topo_bgp_remove_path(nq, conn) == 1) {
if (rt) route_delete(rt, nq); if (rt) route_delete(rt, nq);
if (conn->instance && conn->instance->control_srv) control_server_notify_node_removed(conn->instance->control_srv, nq->hash_node_id); if (conn->instance && conn->instance->control_srv) control_server_notify_node_removed(conn->instance->control_srv, nq->hash_node_id);
nq->dirty = 1; nq->dirty = 1;
route_connectivity_cancel_node(conn->instance, nq); route_connectivity_cancel_node(conn->instance, nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
uint64_t key = nq->hash_node_id; uint64_t key = nq->hash_node_id;
nodeinfo_free_lists(bgp, nq); topo_node_free_lists(bgp, nq);
struct ll_entry* entry = node_entry; struct ll_entry* entry = node_entry;
if (entry) { queue_remove_data(bgp->nodes, entry); queue_entry_free(entry); } if (entry) { queue_remove_data(bgp->nodes, entry); queue_entry_free(entry); }
nodes_removed++; nodes_removed++;
etcp_router_conn_close_all_for_node(bgp->instance, key); etcp_router_conn_close_all_for_node(bgp->instance, key);
uint64_t wd_src = (key == conn->peer_node_id) ? conn->instance->node_id : conn->peer_node_id; uint64_t wd_src = (key == conn->peer_node_id) ? conn->instance->node_id : conn->peer_node_id;
route_bgp_broadcast_withdraw(bgp, key, wd_src, NULL); topo_bgp_broadcast_withdraw(bgp, key, wd_src, NULL);
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Removed node %016llx after link down", (unsigned long long)key); DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Removed node %016llx after link down", (unsigned long long)key);
} }
node_entry = next; node_entry = next;
} }
e = bgp->senders_list->head; e = bgp->senders_list->head;
while (e) { struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; if (item->conn == conn) { queue_remove_data(bgp->senders_list, e); queue_entry_free(e); break; } e = e->next; } while (e) { struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data; if (item->conn == conn) { queue_remove_data(bgp->senders_list, e); queue_entry_free(e); break; } e = e->next; }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer removed: %s nodes=%d", conn->log_name, nodes_removed); DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer removed: %s nodes=%d", conn->log_name, nodes_removed);
} }
// ============================================================================ // ============================================================================
// NEW NODEINFO BASED IMPLEMENTATION // NODEINFO BASED IMPLEMENTATION
// ============================================================================ // ============================================================================
struct ETCP_CONN* route_bgp_find_conn_for_node(struct ROUTE_BGP* bgp, uint64_t node_id) { struct ETCP_CONN* topo_bgp_find_conn_for_node(struct TOPO_BGP* bgp, uint64_t node_id) {
if (!bgp) return NULL; if (!bgp) return NULL;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, node_id);
if (!nq || !nq->paths || !nq->paths->head) return NULL; if (!nq || !nq->paths || !nq->paths->head) return NULL;
struct ll_entry* e = nq->paths->head; struct ll_entry* e = nq->paths->head;
struct NODEINFO_PATH* best_live = NULL; uint8_t best_live_hops = 255; struct TOPO_NODEPATH* best_live = NULL; uint8_t best_live_hops = 255;
struct NODEINFO_PATH* best_any = NULL; uint8_t best_any_hops = 255; struct TOPO_NODEPATH* best_any = NULL; uint8_t best_any_hops = 255;
while (e) { while (e) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)e;
if (path->conn) { if (path->conn->links_up && path->hop_count < best_live_hops) { best_live = path; best_live_hops = path->hop_count; } if (path->hop_count < best_any_hops) { best_any = path; best_any_hops = path->hop_count; } } if (path->conn) { if (path->conn->links_up && path->hop_count < best_live_hops) { best_live = path; best_live_hops = path->hop_count; } if (path->hop_count < best_any_hops) { best_any = path; best_any_hops = path->hop_count; } }
e = e->next; e = e->next;
} }
@ -333,25 +333,25 @@ struct ETCP_CONN* route_bgp_find_conn_for_node(struct ROUTE_BGP* bgp, uint64_t n
return best_live ? best_live->conn : (best_any ? best_any->conn : NULL); return best_live ? best_live->conn : (best_any ? best_any->conn : NULL);
} }
int route_bgp_add_path(struct NODEINFO_Q* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count) { int topo_bgp_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count) {
if (!nq || !conn || hop_count > MAX_HOPS || !hop_list) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "add_path: invalid args"); return -1; } if (!nq || !conn || hop_count > MAX_HOPS || !hop_list) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "add_path: invalid args"); return -1; }
if (!nq->paths) { nq->paths = queue_new(conn->instance->ua, 0, 0, 0, "node_paths"); if (!nq->paths) return -1; } if (!nq->paths) { nq->paths = queue_new(conn->instance->ua, 0, 0, 0, "node_paths"); if (!nq->paths) return -1; }
size_t path_size = sizeof(struct NODEINFO_PATH) - sizeof(struct ll_entry) + hop_count * 8; size_t path_size = sizeof(struct TOPO_NODEPATH) - sizeof(struct ll_entry) + hop_count * 8;
struct ll_entry* pe = queue_entry_new(path_size); if (!pe) return -1; struct ll_entry* pe = queue_entry_new(path_size); if (!pe) return -1;
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)pe; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)pe;
path->conn = conn; path->hop_count = hop_count; path->conn = conn; path->hop_count = hop_count;
memcpy((uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)), hop_list, hop_count * 8); memcpy((uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH)), hop_list, hop_count * 8);
queue_data_put(nq->paths, pe); queue_data_put(nq->paths, pe);
return 0; return 0;
} }
int route_bgp_remove_path_by_hop(struct NODEINFO_Q* nq, uint64_t wd_source) { int topo_bgp_remove_path_by_hop(struct TOPO_NODEQ* nq, uint64_t wd_source) {
if (!nq || !nq->paths) return 0; if (!nq || !nq->paths) return 0;
int removed = 0; int removed = 0;
struct ll_entry* e = nq->paths->head; struct ll_entry* e = nq->paths->head;
while (e) { while (e) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)e;
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH));
bool has_wd = false; for (uint8_t i = 0; i < path->hop_count; i++) if (hop[i] == wd_source) { has_wd = true; break; } bool has_wd = false; for (uint8_t i = 0; i < path->hop_count; i++) if (hop[i] == wd_source) { has_wd = true; break; }
if (has_wd) { struct ll_entry* next = e->next; queue_remove_data(nq->paths, e); queue_entry_free(e); removed++; e = next; continue; } if (has_wd) { struct ll_entry* next = e->next; queue_remove_data(nq->paths, e); queue_entry_free(e); removed++; e = next; continue; }
e = e->next; e = e->next;
@ -360,10 +360,10 @@ int route_bgp_remove_path_by_hop(struct NODEINFO_Q* nq, uint64_t wd_source) {
return removed; return removed;
} }
int route_bgp_remove_path(struct NODEINFO_Q* nq, struct ETCP_CONN* conn) { int topo_bgp_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn) {
if (!nq || !conn || !nq->paths) return -1; if (!nq || !conn || !nq->paths) return -1;
struct ll_entry* e = nq->paths->head; struct ll_entry* e = nq->paths->head;
while (e) { struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; if (path->conn == conn) { queue_remove_data(nq->paths, e); queue_entry_free(e); break; } e = e->next; } while (e) { struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)e; if (path->conn == conn) { queue_remove_data(nq->paths, e); queue_entry_free(e); break; } e = e->next; }
int remaining = nq->paths ? queue_entry_count(nq->paths) : 0; int remaining = nq->paths ? queue_entry_count(nq->paths) : 0;
if (remaining == 0) { if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } return 1; } if (remaining == 0) { if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } return 1; }
return 0; return 0;
@ -378,29 +378,24 @@ static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent,
if (link->nat_check_status != NAT_CHECK_IN_PROGRESS) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "nat check cb: link status=%d, skip (conn down?)", link->nat_check_status); u_free(na); return; } if (link->nat_check_status != NAT_CHECK_IN_PROGRESS) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "nat check cb: link status=%d, skip (conn down?)", link->nat_check_status); u_free(na); return; }
link->nat_type = success ? NAT_TYPE_EIM : NAT_TYPE_STRICT; link->nat_type = success ? NAT_TYPE_EIM : NAT_TYPE_STRICT;
link->nat_check_status = success ? NAT_CHECK_EIM : NAT_CHECK_STRICT; link->nat_check_status = success ? NAT_CHECK_EIM : NAT_CHECK_STRICT;
if (link->etcp) route_bgp_send_nat_info(link->etcp, link->remote_socket_id, na->nat_ip, na->nat_port, link->nat_type); if (link->etcp) topo_bgp_send_nat_info(link->etcp, link->remote_socket_id, na->nat_ip, na->nat_port, link->nat_type);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT check result: type=%s for conn=%s nat=%s:%u", success ? "EIM" : "STRICT", link->etcp->log_name, ip_to_str(&na->nat_ip, AF_INET).str, na->nat_port); DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT check result: type=%s for conn=%s nat=%s:%u", success ? "EIM" : "STRICT", link->etcp->log_name, ip_to_str(&na->nat_ip, AF_INET).str, na->nat_port);
u_free(na); u_free(na);
} }
static struct ETCP_CONN* route_bgp_find_third_node(struct ROUTE_BGP* bgp, struct ETCP_CONN* exclude) { static struct ETCP_CONN* topo_bgp_find_third_node(struct TOPO_BGP* bgp, struct ETCP_CONN* exclude) {
if (!bgp || !bgp->senders_list) return NULL; if (!bgp || !bgp->senders_list) return NULL;
struct ll_entry* e = bgp->senders_list->head; struct ll_entry* e = bgp->senders_list->head;
while (e) { struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data; if (item && item->conn && item->conn != exclude && item->conn->links && item->conn->links->remote_only_local==0 && item->conn->links->remote_type != CFG_SERVER_TYPE_PRIVATE && item->conn->links->remote_type != CFG_SERVER_TYPE_LOCAL) return item->conn; e = e->next; } while (e) { struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data; if (item && item->conn && item->conn != exclude && item->conn->links && item->conn->links->remote_only_local==0 && item->conn->links->remote_type != CFG_SERVER_TYPE_PRIVATE && item->conn->links->remote_type != CFG_SERVER_TYPE_LOCAL) return item->conn; e = e->next; }
return NULL; return NULL;
} }
static void route_bgp_extract_nat_addr(struct ETCP_CONN* conn, uint32_t* nat_ip, uint16_t* nat_port) { void topo_bgp_start_link_nat_check(struct TOPO_BGP* bgp, struct ETCP_LINK* link) {
*nat_ip = 0; *nat_port = 0; if (!conn) return;
struct ETCP_LINK* l = conn->links; while (l) { if (l->nat_ip != 0) { *nat_ip = l->nat_ip; *nat_port = l->nat_port; return; } l = l->next; }
}
void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) {
if (!bgp || !link || !link->conn || !link->etcp) return; if (!bgp || !link || !link->conn || !link->etcp) return;
if (link->nat_type == NAT_TYPE_DIRECT) return; if (link->nat_type == NAT_TYPE_DIRECT) return;
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return;
if (link->conn->type == CFG_SERVER_TYPE_PRIVATE || link->conn->type == CFG_SERVER_TYPE_LOCAL) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "skip nat check for private/local socket link"); return; } if (link->conn->type == CFG_SERVER_TYPE_PRIVATE || link->conn->type == CFG_SERVER_TYPE_LOCAL) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "skip nat check for private/local socket link"); return; }
struct ETCP_CONN* third_conn = route_bgp_find_third_node(bgp, link->etcp); struct ETCP_CONN* third_conn = topo_bgp_find_third_node(bgp, link->etcp);
if (!third_conn) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no third node found for link"); return; } if (!third_conn) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no third node found for link"); return; }
uint32_t target_ip; uint16_t target_port; uint32_t target_ip; uint16_t target_port;
@ -420,30 +415,30 @@ void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* lin
// ===== NODEINFO process ===== // ===== NODEINFO process =====
int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, const uint8_t* data, size_t len) { int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, const uint8_t* data, size_t len) {
if (!bgp || !from || len < sizeof(struct BGP_NODEINFO_PACKET)) return -1; if (!bgp || !from || len < sizeof(struct TOPOMSG_NODEINFO_PKT)) return -1;
struct BGP_NODEINFO_PACKET* pkt = (struct BGP_NODEINFO_PACKET*)data; struct TOPOMSG_NODEINFO_PKT* pkt = (struct TOPOMSG_NODEINFO_PKT*)data;
struct NODEINFO_MSG* ni = &pkt->node; struct TOPOMSG_NODE* ni = &pkt->node;
int dyn = nodeinfo_dyn_size(ni); int dyn = topo_node_dyn_size(ni);
if ((size_t)dyn + sizeof(struct BGP_NODEINFO_PACKET) != len) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "Incorrect packet size (%s)", from->log_name); return -1; } if ((size_t)dyn + sizeof(struct TOPOMSG_NODEINFO_PKT) != len) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "Incorrect packet size (%s)", from->log_name); return -1; }
uint64_t node_id = ni->node_id; uint64_t node_id = ni->node_id;
if (ni->hop_count >= MAX_HOPS) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "NODEINFO from %s dropped: too many hops (%d)", from->log_name, ni->hop_count); return -1; } if (ni->hop_count >= MAX_HOPS) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "NODEINFO from %s dropped: too many hops (%d)", from->log_name, ni->hop_count); return -1; }
if (node_id == bgp->instance->node_id) return 0; if (node_id == bgp->instance->node_id) return 0;
struct NODEINFO_Q* nodeinfo1 = nodeinfo_find_by_id(bgp, node_id); struct TOPO_NODEQ* nodeinfo1 = topo_node_find_by_id(bgp, node_id);
uint8_t new_ver = ni->ver; uint8_t new_ver = ni->ver;
if (nodeinfo1 && (int8_t)(nodeinfo1->last_ver - new_ver) >= 0) { if (nodeinfo1 && (int8_t)(nodeinfo1->last_ver - new_ver) >= 0) {
int new_hops = ni->hop_count + 1; int new_hops = ni->hop_count + 1;
if (new_hops <= MAX_HOPS) { if (new_hops <= MAX_HOPS) {
uint64_t hop_list[MAX_HOPS]; uint64_t hop_list[MAX_HOPS];
const uint8_t* hop_src = (const uint8_t*)ni + sizeof(struct NODEINFO_MSG) + dyn - ni->hop_count * 8; const uint8_t* hop_src = (const uint8_t*)ni + sizeof(struct TOPOMSG_NODE) + dyn - ni->hop_count * 8;
memcpy(hop_list, hop_src, ni->hop_count * 8); memcpy(hop_list, hop_src, ni->hop_count * 8);
hop_list[ni->hop_count] = from->peer_node_id; hop_list[ni->hop_count] = from->peer_node_id;
route_bgp_remove_path(nodeinfo1, from); topo_bgp_remove_path(nodeinfo1, from);
route_bgp_add_path(nodeinfo1, from, hop_list, new_hops); topo_bgp_add_path(nodeinfo1, from, hop_list, new_hops);
} }
return 0; return 0;
} }
@ -455,39 +450,39 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
struct ll_queue* paths = NULL; struct ll_queue* paths = NULL;
int is_new_node = 0; int is_new_node = 0;
if (nodeinfo1) { if (nodeinfo1) {
nodeinfo_free_lists(bgp, nodeinfo1); topo_node_free_lists(bgp, nodeinfo1);
paths = nodeinfo1->paths; nodeinfo1->paths = NULL; paths = nodeinfo1->paths; nodeinfo1->paths = NULL;
} else { is_new_node = 1; } } else { is_new_node = 1; }
// deserialize from protocol // deserialize from protocol
const uint8_t* ser_data = data + 2; const uint8_t* ser_data = data + 2;
size_t ser_len = len - 2; size_t ser_len = len - 2;
struct NODEINFO* new_ni = NULL; struct TOPO_NODE* new_ni = NULL;
struct NODEINFO_ROUTES* new_routes = NULL; struct TOPO_NODESUBNETS* new_subnets = NULL;
struct NODEINFO_TRANZIT_NODE* new_tranzit = NULL; uint8_t new_tranzit_count = 0; struct TOPOMSG_TRANZIT* new_tranzit = NULL; uint8_t new_tranzit_count = 0;
uint64_t* new_hop_list = NULL; uint8_t new_hop_count = 0; uint64_t* new_hop_list = NULL; uint8_t new_hop_count = 0;
if (nodeinfo_deserialize(bgp, ser_data, ser_len, &new_ni, &new_routes, &new_tranzit, &new_tranzit_count, &new_hop_list, &new_hop_count) != 0) { if (topo_node_deserialize(bgp, ser_data, ser_len, &new_ni, &new_subnets, &new_tranzit, &new_tranzit_count, &new_hop_list, &new_hop_count) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NODEINFO deserialize failed from %s", from->log_name); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NODEINFO deserialize failed from %s", from->log_name);
if (nodeinfo1) { queue_remove_data(bgp->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); } if (nodeinfo1) { queue_remove_data(bgp->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); }
return -1; return -1;
} }
if (nodeinfo1) { if (nodeinfo1) {
nodeinfo1->node = new_ni; nodeinfo_ref(new_ni); nodeinfo1->node = new_ni; topo_node_ref(new_ni);
nodeinfo1->hash_node_id = new_ni->node_id; nodeinfo1->hash_node_id = new_ni->node_id;
nodeinfo1->routes = new_routes; nodeinfo1->subnets = new_subnets;
u_free(nodeinfo1->tranzit_data); nodeinfo1->tranzit_data = new_tranzit; u_free(nodeinfo1->tranzit_data); nodeinfo1->tranzit_data = new_tranzit;
nodeinfo1->tranzit_count = new_tranzit_count; nodeinfo1->tranzit_count = new_tranzit_count;
u_free(nodeinfo1->hop_list); nodeinfo1->hop_list = new_hop_list; u_free(nodeinfo1->hop_list); nodeinfo1->hop_list = new_hop_list;
nodeinfo1->hop_count = new_hop_count; nodeinfo1->hop_count = new_hop_count;
} else { } else {
struct ll_entry* qe = queue_entry_new(sizeof(struct NODEINFO_Q)); struct ll_entry* qe = queue_entry_new(sizeof(struct TOPO_NODEQ));
if (!qe) { nodeinfo_unref(new_ni); u_free(new_tranzit); u_free(new_hop_list); u_free(new_routes); return -1; } if (!qe) { topo_node_unref(new_ni); u_free(new_tranzit); u_free(new_hop_list); u_free(new_subnets); return -1; }
nodeinfo1 = (struct NODEINFO_Q*)qe; nodeinfo1 = (struct TOPO_NODEQ*)qe;
memset((uint8_t*)nodeinfo1 + sizeof(struct ll_entry), 0, sizeof(*nodeinfo1) - sizeof(struct ll_entry)); memset((uint8_t*)nodeinfo1 + sizeof(struct ll_entry), 0, sizeof(*nodeinfo1) - sizeof(struct ll_entry));
nodeinfo1->node = new_ni; nodeinfo_ref(new_ni); nodeinfo1->node = new_ni; topo_node_ref(new_ni);
nodeinfo1->hash_node_id = new_ni->node_id; nodeinfo1->hash_node_id = new_ni->node_id;
nodeinfo1->routes = new_routes; nodeinfo1->subnets = new_subnets;
nodeinfo1->tranzit_data = new_tranzit; nodeinfo1->tranzit_count = new_tranzit_count; nodeinfo1->tranzit_data = new_tranzit; nodeinfo1->tranzit_count = new_tranzit_count;
nodeinfo1->hop_list = new_hop_list; nodeinfo1->hop_count = new_hop_count; nodeinfo1->hop_list = new_hop_list; nodeinfo1->hop_count = new_hop_count;
nodeinfo1->connectivity.probe_status = PROBE_STATUS_NONE; nodeinfo1->connectivity.probe_status = PROBE_STATUS_NONE;
@ -511,22 +506,22 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
nodeinfo1->hop_list = u_malloc(nodeinfo1->hop_count * 8); nodeinfo1->hop_list = u_malloc(nodeinfo1->hop_count * 8);
memcpy(nodeinfo1->hop_list, hop_list, nodeinfo1->hop_count * 8); memcpy(nodeinfo1->hop_list, hop_list, nodeinfo1->hop_count * 8);
route_bgp_remove_path_by_hop(nodeinfo1, from->peer_node_id); topo_bgp_remove_path_by_hop(nodeinfo1, from->peer_node_id);
route_bgp_add_path(nodeinfo1, from, hop_list, nodeinfo1->hop_count); topo_bgp_add_path(nodeinfo1, from, hop_list, nodeinfo1->hop_count);
if (bgp->instance->rt) route_insert(bgp->instance->rt, nodeinfo1); if (bgp->instance->rt) route_insert(bgp->instance->rt, nodeinfo1);
if (node_id != bgp->instance->node_id) route_node_lmdb_put(bgp, nodeinfo1); if (node_id != bgp->instance->node_id) topo_node_lmdb_put(bgp, nodeinfo1);
if (bgp->instance->control_srv) control_server_notify_node_change(bgp->instance->control_srv, nodeinfo1); if (bgp->instance->control_srv) control_server_notify_node_change(bgp->instance->control_srv, nodeinfo1);
int hop_count = nodeinfo1->hop_count; int hop_count = nodeinfo1->hop_count;
struct ll_entry* se = bgp->senders_list ? bgp->senders_list->head : NULL; struct ll_entry* se = bgp->senders_list ? bgp->senders_list->head : NULL;
while (se) { while (se) {
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)se->data;
if (item->conn) { if (item->conn) {
uint64_t id = item->conn->peer_node_id; uint64_t id = item->conn->peer_node_id;
if (id != node_id) { if (id != node_id) {
int found = 0; for (int i = 0; i < hop_count; i++) if (hop_list[i] == id) found = 1; int found = 0; for (int i = 0; i < hop_count; i++) if (hop_list[i] == id) found = 1;
if (found == 0) route_bgp_send_nodeinfo(nodeinfo1, item->conn); if (found == 0) topo_bgp_send_nodeinfo(nodeinfo1, item->conn);
} }
} }
se = se->next; se = se->next;
@ -536,46 +531,46 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
if (!is_new_node) socks_changed = 1; if (!is_new_node) socks_changed = 1;
if (node_id != bgp->instance->node_id && (is_new_node || socks_changed)) { if (node_id != bgp->instance->node_id && (is_new_node || socks_changed)) {
int v4a = ni_list_count((struct _ni_head*)nodeinfo1->node->v4_addrs); int v4a = topo_list_count((struct _topo_head*)nodeinfo1->node->v4_addrs);
int v6a = ni_list_count((struct _ni_head*)nodeinfo1->node->v6_addrs); int v6a = topo_list_count((struct _topo_head*)nodeinfo1->node->v6_addrs);
if (v4a > 0 || v6a > 0) route_connectivity_probe_node(bgp->instance, nodeinfo1); if (v4a > 0 || v6a > 0) route_connectivity_probe_node(bgp->instance, nodeinfo1);
} }
return 0; return 0;
} }
int route_bgp_process_withdraw(struct ROUTE_BGP* bgp, struct ETCP_CONN* sender, const uint8_t* data, size_t len) { int topo_bgp_process_withdraw(struct TOPO_BGP* bgp, struct ETCP_CONN* sender, const uint8_t* data, size_t len) {
if (!bgp || len < sizeof(struct BGP_WITHDRAW_PACKET)) return -1; if (!bgp || len < sizeof(struct TOPOMSG_WITHDRAW_PKT)) return -1;
struct BGP_WITHDRAW_PACKET* wp = (struct BGP_WITHDRAW_PACKET*)data; struct TOPOMSG_WITHDRAW_PKT* wp = (struct TOPOMSG_WITHDRAW_PKT*)data;
uint64_t node_id = wp->node_id, wd_source = wp->wd_source; uint64_t node_id = wp->node_id, wd_source = wp->wd_source;
struct NODEINFO_Q* nq = nodeinfo_find_by_id(bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, node_id);
if (!nq) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "node not found"); return 0; } if (!nq) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "node not found"); return 0; }
int ret = route_bgp_remove_path_by_hop(nq, wd_source); int ret = topo_bgp_remove_path_by_hop(nq, wd_source);
if (ret == 1) { if (ret == 1) {
if (bgp->instance && bgp->instance->rt) route_delete(bgp->instance->rt, nq); if (bgp->instance && bgp->instance->rt) route_delete(bgp->instance->rt, nq);
if (bgp->instance->control_srv) control_server_notify_node_removed(bgp->instance->control_srv, node_id); if (bgp->instance->control_srv) control_server_notify_node_removed(bgp->instance->control_srv, node_id);
nq->dirty = 1; nq->dirty = 1;
route_connectivity_cancel_node(bgp->instance, nq); route_connectivity_cancel_node(bgp->instance, nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
nodeinfo_free_lists(bgp, nq); topo_node_free_lists(bgp, nq);
struct ll_entry* entry = queue_find_data_by_index(bgp->nodes, &node_id); struct ll_entry* entry = queue_find_data_by_index(bgp->nodes, &node_id);
if (entry) { queue_remove_data(bgp->nodes, entry); queue_entry_free(entry); } if (entry) { queue_remove_data(bgp->nodes, entry); queue_entry_free(entry); }
route_bgp_broadcast_withdraw(bgp, node_id, wd_source, sender); topo_bgp_broadcast_withdraw(bgp, node_id, wd_source, sender);
} }
return 0; return 0;
} }
void route_bgp_send_nodeinfo(struct NODEINFO_Q* node, struct ETCP_CONN* conn) { void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* node, struct ETCP_CONN* conn) {
if (!node || !conn) return; if (!node || !conn) return;
size_t max_sz = sizeof(struct BGP_NODEINFO_PACKET) + 4096; size_t max_sz = sizeof(struct TOPOMSG_NODEINFO_PKT) + 4096;
uint8_t* p = u_malloc(max_sz); uint8_t* p = u_malloc(max_sz);
if (!p) return; if (!p) return;
p[0] = ETCP_ID_ROUTE_ENTRY; p[1] = ROUTE_SUBCMD_NODEINFO; p[0] = ETCP_ID_TOPO_ENTRY; p[1] = TOPO_SUBCMD_NODEINFO;
int ser_len = nodeinfo_serialize(conn->instance->bgp, node, p + 2, max_sz - 2); int ser_len = topo_node_serialize(conn->instance->bgp, node, p + 2, max_sz - 2);
if (ser_len < 0) { u_free(p); return; } if (ser_len < 0) { u_free(p); return; }
struct ll_entry* e = queue_entry_new(0); struct ll_entry* e = queue_entry_new(0);
@ -585,24 +580,24 @@ void route_bgp_send_nodeinfo(struct NODEINFO_Q* node, struct ETCP_CONN* conn) {
if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NODEINFO failed"); u_free(p); queue_entry_free(e); } if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NODEINFO failed"); u_free(p); queue_entry_free(e); }
} }
static void route_bgp_add_to_senders(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { static void topo_bgp_add_to_senders(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn || !bgp->senders_list) return; if (!bgp || !conn || !bgp->senders_list) return;
bool already = false; bool already = false;
struct ll_entry* e = bgp->senders_list->head; struct ll_entry* e = bgp->senders_list->head;
while (e) { if (((struct ROUTE_BGP_CONN_ITEM*)e->data)->conn == conn) { already = true; break; } e = e->next; } while (e) { if (((struct TOPO_BGP_CONN_ITEM*)e->data)->conn == conn) { already = true; break; } e = e->next; }
if (!already) { if (!already) {
struct ll_entry* item_entry = queue_entry_new(sizeof(struct ROUTE_BGP_CONN_ITEM)); struct ll_entry* item_entry = queue_entry_new(sizeof(struct TOPO_BGP_CONN_ITEM));
if (item_entry) { ((struct ROUTE_BGP_CONN_ITEM*)item_entry->data)->conn = conn; queue_data_put(bgp->senders_list, item_entry); } if (item_entry) { ((struct TOPO_BGP_CONN_ITEM*)item_entry->data)->conn = conn; queue_data_put(bgp->senders_list, item_entry); }
} }
} }
static bool route_bgp_should_send_to(const struct NODEINFO_Q* nq, uint64_t target_id) { static bool topo_bgp_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id) {
if (!nq || !nq->node || !nq->paths) return false; if (!nq || !nq->node || !nq->paths) return false;
if (target_id == nq->node->node_id) return false; if (target_id == nq->node->node_id) return false;
struct ll_entry* e = nq->paths->head; struct ll_entry* e = nq->paths->head;
while (e) { while (e) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)e;
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH));
bool has_id = false; for (uint8_t i = 0; i < path->hop_count; i++) if (hop[i] == target_id) { has_id = true; break; } bool has_id = false; for (uint8_t i = 0; i < path->hop_count; i++) if (hop[i] == target_id) { has_id = true; break; }
if (!has_id) return true; if (!has_id) return true;
e = e->next; e = e->next;
@ -610,31 +605,31 @@ static bool route_bgp_should_send_to(const struct NODEINFO_Q* nq, uint64_t targe
return false; return false;
} }
static void route_bgp_send_full_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { static void topo_bgp_send_full_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn) return; if (!bgp || !conn) return;
uint64_t target = conn->peer_node_id; uint64_t target = conn->peer_node_id;
struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL;
while (e) { while (e) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
if (nq->hop_count == 0) { e = e->next; continue; } if (nq->hop_count == 0) { e = e->next; continue; }
if (!nq->paths) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "node has no paths"); e = e->next; continue; } if (!nq->paths) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "node has no paths"); e = e->next; continue; }
if (route_bgp_should_send_to(nq, target)) route_bgp_send_nodeinfo(nq, conn); if (topo_bgp_should_send_to(nq, target)) topo_bgp_send_nodeinfo(nq, conn);
e = e->next; e = e->next;
} }
} }
static void route_bgp_handle_request_table(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { static void topo_bgp_handle_request_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) {
if (!bgp || !conn) return; if (!bgp || !conn) return;
route_bgp_send_nodeinfo(bgp->local_node, conn); topo_bgp_send_nodeinfo(bgp->local_node, conn);
route_bgp_send_full_table(bgp, conn); topo_bgp_send_full_table(bgp, conn);
route_bgp_add_to_senders(bgp, conn); topo_bgp_add_to_senders(bgp, conn);
route_bgp_send_table_complete(bgp, conn); topo_bgp_send_table_complete(bgp, conn);
} }
static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { static void topo_bgp_handle_nat_info(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) {
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_NAT_INFO) || !bgp->local_node || !bgp->local_node->node) return; if (!bgp || !from_conn || !data || len < sizeof(struct TOPOMSG_NAT_INFO) || !bgp->local_node || !bgp->local_node->node) return;
const struct BGP_NAT_INFO* info = (const struct BGP_NAT_INFO*)data; const struct TOPOMSG_NAT_INFO* info = (const struct TOPOMSG_NAT_INFO*)data;
uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | (info->nat_ip[2] << 8) | info->nat_ip[3]; uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) | (info->nat_ip[2] << 8) | info->nat_ip[3];
uint16_t nat_port = ntohs(info->nat_port); uint8_t socket_id = info->socket_id; uint16_t nat_port = ntohs(info->nat_port); uint8_t socket_id = info->socket_id;
@ -645,7 +640,7 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f
else verified_type = NAT_VERIFIED_UNKNOWN; else verified_type = NAT_VERIFIED_UNKNOWN;
int data_changed = 0; int data_changed = 0;
{ struct NI_IPV4_SOCKET_META* sm = bgp->local_node->node->v4_sock_meta; while (sm) { if (sm->id == socket_id) { if (sm->nat_type != verified_type) { sm->nat_type = verified_type; data_changed = 1; } break; } sm = sm->next; } } { struct TOPO_SOCKMETA4* sm = bgp->local_node->node->v4_sock_meta; while (sm) { if (sm->id == socket_id) { if (sm->nat_type != verified_type) { sm->nat_type = verified_type; data_changed = 1; } break; } sm = sm->next; } }
struct ETCP_SOCKET* es = bgp->instance->etcp_sockets; struct ETCP_SOCKET* es = bgp->instance->etcp_sockets;
while (es) { if (es->sock_id == socket_id) { while (es) { if (es->sock_id == socket_id) {
@ -654,58 +649,58 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f
es = es->next; } es = es->next; }
if (data_changed) { if (data_changed) {
int prev_v4a = ni_list_count((struct _ni_head*)bgp->local_node->node->v4_addrs); int prev_v4a = topo_list_count((struct _topo_head*)bgp->local_node->node->v4_addrs);
route_bgp_update_my_nodeinfo(bgp->instance, bgp); topo_bgp_update_my_nodeinfo(bgp->instance, bgp);
if (ni_list_count((struct _ni_head*)bgp->local_node->node->v4_addrs) != prev_v4a) { if (topo_list_count((struct _topo_head*)bgp->local_node->node->v4_addrs) != prev_v4a) {
bgp->local_node->dirty = 1; bgp->local_node->dirty = 1;
bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1; bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1;
bgp->local_node->last_ver = bgp->local_node->node->ver; bgp->local_node->last_ver = bgp->local_node->node->ver;
} }
if (bgp->local_node->dirty && bgp->senders_list) { if (bgp->local_node->dirty && bgp->senders_list) {
struct ll_entry* se = bgp->senders_list->head; struct ll_entry* se = bgp->senders_list->head;
while (se) { struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)se->data; if (item && item->conn) route_bgp_send_nodeinfo(bgp->local_node, item->conn); se = se->next; } while (se) { struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)se->data; if (item && item->conn) topo_bgp_send_nodeinfo(bgp->local_node, item->conn); se = se->next; }
} }
} }
struct ETCP_LINK* l = from_conn->links; while (l) { l->nat_type = info->nat_type; l = l->next; } struct ETCP_LINK* l = from_conn->links; while (l) { l->nat_type = info->nat_type; l = l->next; }
} }
static void route_bgp_handle_nat_check_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { static void topo_bgp_handle_nat_check_req(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) {
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_NAT_CHECK_REQ)) return; if (!bgp || !from_conn || !data || len < sizeof(struct TOPOMSG_NAT_CHECK_REQ)) return;
const struct BGP_NAT_CHECK_REQ* req = (const struct BGP_NAT_CHECK_REQ*)data; const struct TOPOMSG_NAT_CHECK_REQ* req = (const struct TOPOMSG_NAT_CHECK_REQ*)data;
uint8_t socket_id = req->socket_id; uint8_t socket_id = req->socket_id;
struct ETCP_LINK* target_link = NULL; struct ETCP_LINK* target_link = NULL;
struct ETCP_LINK* l = from_conn->links; while (l) { if (l->remote_socket_id == socket_id) { target_link = l; break; } l = l->next; } struct ETCP_LINK* l = from_conn->links; while (l) { if (l->remote_socket_id == socket_id) { target_link = l; break; } l = l->next; }
if (!target_link) return; if (!target_link) return;
if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) return;
route_bgp_start_link_nat_check(bgp, target_link); topo_bgp_start_link_nat_check(bgp, target_link);
} }
void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type) { void topo_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type) {
if (!conn) return; if (!conn) return;
struct BGP_NAT_INFO* pkt = u_calloc(1, sizeof(struct BGP_NAT_INFO)); if (!pkt) return; struct TOPOMSG_NAT_INFO* pkt = u_calloc(1, sizeof(struct TOPOMSG_NAT_INFO)); if (!pkt) return;
pkt->cmd = ETCP_ID_ROUTE_ENTRY; pkt->subcmd = ROUTE_SUBCMD_NAT_INFO; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_NAT_INFO;
pkt->socket_id = socket_id; pkt->socket_id = socket_id;
pkt->nat_ip[0] = (nat_ip >> 24) & 0xFF; pkt->nat_ip[1] = (nat_ip >> 16) & 0xFF; pkt->nat_ip[0] = (nat_ip >> 24) & 0xFF; pkt->nat_ip[1] = (nat_ip >> 16) & 0xFF;
pkt->nat_ip[2] = (nat_ip >> 8) & 0xFF; pkt->nat_ip[3] = nat_ip & 0xFF; pkt->nat_ip[2] = (nat_ip >> 8) & 0xFF; pkt->nat_ip[3] = nat_ip & 0xFF;
pkt->nat_port = htons(nat_port); pkt->nat_type = nat_type; pkt->nat_port = htons(nat_port); pkt->nat_type = nat_type;
struct ll_entry* e = queue_entry_new(0); if (!e) { u_free(pkt); return; } struct ll_entry* e = queue_entry_new(0); if (!e) { u_free(pkt); return; }
e->dgram = (uint8_t*)pkt; e->len = sizeof(struct BGP_NAT_INFO); e->dgram = (uint8_t*)pkt; e->len = sizeof(struct TOPOMSG_NAT_INFO);
if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NAT_INFO failed"); u_free(pkt); queue_entry_free(e); } if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NAT_INFO failed"); u_free(pkt); queue_entry_free(e); }
} }
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { void topo_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) {
if (!conn) return; if (!conn) return;
struct BGP_NAT_CHECK_REQ* pkt = u_calloc(1, sizeof(struct BGP_NAT_CHECK_REQ)); if (!pkt) return; struct TOPOMSG_NAT_CHECK_REQ* pkt = u_calloc(1, sizeof(struct TOPOMSG_NAT_CHECK_REQ)); if (!pkt) return;
pkt->cmd = ETCP_ID_ROUTE_ENTRY; pkt->subcmd = ROUTE_SUBCMD_NAT_CHECK_REQ; pkt->socket_id = socket_id; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_NAT_CHECK_REQ; pkt->socket_id = socket_id;
struct ETCP_LINK* l = conn->links; while (l) { if (l->remote_socket_id == socket_id) { struct sockaddr_in* sin = (struct sockaddr_in*)&l->conn->interface_addr; if (sin->sin_family == AF_INET) { pkt->interface_ip = sin->sin_addr.s_addr; pkt->interface_port = sin->sin_port; } break; } l = l->next; } struct ETCP_LINK* l = conn->links; while (l) { if (l->remote_socket_id == socket_id) { struct sockaddr_in* sin = (struct sockaddr_in*)&l->conn->interface_addr; if (sin->sin_family == AF_INET) { pkt->interface_ip = sin->sin_addr.s_addr; pkt->interface_port = sin->sin_port; } break; } l = l->next; }
struct ll_entry* e = queue_entry_new(0); if (!e) { u_free(pkt); return; } struct ll_entry* e = queue_entry_new(0); if (!e) { u_free(pkt); return; }
e->dgram = (uint8_t*)pkt; e->len = sizeof(struct BGP_NAT_CHECK_REQ); e->dgram = (uint8_t*)pkt; e->len = sizeof(struct TOPOMSG_NAT_CHECK_REQ);
if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NAT_CHECK_REQ failed"); u_free(pkt); queue_entry_free(e); } if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NAT_CHECK_REQ failed"); u_free(pkt); queue_entry_free(e); }
} }
void route_bgp_request_nat_check_all(struct ROUTE_BGP* bgp) { void topo_bgp_request_nat_check_all(struct TOPO_BGP* bgp) {
if (!bgp || !bgp->instance) return; if (!bgp || !bgp->instance) return;
int count = 0; int count = 0;
struct ETCP_CONN* conn = bgp->instance->connections; while (conn) { struct ETCP_LINK* link = conn->links; while (link) { if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) route_bgp_start_link_nat_check(bgp, link); count++; link = link->next; } conn = conn->next; } struct ETCP_CONN* conn = bgp->instance->connections; while (conn) { struct ETCP_LINK* link = conn->links; while (link) { if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_bgp_start_link_nat_check(bgp, link); count++; link = link->next; } conn = conn->next; }
} }

90
src/route_bgp.h → src/topo_bgp.h

@ -1,5 +1,5 @@
#ifndef ROUTE_BGP_H #ifndef TOPO_BGP_H
#define ROUTE_BGP_H #define TOPO_BGP_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -12,20 +12,20 @@ extern "C" {
#include "../lib/memory_pool.h" #include "../lib/memory_pool.h"
#include "../lib/liblmdb/lmdb.h" #include "../lib/liblmdb/lmdb.h"
#include "route_lib.h" #include "route_lib.h"
#include "route_node.h" #include "topo_node.h"
#include "secure_channel.h" #include "secure_channel.h"
// ETCP ID для маршрутных пакетов // ETCP ID для пакетов топологии
#define ETCP_ID_ROUTE_ENTRY 0x01 #define ETCP_ID_TOPO_ENTRY 0x01
// Sub-команды // Sub-команды
#define ROUTE_SUBCMD_NODEINFO 0x04 // полная информация об узле + маршруты #define TOPO_SUBCMD_NODEINFO 0x04 // полная информация об узле + подсети
#define ROUTE_SUBCMD_REQUEST_TABLE 0x05 // запрос полной таблицы #define TOPO_SUBCMD_REQUEST_TABLE 0x05 // запрос полной таблицы
#define ROUTE_SUBCMD_WITHDRAW 0x06 // узел стал недоступен #define TOPO_SUBCMD_WITHDRAW 0x06 // узел стал недоступен
#define ROUTE_SUBCMD_NAT_INFO 0x09 // информация о типе NAT клиента #define TOPO_SUBCMD_NAT_INFO 0x09 // информация о типе NAT клиента
#define ROUTE_SUBCMD_NAT_CHECK_REQ 0x0A // запрос от клиента на проверку NAT для сокета #define TOPO_SUBCMD_NAT_CHECK_REQ 0x0A // запрос от клиента на проверку NAT для сокета
#define ROUTE_SUBCMD_TABLE_COMPLETE 0x0B // завершение начальной синхронизации таблицы #define TOPO_SUBCMD_TABLE_COMPLETE 0x0B // завершение начальной синхронизации таблицы
#define MAX_HOPS 16 #define MAX_HOPS 16
#define BGP_NODES_HASH_SIZE 256 #define BGP_NODES_HASH_SIZE 256
@ -33,16 +33,16 @@ extern "C" {
/** /**
* @brief Пакет с информацией об узле (NODEINFO) * @brief Пакет с информацией об узле (NODEINFO)
*/ */
struct BGP_NODEINFO_PACKET { struct TOPOMSG_NODEINFO_PKT {
uint8_t cmd; // ETCP_ID_ROUTE_ENTRY uint8_t cmd; // ETCP_ID_TOPO_ENTRY
uint8_t subcmd; // ROUTE_SUBCMD_NODEINFO uint8_t subcmd; // TOPO_SUBCMD_NODEINFO
struct NODEINFO_MSG node; struct TOPOMSG_NODE node;
} __attribute__((packed)); } __attribute__((packed));
/** /**
* @brief Пакет WITHDRAW (фиксированный) * @brief Пакет WITHDRAW (фиксированный)
*/ */
struct BGP_WITHDRAW_PACKET { struct TOPOMSG_WITHDRAW_PKT {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; uint8_t subcmd;
uint64_t node_id; // удаляемый узел (который стал недоступен) uint64_t node_id; // удаляемый узел (который стал недоступен)
@ -52,12 +52,12 @@ struct BGP_WITHDRAW_PACKET {
/** /**
* @brief Пакет запроса полной таблицы * @brief Пакет запроса полной таблицы
*/ */
struct BGP_ROUTE_REQUEST { struct TOPOMSG_TABLE_REQ {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; uint8_t subcmd;
} __attribute__((packed)); } __attribute__((packed));
struct ROUTE_BGP_CONN_ITEM { struct TOPO_BGP_CONN_ITEM {
struct ll_entry ll; struct ll_entry ll;
struct ETCP_CONN* conn; struct ETCP_CONN* conn;
}; };
@ -65,7 +65,7 @@ struct ROUTE_BGP_CONN_ITEM {
/** /**
* @brief Пакет NAT_INFO (фиксированный) * @brief Пакет NAT_INFO (фиксированный)
*/ */
struct BGP_NAT_INFO { struct TOPOMSG_NAT_INFO {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; uint8_t subcmd;
uint8_t socket_id; // MY socket id (link->conn->sock_id) uint8_t socket_id; // MY socket id (link->conn->sock_id)
@ -77,9 +77,9 @@ struct BGP_NAT_INFO {
/** /**
* @brief Пакет запроса на проверку NAT от клиента к серверу * @brief Пакет запроса на проверку NAT от клиента к серверу
*/ */
struct BGP_NAT_CHECK_REQ { struct TOPOMSG_NAT_CHECK_REQ {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; // ROUTE_SUBCMD_NAT_CHECK_REQ uint8_t subcmd; // TOPO_SUBCMD_NAT_CHECK_REQ
uint8_t socket_id; // ID сокета клиента, который надо проверить uint8_t socket_id; // ID сокета клиента, который надо проверить
uint32_t interface_ip; // interface_addr IP клиента (network byte order) uint32_t interface_ip; // interface_addr IP клиента (network byte order)
uint16_t interface_port; // interface_addr port клиента (network byte order) uint16_t interface_port; // interface_addr port клиента (network byte order)
@ -88,11 +88,11 @@ struct BGP_NAT_CHECK_REQ {
struct route_ping_pending; struct route_ping_pending;
struct ETCP_LINK; struct ETCP_LINK;
struct ROUTE_BGP { struct TOPO_BGP {
struct UTUN_INSTANCE* instance; struct UTUN_INSTANCE* instance;
struct ll_queue* senders_list; struct ll_queue* senders_list;
struct ll_queue* nodes; struct ll_queue* nodes;
struct NODEINFO_Q* local_node; struct TOPO_NODEQ* local_node;
struct route_ping_pending* ping_pending; struct route_ping_pending* ping_pending;
uint32_t next_ping_req_id; uint32_t next_ping_req_id;
uint8_t allow_nat_check_local; uint8_t allow_nat_check_local;
@ -108,47 +108,47 @@ struct ROUTE_BGP {
}; };
/** /**
* @brief Инициализирует модуль BGP маршрутизации. * @brief Инициализирует модуль топологии BGP.
* *
* Создает очереди, local_node из подсетей конфига, привязывает к ETCP_ID_ROUTE_ENTRY, * Создает очереди, local_node из подсетей конфига, привязывает к ETCP_ID_TOPO_ENTRY,
* устанавливает коллбеки new_conn для on_up/on_down. * устанавливает коллбеки new_conn для on_up/on_down.
* *
* @param instance экземпляр utun с node_id и конфигом * @param instance экземпляр utun с node_id и конфигом
* @return ROUTE_BGP или NULL при ошибке * @return TOPO_BGP или NULL при ошибке
*/ */
struct ROUTE_BGP* route_bgp_init(struct UTUN_INSTANCE* instance); struct TOPO_BGP* topo_bgp_init(struct UTUN_INSTANCE* instance);
/** /**
* @brief Освобождает ресурсы BGP (очереди, local_node, снимает привязку ETCP). * @brief Освобождает ресурсы BGP (очереди, local_node, снимает привязку ETCP).
* *
* @param instance экземпляр utun * @param instance экземпляр utun
*/ */
void route_bgp_destroy(struct UTUN_INSTANCE* instance); void topo_bgp_destroy(struct UTUN_INSTANCE* instance);
/** /**
* @brief Добавляет conn в senders_list (если нет), отправляет запрос таблицы (nodeinfo). * @brief Добавляет conn в senders_list (если нет), отправляет запрос таблицы (nodeinfo).
* *
* Вызывается при ETCP on_up. * Вызывается при ETCP on_up.
*/ */
void route_bgp_new_conn(struct ETCP_CONN* conn); void topo_bgp_new_conn(struct ETCP_CONN* conn);
/** /**
* @brief Удаляет conn из senders_list, очищает paths во всех nodes, отправляет withdraw если node unreachable. * @brief Удаляет conn из senders_list, очищает paths во всех nodes, отправляет withdraw если node unreachable.
* *
* Вызывается при ETCP on_down. * Вызывается при ETCP on_down.
*/ */
void route_bgp_remove_conn(struct ETCP_CONN* conn); void topo_bgp_remove_conn(struct ETCP_CONN* conn);
/** /**
* @brief Обрабатывает пакет NODEINFO. * @brief Обрабатывает пакет NODEINFO.
* *
* Проверка версии, обновление или создание NODEINFO_Q, добавление пути, * Проверка версии, обновление или создание TOPO_NODEQ, добавление пути,
* вставка в роутинг, broadcast если не max hops. * вставка в роутинг, broadcast если не max hops.
* *
* @return 0 при успехе * @return 0 при успехе
*/ */
int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, const uint8_t* data, size_t len); int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, const uint8_t* data, size_t len);
/** /**
* @brief Обрабатывает WITHDRAW. * @brief Обрабатывает WITHDRAW.
* *
@ -156,42 +156,42 @@ int route_bgp_process_nodeinfo(struct ROUTE_BGP* bgp, struct ETCP_CONN* from, co
* *
* @return 0 при успехе * @return 0 при успехе
*/ */
int route_bgp_process_withdraw(struct ROUTE_BGP* bgp, struct ETCP_CONN* sender, const uint8_t* data, size_t len); int topo_bgp_process_withdraw(struct TOPO_BGP* bgp, struct ETCP_CONN* sender, const uint8_t* data, size_t len);
/** /**
* @brief Отправляет NODEINFO пакет одному conn (всегда local_node). * @brief Отправляет NODEINFO пакет одному conn (всегда local_node).
*/ */
void route_bgp_send_nodeinfo(struct NODEINFO_Q* node, struct ETCP_CONN* conn); void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* node, struct ETCP_CONN* conn);
/** /**
* @brief Отправляет WITHDRAW для node_id (вызывает broadcast_withdraw). * @brief Отправляет WITHDRAW для node_id (вызывает broadcast_withdraw).
*/ */
void route_bgp_send_withdraw(struct ROUTE_BGP* bgp, uint64_t node_id); void topo_bgp_send_withdraw(struct TOPO_BGP* bgp, uint64_t node_id);
/** /**
* @brief Поиск оптимального ETCP соединения для указанного node_id. * @brief Поиск оптимального ETCP соединения для указанного node_id.
* *
* Перебирает paths узла, выбирает путь с минимальным hop_count. * Перебирает paths узла, выбирает путь с минимальным hop_count.
* *
* @param bgp указатель на ROUTE_BGP * @param bgp указатель на TOPO_BGP
* @param node_id целевой узел * @param node_id целевой узел
* @return оптимальный ETCP_CONN* или NULL * @return оптимальный ETCP_CONN* или NULL
*/ */
struct ETCP_CONN* route_bgp_find_conn_for_node(struct ROUTE_BGP* bgp, uint64_t node_id); struct ETCP_CONN* topo_bgp_find_conn_for_node(struct TOPO_BGP* bgp, uint64_t node_id);
/** /**
* @brief Добавляет путь (conn) в paths узла. * @brief Добавляет путь (conn) в paths узла.
* *
* @return 0 при успехе * @return 0 при успехе
*/ */
int route_bgp_add_path(struct NODEINFO_Q* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count); int topo_bgp_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count);
/** /**
* @brief Удаляет conn из paths узла. * @brief Удаляет conn из paths узла.
* *
* @return 1 если путей не осталось (unreachable) * @return 1 если путей не осталось (unreachable)
*/ */
int route_bgp_remove_path(struct NODEINFO_Q* nq, struct ETCP_CONN* conn); int topo_bgp_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn);
/** /**
* @brief Отправляет NAT_INFO клиенту с его типом NAT. * @brief Отправляет NAT_INFO клиенту с его типом NAT.
@ -201,7 +201,7 @@ int route_bgp_remove_path(struct NODEINFO_Q* nq, struct ETCP_CONN* conn);
* @param nat_port порт клиента (network byte order) * @param nat_port порт клиента (network byte order)
* @param nat_type NAT_TYPE_EIM или NAT_TYPE_STRICT * @param nat_type NAT_TYPE_EIM или NAT_TYPE_STRICT
*/ */
void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type); void topo_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t nat_ip, uint16_t nat_port, uint8_t nat_type);
/** /**
* @brief Отправляет запрос на проверку NAT для указанного socket_id серверу. * @brief Отправляет запрос на проверку NAT для указанного socket_id серверу.
@ -209,23 +209,23 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t
* @param conn соединение к серверу * @param conn соединение к серверу
* @param socket_id ID сокета для проверки * @param socket_id ID сокета для проверки
*/ */
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id); void topo_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id);
/** /**
* @brief Разрешить/запретить NAT check для локальных подсетей (127.0.0.1, 10.x.x.x и т.д.) * @brief Разрешить/запретить NAT check для локальных подсетей (127.0.0.1, 10.x.x.x и т.д.)
* По умолчанию запрещено. Полезно для тестов. * По умолчанию запрещено. Полезно для тестов.
*/ */
void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow); void topo_bgp_set_nat_check_local(struct TOPO_BGP* bgp, int allow);
/** /**
* @brief Запускает NAT check для всех линков всех соединений. * @brief Запускает NAT check для всех линков всех соединений.
*/ */
void route_bgp_request_nat_check_all(struct ROUTE_BGP* bgp); void topo_bgp_request_nat_check_all(struct TOPO_BGP* bgp);
/** /**
* @brief Запускает NAT check для одного линка. * @brief Запускает NAT check для одного линка.
*/ */
void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link); void topo_bgp_start_link_nat_check(struct TOPO_BGP* bgp, struct ETCP_LINK* link);
/* Аргумент callback NAT check */ /* Аргумент callback NAT check */
struct nat_check_arg { struct nat_check_arg {
@ -238,4 +238,4 @@ struct nat_check_arg {
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // ROUTE_BGP_H #endif // TOPO_BGP_H

335
src/route_node.c → src/topo_node.c

@ -9,17 +9,17 @@
#include "utun_instance.h" #include "utun_instance.h"
#include "etcp.h" #include "etcp.h"
#include "config_parser.h" #include "config_parser.h"
#include "route_node.h" #include "topo_node.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "route_lib.h" #include "route_lib.h"
#include "etcp_debug.h" #include "etcp_debug.h"
void nodeinfo_ref(struct NODEINFO* ni) { void topo_node_ref(struct TOPO_NODE* ni) {
if (!ni) return; if (!ni) return;
ni->ref_count++; ni->ref_count++;
} }
void nodeinfo_unref(struct NODEINFO* ni) { void topo_node_unref(struct TOPO_NODE* ni) {
if (!ni) return; if (!ni) return;
if (--ni->ref_count == 0) { if (--ni->ref_count == 0) {
u_free(ni->node_name); u_free(ni->node_name);
@ -27,26 +27,26 @@ void nodeinfo_unref(struct NODEINFO* ni) {
} }
} }
static void free_v4_sock_list(struct memory_pool* pool, struct NI_IPV4_SOCKET_META* head) { static void free_v4_sock_list(struct memory_pool* pool, struct TOPO_SOCKMETA4* head) {
while (head) { struct NI_IPV4_SOCKET_META* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_SOCKMETA4* next = head->next; memory_pool_free(pool, head); head = next; }
} }
static void free_v4_addr_list(struct memory_pool* pool, struct NI_IPV4_ADDR* head) { static void free_v4_addr_list(struct memory_pool* pool, struct TOPO_ADDR4* head) {
while (head) { struct NI_IPV4_ADDR* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_ADDR4* next = head->next; memory_pool_free(pool, head); head = next; }
} }
static void free_v6_sock_list(struct memory_pool* pool, struct NI_IPV6_SOCKET_META* head) { static void free_v6_sock_list(struct memory_pool* pool, struct TOPO_SOCKMETA6* head) {
while (head) { struct NI_IPV6_SOCKET_META* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_SOCKMETA6* next = head->next; memory_pool_free(pool, head); head = next; }
} }
static void free_v6_addr_list(struct memory_pool* pool, struct NI_IPV6_ADDR* head) { static void free_v6_addr_list(struct memory_pool* pool, struct TOPO_ADDR6* head) {
while (head) { struct NI_IPV6_ADDR* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_ADDR6* next = head->next; memory_pool_free(pool, head); head = next; }
} }
static void free_v4_sub_list(struct memory_pool* pool, struct NI_IPV4_SUBNET* head) { static void free_v4_sub_list(struct memory_pool* pool, struct TOPO_SUBNET4* head) {
while (head) { struct NI_IPV4_SUBNET* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_SUBNET4* next = head->next; memory_pool_free(pool, head); head = next; }
} }
static void free_v6_sub_list(struct memory_pool* pool, struct NI_IPV6_SUBNET* head) { static void free_v6_sub_list(struct memory_pool* pool, struct TOPO_SUBNET6* head) {
while (head) { struct NI_IPV6_SUBNET* next = head->next; memory_pool_free(pool, head); head = next; } while (head) { struct TOPO_SUBNET6* next = head->next; memory_pool_free(pool, head); head = next; }
} }
void nodeinfo_free_lists(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) { void topo_node_free_lists(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq) {
if (!bgp || !nq) return; if (!bgp || !nq) return;
if (nq->node) { if (nq->node) {
free_v4_sock_list(bgp->v4_sock_meta_pool, nq->node->v4_sock_meta); free_v4_sock_list(bgp->v4_sock_meta_pool, nq->node->v4_sock_meta);
@ -55,14 +55,14 @@ void nodeinfo_free_lists(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) {
free_v6_addr_list(bgp->v6_addr_pool, nq->node->v6_addrs); free_v6_addr_list(bgp->v6_addr_pool, nq->node->v6_addrs);
nq->node->v4_sock_meta = NULL; nq->node->v4_addrs = NULL; nq->node->v4_sock_meta = NULL; nq->node->v4_addrs = NULL;
nq->node->v6_sock_meta = NULL; nq->node->v6_addrs = NULL; nq->node->v6_sock_meta = NULL; nq->node->v6_addrs = NULL;
nodeinfo_unref(nq->node); topo_node_unref(nq->node);
nq->node = NULL; nq->node = NULL;
} }
if (nq->routes) { if (nq->subnets) {
free_v4_sub_list(bgp->v4_subnet_pool, nq->routes->v4_subnets); free_v4_sub_list(bgp->v4_subnet_pool, nq->subnets->v4_subnets);
free_v6_sub_list(bgp->v6_subnet_pool, nq->routes->v6_subnets); free_v6_sub_list(bgp->v6_subnet_pool, nq->subnets->v6_subnets);
u_free(nq->routes); u_free(nq->subnets);
nq->routes = NULL; nq->subnets = NULL;
} }
u_free(nq->tranzit_data); nq->tranzit_data = NULL; nq->tranzit_count = 0; u_free(nq->tranzit_data); nq->tranzit_data = NULL; nq->tranzit_count = 0;
u_free(nq->hop_list); nq->hop_list = NULL; nq->hop_count = 0; u_free(nq->hop_list); nq->hop_list = NULL; nq->hop_count = 0;
@ -70,24 +70,24 @@ void nodeinfo_free_lists(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) {
// ===== serialization ===== // ===== serialization =====
int nodeinfo_dyn_size(const struct NODEINFO_MSG* msg) { int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) {
return msg->node_name_len return msg->node_name_len
+ msg->local_v4_sockets * sizeof(struct NODEINFO_IPV4_SOCKET_META) + msg->local_v4_sockets * sizeof(struct TOPOMSG_SOCKMETA4)
+ msg->local_v4_addrs * sizeof(struct NODEINFO_IPV4_ADDR) + msg->local_v4_addrs * sizeof(struct TOPOMSG_ADDR4)
+ msg->local_v6_sockets * sizeof(struct NODEINFO_IPV6_SOCKET_META) + msg->local_v6_sockets * sizeof(struct TOPOMSG_SOCKMETA6)
+ msg->local_v6_addrs * sizeof(struct NODEINFO_IPV6_ADDR) + msg->local_v6_addrs * sizeof(struct TOPOMSG_ADDR6)
+ ((msg->flags & NODEINFO_FLAG_SEND_SUBNETS) + ((msg->flags & TOPO_FLAG_SEND_SUBNETS)
? (msg->local_v4_subnets * sizeof(struct NODEINFO_IPV4_SUBNET) + msg->local_v6_subnets * sizeof(struct NODEINFO_IPV6_SUBNET)) ? (msg->local_v4_subnets * sizeof(struct TOPOMSG_SUBNET4) + msg->local_v6_subnets * sizeof(struct TOPOMSG_SUBNET6))
: 0) : 0)
+ msg->tranzit_nodes * sizeof(struct NODEINFO_TRANZIT_NODE) + msg->tranzit_nodes * sizeof(struct TOPOMSG_TRANZIT)
+ msg->hop_count * 8; + msg->hop_count * 8;
} }
int nodeinfo_serialize(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq, uint8_t* out, size_t out_max) { int topo_node_serialize(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max) {
if (!bgp || !nq || !nq->node || !out) return -1; if (!bgp || !nq || !nq->node || !out) return -1;
struct NODEINFO* ni = nq->node; struct TOPO_NODE* ni = nq->node;
struct NODEINFO_MSG msg; struct TOPOMSG_NODE msg;
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
msg.flags = ni->flags; msg.flags = ni->flags;
msg.group_id = ni->group_id; msg.group_id = ni->group_id;
@ -96,53 +96,53 @@ int nodeinfo_serialize(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq, uint8_t* ou
memcpy(msg.public_key, ni->public_key, SC_PUBKEY_SIZE); memcpy(msg.public_key, ni->public_key, SC_PUBKEY_SIZE);
memcpy(msg.ed25519_public_key, ni->ed25519_public_key, SC_PUBKEY_SIZE); memcpy(msg.ed25519_public_key, ni->ed25519_public_key, SC_PUBKEY_SIZE);
msg.node_name_len = ni->node_name ? (uint8_t)strlen(ni->node_name) : 0; msg.node_name_len = ni->node_name ? (uint8_t)strlen(ni->node_name) : 0;
msg.local_v4_sockets = ni_list_count((struct _ni_head*)ni->v4_sock_meta); msg.local_v4_sockets = topo_list_count((struct _topo_head*)ni->v4_sock_meta);
msg.local_v4_addrs = ni_list_count((struct _ni_head*)ni->v4_addrs); msg.local_v4_addrs = topo_list_count((struct _topo_head*)ni->v4_addrs);
msg.local_v6_sockets = ni_list_count((struct _ni_head*)ni->v6_sock_meta); msg.local_v6_sockets = topo_list_count((struct _topo_head*)ni->v6_sock_meta);
msg.local_v6_addrs = ni_list_count((struct _ni_head*)ni->v6_addrs); msg.local_v6_addrs = topo_list_count((struct _topo_head*)ni->v6_addrs);
msg.local_v4_subnets = nq->routes ? ni_list_count((struct _ni_head*)nq->routes->v4_subnets) : 0; msg.local_v4_subnets = nq->subnets ? topo_list_count((struct _topo_head*)nq->subnets->v4_subnets) : 0;
msg.local_v6_subnets = nq->routes ? ni_list_count((struct _ni_head*)nq->routes->v6_subnets) : 0; msg.local_v6_subnets = nq->subnets ? topo_list_count((struct _topo_head*)nq->subnets->v6_subnets) : 0;
msg.tranzit_nodes = nq->tranzit_count; msg.tranzit_nodes = nq->tranzit_count;
msg.hop_count = nq->hop_count; msg.hop_count = nq->hop_count;
size_t total = NODEINFO_MSG_HDR_SIZE + (size_t)nodeinfo_dyn_size(&msg); size_t total = TOPOMSG_NODE_HDR_SIZE + (size_t)topo_node_dyn_size(&msg);
if (total > out_max) return -1; if (total > out_max) return -1;
memcpy(out, &msg, NODEINFO_MSG_HDR_SIZE); memcpy(out, &msg, TOPOMSG_NODE_HDR_SIZE);
uint8_t* dp = out + NODEINFO_MSG_HDR_SIZE; uint8_t* dp = out + TOPOMSG_NODE_HDR_SIZE;
if (msg.node_name_len) { memcpy(dp, ni->node_name, msg.node_name_len); dp += msg.node_name_len; } if (msg.node_name_len) { memcpy(dp, ni->node_name, msg.node_name_len); dp += msg.node_name_len; }
{ struct NI_IPV4_SOCKET_META* e = ni->v4_sock_meta; while (e) { { struct TOPO_SOCKMETA4* e = ni->v4_sock_meta; while (e) {
struct NODEINFO_IPV4_SOCKET_META w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type }; struct TOPOMSG_SOCKMETA4 w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type };
memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
{ struct NI_IPV4_ADDR* e = ni->v4_addrs; while (e) { { struct TOPO_ADDR4* e = ni->v4_addrs; while (e) {
struct NODEINFO_IPV4_ADDR w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol }; struct TOPOMSG_ADDR4 w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol };
memcpy(w.addr, e->addr, 4); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(w.addr, e->addr, 4); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
{ struct NI_IPV6_SOCKET_META* e = ni->v6_sock_meta; while (e) { { struct TOPO_SOCKMETA6* e = ni->v6_sock_meta; while (e) {
struct NODEINFO_IPV6_SOCKET_META w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type }; struct TOPOMSG_SOCKMETA6 w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type };
memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
{ struct NI_IPV6_ADDR* e = ni->v6_addrs; while (e) { { struct TOPO_ADDR6* e = ni->v6_addrs; while (e) {
struct NODEINFO_IPV6_ADDR w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol }; struct TOPOMSG_ADDR6 w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol };
memcpy(w.addr, e->addr, 16); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(w.addr, e->addr, 16); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
if (msg.flags & NODEINFO_FLAG_SEND_SUBNETS) { if (msg.flags & TOPO_FLAG_SEND_SUBNETS) {
if (nq->routes) { if (nq->subnets) {
{ struct NI_IPV4_SUBNET* e = nq->routes->v4_subnets; while (e) { { struct TOPO_SUBNET4* e = nq->subnets->v4_subnets; while (e) {
struct NODEINFO_IPV4_SUBNET w = { .prefix_length=e->prefix_length }; struct TOPOMSG_SUBNET4 w = { .prefix_length=e->prefix_length };
memcpy(w.addr, e->addr, 4); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(w.addr, e->addr, 4); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
{ struct NI_IPV6_SUBNET* e = nq->routes->v6_subnets; while (e) { { struct TOPO_SUBNET6* e = nq->subnets->v6_subnets; while (e) {
struct NODEINFO_IPV6_SUBNET w = { .prefix_length=e->prefix_length }; struct TOPOMSG_SUBNET6 w = { .prefix_length=e->prefix_length };
memcpy(w.addr, e->addr, 16); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next; memcpy(w.addr, e->addr, 16); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
}} }}
} }
} }
if (msg.tranzit_nodes && nq->tranzit_data) { if (msg.tranzit_nodes && nq->tranzit_data) {
size_t sz = msg.tranzit_nodes * sizeof(struct NODEINFO_TRANZIT_NODE); size_t sz = msg.tranzit_nodes * sizeof(struct TOPOMSG_TRANZIT);
memcpy(dp, nq->tranzit_data, sz); dp += sz; memcpy(dp, nq->tranzit_data, sz); dp += sz;
} }
if (msg.hop_count && nq->hop_list) { if (msg.hop_count && nq->hop_list) {
@ -154,17 +154,17 @@ int nodeinfo_serialize(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq, uint8_t* ou
// ===== deserialization ===== // ===== deserialization =====
int nodeinfo_deserialize(struct ROUTE_BGP* bgp, const uint8_t* data, size_t len, struct NODEINFO** out_ni, struct NODEINFO_ROUTES** out_routes, int topo_node_deserialize(struct TOPO_BGP* bgp, const uint8_t* data, size_t len, struct TOPO_NODE** out_ni, struct TOPO_NODESUBNETS** out_subnets,
struct NODEINFO_TRANZIT_NODE** out_tranzit, uint8_t* out_tranzit_count, struct TOPOMSG_TRANZIT** out_tranzit, uint8_t* out_tranzit_count,
uint64_t** out_hop_list, uint8_t* out_hop_count) { uint64_t** out_hop_list, uint8_t* out_hop_count) {
if (!bgp || !data || len < NODEINFO_MSG_HDR_SIZE || !out_ni) return -1; if (!bgp || !data || len < TOPOMSG_NODE_HDR_SIZE || !out_ni) return -1;
const struct NODEINFO_MSG* msg = (const struct NODEINFO_MSG*)data; const struct TOPOMSG_NODE* msg = (const struct TOPOMSG_NODE*)data;
int dyn = nodeinfo_dyn_size(msg); int dyn = topo_node_dyn_size(msg);
if ((size_t)dyn + NODEINFO_MSG_HDR_SIZE != len) return -1; if ((size_t)dyn + TOPOMSG_NODE_HDR_SIZE != len) return -1;
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "nodeinfo_deserialize: alloc NODEINFO failed"); return -1; } if (!ni) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_node_deserialize: alloc TOPO_NODE failed"); return -1; }
ni->ref_count = 1; ni->ref_count = 1;
ni->flags = msg->flags; ni->flags = msg->flags;
ni->group_id = msg->group_id; ni->group_id = msg->group_id;
@ -173,7 +173,7 @@ int nodeinfo_deserialize(struct ROUTE_BGP* bgp, const uint8_t* data, size_t len,
memcpy(ni->public_key, msg->public_key, SC_PUBKEY_SIZE); memcpy(ni->public_key, msg->public_key, SC_PUBKEY_SIZE);
memcpy(ni->ed25519_public_key, msg->ed25519_public_key, SC_PUBKEY_SIZE); memcpy(ni->ed25519_public_key, msg->ed25519_public_key, SC_PUBKEY_SIZE);
const uint8_t* dp = data + NODEINFO_MSG_HDR_SIZE; const uint8_t* dp = data + TOPOMSG_NODE_HDR_SIZE;
if (msg->node_name_len) { if (msg->node_name_len) {
ni->node_name = u_malloc(msg->node_name_len + 1); ni->node_name = u_malloc(msg->node_name_len + 1);
@ -182,71 +182,71 @@ int nodeinfo_deserialize(struct ROUTE_BGP* bgp, const uint8_t* data, size_t len,
} }
for (int i = 0; i < msg->local_v4_sockets; i++) { for (int i = 0; i < msg->local_v4_sockets; i++) {
const struct NODEINFO_IPV4_SOCKET_META* w = (const struct NODEINFO_IPV4_SOCKET_META*)dp; dp += sizeof(*w); const struct TOPOMSG_SOCKMETA4* w = (const struct TOPOMSG_SOCKMETA4*)dp; dp += sizeof(*w);
struct NI_IPV4_SOCKET_META* e = memory_pool_alloc(bgp->v4_sock_meta_pool); struct TOPO_SOCKMETA4* e = memory_pool_alloc(bgp->v4_sock_meta_pool);
if (!e) { nodeinfo_unref(ni); return -1; } if (!e) { topo_node_unref(ni); return -1; }
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type; e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type;
e->next = ni->v4_sock_meta; ni->v4_sock_meta = e; e->next = ni->v4_sock_meta; ni->v4_sock_meta = e;
} }
for (int i = 0; i < msg->local_v4_addrs; i++) { for (int i = 0; i < msg->local_v4_addrs; i++) {
const struct NODEINFO_IPV4_ADDR* w = (const struct NODEINFO_IPV4_ADDR*)dp; dp += sizeof(*w); const struct TOPOMSG_ADDR4* w = (const struct TOPOMSG_ADDR4*)dp; dp += sizeof(*w);
struct NI_IPV4_ADDR* e = memory_pool_alloc(bgp->v4_addr_pool); struct TOPO_ADDR4* e = memory_pool_alloc(bgp->v4_addr_pool);
if (!e) { nodeinfo_unref(ni); return -1; } if (!e) { topo_node_unref(ni); return -1; }
memcpy(e->addr, w->addr, 4); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol; memcpy(e->addr, w->addr, 4); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol;
e->next = ni->v4_addrs; ni->v4_addrs = e; e->next = ni->v4_addrs; ni->v4_addrs = e;
} }
for (int i = 0; i < msg->local_v6_sockets; i++) { for (int i = 0; i < msg->local_v6_sockets; i++) {
const struct NODEINFO_IPV6_SOCKET_META* w = (const struct NODEINFO_IPV6_SOCKET_META*)dp; dp += sizeof(*w); const struct TOPOMSG_SOCKMETA6* w = (const struct TOPOMSG_SOCKMETA6*)dp; dp += sizeof(*w);
struct NI_IPV6_SOCKET_META* e = memory_pool_alloc(bgp->v6_sock_meta_pool); struct TOPO_SOCKMETA6* e = memory_pool_alloc(bgp->v6_sock_meta_pool);
if (!e) { nodeinfo_unref(ni); return -1; } if (!e) { topo_node_unref(ni); return -1; }
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type; e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type;
e->next = ni->v6_sock_meta; ni->v6_sock_meta = e; e->next = ni->v6_sock_meta; ni->v6_sock_meta = e;
} }
for (int i = 0; i < msg->local_v6_addrs; i++) { for (int i = 0; i < msg->local_v6_addrs; i++) {
const struct NODEINFO_IPV6_ADDR* w = (const struct NODEINFO_IPV6_ADDR*)dp; dp += sizeof(*w); const struct TOPOMSG_ADDR6* w = (const struct TOPOMSG_ADDR6*)dp; dp += sizeof(*w);
struct NI_IPV6_ADDR* e = memory_pool_alloc(bgp->v6_addr_pool); struct TOPO_ADDR6* e = memory_pool_alloc(bgp->v6_addr_pool);
if (!e) { nodeinfo_unref(ni); return -1; } if (!e) { topo_node_unref(ni); return -1; }
memcpy(e->addr, w->addr, 16); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol; memcpy(e->addr, w->addr, 16); e->port = w->port; e->type = w->type; e->socket_id = w->socket_id; e->protocol = w->protocol;
e->next = ni->v6_addrs; ni->v6_addrs = e; e->next = ni->v6_addrs; ni->v6_addrs = e;
} }
if (out_routes && (msg->flags & NODEINFO_FLAG_SEND_SUBNETS) && (msg->local_v4_subnets || msg->local_v6_subnets)) { if (out_subnets && (msg->flags & TOPO_FLAG_SEND_SUBNETS) && (msg->local_v4_subnets || msg->local_v6_subnets)) {
struct NODEINFO_ROUTES* r = u_calloc(1, sizeof(struct NODEINFO_ROUTES)); struct TOPO_NODESUBNETS* r = u_calloc(1, sizeof(struct TOPO_NODESUBNETS));
if (!r) { nodeinfo_unref(ni); return -1; } if (!r) { topo_node_unref(ni); return -1; }
for (int i = 0; i < msg->local_v4_subnets; i++) { for (int i = 0; i < msg->local_v4_subnets; i++) {
const struct NODEINFO_IPV4_SUBNET* w = (const struct NODEINFO_IPV4_SUBNET*)dp; dp += sizeof(*w); const struct TOPOMSG_SUBNET4* w = (const struct TOPOMSG_SUBNET4*)dp; dp += sizeof(*w);
struct NI_IPV4_SUBNET* e = memory_pool_alloc(bgp->v4_subnet_pool); struct TOPO_SUBNET4* e = memory_pool_alloc(bgp->v4_subnet_pool);
if (!e) { u_free(r); nodeinfo_unref(ni); return -1; } if (!e) { u_free(r); topo_node_unref(ni); return -1; }
memcpy(e->addr, w->addr, 4); e->prefix_length = w->prefix_length; memcpy(e->addr, w->addr, 4); e->prefix_length = w->prefix_length;
e->next = r->v4_subnets; r->v4_subnets = e; e->next = r->v4_subnets; r->v4_subnets = e;
} }
for (int i = 0; i < msg->local_v6_subnets; i++) { for (int i = 0; i < msg->local_v6_subnets; i++) {
const struct NODEINFO_IPV6_SUBNET* w = (const struct NODEINFO_IPV6_SUBNET*)dp; dp += sizeof(*w); const struct TOPOMSG_SUBNET6* w = (const struct TOPOMSG_SUBNET6*)dp; dp += sizeof(*w);
struct NI_IPV6_SUBNET* e = memory_pool_alloc(bgp->v6_subnet_pool); struct TOPO_SUBNET6* e = memory_pool_alloc(bgp->v6_subnet_pool);
if (!e) { u_free(r); nodeinfo_unref(ni); return -1; } if (!e) { u_free(r); topo_node_unref(ni); return -1; }
memcpy(e->addr, w->addr, 16); e->prefix_length = w->prefix_length; memcpy(e->addr, w->addr, 16); e->prefix_length = w->prefix_length;
e->next = r->v6_subnets; r->v6_subnets = e; e->next = r->v6_subnets; r->v6_subnets = e;
} }
*out_routes = r; *out_subnets = r;
} else if (!(msg->flags & NODEINFO_FLAG_SEND_SUBNETS)) { } else if (!(msg->flags & TOPO_FLAG_SEND_SUBNETS)) {
dp += msg->local_v4_subnets * sizeof(struct NODEINFO_IPV4_SUBNET) dp += msg->local_v4_subnets * sizeof(struct TOPOMSG_SUBNET4)
+ msg->local_v6_subnets * sizeof(struct NODEINFO_IPV6_SUBNET); + msg->local_v6_subnets * sizeof(struct TOPOMSG_SUBNET6);
if (out_routes) *out_routes = NULL; if (out_subnets) *out_subnets = NULL;
} else { } else {
if (out_routes) *out_routes = NULL; if (out_subnets) *out_subnets = NULL;
} }
if (out_tranzit && msg->tranzit_nodes > 0) { if (out_tranzit && msg->tranzit_nodes > 0) {
size_t tsz = msg->tranzit_nodes * sizeof(struct NODEINFO_TRANZIT_NODE); size_t tsz = msg->tranzit_nodes * sizeof(struct TOPOMSG_TRANZIT);
*out_tranzit = u_malloc(tsz); *out_tranzit = u_malloc(tsz);
if (!*out_tranzit) { nodeinfo_unref(ni); return -1; } if (!*out_tranzit) { topo_node_unref(ni); return -1; }
memcpy(*out_tranzit, dp, tsz); dp += tsz; memcpy(*out_tranzit, dp, tsz); dp += tsz;
*out_tranzit_count = msg->tranzit_nodes; *out_tranzit_count = msg->tranzit_nodes;
} }
if (out_hop_list && msg->hop_count > 0) { if (out_hop_list && msg->hop_count > 0) {
size_t hsz = msg->hop_count * 8; size_t hsz = msg->hop_count * 8;
*out_hop_list = u_malloc(hsz); *out_hop_list = u_malloc(hsz);
if (!*out_hop_list) { nodeinfo_unref(ni); return -1; } if (!*out_hop_list) { topo_node_unref(ni); return -1; }
memcpy(*out_hop_list, dp, hsz); dp += hsz; memcpy(*out_hop_list, dp, hsz); dp += hsz;
*out_hop_count = msg->hop_count; *out_hop_count = msg->hop_count;
} }
@ -255,16 +255,16 @@ int nodeinfo_deserialize(struct ROUTE_BGP* bgp, const uint8_t* data, size_t len,
return 0; return 0;
} }
struct NODEINFO_Q* nodeinfo_find_by_id(struct ROUTE_BGP* bgp, uint64_t node_id) { struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_BGP* bgp, uint64_t node_id) {
if (!bgp || !bgp->nodes) return NULL; if (!bgp || !bgp->nodes) return NULL;
uint64_t key = node_id; uint64_t key = node_id;
struct ll_entry* e = queue_find_data_by_index(bgp->nodes, &key); struct ll_entry* e = queue_find_data_by_index(bgp->nodes, &key);
return e ? (struct NODEINFO_Q*)e : NULL; return e ? (struct TOPO_NODEQ*)e : NULL;
} }
// ===== dump / format (updated for new structures) ===== // ===== dump / format =====
static int is_node_connectivity_active(struct NODE_CONNECTIVITY* c) { static int is_node_connectivity_active(struct TOPO_CONNECTIVITY* c) {
return c->probe_status != PROBE_STATUS_NONE return c->probe_status != PROBE_STATUS_NONE
|| c->interface_status != PROBE_RESULT_UNKNOWN || c->interface_status != PROBE_RESULT_UNKNOWN
|| c->nat_status != PROBE_RESULT_UNKNOWN || c->nat_status != PROBE_RESULT_UNKNOWN
@ -283,7 +283,7 @@ static const char* conn_mgr_type_str(uint8_t t) {
switch (t) { case 1: return "DIRECT"; case 2: return "REVERSE"; case 3: return "INDIRECT"; default: return "NONE"; } switch (t) { case 1: return "DIRECT"; case 2: return "REVERSE"; case 3: return "INDIRECT"; default: return "NONE"; }
} }
void route_node_dump_all(struct ROUTE_BGP* bgp) { void topo_node_dump_all(struct TOPO_BGP* bgp) {
if (!bgp || !bgp->nodes) return; if (!bgp || !bgp->nodes) return;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "=== BGP Nodes dump: %d nodes ===", queue_entry_count(bgp->nodes)); DEBUG_INFO(DEBUG_CATEGORY_BGP, "=== BGP Nodes dump: %d nodes ===", queue_entry_count(bgp->nodes));
@ -291,8 +291,8 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
int idx = 0; int idx = 0;
struct ll_entry* e = bgp->nodes->head; struct ll_entry* e = bgp->nodes->head;
while (e) { while (e) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
struct NODEINFO* ni = nq->node; struct TOPO_NODE* ni = nq->node;
if (!ni) { e = e->next; continue; } if (!ni) { e = e->next; continue; }
int is_local = (bgp->local_node == nq); int is_local = (bgp->local_node == nq);
const char* name_s = ni->node_name ? ni->node_name : ""; const char* name_s = ni->node_name ? ni->node_name : "";
@ -307,33 +307,33 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
log_dump(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_BGP, " ed25519", ni->ed25519_public_key, SC_PUBKEY_SIZE); log_dump(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_BGP, " ed25519", ni->ed25519_public_key, SC_PUBKEY_SIZE);
int si = 0; int si = 0;
{ struct NI_IPV4_SOCKET_META* sm = ni->v4_sock_meta; while (sm) { { struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; while (sm) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u config=%u nat=%u", si++, sm->id, sm->config_type, sm->nat_type); DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u config=%u nat=%u", si++, sm->id, sm->config_type, sm->nat_type);
sm = sm->next; sm = sm->next;
}} }}
{ const char* atn[] = {"INTERFACE","NAT","REAL"}; { const char* atn[] = {"INTERFACE","NAT","REAL"};
int ai = 0; struct NI_IPV4_ADDR* a = ni->v4_addrs; while (a) { int ai = 0; struct TOPO_ADDR4* a = ni->v4_addrs; while (a) {
const char* proto = (a->protocol & NODE_PROTO_TCP) ? "tcp" : (a->protocol & NODE_PROTO_UDP) ? "udp" : "?"; const char* proto = (a->protocol & TOPO_PROTO_TCP) ? "tcp" : (a->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4addr[%d]: %s:%u %s sock=%u proto=%s", ai++, DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4addr[%d]: %s:%u %s sock=%u proto=%s", ai++,
ip_to_str(a->addr, AF_INET).str, a->port, (a->type<=2)?atn[a->type]:"?", a->socket_id, proto); ip_to_str(a->addr, AF_INET).str, a->port, (a->type<=2)?atn[a->type]:"?", a->socket_id, proto);
a = a->next; a = a->next;
}} }}
{ int si6 = 0; struct NI_IPV6_SOCKET_META* sm6 = ni->v6_sock_meta; while (sm6) { { int si6 = 0; struct TOPO_SOCKMETA6* sm6 = ni->v6_sock_meta; while (sm6) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u config=%u nat=%u", si6++, sm6->id, sm6->config_type, sm6->nat_type); DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u config=%u nat=%u", si6++, sm6->id, sm6->config_type, sm6->nat_type);
sm6 = sm6->next; sm6 = sm6->next;
}} }}
{ int ai6 = 0; struct NI_IPV6_ADDR* a6 = ni->v6_addrs; while (a6) { { int ai6 = 0; struct TOPO_ADDR6* a6 = ni->v6_addrs; while (a6) {
const char* proto = (a6->protocol & NODE_PROTO_TCP) ? "tcp" : (a6->protocol & NODE_PROTO_UDP) ? "udp" : "?"; const char* proto = (a6->protocol & TOPO_PROTO_TCP) ? "tcp" : (a6->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6addr[%d]: %s:%u type=%u sock=%u proto=%s", ai6++, DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6addr[%d]: %s:%u type=%u sock=%u proto=%s", ai6++,
ip_to_str(a6->addr, AF_INET6).str, a6->port, a6->type, a6->socket_id, proto); ip_to_str(a6->addr, AF_INET6).str, a6->port, a6->type, a6->socket_id, proto);
a6 = a6->next; a6 = a6->next;
}} }}
if (nq->routes) { if (nq->subnets) {
{ int ri = 0; struct NI_IPV4_SUBNET* sub = nq->routes->v4_subnets; while (sub) { { int ri = 0; struct TOPO_SUBNET4* sub = nq->subnets->v4_subnets; while (sub) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sub[%d]: %s/%d", ri++, ip_to_str(sub->addr, AF_INET).str, sub->prefix_length); DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sub[%d]: %s/%d", ri++, ip_to_str(sub->addr, AF_INET).str, sub->prefix_length);
sub = sub->next; sub = sub->next;
}} }}
{ int ri6 = 0; struct NI_IPV6_SUBNET* sub6 = nq->routes->v6_subnets; while (sub6) { { int ri6 = 0; struct TOPO_SUBNET6* sub6 = nq->subnets->v6_subnets; while (sub6) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sub[%d]: %s/%d", ri6++, ip_to_str(sub6->addr, AF_INET6).str, sub6->prefix_length); DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sub[%d]: %s/%d", ri6++, ip_to_str(sub6->addr, AF_INET6).str, sub6->prefix_length);
sub6 = sub6->next; sub6 = sub6->next;
}} }}
@ -347,8 +347,8 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
if (nq->paths) { if (nq->paths) {
struct ll_entry* pe = nq->paths->head; struct ll_entry* pe = nq->paths->head;
while (pe) { while (pe) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)pe; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)pe;
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH));
char hop_buf[256] = ""; int hop_pos = 0; char hop_buf[256] = ""; int hop_pos = 0;
for (uint8_t hi = 0; hi < path->hop_count && hop_pos < (int)sizeof(hop_buf)-20; hi++) for (uint8_t hi = 0; hi < path->hop_count && hop_pos < (int)sizeof(hop_buf)-20; hi++)
hop_pos += snprintf(hop_buf + hop_pos, sizeof(hop_buf) - hop_pos, "%s%016llx", hi ? "->" : "", (unsigned long long)hop[hi]); hop_pos += snprintf(hop_buf + hop_pos, sizeof(hop_buf) - hop_pos, "%s%016llx", hi ? "->" : "", (unsigned long long)hop[hi]);
@ -358,7 +358,7 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
} }
} }
struct NODE_CONNECTIVITY* c = &nq->connectivity; struct TOPO_CONNECTIVITY* c = &nq->connectivity;
if (is_node_connectivity_active(c)) { if (is_node_connectivity_active(c)) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, " connectivity: probe=%s iface=%s(%u) nat=%s(%u) real=%s(%u) pend=%u iface_rtt=%u nat_rtt=%u real_rtt=%u start_tb=%llu ping_req_tb=%llu", DEBUG_INFO(DEBUG_CATEGORY_BGP, " connectivity: probe=%s iface=%s(%u) nat=%s(%u) real=%s(%u) pend=%u iface_rtt=%u nat_rtt=%u real_rtt=%u start_tb=%llu ping_req_tb=%llu",
probe_status_str(c->probe_status), probe_result_str(c->interface_status), c->interface_min_rtt, probe_status_str(c->probe_status), probe_result_str(c->interface_status), c->interface_min_rtt,
@ -377,7 +377,7 @@ void route_node_dump_all(struct ROUTE_BGP* bgp) {
} }
} }
int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) { int topo_node_format_all(struct TOPO_BGP* bgp, char* buf, size_t buf_size) {
if (!bgp || !bgp->nodes || !buf || buf_size == 0) return 0; if (!bgp || !bgp->nodes || !buf || buf_size == 0) return 0;
int pos = 0; int pos = 0;
@ -387,8 +387,8 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
int idx = 0; int idx = 0;
struct ll_entry* e = bgp->nodes->head; struct ll_entry* e = bgp->nodes->head;
while (e && (size_t)pos < buf_size) { while (e && (size_t)pos < buf_size) {
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e;
struct NODEINFO* ni = nq->node; struct TOPO_NODE* ni = nq->node;
if (!ni) { e = e->next; continue; } if (!ni) { e = e->next; continue; }
int is_local = (bgp->local_node == nq); int is_local = (bgp->local_node == nq);
const char* name_s = ni->node_name ? ni->node_name : ""; const char* name_s = ni->node_name ? ni->node_name : "";
@ -404,29 +404,29 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
FMT_ADD(" pubkey: "); for (int k = 0; k < SC_PUBKEY_SIZE; k++) FMT_ADD("%02x", ni->public_key[k]); FMT_ADD("\n"); FMT_ADD(" pubkey: "); for (int k = 0; k < SC_PUBKEY_SIZE; k++) FMT_ADD("%02x", ni->public_key[k]); FMT_ADD("\n");
FMT_ADD(" ed25519: "); for (int k = 0; k < SC_PUBKEY_SIZE; k++) FMT_ADD("%02x", ni->ed25519_public_key[k]); FMT_ADD("\n"); FMT_ADD(" ed25519: "); for (int k = 0; k < SC_PUBKEY_SIZE; k++) FMT_ADD("%02x", ni->ed25519_public_key[k]); FMT_ADD("\n");
{ struct NI_IPV4_SOCKET_META* sm = ni->v4_sock_meta; int si = 0; while (sm) { { struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; int si = 0; while (sm) {
FMT_ADD(" v4sock[%d]: id=%u config=%u nat=%u\n", si++, sm->id, sm->config_type, sm->nat_type); sm = sm->next; FMT_ADD(" v4sock[%d]: id=%u config=%u nat=%u\n", si++, sm->id, sm->config_type, sm->nat_type); sm = sm->next;
}} }}
{ const char* atn[] = {"INTERFACE","NAT","REAL"}; struct NI_IPV4_ADDR* a = ni->v4_addrs; int ai = 0; while (a) { { const char* atn[] = {"INTERFACE","NAT","REAL"}; struct TOPO_ADDR4* a = ni->v4_addrs; int ai = 0; while (a) {
const char* proto = (a->protocol & NODE_PROTO_TCP) ? "tcp" : (a->protocol & NODE_PROTO_UDP) ? "udp" : "?"; const char* proto = (a->protocol & TOPO_PROTO_TCP) ? "tcp" : (a->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
FMT_ADD(" v4addr[%d]: %s:%u %s sock=%u proto=%s\n", FMT_ADD(" v4addr[%d]: %s:%u %s sock=%u proto=%s\n",
ai++, ip_to_str(a->addr, AF_INET).str, a->port, (a->type<=2)?atn[a->type]:"?", a->socket_id, proto); ai++, ip_to_str(a->addr, AF_INET).str, a->port, (a->type<=2)?atn[a->type]:"?", a->socket_id, proto);
a = a->next; a = a->next;
}} }}
{ struct NI_IPV6_SOCKET_META* sm6 = ni->v6_sock_meta; int s6i = 0; while (sm6) { { struct TOPO_SOCKMETA6* sm6 = ni->v6_sock_meta; int s6i = 0; while (sm6) {
FMT_ADD(" v6sock[%d]: id=%u config=%u nat=%u\n", s6i++, sm6->id, sm6->config_type, sm6->nat_type); sm6 = sm6->next; FMT_ADD(" v6sock[%d]: id=%u config=%u nat=%u\n", s6i++, sm6->id, sm6->config_type, sm6->nat_type); sm6 = sm6->next;
}} }}
{ struct NI_IPV6_ADDR* a6 = ni->v6_addrs; int a6i = 0; while (a6) { { struct TOPO_ADDR6* a6 = ni->v6_addrs; int a6i = 0; while (a6) {
const char* proto = (a6->protocol & NODE_PROTO_TCP) ? "tcp" : (a6->protocol & NODE_PROTO_UDP) ? "udp" : "?"; const char* proto = (a6->protocol & TOPO_PROTO_TCP) ? "tcp" : (a6->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
FMT_ADD(" v6addr[%d]: %s:%u type=%u sock=%u proto=%s\n", FMT_ADD(" v6addr[%d]: %s:%u type=%u sock=%u proto=%s\n",
a6i++, ip_to_str(a6->addr, AF_INET6).str, a6->port, a6->type, a6->socket_id, proto); a6i++, ip_to_str(a6->addr, AF_INET6).str, a6->port, a6->type, a6->socket_id, proto);
a6 = a6->next; a6 = a6->next;
}} }}
if (nq->routes) { if (nq->subnets) {
{ struct NI_IPV4_SUBNET* sub = nq->routes->v4_subnets; int ri = 0; while (sub) { { struct TOPO_SUBNET4* sub = nq->subnets->v4_subnets; int ri = 0; while (sub) {
FMT_ADD(" v4sub[%d]: %s/%d\n", ri++, ip_to_str(sub->addr, AF_INET).str, sub->prefix_length); sub = sub->next; FMT_ADD(" v4sub[%d]: %s/%d\n", ri++, ip_to_str(sub->addr, AF_INET).str, sub->prefix_length); sub = sub->next;
}} }}
{ struct NI_IPV6_SUBNET* sub6 = nq->routes->v6_subnets; int r6i = 0; while (sub6) { { struct TOPO_SUBNET6* sub6 = nq->subnets->v6_subnets; int r6i = 0; while (sub6) {
FMT_ADD(" v6sub[%d]: %s/%d\n", r6i++, ip_to_str(sub6->addr, AF_INET6).str, sub6->prefix_length); sub6 = sub6->next; FMT_ADD(" v6sub[%d]: %s/%d\n", r6i++, ip_to_str(sub6->addr, AF_INET6).str, sub6->prefix_length); sub6 = sub6->next;
}} }}
} }
@ -437,8 +437,8 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
if (nq->paths) { if (nq->paths) {
struct ll_entry* pe = nq->paths->head; int pi = 0; struct ll_entry* pe = nq->paths->head; int pi = 0;
while (pe) { while (pe) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)pe; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)pe;
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH));
FMT_ADD(" path[%d]: conn=%s hop_count=%u hops=[", pi++, path->conn ? path->conn->log_name : "NULL", path->hop_count); FMT_ADD(" path[%d]: conn=%s hop_count=%u hops=[", pi++, path->conn ? path->conn->log_name : "NULL", path->hop_count);
for (uint8_t hi = 0; hi < path->hop_count; hi++) for (uint8_t hi = 0; hi < path->hop_count; hi++)
FMT_ADD("%s%016llx", hi ? "->" : "", (unsigned long long)hop[hi]); FMT_ADD("%s%016llx", hi ? "->" : "", (unsigned long long)hop[hi]);
@ -446,7 +446,7 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
} }
} }
struct NODE_CONNECTIVITY* c = &nq->connectivity; struct TOPO_CONNECTIVITY* c = &nq->connectivity;
if (is_node_connectivity_active(c)) { if (is_node_connectivity_active(c)) {
FMT_ADD(" connectivity: probe=%s iface=%s(%u) nat=%s(%u) real=%s(%u) pend=%u iface_rtt=%u nat_rtt=%u real_rtt=%u start_tb=%llu ping_req_tb=%llu\n", FMT_ADD(" connectivity: probe=%s iface=%s(%u) nat=%s(%u) real=%s(%u) pend=%u iface_rtt=%u nat_rtt=%u real_rtt=%u start_tb=%llu ping_req_tb=%llu\n",
probe_status_str(c->probe_status), probe_result_str(c->interface_status), c->interface_min_rtt, probe_status_str(c->probe_status), probe_result_str(c->interface_status), c->interface_min_rtt,
@ -472,10 +472,10 @@ int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size) {
return pos; return pos;
} }
// ===== update my nodeinfo (rewritten for new structures) ===== // ===== update my nodeinfo =====
int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BGP* bgp) { int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* bgp) {
if (!instance || !bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_update_my_nodeinfo: invalid args"); return -1; } if (!instance || !bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_update_my_nodeinfo: invalid args"); return -1; }
size_t name_len = 0; size_t name_len = 0;
if (instance->name[0]) { name_len = strlen(instance->name); if (name_len > 63) name_len = 63; } if (instance->name[0]) { name_len = strlen(instance->name); if (name_len > 63) name_len = 63; }
int vc = 0, vc6 = 0; int vc = 0, vc6 = 0;
@ -502,17 +502,16 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
int changed = 1; uint8_t old_ver = 0; int changed = 1; uint8_t old_ver = 0;
if (bgp->local_node && bgp->local_node->node) { if (bgp->local_node && bgp->local_node->node) {
struct NODEINFO* oni = bgp->local_node->node; struct TOPO_NODE* oni = bgp->local_node->node;
old_ver = oni->ver; old_ver = oni->ver;
int v4a_cnt = ni_list_count((struct _ni_head*)oni->v4_addrs); changed = (vc != (bgp->local_node->subnets ? topo_list_count((struct _topo_head*)bgp->local_node->subnets->v4_subnets) : 0))
changed = (vc != (bgp->local_node->routes ? ni_list_count((struct _ni_head*)bgp->local_node->routes->v4_subnets) : 0)) || (sock_count != topo_list_count((struct _topo_head*)oni->v4_sock_meta))
|| (sock_count != ni_list_count((struct _ni_head*)oni->v4_sock_meta)) || (addr_count != topo_list_count((struct _topo_head*)oni->v4_addrs))
|| (addr_count != v4a_cnt)
|| (name_len != (oni->node_name ? strlen(oni->node_name) : 0)) || (name_len != (oni->node_name ? strlen(oni->node_name) : 0))
|| (memcmp(oni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE) != 0) || (memcmp(oni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE) != 0)
|| (vc6 != (bgp->local_node->routes ? ni_list_count((struct _ni_head*)bgp->local_node->routes->v6_subnets) : 0)) || (vc6 != (bgp->local_node->subnets ? topo_list_count((struct _topo_head*)bgp->local_node->subnets->v6_subnets) : 0))
|| (sock6_count != ni_list_count((struct _ni_head*)oni->v6_sock_meta)) || (sock6_count != topo_list_count((struct _topo_head*)oni->v6_sock_meta))
|| (addr6_count != ni_list_count((struct _ni_head*)oni->v6_addrs)); || (addr6_count != topo_list_count((struct _topo_head*)oni->v6_addrs));
if (bgp->local_node && bgp->instance && bgp->instance->bgp) if (bgp->local_node && bgp->instance && bgp->instance->bgp)
if (memcmp(oni->ed25519_public_key, bgp->instance->bgp->ed25519_public_key, SC_PUBKEY_SIZE) != 0) changed = 1; if (memcmp(oni->ed25519_public_key, bgp->instance->bgp->ed25519_public_key, SC_PUBKEY_SIZE) != 0) changed = 1;
} }
@ -520,20 +519,20 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
if (changed) { if (changed) {
if (bgp->local_node) { if (bgp->local_node) {
if (instance->rt) route_delete(instance->rt, bgp->local_node); if (instance->rt) route_delete(instance->rt, bgp->local_node);
nodeinfo_free_lists(bgp, bgp->local_node); topo_node_free_lists(bgp, bgp->local_node);
u_free(bgp->local_node); u_free(bgp->local_node);
bgp->local_node = NULL; bgp->local_node = NULL;
} }
bgp->local_node = u_calloc(1, sizeof(struct NODEINFO_Q)); bgp->local_node = u_calloc(1, sizeof(struct TOPO_NODEQ));
if (!bgp->local_node) return -1; if (!bgp->local_node) return -1;
struct NODEINFO_Q* lq = bgp->local_node; struct TOPO_NODEQ* lq = bgp->local_node;
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { u_free(lq); bgp->local_node = NULL; return -1; } if (!ni) { u_free(lq); bgp->local_node = NULL; return -1; }
ni->ref_count = 1; ni->ref_count = 1;
ni->flags = NODEINFO_FLAG_SEND_SUBNETS; ni->flags = TOPO_FLAG_SEND_SUBNETS;
ni->group_id = NODEINFO_GROUP_UTUN; ni->group_id = TOPO_GROUP_UTUN;
ni->node_id = instance->node_id; ni->node_id = instance->node_id;
ni->ver = (old_ver % 255) + 1; ni->ver = (old_ver % 255) + 1;
memcpy(ni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE); memcpy(ni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE);
@ -550,37 +549,37 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
while (e_sock) { while (e_sock) {
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) { e_sock = e_sock->next; continue; } if (e_sock->type == CFG_SERVER_TYPE_PRIVATE || e_sock->type == CFG_SERVER_TYPE_LOCAL) { e_sock = e_sock->next; continue; }
if (e_sock->local_addr.ss_family == AF_INET) { if (e_sock->local_addr.ss_family == AF_INET) {
{ struct NI_IPV4_SOCKET_META* sm = memory_pool_alloc(bgp->v4_sock_meta_pool); { struct TOPO_SOCKMETA4* sm = memory_pool_alloc(bgp->v4_sock_meta_pool);
sm->id = e_sock->sock_id; sm->config_type = e_sock->type; sm->nat_type = e_sock->nat_type; sm->id = e_sock->sock_id; sm->config_type = e_sock->type; sm->nat_type = e_sock->nat_type;
sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; } sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; }
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr;
{ struct NI_IPV4_ADDR* a = memory_pool_alloc(bgp->v4_addr_pool); { struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool);
memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port); memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port);
a->type = ADDR_TYPE_INTERFACE; a->socket_id = e_sock->sock_id; a->protocol = NODE_PROTO_UDP; a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id; a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a; } a->next = ni->v4_addrs; ni->v4_addrs = a; }
if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT) { if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT) {
struct NI_IPV4_ADDR* a = memory_pool_alloc(bgp->v4_addr_pool); struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool);
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port); memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
a->type = ADDR_TYPE_NAT; a->socket_id = e_sock->sock_id; a->protocol = NODE_PROTO_UDP; a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id; a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a; a->next = ni->v4_addrs; ni->v4_addrs = a;
} }
if (e_sock->nat_type == NAT_VERIFIED_DIRECT || ((e_sock->type == CFG_SERVER_TYPE_PUBLIC || e_sock->type == CFG_SERVER_TYPE_UNKNOWN) && e_sock->nat_type < NAT_VERIFIED_UNKNOWN)) { if (e_sock->nat_type == NAT_VERIFIED_DIRECT || ((e_sock->type == CFG_SERVER_TYPE_PUBLIC || e_sock->type == CFG_SERVER_TYPE_UNKNOWN) && e_sock->nat_type < NAT_VERIFIED_UNKNOWN)) {
struct NI_IPV4_ADDR* a = memory_pool_alloc(bgp->v4_addr_pool); struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool);
memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port); memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port);
a->type = ADDR_TYPE_REAL; a->socket_id = e_sock->sock_id; a->protocol = NODE_PROTO_UDP; a->type = TOPO_ADDR_REAL; a->socket_id = e_sock->sock_id; a->protocol = TOPO_PROTO_UDP;
a->next = ni->v4_addrs; ni->v4_addrs = a; a->next = ni->v4_addrs; ni->v4_addrs = a;
} }
} else if (e_sock->local_addr.ss_family == AF_INET6) { } else if (e_sock->local_addr.ss_family == AF_INET6) {
{ struct NI_IPV6_SOCKET_META* sm6 = memory_pool_alloc(bgp->v6_sock_meta_pool); { struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(bgp->v6_sock_meta_pool);
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type; sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type;
sm6->next = ni->v6_sock_meta; ni->v6_sock_meta = sm6; } sm6->next = ni->v6_sock_meta; ni->v6_sock_meta = sm6; }
struct sockaddr_in6* if_sin6 = (struct sockaddr_in6*)&e_sock->interface_addr; struct sockaddr_in6* if_sin6 = (struct sockaddr_in6*)&e_sock->interface_addr;
{ struct NI_IPV6_ADDR* a6 = memory_pool_alloc(bgp->v6_addr_pool); { struct TOPO_ADDR6* a6 = memory_pool_alloc(bgp->v6_addr_pool);
memcpy(a6->addr, &if_sin6->sin6_addr, 16); a6->port = ntohs(if_sin6->sin6_port); memcpy(a6->addr, &if_sin6->sin6_addr, 16); a6->port = ntohs(if_sin6->sin6_port);
a6->type = ADDR_TYPE_INTERFACE; a6->socket_id = e_sock->sock_id; a6->protocol = NODE_PROTO_UDP; a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = e_sock->sock_id; a6->protocol = TOPO_PROTO_UDP;
a6->next = ni->v6_addrs; ni->v6_addrs = a6; } a6->next = ni->v6_addrs; ni->v6_addrs = a6; }
} }
e_sock = e_sock->next; e_sock = e_sock->next;
@ -588,41 +587,41 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
{ struct CFG_SERVER* srv = instance->config->servers; { struct CFG_SERVER* srv = instance->config->servers;
while (srv) { if (srv->transport && srv->ip.ss_family == AF_INET) { while (srv) { if (srv->transport && srv->ip.ss_family == AF_INET) {
struct sockaddr_in* tcp_sin = (struct sockaddr_in*)&srv->ip; struct sockaddr_in* tcp_sin = (struct sockaddr_in*)&srv->ip;
struct NI_IPV4_ADDR* a = memory_pool_alloc(bgp->v4_addr_pool); struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool);
memcpy(a->addr, &tcp_sin->sin_addr.s_addr, 4); a->port = ntohs(tcp_sin->sin_port); memcpy(a->addr, &tcp_sin->sin_addr.s_addr, 4); a->port = ntohs(tcp_sin->sin_port);
a->type = ADDR_TYPE_INTERFACE; a->socket_id = 0; a->protocol = NODE_PROTO_TCP; a->type = TOPO_ADDR_INTERFACE; a->socket_id = 0; a->protocol = TOPO_PROTO_TCP;
a->next = ni->v4_addrs; ni->v4_addrs = a; a->next = ni->v4_addrs; ni->v4_addrs = a;
} else if (srv->transport && srv->ip.ss_family == AF_INET6) { } else if (srv->transport && srv->ip.ss_family == AF_INET6) {
struct sockaddr_in6* tcp_sin6 = (struct sockaddr_in6*)&srv->ip; struct sockaddr_in6* tcp_sin6 = (struct sockaddr_in6*)&srv->ip;
struct NI_IPV6_ADDR* a6 = memory_pool_alloc(bgp->v6_addr_pool); struct TOPO_ADDR6* a6 = memory_pool_alloc(bgp->v6_addr_pool);
memcpy(a6->addr, &tcp_sin6->sin6_addr, 16); a6->port = ntohs(tcp_sin6->sin6_port); memcpy(a6->addr, &tcp_sin6->sin6_addr, 16); a6->port = ntohs(tcp_sin6->sin6_port);
a6->type = ADDR_TYPE_INTERFACE; a6->socket_id = 0; a6->protocol = NODE_PROTO_TCP; a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = 0; a6->protocol = TOPO_PROTO_TCP;
a6->next = ni->v6_addrs; ni->v6_addrs = a6; a6->next = ni->v6_addrs; ni->v6_addrs = a6;
} srv = srv->next; } } srv = srv->next; }
} }
if (vc || vc6) { if (vc || vc6) {
struct NODEINFO_ROUTES* r = u_calloc(1, sizeof(struct NODEINFO_ROUTES)); struct TOPO_NODESUBNETS* r = u_calloc(1, sizeof(struct TOPO_NODESUBNETS));
s = instance->config->my_subnets; s = instance->config->my_subnets;
while (s) { while (s) {
if (s->ip.family == AF_INET) { if (s->ip.family == AF_INET) {
struct NI_IPV4_SUBNET* sub = memory_pool_alloc(bgp->v4_subnet_pool); struct TOPO_SUBNET4* sub = memory_pool_alloc(bgp->v4_subnet_pool);
memcpy(sub->addr, &s->ip.addr.v4, 4); sub->prefix_length = s->netmask; memcpy(sub->addr, &s->ip.addr.v4, 4); sub->prefix_length = s->netmask;
sub->next = r->v4_subnets; r->v4_subnets = sub; sub->next = r->v4_subnets; r->v4_subnets = sub;
} else if (s->ip.family == AF_INET6) { } else if (s->ip.family == AF_INET6) {
struct NI_IPV6_SUBNET* sub6 = memory_pool_alloc(bgp->v6_subnet_pool); struct TOPO_SUBNET6* sub6 = memory_pool_alloc(bgp->v6_subnet_pool);
memcpy(sub6->addr, &s->ip.addr.v6, 16); sub6->prefix_length = s->netmask; memcpy(sub6->addr, &s->ip.addr.v6, 16); sub6->prefix_length = s->netmask;
sub6->next = r->v6_subnets; r->v6_subnets = sub6; sub6->next = r->v6_subnets; r->v6_subnets = sub6;
} }
s = s->next; s = s->next;
} }
lq->routes = r; lq->subnets = r;
} }
DEBUG_INFO(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: v4s=%d v4a=%d v6s=%d v6a=%d v4sub=%d v6sub=%d ver=%d", DEBUG_INFO(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: v4s=%d v4a=%d v6s=%d v6a=%d v4sub=%d v6sub=%d ver=%d",
sock_count, addr_count, sock6_count, addr6_count, vc, vc6, ni->ver); sock_count, addr_count, sock6_count, addr6_count, vc, vc6, ni->ver);
if (instance->rt && !route_insert(instance->rt, lq)) if (instance->rt && !route_insert(instance->rt, lq))
DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "route_bgp_update_my_nodeinfo: failed to insert local routes"); DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "topo_bgp_update_my_nodeinfo: failed to insert local routes");
} else { } else {
bgp->local_node->last_ver = bgp->local_node->node->ver; bgp->local_node->last_ver = bgp->local_node->node->ver;
} }

130
src/route_node.h → src/topo_node.h

@ -1,5 +1,5 @@
#ifndef ROUTE_NODE_H #ifndef TOPO_NODE_H
#define ROUTE_NODE_H #define TOPO_NODE_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -10,19 +10,19 @@ extern "C" {
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
#include "secure_channel.h" #include "secure_channel.h"
struct ROUTE_BGP; struct TOPO_BGP;
struct ETCP_SOCKET; struct ETCP_SOCKET;
struct UTUN_INSTANCE; struct UTUN_INSTANCE;
// ---- типы адресов в плоском списке NODEINFO_IPV4_ADDR ---- // ---- типы адресов в плоском списке TOPOMSG_ADDR4 ----
#define ADDR_TYPE_INTERFACE 0 // interface_addr сокета (LAN) #define TOPO_ADDR_INTERFACE 0 // interface_addr сокета (LAN)
#define ADDR_TYPE_NAT 1 // nat_addr после детекции NAT #define TOPO_ADDR_NAT 1 // nat_addr после детекции NAT
#define ADDR_TYPE_REAL 2 // подтверждённый прямой интернет-адрес (nat проверка показала совпадение с interface_addr) #define TOPO_ADDR_REAL 2 // подтверждённый прямой интернет-адрес (nat проверка показала совпадение с interface_addr)
// ---- протоколы транспорта (поле protocol в NODEINFO_IPV4_ADDR/NODEINFO_IPV6_ADDR) ---- // ---- протоколы транспорта (поле protocol в TOPOMSG_ADDR4/TOPOMSG_ADDR6) ----
#define NODE_PROTO_UDP 0x01 #define TOPO_PROTO_UDP 0x01
#define NODE_PROTO_TCP 0x02 #define TOPO_PROTO_TCP 0x02
// ---- типы NAT (etcp_connections.h) ---- // ---- типы NAT (etcp_connections.h) ----
// NAT_TYPE_UNKNOWN(0), NAT_TYPE_EIM(1), NAT_TYPE_STRICT(2) // NAT_TYPE_UNKNOWN(0), NAT_TYPE_EIM(1), NAT_TYPE_STRICT(2)
@ -47,15 +47,15 @@ struct UTUN_INSTANCE;
#define CONN_TYPE_INDIRECT 3 #define CONN_TYPE_INDIRECT 3
#define CONN_MGR_MAX_INTERMEDIARIES 3 #define CONN_MGR_MAX_INTERMEDIARIES 3
// ---- флаги nodeinfo (protocol) ---- // ---- флаги nodeinfo ----
#define NODEINFO_FLAG_SEND_SUBNETS 0x01 #define TOPO_FLAG_SEND_SUBNETS 0x01
// ---- group_id по умолчанию ---- // ---- group_id по умолчанию ----
#define NODEINFO_GROUP_UTUN 1 #define TOPO_GROUP_UTUN 1
// ---- состояние связности с удалённым узлом (локальное, не передаётся по BGP) ---- // ---- состояние связности с удалённым узлом (локальное, не передаётся по BGP) ----
struct NODE_CONNECTIVITY { struct TOPO_CONNECTIVITY {
uint8_t probe_status; uint8_t probe_status;
uint8_t pending_count; uint8_t pending_count;
uint64_t probe_start_time; uint64_t probe_start_time;
@ -77,13 +77,13 @@ struct NODE_CONNECTIVITY {
// Протокольные структуры (wire-format, packed, без next) // Протокольные структуры (wire-format, packed, без next)
// ======================================================================= // =======================================================================
struct NODEINFO_IPV4_SOCKET_META { struct TOPOMSG_SOCKMETA4 {
uint8_t id; uint8_t id;
uint8_t config_type; uint8_t config_type;
uint8_t nat_type; uint8_t nat_type;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_IPV4_ADDR { struct TOPOMSG_ADDR4 {
uint8_t addr[4]; uint8_t addr[4];
uint16_t port; uint16_t port;
uint8_t type; uint8_t type;
@ -91,13 +91,13 @@ struct NODEINFO_IPV4_ADDR {
uint8_t protocol; uint8_t protocol;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_IPV6_SOCKET_META { struct TOPOMSG_SOCKMETA6 {
uint8_t id; uint8_t id;
uint8_t config_type; uint8_t config_type;
uint8_t nat_type; uint8_t nat_type;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_IPV6_ADDR { struct TOPOMSG_ADDR6 {
uint8_t addr[16]; uint8_t addr[16];
uint16_t port; uint16_t port;
uint8_t type; uint8_t type;
@ -105,17 +105,17 @@ struct NODEINFO_IPV6_ADDR {
uint8_t protocol; uint8_t protocol;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_IPV4_SUBNET { struct TOPOMSG_SUBNET4 {
uint8_t addr[4]; uint8_t addr[4];
uint8_t prefix_length; uint8_t prefix_length;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_IPV6_SUBNET { struct TOPOMSG_SUBNET6 {
uint8_t addr[16]; uint8_t addr[16];
uint8_t prefix_length; uint8_t prefix_length;
} __attribute__((packed)); } __attribute__((packed));
struct NODEINFO_TRANZIT_NODE { struct TOPOMSG_TRANZIT {
uint64_t node_id; uint64_t node_id;
uint16_t rtt; uint16_t rtt;
uint16_t link_q; uint16_t link_q;
@ -124,7 +124,7 @@ struct NODEINFO_TRANZIT_NODE {
/** /**
* @brief Протокольный формат NODEINFO сообщения (wire-format) * @brief Протокольный формат NODEINFO сообщения (wire-format)
*/ */
struct NODEINFO_MSG { struct TOPOMSG_NODE {
uint8_t flags; uint8_t flags;
uint64_t group_id; uint64_t group_id;
uint64_t node_id; uint64_t node_id;
@ -142,28 +142,28 @@ struct NODEINFO_MSG {
uint8_t hop_count; uint8_t hop_count;
} __attribute__((packed)); } __attribute__((packed));
#define NODEINFO_MSG_HDR_SIZE sizeof(struct NODEINFO_MSG) #define TOPOMSG_NODE_HDR_SIZE sizeof(struct TOPOMSG_NODE)
// ======================================================================= // =======================================================================
// Структуры для хранения в памяти (linked list с next* первым полем) // Структуры для хранения в памяти (linked list с next* первым полем)
// ======================================================================= // =======================================================================
struct NI_IPV4_SOCKET_META { struct NI_IPV4_SOCKET_META* next; uint8_t id, config_type, nat_type; }; struct TOPO_SOCKMETA4 { struct TOPO_SOCKMETA4* next; uint8_t id, config_type, nat_type; };
struct NI_IPV4_ADDR { struct NI_IPV4_ADDR* next; uint8_t addr[4]; uint16_t port; uint8_t type, socket_id, protocol; }; struct TOPO_ADDR4 { struct TOPO_ADDR4* next; uint8_t addr[4]; uint16_t port; uint8_t type, socket_id, protocol; };
struct NI_IPV6_SOCKET_META { struct NI_IPV6_SOCKET_META* next; uint8_t id, config_type, nat_type; }; struct TOPO_SOCKMETA6 { struct TOPO_SOCKMETA6* next; uint8_t id, config_type, nat_type; };
struct NI_IPV6_ADDR { struct NI_IPV6_ADDR* next; uint8_t addr[16]; uint16_t port; uint8_t type, socket_id, protocol; }; struct TOPO_ADDR6 { struct TOPO_ADDR6* next; uint8_t addr[16]; uint16_t port; uint8_t type, socket_id, protocol; };
struct NI_IPV4_SUBNET { struct NI_IPV4_SUBNET* next; uint8_t addr[4]; uint8_t prefix_length; }; struct TOPO_SUBNET4 { struct TOPO_SUBNET4* next; uint8_t addr[4]; uint8_t prefix_length; };
struct NI_IPV6_SUBNET { struct NI_IPV6_SUBNET* next; uint8_t addr[16]; uint8_t prefix_length; }; struct TOPO_SUBNET6 { struct TOPO_SUBNET6* next; uint8_t addr[16]; uint8_t prefix_length; };
// Универсальная голова списка (next — первое поле во всех NI_*) // Универсальная голова списка (next — первое поле во всех TOPO_*)
struct _ni_head { struct _ni_head* next; }; struct _topo_head { struct _topo_head* next; };
static inline int ni_list_count(struct _ni_head* head) { int n = 0; while (head) { n++; head = head->next; } return n; } static inline int topo_list_count(struct _topo_head* head) { int n = 0; while (head) { n++; head = head->next; } return n; }
/** /**
* @brief Идентификационная информация об узле (память, разделяется между группами) * @brief Идентификационная информация об узле (память, разделяется между группами)
*/ */
struct NODEINFO { struct TOPO_NODE {
uint32_t ref_count; uint32_t ref_count;
uint8_t flags; uint8_t flags;
uint64_t group_id; uint64_t group_id;
@ -172,32 +172,32 @@ struct NODEINFO {
uint8_t public_key[SC_PUBKEY_SIZE]; uint8_t public_key[SC_PUBKEY_SIZE];
uint8_t ed25519_public_key[SC_PUBKEY_SIZE]; uint8_t ed25519_public_key[SC_PUBKEY_SIZE];
char* node_name; // отдельный u_strdup/u_free char* node_name; // отдельный u_strdup/u_free
struct NI_IPV4_SOCKET_META* v4_sock_meta; // linked list head struct TOPO_SOCKMETA4* v4_sock_meta; // linked list head
struct NI_IPV4_ADDR* v4_addrs; // linked list head struct TOPO_ADDR4* v4_addrs; // linked list head
struct NI_IPV6_SOCKET_META* v6_sock_meta; struct TOPO_SOCKMETA6* v6_sock_meta;
struct NI_IPV6_ADDR* v6_addrs; struct TOPO_ADDR6* v6_addrs;
}; };
/** /**
* @brief Маршруты узла (отдельный malloc, NULL если нет подсетей) * @brief Подсети узла (отдельный malloc, NULL если нет подсетей)
*/ */
struct NODEINFO_ROUTES { struct TOPO_NODESUBNETS {
struct NI_IPV4_SUBNET* v4_subnets; // linked list head struct TOPO_SUBNET4* v4_subnets; // linked list head
struct NI_IPV6_SUBNET* v6_subnets; struct TOPO_SUBNET6* v6_subnets;
}; };
struct NODEINFO_PATH { struct TOPO_NODEPATH {
struct ll_entry ll; struct ll_entry ll;
struct ETCP_CONN* conn; struct ETCP_CONN* conn;
uint8_t hop_count; uint8_t hop_count;
}; };
struct NODEINFO_Q { struct TOPO_NODEQ {
struct ll_entry ll; struct ll_entry ll;
uint64_t hash_node_id; // копия node_id для хеш-индекса uint64_t hash_node_id; // копия node_id для хеш-индекса
struct NODEINFO* node; // отдельный malloc, ref_count struct TOPO_NODE* node; // отдельный malloc, ref_count
struct NODEINFO_ROUTES* routes; // отдельный malloc (NULL если без подсетей) struct TOPO_NODESUBNETS* subnets; // отдельный malloc (NULL если без подсетей)
struct NODEINFO_TRANZIT_NODE* tranzit_data; // отдельный malloc struct TOPOMSG_TRANZIT* tranzit_data; // отдельный malloc
uint64_t* hop_list; // отдельный malloc uint64_t* hop_list; // отдельный malloc
uint8_t tranzit_count; uint8_t tranzit_count;
uint8_t hop_count; uint8_t hop_count;
@ -208,7 +208,7 @@ struct NODEINFO_Q {
uint8_t conn_mgr_type; uint8_t conn_mgr_type;
uint64_t conn_mgr_intermediaries[CONN_MGR_MAX_INTERMEDIARIES]; uint64_t conn_mgr_intermediaries[CONN_MGR_MAX_INTERMEDIARIES];
uint8_t conn_mgr_intermediariy_count; uint8_t conn_mgr_intermediariy_count;
struct NODE_CONNECTIVITY connectivity; struct TOPO_CONNECTIVITY connectivity;
struct ETCP_SOCKET* best_socket; struct ETCP_SOCKET* best_socket;
}; };
@ -217,32 +217,32 @@ struct NODEINFO_Q {
// API // API
// ======================================================================= // =======================================================================
struct NODEINFO_Q* nodeinfo_find_by_id(struct ROUTE_BGP* bgp, uint64_t node_id); struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_BGP* bgp, uint64_t node_id);
void nodeinfo_ref(struct NODEINFO* ni); void topo_node_ref(struct TOPO_NODE* ni);
void nodeinfo_unref(struct NODEINFO* ni); void topo_node_unref(struct TOPO_NODE* ni);
void nodeinfo_free_lists(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq); void topo_node_free_lists(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq);
int nodeinfo_dyn_size(const struct NODEINFO_MSG* msg); int topo_node_dyn_size(const struct TOPOMSG_NODE* msg);
// convenience accessors // convenience accessors
static inline const struct NI_IPV4_SOCKET_META* ni_v4_sock_meta(const struct NODEINFO* ni) { return ni->v4_sock_meta; } static inline const struct TOPO_SOCKMETA4* topo_v4_sock_meta(const struct TOPO_NODE* ni) { return ni->v4_sock_meta; }
static inline const struct NI_IPV4_ADDR* ni_v4_addrs(const struct NODEINFO* ni) { return ni->v4_addrs; } static inline const struct TOPO_ADDR4* topo_v4_addrs(const struct TOPO_NODE* ni) { return ni->v4_addrs; }
static inline const struct NI_IPV6_SOCKET_META* ni_v6_sock_meta(const struct NODEINFO* ni) { return ni->v6_sock_meta; } static inline const struct TOPO_SOCKMETA6* topo_v6_sock_meta(const struct TOPO_NODE* ni) { return ni->v6_sock_meta; }
static inline const struct NI_IPV6_ADDR* ni_v6_addrs(const struct NODEINFO* ni) { return ni->v6_addrs; } static inline const struct TOPO_ADDR6* topo_v6_addrs(const struct TOPO_NODE* ni) { return ni->v6_addrs; }
static inline const struct NI_IPV4_SUBNET* ni_v4_subnets(const struct NODEINFO_ROUTES* r) { return r ? r->v4_subnets : NULL; } static inline const struct TOPO_SUBNET4* topo_v4_subnets(const struct TOPO_NODESUBNETS* r) { return r ? r->v4_subnets : NULL; }
static inline const struct NI_IPV6_SUBNET* ni_v6_subnets(const struct NODEINFO_ROUTES* r) { return r ? r->v6_subnets : NULL; } static inline const struct TOPO_SUBNET6* topo_v6_subnets(const struct TOPO_NODESUBNETS* r) { return r ? r->v6_subnets : NULL; }
int nodeinfo_serialize(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq, uint8_t* out, size_t out_max); int topo_node_serialize(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max);
int nodeinfo_deserialize(struct ROUTE_BGP* bgp, const uint8_t* data, size_t len, struct NODEINFO** out_ni, struct NODEINFO_ROUTES** out_routes, int topo_node_deserialize(struct TOPO_BGP* bgp, const uint8_t* data, size_t len, struct TOPO_NODE** out_ni, struct TOPO_NODESUBNETS** out_subnets,
struct NODEINFO_TRANZIT_NODE** out_tranzit, uint8_t* out_tranzit_count, uint64_t** out_hop_list, uint8_t* out_hop_count); struct TOPOMSG_TRANZIT** out_tranzit, uint8_t* out_tranzit_count, uint64_t** out_hop_list, uint8_t* out_hop_count);
int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BGP* bgp); int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* bgp);
void route_node_dump_all(struct ROUTE_BGP* bgp); void topo_node_dump_all(struct TOPO_BGP* bgp);
int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size); int topo_node_format_all(struct TOPO_BGP* bgp, char* buf, size_t buf_size);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // ROUTE_NODE_H #endif // TOPO_NODE_H

14
src/route_node_lmdb.c → src/topo_node_lmdb.c

@ -2,14 +2,14 @@
#include <string.h> #include <string.h>
#include <stdint.h> #include <stdint.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "route_node_lmdb.h" #include "topo_node_lmdb.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
#define NODEINFO_DB_MAPSIZE (10UL * 1024 * 1024) #define NODEINFO_DB_MAPSIZE (10UL * 1024 * 1024)
int route_node_lmdb_init(struct ROUTE_BGP* bgp, const char* db_path) { int topo_node_lmdb_init(struct TOPO_BGP* bgp, const char* db_path) {
if (!bgp || !db_path || !db_path[0]) return -1; if (!bgp || !db_path || !db_path[0]) return -1;
int rc = mdb_env_create(&bgp->nodeinfo_env); int rc = mdb_env_create(&bgp->nodeinfo_env);
if (rc != MDB_SUCCESS) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_create failed: %s", mdb_strerror(rc)); return -1; } if (rc != MDB_SUCCESS) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "LMDB mdb_env_create failed: %s", mdb_strerror(rc)); return -1; }
@ -29,15 +29,15 @@ int route_node_lmdb_init(struct ROUTE_BGP* bgp, const char* db_path) {
return 0; return 0;
} }
void route_node_lmdb_destroy(struct ROUTE_BGP* bgp) { void topo_node_lmdb_destroy(struct TOPO_BGP* bgp) {
if (!bgp) return; if (!bgp) return;
if (bgp->nodeinfo_env) { mdb_env_close(bgp->nodeinfo_env); bgp->nodeinfo_env = NULL; DEBUG_INFO(DEBUG_CATEGORY_BGP, "LMDB nodeinfo database closed"); } if (bgp->nodeinfo_env) { mdb_env_close(bgp->nodeinfo_env); bgp->nodeinfo_env = NULL; DEBUG_INFO(DEBUG_CATEGORY_BGP, "LMDB nodeinfo database closed"); }
} }
int route_node_lmdb_put(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) { int topo_node_lmdb_put(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq) {
if (!bgp || !bgp->nodeinfo_env || !nq || !nq->node) return -1; if (!bgp || !bgp->nodeinfo_env || !nq || !nq->node) return -1;
uint8_t buf[8192]; uint8_t buf[8192];
int ser_len = nodeinfo_serialize(bgp, nq, buf, sizeof(buf)); int ser_len = topo_node_serialize(bgp, nq, buf, sizeof(buf));
if (ser_len < 0) return -1; if (ser_len < 0) return -1;
MDB_val key, data; MDB_val key, data;
@ -53,7 +53,7 @@ int route_node_lmdb_put(struct ROUTE_BGP* bgp, struct NODEINFO_Q* nq) {
return 0; return 0;
} }
int route_node_lmdb_del(struct ROUTE_BGP* bgp, uint64_t node_id) { int topo_node_lmdb_del(struct TOPO_BGP* bgp, uint64_t node_id) {
if (!bgp || !bgp->nodeinfo_env) return -1; if (!bgp || !bgp->nodeinfo_env) return -1;
MDB_val key; key.mv_size = 8; key.mv_data = &node_id; MDB_val key; key.mv_size = 8; key.mv_data = &node_id;
MDB_txn* txn = NULL; int rc = mdb_txn_begin(bgp->nodeinfo_env, NULL, 0, &txn); MDB_txn* txn = NULL; int rc = mdb_txn_begin(bgp->nodeinfo_env, NULL, 0, &txn);

23
src/topo_node_lmdb.h

@ -0,0 +1,23 @@
#ifndef TOPO_NODE_LMDB_H
#define TOPO_NODE_LMDB_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "topo_node.h"
struct TOPO_BGP;
int topo_node_lmdb_init(struct TOPO_BGP* bgp, const char* db_path);
void topo_node_lmdb_destroy(struct TOPO_BGP* bgp);
int topo_node_lmdb_put(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq);
int topo_node_lmdb_del(struct TOPO_BGP* bgp, uint64_t node_id);
#ifdef __cplusplus
}
#endif
#endif

10
src/utun_instance.c

@ -5,10 +5,10 @@
#include "config_updater.h" #include "config_updater.h"
#include "tun_if.h" #include "tun_if.h"
#include "tun_route.h" #include "tun_route.h"
#include "route_node.h" #include "topo_node.h"
#include "route_lib.h" #include "route_lib.h"
#include "routing.h" #include "routing.h"
#include "route_bgp.h" #include "topo_bgp.h"
#include "etcp_connections.h" #include "etcp_connections.h"
#include "etcp.h" #include "etcp.h"
#include "conn_mgr.h" #include "conn_mgr.h"
@ -159,13 +159,13 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
if (socket_result == 1) { if (socket_result == 1) {
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "Partial socket initialization - some servers failed to bind"); DEBUG_WARN(DEBUG_CATEGORY_ETCP, "Partial socket initialization - some servers failed to bind");
} }
instance->bgp = route_bgp_init(instance); instance->bgp = topo_bgp_init(instance);
if (!instance->bgp) { if (!instance->bgp) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to initialize BGP module"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to initialize BGP module");
} else { } else {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized");
if (instance->rt && instance->bgp->local_node) { if (instance->rt && instance->bgp->local_node) {
route_bgp_update_my_nodeinfo(instance, instance->bgp); topo_bgp_update_my_nodeinfo(instance, instance->bgp);
} }
} }
@ -456,7 +456,7 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
// Cleanup BGP module // Cleanup BGP module
if (instance->bgp) { if (instance->bgp) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Destroying BGP module"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Destroying BGP module");
route_bgp_destroy(instance); topo_bgp_destroy(instance);
instance->bgp = NULL; instance->bgp = NULL;
} }

4
src/utun_instance.h

@ -34,7 +34,7 @@ struct ETCP_SOCKET;
struct tun_if; struct tun_if;
struct ETCP_BINDINGS; struct ETCP_BINDINGS;
struct ETCP_ROUTER_BINDINGS; struct ETCP_ROUTER_BINDINGS;
struct ROUTE_BGP; struct TOPO_BGP;
struct control_server; struct control_server;
struct msg_transport; struct msg_transport;
struct PING_CONTEXT; struct PING_CONTEXT;
@ -64,7 +64,7 @@ struct UTUN_INSTANCE {
struct CFG_ROUTE_ENTRY* route_subnets; struct CFG_ROUTE_ENTRY* route_subnets;
struct ROUTE_TABLE* rt; struct ROUTE_TABLE* rt;
struct ROUTE_BGP* bgp; // BGP module for route exchange struct TOPO_BGP* bgp; // BGP module for topology exchange
// Identification // Identification
uint64_t node_id; uint64_t node_id;

2
tests/test_bgp_route_exchange.c

@ -39,7 +39,7 @@
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_lib.h" #include "../src/route_lib.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/dummynet.h" #include "../src/dummynet.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"

16
tests/test_bgp_triangle.c

@ -43,8 +43,8 @@
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_lib.h" #include "../src/route_lib.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/dummynet.h" #include "../src/dummynet.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
@ -122,22 +122,22 @@ static void build_node_config(char* buf, size_t size, const struct ncfg* c) {
static int peer_in_nodes(struct UTUN_INSTANCE* inst, uint64_t node_id) { static int peer_in_nodes(struct UTUN_INSTANCE* inst, uint64_t node_id) {
if (!inst || !inst->bgp || !inst->bgp->nodes) return 0; if (!inst || !inst->bgp || !inst->bgp->nodes) return 0;
return nodeinfo_find_by_id(inst->bgp, node_id) != NULL; return topo_node_find_by_id(inst->bgp, node_id) != NULL;
} }
static int node_path_count(struct UTUN_INSTANCE* inst, uint64_t node_id) { static int node_path_count(struct UTUN_INSTANCE* inst, uint64_t node_id) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(inst->bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id);
if (!nq || !nq->paths) return 0; if (!nq || !nq->paths) return 0;
return queue_entry_count(nq->paths); return queue_entry_count(nq->paths);
} }
static int node_path_has_peer(struct UTUN_INSTANCE* inst, uint64_t node_id, uint64_t peer_id) { static int node_path_has_peer(struct UTUN_INSTANCE* inst, uint64_t node_id, uint64_t peer_id) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(inst->bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id);
if (!nq || !nq->paths) return 0; if (!nq || !nq->paths) return 0;
struct ll_entry* e = nq->paths->head; struct ll_entry* e = nq->paths->head;
while (e) { while (e) {
struct NODEINFO_PATH* path = (struct NODEINFO_PATH*)e; struct TOPO_NODEPATH* path = (struct TOPO_NODEPATH*)e;
uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct NODEINFO_PATH)); uint64_t* hop = (uint64_t*)((uint8_t*)path + sizeof(struct TOPO_NODEPATH));
for (uint8_t i = 0; i < path->hop_count; i++) for (uint8_t i = 0; i < path->hop_count; i++)
if (hop[i] == peer_id) return 1; if (hop[i] == peer_id) return 1;
e = e->next; e = e->next;
@ -146,7 +146,7 @@ static int node_path_has_peer(struct UTUN_INSTANCE* inst, uint64_t node_id, uint
} }
static int node_version(struct UTUN_INSTANCE* inst, uint64_t node_id) { static int node_version(struct UTUN_INSTANCE* inst, uint64_t node_id) {
struct NODEINFO_Q* nq = nodeinfo_find_by_id(inst->bgp, node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id);
return nq ? nq->last_ver : -1; return nq ? nq->last_ver : -1;
} }

10
tests/test_conn_mgr.c

@ -4,7 +4,7 @@
* *
* Test 1: Direct via existing ETCP conn → CONN_TYPE_DIRECT * Test 1: Direct via existing ETCP conn → CONN_TYPE_DIRECT
* Test 2: Status check → state/type * Test 2: Status check → state/type
* Test 3: Alien node → NODEINFO_Q.alien=1 * Test 3: Alien node → TOPO_NODEQ.alien=1
* *
* Pending: * Pending:
* Test 4: New link UP callback (INIT to new peer via conn_mgr) * Test 4: New link UP callback (INIT to new peer via conn_mgr)
@ -26,7 +26,7 @@
#include "../src/config_parser.h" #include "../src/config_parser.h"
#include "../src/config_updater.h" #include "../src/config_updater.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/conn_mgr.h" #include "../src/conn_mgr.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
@ -73,7 +73,7 @@ static void ccb(int r, uint64_t id, void* arg) {
static void test1(void* arg) { static void test1(void* arg) {
(void)arg; if (result) return; (void)arg; if (result) return;
if (!nodeinfo_find_by_id(g_a->bgp, NID_B)) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1"); return; } if (!topo_node_find_by_id(g_a->bgp, NID_B)) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1"); return; }
fprintf(stderr, "Test 1: direct — conn_mgr_connect_node(B)\n"); fflush(stderr); fprintf(stderr, "Test 1: direct — conn_mgr_connect_node(B)\n"); fflush(stderr);
conn_mgr_connect_node(g_a->conn_mgr, NID_B, 0, ccb, NULL); conn_mgr_connect_node(g_a->conn_mgr, NID_B, 0, ccb, NULL);
uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test2, "t2a"); uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test2, "t2a");
@ -91,9 +91,9 @@ static void test2(void* arg) {
static void test3(void* arg) { static void test3(void* arg) {
(void)arg; (void)arg;
uint64_t aid = 0xEEEE000000000001ULL; uint64_t aid = 0xEEEE000000000001ULL;
struct NODEINFO ni; memset(&ni, 0, sizeof(ni)); ni.node_id = aid; ni.ver = 1; struct TOPO_NODE ni; memset(&ni, 0, sizeof(ni)); ni.node_id = aid; ni.ver = 1;
conn_mgr_add_alien_node(g_a->conn_mgr, (uint8_t*)&ni, sizeof(ni)); conn_mgr_add_alien_node(g_a->conn_mgr, (uint8_t*)&ni, sizeof(ni));
struct NODEINFO_Q* nq = nodeinfo_find_by_id(g_a->bgp, aid); struct TOPO_NODEQ* nq = topo_node_find_by_id(g_a->bgp, aid);
fprintf(stderr, "Test 3: alien alien=%d\n", nq ? nq->alien : -1); fflush(stderr); fprintf(stderr, "Test 3: alien alien=%d\n", nq ? nq->alien : -1); fflush(stderr);
if (nq && nq->alien == 1) fprintf(stderr, " OK: alien flag set\n"); if (nq && nq->alien == 1) fprintf(stderr, " OK: alien flag set\n");
else { fail("alien flag not set"); return; } else { fail("alien flag not set"); return; }

30
tests/test_etcp_connect.c

@ -14,8 +14,8 @@
#include "../src/config_parser.h" #include "../src/config_parser.h"
#include "../src/config_updater.h" #include "../src/config_updater.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -63,20 +63,20 @@ static volatile int cb_type = 0, cb_conn_ok = 0, cb_count = 0;
static void connect_ccb(void* a, struct ETCP_CONN* conn, int type) { cb_type = type; cb_conn_ok = (conn != NULL); cb_count++; } static void connect_ccb(void* a, struct ETCP_CONN* conn, int type) { cb_type = type; cb_conn_ok = (conn != NULL); cb_count++; }
/* ----- helper: create minimal NODEINFO_Q with 1 v4 addr ----- */ /* ----- helper: create minimal TOPO_NODEQ with 1 v4 addr ----- */
static struct NODEINFO_Q* mknode(uint64_t nid, const uint8_t pubkey[32], static struct TOPO_NODEQ* mknode(uint64_t nid, const uint8_t pubkey[32],
uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port) { uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port) {
struct NODEINFO_Q* nq = u_calloc(1, sizeof(struct NODEINFO_Q)); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ));
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; } if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; }
ni->ref_count = 1; ni->node_id = nid; ni->ver = 0; ni->ref_count = 1; ni->node_id = nid; ni->ver = 0;
memcpy(ni->public_key, pubkey, SC_PUBKEY_SIZE); memcpy(ni->public_key, pubkey, SC_PUBKEY_SIZE);
nq->ll.size = sizeof(struct NODEINFO_Q) - sizeof(struct ll_entry); nq->ll.size = sizeof(struct TOPO_NODEQ) - sizeof(struct ll_entry);
nq->node = ni; nq->hash_node_id = nid; nq->node = ni; nq->hash_node_id = nid;
struct NI_IPV4_SOCKET_META* sm = u_calloc(1, sizeof(struct NI_IPV4_SOCKET_META)); struct TOPO_SOCKMETA4* sm = u_calloc(1, sizeof(struct TOPO_SOCKMETA4));
if (sm) { sm->id = 0; sm->config_type = CFG_SERVER_TYPE_PUBLIC; sm->nat_type = NAT_TYPE_UNKNOWN; sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; } if (sm) { sm->id = 0; sm->config_type = CFG_SERVER_TYPE_PUBLIC; sm->nat_type = NAT_TYPE_UNKNOWN; sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; }
struct NI_IPV4_ADDR* addr = u_calloc(1, sizeof(struct NI_IPV4_ADDR)); struct TOPO_ADDR4* addr = u_calloc(1, sizeof(struct TOPO_ADDR4));
if (addr) { addr->addr[0] = a; addr->addr[1] = b; addr->addr[2] = c; addr->addr[3] = d; addr->port = port; addr->type = ADDR_TYPE_INTERFACE; addr->socket_id = 0; addr->next = ni->v4_addrs; ni->v4_addrs = addr; } if (addr) { addr->addr[0] = a; addr->addr[1] = b; addr->addr[2] = c; addr->addr[3] = d; addr->port = port; addr->type = TOPO_ADDR_INTERFACE; addr->socket_id = 0; addr->next = ni->v4_addrs; ni->v4_addrs = addr; }
return nq; return nq;
} }
@ -84,7 +84,7 @@ static struct NODEINFO_Q* mknode(uint64_t nid, const uint8_t pubkey[32],
static void test1(void* arg) { static void test1(void* arg) {
(void)arg; if (result) return; (void)arg; if (result) return;
if (lks(g_a) < 1 || lks(g_b) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1"); return; } if (lks(g_a) < 1 || lks(g_b) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1"); return; }
struct NODEINFO_Q* nb = nodeinfo_find_by_id(g_a->bgp, NID_B); struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B);
if (!nb) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1b"); return; } if (!nb) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test1, "t1b"); return; }
fprintf(stderr, "Test 1: already connected → EARLY|LATE\n"); fflush(stderr); fprintf(stderr, "Test 1: already connected → EARLY|LATE\n"); fflush(stderr);
cb_type = 0; cb_conn_ok = 0; cb_count = 0; cb_type = 0; cb_conn_ok = 0; cb_count = 0;
@ -108,7 +108,7 @@ static void test3(void* arg) {
fprintf(stderr, "Test 3: unreachable node → error\n"); fflush(stderr); fprintf(stderr, "Test 3: unreachable node → error\n"); fflush(stderr);
struct SC_MYKEYS fk; sc_generate_keypair(&fk); struct SC_MYKEYS fk; sc_generate_keypair(&fk);
uint64_t fnid = 0xF000000000000001ULL; uint64_t fnid = 0xF000000000000001ULL;
struct NODEINFO_Q* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49999); struct TOPO_NODEQ* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49999);
if (!fn) { fail("mknode failed"); return; } if (!fn) { fail("mknode failed"); return; }
queue_data_put_with_index(g_a->bgp->nodes, &fn->ll); queue_data_put_with_index(g_a->bgp->nodes, &fn->ll);
g_a->etcp_connect_timeout_tb = 2000; g_a->etcp_connect_timeout_tb = 2000;
@ -138,7 +138,7 @@ static void test5(void* arg) {
fprintf(stderr, "Test 5: double connect to unreachable → both callbacks\n"); fflush(stderr); fprintf(stderr, "Test 5: double connect to unreachable → both callbacks\n"); fflush(stderr);
struct SC_MYKEYS fk; sc_generate_keypair(&fk); struct SC_MYKEYS fk; sc_generate_keypair(&fk);
uint64_t fnid = 0xF000000000000002ULL; uint64_t fnid = 0xF000000000000002ULL;
struct NODEINFO_Q* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49998); struct TOPO_NODEQ* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49998);
if (!fn) { fail("mknode failed"); return; } if (!fn) { fail("mknode failed"); return; }
queue_data_put_with_index(g_a->bgp->nodes, &fn->ll); queue_data_put_with_index(g_a->bgp->nodes, &fn->ll);
g_a->etcp_connect_timeout_tb = 2000; g_a->etcp_connect_timeout_tb = 2000;
@ -159,7 +159,7 @@ static void test6(void* arg) {
/* ======================== Test 7: EARLY-only flag ======================== */ /* ======================== Test 7: EARLY-only flag ======================== */
static void test7(void* arg) { static void test7(void* arg) {
(void)arg; if (result) return; (void)arg; if (result) return;
struct NODEINFO_Q* nb = nodeinfo_find_by_id(g_a->bgp, NID_B); struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B);
if (!nb || lks(g_a) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test7, "t7"); return; } if (!nb || lks(g_a) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test7, "t7"); return; }
fprintf(stderr, "Test 7: EARLY-only flag\n"); fflush(stderr); fprintf(stderr, "Test 7: EARLY-only flag\n"); fflush(stderr);
cb_type = 0; cb_conn_ok = 0; cb_count = 0; cb_type = 0; cb_conn_ok = 0; cb_count = 0;
@ -179,7 +179,7 @@ static void test8(void* arg) {
/* ======================== Test 9: LATE-only flag ======================== */ /* ======================== Test 9: LATE-only flag ======================== */
static void test9(void* arg) { static void test9(void* arg) {
(void)arg; if (result) return; (void)arg; if (result) return;
struct NODEINFO_Q* nb = nodeinfo_find_by_id(g_a->bgp, NID_B); struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B);
if (!nb || lks(g_a) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test9, "t9"); return; } if (!nb || lks(g_a) < 1) { uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test9, "t9"); return; }
fprintf(stderr, "Test 9: LATE-only flag\n"); fflush(stderr); fprintf(stderr, "Test 9: LATE-only flag\n"); fflush(stderr);
cb_type = 0; cb_conn_ok = 0; cb_count = 0; cb_type = 0; cb_conn_ok = 0; cb_count = 0;

2
tests/test_etcp_router.c

@ -30,7 +30,7 @@
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
#include "../src/pkt_normalizer.h" #include "../src/pkt_normalizer.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"

28
tests/test_etcp_router_reconnect.c

@ -20,8 +20,8 @@
#include "../src/etcp_connections.h" #include "../src/etcp_connections.h"
#include "../src/etcp_router.h" #include "../src/etcp_router.h"
#include "../src/etcp_api.h" #include "../src/etcp_api.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/config_parser.h" #include "../src/config_parser.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
@ -78,18 +78,18 @@ static void gen_payload(uint32_t seq, uint8_t* buf, int len) {
for (int i=0;i<len;i++) buf[i]=(uint8_t)((i^seq^0xA5)&0xFF); for (int i=0;i<len;i++) buf[i]=(uint8_t)((i^seq^0xA5)&0xFF);
} }
static struct NODEINFO_Q* mknode(uint64_t nid, const uint8_t pubkey[32], static struct TOPO_NODEQ* mknode(uint64_t nid, const uint8_t pubkey[32],
uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port) { uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint16_t port) {
struct NODEINFO_Q* nq = u_calloc(1, sizeof(struct NODEINFO_Q)); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ));
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; } if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; }
ni->ref_count = 1; ni->node_id = nid; ni->ver = 0; ni->ref_count = 1; ni->node_id = nid; ni->ver = 0;
memcpy(ni->public_key, pubkey, SC_PUBKEY_SIZE); memcpy(ni->public_key, pubkey, SC_PUBKEY_SIZE);
nq->node = ni; nq->hash_node_id = nid; nq->node = ni; nq->hash_node_id = nid;
struct NI_IPV4_SOCKET_META* sm = u_calloc(1, sizeof(struct NI_IPV4_SOCKET_META)); struct TOPO_SOCKMETA4* sm = u_calloc(1, sizeof(struct TOPO_SOCKMETA4));
if (sm) { sm->id = 0; sm->config_type = CFG_SERVER_TYPE_PUBLIC; sm->nat_type = NAT_TYPE_UNKNOWN; sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; } if (sm) { sm->id = 0; sm->config_type = CFG_SERVER_TYPE_PUBLIC; sm->nat_type = NAT_TYPE_UNKNOWN; sm->next = ni->v4_sock_meta; ni->v4_sock_meta = sm; }
struct NI_IPV4_ADDR* addr = u_calloc(1, sizeof(struct NI_IPV4_ADDR)); struct TOPO_ADDR4* addr = u_calloc(1, sizeof(struct TOPO_ADDR4));
if (addr) { addr->addr[0] = a; addr->addr[1] = b; addr->addr[2] = c; addr->addr[3] = d; addr->port = port; addr->type = ADDR_TYPE_INTERFACE; addr->socket_id = 0; addr->next = ni->v4_addrs; ni->v4_addrs = addr; } if (addr) { addr->addr[0] = a; addr->addr[1] = b; addr->addr[2] = c; addr->addr[3] = d; addr->port = port; addr->type = TOPO_ADDR_INTERFACE; addr->socket_id = 0; addr->next = ni->v4_addrs; ni->v4_addrs = addr; }
return nq; return nq;
} }
@ -172,7 +172,7 @@ static void state_step(void) {
switch (g_state) { switch (g_state) {
case ST_INIT: case ST_INIT:
if (g_bgp_ready_mask == 3) { if (g_bgp_ready_mask == 3) {
struct ETCP_CONN* rc = route_bgp_find_conn_for_node(g_a->bgp, node_c); struct ETCP_CONN* rc = topo_bgp_find_conn_for_node(g_a->bgp, node_c);
if (rc) g_state=ST_PHASE1_SEND; if (rc) g_state=ST_PHASE1_SEND;
} }
break; break;
@ -196,15 +196,15 @@ static void state_step(void) {
g_b=utun_instance_create(ua,b_conf); g_b=utun_instance_create(ua,b_conf);
if (!g_b||utun_instance_init(g_b)<0) { fprintf(stderr,"FAIL: b restart\n"); g_test_ok=-1; g_fail_code=20; return; } if (!g_b||utun_instance_init(g_b)<0) { fprintf(stderr,"FAIL: b restart\n"); g_test_ok=-1; g_fail_code=20; return; }
g_b->etcp_connect_timeout_tb = 300000; g_b->etcp_connect_timeout_tb = 300000;
struct NODEINFO_Q* nq_a = mknode(node_a, keys_a.public_key, 127,0,0,1, (uint16_t)a_port); struct TOPO_NODEQ* nq_a = mknode(node_a, keys_a.public_key, 127,0,0,1, (uint16_t)a_port);
struct NODEINFO_Q* nq_c = mknode(node_c, keys_c.public_key, 127,0,0,1, (uint16_t)c_port); struct TOPO_NODEQ* nq_c = mknode(node_c, keys_c.public_key, 127,0,0,1, (uint16_t)c_port);
if (!nq_a || !nq_c) { fprintf(stderr,"FAIL: mknode\n"); g_test_ok=-1; return; } if (!nq_a || !nq_c) { fprintf(stderr,"FAIL: mknode\n"); g_test_ok=-1; return; }
static int cc_a=0,cc_c=1; static int cc_a=0,cc_c=1;
etcp_connect(g_b,nq_a,connect_bgp_ready_cb,&cc_a,ETCP_CONNECT_BGP_READY); etcp_connect(g_b,nq_a,connect_bgp_ready_cb,&cc_a,ETCP_CONNECT_BGP_READY);
etcp_connect(g_b,nq_c,connect_bgp_ready_cb,&cc_c,ETCP_CONNECT_BGP_READY); etcp_connect(g_b,nq_c,connect_bgp_ready_cb,&cc_c,ETCP_CONNECT_BGP_READY);
} }
if (g_bgp_ready_mask == 3) { if (g_bgp_ready_mask == 3) {
struct ETCP_CONN* rc = route_bgp_find_conn_for_node(g_a->bgp, node_c); struct ETCP_CONN* rc = topo_bgp_find_conn_for_node(g_a->bgp, node_c);
if (rc) { g_phase_sent=0; g_state=ST_PHASE3_SEND; } if (rc) { g_phase_sent=0; g_state=ST_PHASE3_SEND; }
} }
break; break;
@ -244,8 +244,8 @@ int main(void) {
g_b=utun_instance_create(ua,b_conf); if(!g_b||utun_instance_init(g_b)<0){fprintf(stderr,"FAIL: b\n");goto fail;} g_b=utun_instance_create(ua,b_conf); if(!g_b||utun_instance_init(g_b)<0){fprintf(stderr,"FAIL: b\n");goto fail;}
etcp_router_bind(g_c, TEST_SVC_ID, recv_handler); etcp_router_bind(g_c, TEST_SVC_ID, recv_handler);
struct NODEINFO_Q* nq_a = mknode(node_a, keys_a.public_key, 127,0,0,1, (uint16_t)a_port); struct TOPO_NODEQ* nq_a = mknode(node_a, keys_a.public_key, 127,0,0,1, (uint16_t)a_port);
struct NODEINFO_Q* nq_c = mknode(node_c, keys_c.public_key, 127,0,0,1, (uint16_t)c_port); struct TOPO_NODEQ* nq_c = mknode(node_c, keys_c.public_key, 127,0,0,1, (uint16_t)c_port);
if (!nq_a || !nq_c) { fprintf(stderr,"FAIL: mknode\n"); goto fail; } if (!nq_a || !nq_c) { fprintf(stderr,"FAIL: mknode\n"); goto fail; }
g_b->etcp_connect_timeout_tb = 300000; g_b->etcp_connect_timeout_tb = 300000;
{ static int cc_a=0,cc_c=1; { static int cc_a=0,cc_c=1;

12
tests/test_etcp_router_unit.c

@ -11,7 +11,7 @@
#include "../src/etcp.h" #include "../src/etcp.h"
#include "../src/etcp_api.h" #include "../src/etcp_api.h"
#include "../src/etcp_router.h" #include "../src/etcp_router.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -140,18 +140,18 @@ static int setup_sign_keys(void) {
} }
static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519_key) { static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519_key) {
struct ROUTE_BGP* bgp = u_calloc(1, sizeof(struct ROUTE_BGP)); struct TOPO_BGP* bgp = u_calloc(1, sizeof(struct TOPO_BGP));
if (!bgp) { printf(" setup_bgp: u_calloc failed\n"); return; } if (!bgp) { printf(" setup_bgp: u_calloc failed\n"); return; }
bgp->instance = inst; bgp->instance = inst;
bgp->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE, bgp->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE,
offsetof(struct NODEINFO_Q, hash_node_id) - sizeof(struct ll_entry), 8, "bgp_nodes_test"); offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "bgp_nodes_test");
if (!bgp->nodes) { printf(" setup_bgp: queue_new failed\n"); u_free(bgp); return; } if (!bgp->nodes) { printf(" setup_bgp: queue_new failed\n"); u_free(bgp); return; }
inst->bgp = bgp; inst->bgp = bgp;
struct NODEINFO_Q* nq = u_calloc(1, sizeof(struct NODEINFO_Q)); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ));
if (!nq) { printf(" setup_bgp: nq alloc failed\n"); return; } if (!nq) { printf(" setup_bgp: nq alloc failed\n"); return; }
nq->ll.size = sizeof(struct NODEINFO_Q) - sizeof(struct ll_entry); nq->ll.size = sizeof(struct TOPO_NODEQ) - sizeof(struct ll_entry);
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { printf(" setup_bgp: ni alloc failed\n"); u_free(nq); return; } if (!ni) { printf(" setup_bgp: ni alloc failed\n"); u_free(nq); return; }
ni->ref_count = 1; ni->node_id = SIGNER_NODE; ni->ref_count = 1; ni->node_id = SIGNER_NODE;
if (with_ed25519_key) memcpy(ni->ed25519_public_key, g_sign_ed25519_pubkey, SC_PUBKEY_SIZE); if (with_ed25519_key) memcpy(ni->ed25519_public_key, g_sign_ed25519_pubkey, SC_PUBKEY_SIZE);

30
tests/test_ipv6_sockets.c

@ -34,8 +34,8 @@
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_lib.h" #include "../src/route_lib.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -140,7 +140,7 @@ static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* in
printf("FAIL [%s]: no bgp/local_node\n", name); printf("FAIL [%s]: no bgp/local_node\n", name);
return 0; return 0;
} }
struct NODEINFO* ni = inst->bgp->local_node->node; struct TOPO_NODE* ni = inst->bgp->local_node->node;
struct ETCP_SOCKET* es = inst->etcp_sockets; struct ETCP_SOCKET* es = inst->etcp_sockets;
int v6_sock_found = 0; int v6_sock_found = 0;
@ -148,35 +148,35 @@ static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* in
if (!v6_sock_found) { printf("FAIL [%s]: no AF_INET6 socket\n", name); return 0; } if (!v6_sock_found) { printf("FAIL [%s]: no AF_INET6 socket\n", name); return 0; }
printf("PASS [%s]: AF_INET6 socket exists\n", name); printf("PASS [%s]: AF_INET6 socket exists\n", name);
int v6s = ni_list_count((struct _ni_head*)ni->v6_sock_meta); int v6s = topo_list_count((struct _topo_head*)ni->v6_sock_meta);
if (v6s != expect_socks) { printf("FAIL [%s]: v6_socks=%d expected=%d\n", name, v6s, expect_socks); return 0; } if (v6s != expect_socks) { printf("FAIL [%s]: v6_socks=%d expected=%d\n", name, v6s, expect_socks); return 0; }
printf("PASS [%s]: v6_sockets=%d\n", name, v6s); printf("PASS [%s]: v6_sockets=%d\n", name, v6s);
int v6a = ni_list_count((struct _ni_head*)ni->v6_addrs); int v6a = topo_list_count((struct _topo_head*)ni->v6_addrs);
if (v6a != expect_addrs) { printf("FAIL [%s]: v6_addrs=%d expected=%d\n", name, v6a, expect_addrs); return 0; } if (v6a != expect_addrs) { printf("FAIL [%s]: v6_addrs=%d expected=%d\n", name, v6a, expect_addrs); return 0; }
printf("PASS [%s]: v6_addrs=%d\n", name, v6a); printf("PASS [%s]: v6_addrs=%d\n", name, v6a);
int v6sub = inst->bgp->local_node->routes ? ni_list_count((struct _ni_head*)inst->bgp->local_node->routes->v6_subnets) : 0; int v6sub = inst->bgp->local_node->subnets ? topo_list_count((struct _topo_head*)inst->bgp->local_node->subnets->v6_subnets) : 0;
if (v6sub != expect_subnets) { printf("FAIL [%s]: v6_subnets=%d expected=%d\n", name, v6sub, expect_subnets); return 0; } if (v6sub != expect_subnets) { printf("FAIL [%s]: v6_subnets=%d expected=%d\n", name, v6sub, expect_subnets); return 0; }
printf("PASS [%s]: v6_subnets=%d\n", name, v6sub); printf("PASS [%s]: v6_subnets=%d\n", name, v6sub);
{ const struct NI_IPV6_SOCKET_META* m = ni->v6_sock_meta; int i = 0; { const struct TOPO_SOCKMETA6* m = ni->v6_sock_meta; int i = 0;
while (m) { while (m) {
if (m->config_type != CFG_SERVER_TYPE_PUBLIC) { printf("FAIL [%s]: v6 socket meta[%d] config_type=%d expected=%d\n", name, i, m->config_type, CFG_SERVER_TYPE_PUBLIC); return 0; } if (m->config_type != CFG_SERVER_TYPE_PUBLIC) { printf("FAIL [%s]: v6 socket meta[%d] config_type=%d expected=%d\n", name, i, m->config_type, CFG_SERVER_TYPE_PUBLIC); return 0; }
printf("PASS [%s]: v6 socket meta[%d] id=%d config=%d nat=%d\n", name, i, m->id, m->config_type, m->nat_type); printf("PASS [%s]: v6 socket meta[%d] id=%d config=%d nat=%d\n", name, i, m->id, m->config_type, m->nat_type);
i++; m = m->next; i++; m = m->next;
} }
} }
{ const struct NI_IPV6_ADDR* a = ni->v6_addrs; int i = 0; { const struct TOPO_ADDR6* a = ni->v6_addrs; int i = 0;
while (a) { while (a) {
if (a->port == 0) { printf("FAIL [%s]: v6 addr port=0\n", name); return 0; } if (a->port == 0) { printf("FAIL [%s]: v6 addr port=0\n", name); return 0; }
if (a->type != ADDR_TYPE_INTERFACE) { printf("FAIL [%s]: v6 addr[%d] type=%d expected=%d(INTERFACE)\n", name, i, a->type, ADDR_TYPE_INTERFACE); return 0; } if (a->type != TOPO_ADDR_INTERFACE) { printf("FAIL [%s]: v6 addr[%d] type=%d expected=%d(INTERFACE)\n", name, i, a->type, TOPO_ADDR_INTERFACE); return 0; }
printf("PASS [%s]: v6 addr[%d] port=%d type=%d socket_id=%d\n", name, i, a->port, a->type, a->socket_id); printf("PASS [%s]: v6 addr[%d] port=%d type=%d socket_id=%d\n", name, i, a->port, a->type, a->socket_id);
i++; a = a->next; i++; a = a->next;
} }
} }
if (expect_subnets > 0 && inst->bgp->local_node->routes) { if (expect_subnets > 0 && inst->bgp->local_node->subnets) {
const struct NI_IPV6_SUBNET* subs = inst->bgp->local_node->routes->v6_subnets; const struct TOPO_SUBNET6* subs = inst->bgp->local_node->subnets->v6_subnets;
if (subs) { if (subs) {
uint8_t expected_sub[16] = {0x20,0x01,0x0d,0xb8,0x00,0x01,0,0,0,0,0,0,0,0,0,0}; uint8_t expected_sub[16] = {0x20,0x01,0x0d,0xb8,0x00,0x01,0,0,0,0,0,0,0,0,0,0};
if (memcmp(subs->addr, expected_sub, 16) != 0) { printf("FAIL [%s]: v6 subnet != 2001:db8:1::/48\n", name); return 0; } if (memcmp(subs->addr, expected_sub, 16) != 0) { printf("FAIL [%s]: v6 subnet != 2001:db8:1::/48\n", name); return 0; }
@ -189,17 +189,17 @@ static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* in
static int verify_remote_v6_nodeinfo(const char* name, struct UTUN_INSTANCE* inst, uint64_t peer_node_id) { static int verify_remote_v6_nodeinfo(const char* name, struct UTUN_INSTANCE* inst, uint64_t peer_node_id) {
if (!inst || !inst->bgp) { printf("FAIL [%s]: no bgp\n", name); return 0; } if (!inst || !inst->bgp) { printf("FAIL [%s]: no bgp\n", name); return 0; }
struct NODEINFO_Q* nq = nodeinfo_find_by_id(inst->bgp, peer_node_id); struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, peer_node_id);
if (!nq || !nq->node) { printf("FAIL [%s]: remote node %016llx not found\n", name, (unsigned long long)peer_node_id); return 0; } if (!nq || !nq->node) { printf("FAIL [%s]: remote node %016llx not found\n", name, (unsigned long long)peer_node_id); return 0; }
printf("PASS [%s]: remote node %016llx found\n", name, (unsigned long long)peer_node_id); printf("PASS [%s]: remote node %016llx found\n", name, (unsigned long long)peer_node_id);
if (!nq->node->v6_sock_meta) { printf("FAIL [%s]: remote node has no v6 sockets\n", name); return 0; } if (!nq->node->v6_sock_meta) { printf("FAIL [%s]: remote node has no v6 sockets\n", name); return 0; }
printf("PASS [%s]: remote node v6_sockets=%d\n", name, ni_list_count((struct _ni_head*)nq->node->v6_sock_meta)); printf("PASS [%s]: remote node v6_sockets=%d\n", name, topo_list_count((struct _topo_head*)nq->node->v6_sock_meta));
if (!nq->node->v6_addrs) { printf("FAIL [%s]: remote node has no v6 addrs\n", name); return 0; } if (!nq->node->v6_addrs) { printf("FAIL [%s]: remote node has no v6 addrs\n", name); return 0; }
printf("PASS [%s]: remote node v6_addrs=%d\n", name, ni_list_count((struct _ni_head*)nq->node->v6_addrs)); printf("PASS [%s]: remote node v6_addrs=%d\n", name, topo_list_count((struct _topo_head*)nq->node->v6_addrs));
const struct NI_IPV6_ADDR* a = nq->node->v6_addrs; const struct TOPO_ADDR6* a = nq->node->v6_addrs;
if (a) { if (a) {
uint8_t loopback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; uint8_t loopback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
if (memcmp(a->addr, loopback, 16) != 0) { printf("FAIL [%s]: remote v6 addr not ::1\n", name); return 0; } if (memcmp(a->addr, loopback, 16) != 0) { printf("FAIL [%s]: remote v6 addr not ::1\n", name); return 0; }

32
tests/test_nat_detection.c

@ -21,9 +21,9 @@
#include "../src/config_updater.h" #include "../src/config_updater.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_ping.h" #include "../src/route_ping.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
@ -216,7 +216,7 @@ int main(void) {
} }
// Разрешаем NAT check для localhost (для теста) // Разрешаем NAT check для localhost (для теста)
if (inst_s->bgp) route_bgp_set_nat_check_local(inst_s->bgp, 1); if (inst_s->bgp) topo_bgp_set_nat_check_local(inst_s->bgp, 1);
if (init_connections(inst_s) != 0 || init_connections(inst_c1) != 0 || init_connections(inst_c2) != 0) { if (init_connections(inst_s) != 0 || init_connections(inst_c1) != 0 || init_connections(inst_c2) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to init connections"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to init connections");
@ -244,16 +244,16 @@ int main(void) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for BGP exchange (S learns C1 and C2)..."); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for BGP exchange (S learns C1 and C2)...");
int bgp_wait_cycles = 0; int bgp_wait_cycles = 0;
while (!test_timed_out && bgp_wait_cycles < 500) { while (!test_timed_out && bgp_wait_cycles < 500) {
if (inst_s->bgp && nodeinfo_find_by_id(inst_s->bgp, NODE_ID_C1) != NULL && if (inst_s->bgp && topo_node_find_by_id(inst_s->bgp, NODE_ID_C1) != NULL &&
nodeinfo_find_by_id(inst_s->bgp, NODE_ID_C2) != NULL) { topo_node_find_by_id(inst_s->bgp, NODE_ID_C2) != NULL) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "S learned about C1 and C2"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "S learned about C1 and C2");
break; break;
} }
uasync_poll(ua, 10); uasync_poll(ua, 10);
bgp_wait_cycles++; bgp_wait_cycles++;
} }
if (!inst_s->bgp || nodeinfo_find_by_id(inst_s->bgp, NODE_ID_C1) == NULL || if (!inst_s->bgp || topo_node_find_by_id(inst_s->bgp, NODE_ID_C1) == NULL ||
nodeinfo_find_by_id(inst_s->bgp, NODE_ID_C2) == NULL) { topo_node_find_by_id(inst_s->bgp, NODE_ID_C2) == NULL) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "S did not learn about C1/C2 in time"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "S did not learn about C1/C2 in time");
goto cleanup; goto cleanup;
} }
@ -313,9 +313,9 @@ int main(void) {
} }
// 5. Verify all NAT fields on server // 5. Verify all NAT fields on server
struct NODEINFO_Q* node_c1 = nodeinfo_find_by_id(inst_s->bgp, NODE_ID_C1); struct TOPO_NODEQ* node_c1 = topo_node_find_by_id(inst_s->bgp, NODE_ID_C1);
if (!node_c1) { if (!node_c1) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NODEINFO_Q for C1 disappeared"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "TOPO_NODEQ for C1 disappeared");
goto cleanup; goto cleanup;
} }
if (link_sc1->nat_check_status != NAT_CHECK_EIM) { if (link_sc1->nat_check_status != NAT_CHECK_EIM) {
@ -363,7 +363,7 @@ int main(void) {
// Verify local_node socket update on C1 (received NAT_INFO updated nodeinfo) // Verify local_node socket update on C1 (received NAT_INFO updated nodeinfo)
if (inst_c1->bgp && inst_c1->bgp->local_node && inst_c1->bgp->local_node->node) { if (inst_c1->bgp && inst_c1->bgp->local_node && inst_c1->bgp->local_node->node) {
int found = 0; int found = 0;
for (const struct NI_IPV4_SOCKET_META* m = inst_c1->bgp->local_node->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = inst_c1->bgp->local_node->node->v4_sock_meta; m; m = m->next) {
if (m->id == sock_c1->sock_id) { if (m->id == sock_c1->sock_id) {
if (m->nat_type != NAT_VERIFIED_EIM) { if (m->nat_type != NAT_VERIFIED_EIM) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: local_node socket meta not updated on C1: nat_type=%u expected=%u", m->nat_type, NAT_VERIFIED_EIM); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: local_node socket meta not updated on C1: nat_type=%u expected=%u", m->nat_type, NAT_VERIFIED_EIM);
@ -375,8 +375,8 @@ int main(void) {
if (!found) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: socket not found in local_node meta on C1"); goto cleanup; } if (!found) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: socket not found in local_node meta on C1"); goto cleanup; }
// Verify NAT addr in flat address list // Verify NAT addr in flat address list
int nat_found = 0; int nat_found = 0;
for (const struct NI_IPV4_ADDR* a = inst_c1->bgp->local_node->node->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = inst_c1->bgp->local_node->node->v4_addrs; a; a = a->next) {
if (a->type == ADDR_TYPE_NAT && a->socket_id == sock_c1->sock_id) { if (a->type == TOPO_ADDR_NAT && a->socket_id == sock_c1->sock_id) {
uint32_t addr_ip; memcpy(&addr_ip, a->addr, 4); uint32_t addr_ip; memcpy(&addr_ip, a->addr, 4);
if (addr_ip != link_sc1->nat_ip || a->port != link_sc1->nat_port) { if (addr_ip != link_sc1->nat_ip || a->port != link_sc1->nat_port) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: NAT addr mismatch in local_node: addr=%08x nat_ip=%08x port=%u nat_port=%u", DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: NAT addr mismatch in local_node: addr=%08x nat_ip=%08x port=%u nat_port=%u",
@ -395,9 +395,9 @@ int main(void) {
bgp_wait_cycles = 0; bgp_wait_cycles = 0;
int c2_verified_nat = 0; int c2_verified_nat = 0;
while (!test_timed_out && bgp_wait_cycles < 500) { while (!test_timed_out && bgp_wait_cycles < 500) {
struct NODEINFO_Q* node_c1_on_c2 = inst_c2->bgp ? nodeinfo_find_by_id(inst_c2->bgp, NODE_ID_C1) : NULL; struct TOPO_NODEQ* node_c1_on_c2 = inst_c2->bgp ? topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) : NULL;
if (node_c1_on_c2 && node_c1_on_c2->node) { if (node_c1_on_c2 && node_c1_on_c2->node) {
for (const struct NI_IPV4_SOCKET_META* m = node_c1_on_c2->node->v4_sock_meta; m; m = m->next) { for (const struct TOPO_SOCKMETA4* m = node_c1_on_c2->node->v4_sock_meta; m; m = m->next) {
if (m->nat_type == NAT_VERIFIED_EIM) { c2_verified_nat = 1; break; } if (m->nat_type == NAT_VERIFIED_EIM) { c2_verified_nat = 1; break; }
} }
if (c2_verified_nat) break; if (c2_verified_nat) break;
@ -459,14 +459,14 @@ int main(void) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for C2 to learn C1 nodeinfo..."); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for C2 to learn C1 nodeinfo...");
bgp_wait_cycles = 0; bgp_wait_cycles = 0;
while (!test_timed_out && bgp_wait_cycles < 500) { while (!test_timed_out && bgp_wait_cycles < 500) {
if (inst_c2->bgp && nodeinfo_find_by_id(inst_c2->bgp, NODE_ID_C1) != NULL) { if (inst_c2->bgp && topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) != NULL) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "C2 learned C1 nodeinfo"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "C2 learned C1 nodeinfo");
break; break;
} }
uasync_poll(ua, 10); uasync_poll(ua, 10);
bgp_wait_cycles++; bgp_wait_cycles++;
} }
if (!inst_c2->bgp || nodeinfo_find_by_id(inst_c2->bgp, NODE_ID_C1) == NULL) { if (!inst_c2->bgp || topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) == NULL) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: C2 did not learn C1 nodeinfo in time"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: C2 did not learn C1 nodeinfo in time");
goto cleanup; goto cleanup;
} }

6
tests/test_nat_transport.c

@ -21,7 +21,7 @@
#include "../src/config_updater.h" #include "../src/config_updater.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/nat_transport.h" #include "../src/nat_transport.h"
#include "../src/eim_nat.h" #include "../src/eim_nat.h"
@ -565,8 +565,8 @@ int main(void) {
DEBUG_INFO(DEBUG_CATEGORY_NAT, "Waiting for BGP..."); DEBUG_INFO(DEBUG_CATEGORY_NAT, "Waiting for BGP...");
int bgp_cycles = 0; int bgp_cycles = 0;
while (!test_timed_out && bgp_cycles < 500) { while (!test_timed_out && bgp_cycles < 500) {
if (inst_provider->bgp && nodeinfo_find_by_id(inst_provider->bgp, NODE_ID_CLIENT) && if (inst_provider->bgp && topo_node_find_by_id(inst_provider->bgp, NODE_ID_CLIENT) &&
inst_client->bgp && nodeinfo_find_by_id(inst_client->bgp, NODE_ID_PROVIDER)) { inst_client->bgp && topo_node_find_by_id(inst_client->bgp, NODE_ID_PROVIDER)) {
DEBUG_INFO(DEBUG_CATEGORY_NAT, "BGP exchanged"); DEBUG_INFO(DEBUG_CATEGORY_NAT, "BGP exchanged");
break; break;
} }

54
tests/test_route6_lib.c

@ -3,7 +3,7 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <assert.h> #include <assert.h>
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/route6_lib.h" #include "../src/route6_lib.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
@ -19,20 +19,20 @@ static int tests_run = 0;
/* ──── helpers ──── */ /* ──── helpers ──── */
static struct NODEINFO_Q *make_node(uint64_t node_id, static struct TOPO_NODEQ *make_node(uint64_t node_id,
const uint8_t addrs[][16], const uint8_t addrs[][16],
const uint8_t *plens, int N) { const uint8_t *plens, int N) {
struct NODEINFO_Q *nq = u_calloc(1, sizeof(*nq)); struct TOPO_NODEQ *nq = u_calloc(1, sizeof(*nq));
struct NODEINFO *ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE *ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; } if (!nq || !ni) { u_free(nq); u_free(ni); return NULL; }
ni->ref_count = 1; ni->node_id = node_id; ni->ref_count = 1; ni->node_id = node_id;
nq->node = ni; nq->hash_node_id = node_id; nq->node = ni; nq->hash_node_id = node_id;
if (N > 0) { if (N > 0) {
struct NODEINFO_ROUTES *r = u_calloc(1, sizeof(struct NODEINFO_ROUTES)); struct TOPO_NODESUBNETS *r = u_calloc(1, sizeof(struct TOPO_NODESUBNETS));
nq->routes = r; nq->subnets = r;
struct NI_IPV6_SUBNET *head = NULL; struct TOPO_SUBNET6 *head = NULL;
for (int i = N-1; i >= 0; i--) { for (int i = N-1; i >= 0; i--) {
struct NI_IPV6_SUBNET *s = u_calloc(1, sizeof(struct NI_IPV6_SUBNET)); struct TOPO_SUBNET6 *s = u_calloc(1, sizeof(struct TOPO_SUBNET6));
memcpy(s->addr, addrs[i], 16); s->prefix_length = plens[i]; memcpy(s->addr, addrs[i], 16); s->prefix_length = plens[i];
s->next = head; head = s; s->next = head; head = s;
} }
@ -41,12 +41,12 @@ static struct NODEINFO_Q *make_node(uint64_t node_id,
return nq; return nq;
} }
static void free_node(struct NODEINFO_Q *nq) { static void free_node(struct TOPO_NODEQ *nq) {
if (nq) { if (nq) {
if (nq->routes) { if (nq->subnets) {
struct NI_IPV6_SUBNET *s = nq->routes->v6_subnets; struct TOPO_SUBNET6 *s = nq->subnets->v6_subnets;
while (s) { struct NI_IPV6_SUBNET *next = s->next; u_free(s); s = next; } while (s) { struct TOPO_SUBNET6 *next = s->next; u_free(s); s = next; }
u_free(nq->routes); u_free(nq->subnets);
} }
if (nq->node) u_free(nq->node); if (nq->node) u_free(nq->node);
u_free(nq); u_free(nq);
@ -69,7 +69,7 @@ static void test_insert_null_args(void) {
assert(t != NULL); assert(t != NULL);
assert(route6_insert(NULL, NULL) == false); assert(route6_insert(NULL, NULL) == false);
assert(route6_insert(t, NULL) == false); assert(route6_insert(t, NULL) == false);
assert(route6_insert(NULL, t ? (struct NODEINFO_Q*)(uintptr_t)t : NULL) == false); assert(route6_insert(NULL, t ? (struct TOPO_NODEQ*)(uintptr_t)t : NULL) == false);
route6_table_destroy(t); route6_table_destroy(t);
uasync_destroy(ua, 0); uasync_destroy(ua, 0);
} }
@ -81,7 +81,7 @@ static void test_insert_zero_subnets(void) {
int addr[16] = {0}; int addr[16] = {0};
uint8_t zero_plen = 0; uint8_t zero_plen = 0;
struct NODEINFO_Q *nq = make_node(1, (const uint8_t(*)[16])addr, &zero_plen, 0); struct TOPO_NODEQ *nq = make_node(1, (const uint8_t(*)[16])addr, &zero_plen, 0);
assert(route6_insert(t, nq) == false); assert(route6_insert(t, nq) == false);
const uint8_t any[16] = {0}; const uint8_t any[16] = {0};
@ -99,7 +99,7 @@ static void test_insert_duplicate(void) {
uint8_t addr[16] = {0xfd, 0}; uint8_t addr[16] = {0xfd, 0};
uint8_t plen = 64; uint8_t plen = 64;
struct NODEINFO_Q *nq = make_node(10, &addr, &plen, 1); struct TOPO_NODEQ *nq = make_node(10, &addr, &plen, 1);
assert(route6_insert(t, nq) == true); assert(route6_insert(t, nq) == true);
assert(route6_insert(t, nq) == true); // re-insert should not crash assert(route6_insert(t, nq) == true); // re-insert should not crash
@ -117,7 +117,7 @@ static void test_insert_delete_reinsert(void) {
uint8_t addrs[2][16] = {{0xfd, 1}, {0xfd, 2}}; uint8_t addrs[2][16] = {{0xfd, 1}, {0xfd, 2}};
uint8_t plens[2] = {64, 64}; uint8_t plens[2] = {64, 64};
struct NODEINFO_Q *nq = make_node(20, addrs, plens, 2); struct TOPO_NODEQ *nq = make_node(20, addrs, plens, 2);
assert(route6_insert(t, nq) == true); assert(route6_insert(t, nq) == true);
assert(route6_lookup(t, addrs[0]) != NULL); assert(route6_lookup(t, addrs[0]) != NULL);
@ -146,8 +146,8 @@ static void test_delete_nonexistent(void) {
uint8_t addr[16] = {0xfd, 10}; uint8_t addr[16] = {0xfd, 10};
uint8_t plen = 64; uint8_t plen = 64;
struct NODEINFO_Q *nq1 = make_node(1, &addr, &plen, 1); struct TOPO_NODEQ *nq1 = make_node(1, &addr, &plen, 1);
struct NODEINFO_Q *nq2 = make_node(2, &addr, &plen, 1); struct TOPO_NODEQ *nq2 = make_node(2, &addr, &plen, 1);
assert(route6_insert(t, nq1) == true); assert(route6_insert(t, nq1) == true);
route6_delete(t, nq2); // nq2 not in table — should not crash route6_delete(t, nq2); // nq2 not in table — should not crash
@ -165,7 +165,7 @@ static void test_delete_null_args(void) {
route6_delete(NULL, NULL); route6_delete(NULL, NULL);
route6_delete(t, NULL); route6_delete(t, NULL);
route6_delete(NULL, (struct NODEINFO_Q*)(uintptr_t)t); route6_delete(NULL, (struct TOPO_NODEQ*)(uintptr_t)t);
route6_table_destroy(t); route6_table_destroy(t);
uasync_destroy(ua, 0); uasync_destroy(ua, 0);
@ -178,7 +178,7 @@ static void test_delete_multi_subnet(void) {
uint8_t addrs[3][16] = {{0xfc, 1}, {0xfc, 2}, {0xfc, 3}}; uint8_t addrs[3][16] = {{0xfc, 1}, {0xfc, 2}, {0xfc, 3}};
uint8_t plens[3] = {48, 56, 64}; uint8_t plens[3] = {48, 56, 64};
struct NODEINFO_Q *nq = make_node(30, addrs, plens, 3); struct TOPO_NODEQ *nq = make_node(30, addrs, plens, 3);
assert(route6_insert(t, nq) == true); assert(route6_insert(t, nq) == true);
assert(route6_lookup(t, addrs[0]) != NULL); assert(route6_lookup(t, addrs[0]) != NULL);
@ -204,8 +204,8 @@ static void test_delete_one_of_two(void) {
uint8_t addr_a[16] = {0xfc, 0}; uint8_t addr_a[16] = {0xfc, 0};
uint8_t addr_b[16] = {0xfd, 0}; uint8_t addr_b[16] = {0xfd, 0};
uint8_t plen = 64; uint8_t plen = 64;
struct NODEINFO_Q *nqa = make_node(100, &addr_a, &plen, 1); struct TOPO_NODEQ *nqa = make_node(100, &addr_a, &plen, 1);
struct NODEINFO_Q *nqb = make_node(200, &addr_b, &plen, 1); struct TOPO_NODEQ *nqb = make_node(200, &addr_b, &plen, 1);
assert(route6_insert(t, nqa) == true); assert(route6_insert(t, nqa) == true);
assert(route6_insert(t, nqb) == true); assert(route6_insert(t, nqb) == true);
@ -240,7 +240,7 @@ static void test_lookup_returns_correct_data(void) {
uint8_t addr[16] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; uint8_t addr[16] = {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
uint8_t plen = 64; uint8_t plen = 64;
struct NODEINFO_Q *nq = make_node(42, &addr, &plen, 1); struct TOPO_NODEQ *nq = make_node(42, &addr, &plen, 1);
assert(route6_insert(t, nq) == true); assert(route6_insert(t, nq) == true);
const struct ROUTE6_DATA *rd = route6_lookup(t, addr); const struct ROUTE6_DATA *rd = route6_lookup(t, addr);
@ -301,7 +301,7 @@ static void test_stress(void) {
struct saved_route sr[MAX_SAVED]; struct saved_route sr[MAX_SAVED];
int nsr = 0; int nsr = 0;
struct NODEINFO_Q *nodes[STRESS_NODES + STRESS_OPS]; struct TOPO_NODEQ *nodes[STRESS_NODES + STRESS_OPS];
// create nodes with random subnets // create nodes with random subnets
int n_created = 0; int n_created = 0;
@ -392,7 +392,7 @@ static void test_stress(void) {
{ {
uint8_t addr[16] = {0xfc, 0}; uint8_t addr[16] = {0xfc, 0};
uint8_t plen = 64; uint8_t plen = 64;
struct NODEINFO_Q *ghost = make_node(999999, &addr, &plen, 1); struct TOPO_NODEQ *ghost = make_node(999999, &addr, &plen, 1);
route6_delete(t, ghost); // should no-op route6_delete(t, ghost); // should no-op
free_node(ghost); free_node(ghost);
} }
@ -401,7 +401,7 @@ static void test_stress(void) {
{ {
uint8_t addr[16] = {0}; uint8_t addr[16] = {0};
uint8_t zero_plen = 0; uint8_t zero_plen = 0;
struct NODEINFO_Q *z = make_node(777, (const uint8_t(*)[16])addr, &zero_plen, 0); struct TOPO_NODEQ *z = make_node(777, (const uint8_t(*)[16])addr, &zero_plen, 0);
assert(route6_insert(t, z) == false); assert(route6_insert(t, z) == false);
free_node(z); free_node(z);
} }

36
tests/test_route_lib.c

@ -2,7 +2,7 @@
* FULL REFACTORED TEST for new NODEINFO-based routing system * FULL REFACTORED TEST for new NODEINFO-based routing system
* *
* Tests: * Tests:
* - NODEINFO_Q creation and insertion * - TOPO_NODEQ creation and insertion
* - paths management (add/remove) * - paths management (add/remove)
* - versioning (ver field) * - versioning (ver field)
* - WITHDRAW when no paths left * - WITHDRAW when no paths left
@ -20,7 +20,7 @@
#include <time.h> #include <time.h>
//#include "../src/utun_instance.h" //#include "../src/utun_instance.h"
#include "route_node.h" #include "topo_node.h"
#include "route_lib.h" #include "route_lib.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
@ -37,14 +37,14 @@ struct ETCP_CONN {
struct UTUN_INSTANCE { struct UTUN_INSTANCE {
uint64_t node_id; uint64_t node_id;
struct ROUTE_TABLE* rt; struct ROUTE_TABLE* rt;
struct ROUTE_BGP* bgp; struct TOPO_BGP* bgp;
}; };
/* Helper to create test NODEINFO_Q with subnet in linked list */ /* Helper to create test TOPO_NODEQ with subnet in linked list */
static struct NODEINFO_Q* create_test_node(uint64_t node_id, uint8_t ver, uint32_t subnet_net, uint8_t prefix) { static struct TOPO_NODEQ* create_test_node(uint64_t node_id, uint8_t ver, uint32_t subnet_net, uint8_t prefix) {
struct NODEINFO_Q* nq = u_calloc(1, sizeof(struct NODEINFO_Q)); struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ));
if (!nq) return NULL; if (!nq) return NULL;
struct NODEINFO* ni = u_calloc(1, sizeof(struct NODEINFO)); struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE));
if (!ni) { u_free(nq); return NULL; } if (!ni) { u_free(nq); return NULL; }
ni->ref_count = 1; ni->ref_count = 1;
ni->node_id = htobe64(node_id); ni->node_id = htobe64(node_id);
@ -53,21 +53,21 @@ static struct NODEINFO_Q* create_test_node(uint64_t node_id, uint8_t ver, uint32
nq->hash_node_id = ni->node_id; nq->hash_node_id = ni->node_id;
nq->hop_count = 0; nq->hop_count = 0;
nq->paths = queue_new(NULL, 16, 0, 0, "test_paths"); nq->paths = queue_new(NULL, 16, 0, 0, "test_paths");
struct NODEINFO_ROUTES* r = u_calloc(1, sizeof(struct NODEINFO_ROUTES)); struct TOPO_NODESUBNETS* r = u_calloc(1, sizeof(struct TOPO_NODESUBNETS));
if (r) { if (r) {
struct NI_IPV4_SUBNET* sn = u_calloc(1, sizeof(struct NI_IPV4_SUBNET)); struct TOPO_SUBNET4* sn = u_calloc(1, sizeof(struct TOPO_SUBNET4));
uint32_t net = htonl(subnet_net); uint32_t net = htonl(subnet_net);
memcpy(sn->addr, &net, 4); sn->prefix_length = prefix; memcpy(sn->addr, &net, 4); sn->prefix_length = prefix;
r->v4_subnets = sn; r->v4_subnets = sn;
nq->routes = r; nq->subnets = r;
} }
return nq; return nq;
} }
static void free_test_node(struct NODEINFO_Q* nq) { static void free_test_node(struct TOPO_NODEQ* nq) {
if (nq) { if (nq) {
if (nq->paths) queue_free(nq->paths); if (nq->paths) queue_free(nq->paths);
if (nq->routes) { u_free(nq->routes->v4_subnets); u_free(nq->routes); } if (nq->subnets) { u_free(nq->subnets->v4_subnets); u_free(nq->subnets); }
if (nq->node) { u_free(nq->node->node_name); u_free(nq->node); } if (nq->node) { u_free(nq->node->node_name); u_free(nq->node); }
u_free(nq); u_free(nq);
} }
@ -118,9 +118,9 @@ static void test_table_create_destroy(void) {
} }
static void test_nodeinfo_insert(void) { static void test_nodeinfo_insert(void) {
TEST("NODEINFO_Q insert into routing table"); TEST("TOPO_NODEQ insert into routing table");
struct ROUTE_TABLE *t = route_table_create(); struct ROUTE_TABLE *t = route_table_create();
struct NODEINFO_Q* nq = create_test_node(0x12345678ULL, 1, 0x0a000000, 8); struct TOPO_NODEQ* nq = create_test_node(0x12345678ULL, 1, 0x0a000000, 8);
bool inserted = route_insert(t, nq); bool inserted = route_insert(t, nq);
ASSERT(inserted, "insert nodeinfo"); ASSERT(inserted, "insert nodeinfo");
@ -134,8 +134,8 @@ static void test_nodeinfo_insert(void) {
static void test_versioning(void) { static void test_versioning(void) {
TEST("NODEINFO multiple nodes"); TEST("NODEINFO multiple nodes");
struct ROUTE_TABLE *t = route_table_create(); struct ROUTE_TABLE *t = route_table_create();
struct NODEINFO_Q* nq1 = create_test_node(0x1111ULL, 5, 0x0a000000, 8); struct TOPO_NODEQ* nq1 = create_test_node(0x1111ULL, 5, 0x0a000000, 8);
struct NODEINFO_Q* nq2 = create_test_node(0x2222ULL, 1, 0xac100000, 12); struct TOPO_NODEQ* nq2 = create_test_node(0x2222ULL, 1, 0xac100000, 12);
route_insert(t, nq1); route_insert(t, nq1);
bool ins2 = route_insert(t, nq2); bool ins2 = route_insert(t, nq2);
@ -157,7 +157,7 @@ static void test_performance_1000_nodes(void) {
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
uint32_t sub = 0x0a000000 + (i * 0x100); /* distinct 10.0.x.0/24 to avoid overlap */ uint32_t sub = 0x0a000000 + (i * 0x100); /* distinct 10.0.x.0/24 to avoid overlap */
struct NODEINFO_Q* nq = create_test_node(0x1000000ULL + i, 1, sub, 24); struct TOPO_NODEQ* nq = create_test_node(0x1000000ULL + i, 1, sub, 24);
route_insert(t, nq); route_insert(t, nq);
/* note: nq not freed here (table holds ref to it), freed in test cleanup if needed */ /* note: nq not freed here (table holds ref to it), freed in test cleanup if needed */
} }
@ -175,7 +175,7 @@ static void test_performance_1000_nodes(void) {
static void test_destroy_refcount(void) { static void test_destroy_refcount(void) {
TEST("destroy with multiple paths (ref_count safety)"); TEST("destroy with multiple paths (ref_count safety)");
struct ROUTE_TABLE *t = route_table_create(); struct ROUTE_TABLE *t = route_table_create();
/* NODEINFO_Q memory managed externally, table only holds pointers */ /* TOPO_NODEQ memory managed externally, table only holds pointers */
route_table_destroy(t); route_table_destroy(t);
PASS(); PASS();
} }

10
tests/test_route_ping.c

@ -21,7 +21,7 @@
#include "../src/config_updater.h" #include "../src/config_updater.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../src/routing.h" #include "../src/routing.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_ping.h" #include "../src/route_ping.h"
#include "../src/tun_if.h" #include "../src/tun_if.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
@ -248,14 +248,14 @@ int main(void) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for BGP exchange (B learns C)..."); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for BGP exchange (B learns C)...");
int bgp_wait_cycles = 0; int bgp_wait_cycles = 0;
while (!test_timed_out && bgp_wait_cycles < 500) { while (!test_timed_out && bgp_wait_cycles < 500) {
if (inst_b->bgp && nodeinfo_find_by_id(inst_b->bgp, NODE_ID_C) != NULL) { if (inst_b->bgp && topo_node_find_by_id(inst_b->bgp, NODE_ID_C) != NULL) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "B learned about C"); DEBUG_INFO(DEBUG_CATEGORY_BGP, "B learned about C");
break; break;
} }
uasync_poll(ua, 10); uasync_poll(ua, 10);
bgp_wait_cycles++; bgp_wait_cycles++;
} }
if (!inst_b->bgp || nodeinfo_find_by_id(inst_b->bgp, NODE_ID_C) == NULL) { if (!inst_b->bgp || topo_node_find_by_id(inst_b->bgp, NODE_ID_C) == NULL) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "B did not learn about C in time"); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "B did not learn about C in time");
goto cleanup; goto cleanup;
} }
@ -271,9 +271,9 @@ int main(void) {
/* addr[] в network byte order, port в host byte order */ /* addr[] в network byte order, port в host byte order */
uint32_t target_ip = 0; uint32_t target_ip = 0;
uint16_t target_port = 0; uint16_t target_port = 0;
struct NODEINFO_Q* nq = inst_b->bgp ? nodeinfo_find_by_id(inst_b->bgp, NODE_ID_C) : NULL; struct TOPO_NODEQ* nq = inst_b->bgp ? topo_node_find_by_id(inst_b->bgp, NODE_ID_C) : NULL;
if (nq && nq->node) { if (nq && nq->node) {
const struct NI_IPV4_ADDR* a = nq->node->v4_addrs; const struct TOPO_ADDR4* a = nq->node->v4_addrs;
if (a) { if (a) {
memcpy(&target_ip, a->addr, 4); memcpy(&target_ip, a->addr, 4);
target_port = a->port; target_port = a->port;

6
tests/test_stcp_traffic.c

@ -4,8 +4,8 @@
#include "../src/etcp.h" #include "../src/etcp.h"
#include "../src/secure_channel.h" #include "../src/secure_channel.h"
#include "../src/etcp_connections.h" #include "../src/etcp_connections.h"
#include "../src/route_bgp.h" #include "../src/topo_bgp.h"
#include "../src/route_node.h" #include "../src/topo_node.h"
#include "../src/utun_instance.h" #include "../src/utun_instance.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -167,7 +167,7 @@ int main(void) {
TASSERT(etcp_bind(srv_inst, 1, srv_recv_cb) >= 0); TASSERT(etcp_bind(srv_inst, 1, srv_recv_cb) >= 0);
TASSERT(etcp_bind(cli_inst, 2, cli_recv_cb) >= 0); TASSERT(etcp_bind(cli_inst, 2, cli_recv_cb) >= 0);
struct NODEINFO_Q *srv_node = srv_inst->bgp ? srv_inst->bgp->local_node : NULL; struct TOPO_NODEQ *srv_node = srv_inst->bgp ? srv_inst->bgp->local_node : NULL;
TASSERT(srv_node); TASSERT(srv_node);
// Increase timeout for TCP STCP handshake // Increase timeout for TCP STCP handshake
cli_inst->etcp_connect_timeout_tb = 100000; // 10 seconds cli_inst->etcp_connect_timeout_tb = 100000; // 10 seconds

6
tools/chatgui/libutun/CMakeLists.txt

@ -56,10 +56,10 @@ set(UTUN_COMMON_SOURCES
${SRC_DIR}/config_updater.c ${SRC_DIR}/config_updater.c
${SRC_DIR}/route_lib.c ${SRC_DIR}/route_lib.c
${SRC_DIR}/route6_lib.c ${SRC_DIR}/route6_lib.c
${SRC_DIR}/route_bgp.c ${SRC_DIR}/topo_bgp.c
${SRC_DIR}/route_ping.c ${SRC_DIR}/route_ping.c
${SRC_DIR}/route_node.c ${SRC_DIR}/topo_node.c
${SRC_DIR}/route_node_lmdb.c ${SRC_DIR}/topo_node_lmdb.c
${SRC_DIR}/route_connectivity.c ${SRC_DIR}/route_connectivity.c
${SRC_DIR}/conn_mgr.c ${SRC_DIR}/conn_mgr.c
${TRANSPORT_DIR}/db_sync_stub.c ${TRANSPORT_DIR}/db_sync_stub.c

6
tools/chatgui/transport/chat_core.c

@ -12,8 +12,8 @@
#include "../../../src/utun_instance.h" #include "../../../src/utun_instance.h"
#include "../../../src/etcp_router.h" #include "../../../src/etcp_router.h"
#include "../../../src/etcp_api.h" #include "../../../src/etcp_api.h"
#include "../../../src/route_bgp.h" #include "../../../src/topo_bgp.h"
#include "../../../src/route_node.h" #include "../../../src/topo_node.h"
#include "../../../src/conn_mgr.h" #include "../../../src/conn_mgr.h"
#include "../../../src/secure_channel.h" #include "../../../src/secure_channel.h"
#include "../../../lib/u_async.h" #include "../../../lib/u_async.h"
@ -625,7 +625,7 @@ void chat_core_connect_from_invite(struct chat_invite* inv) {
} }
uint64_t node_id = inv->node_id; uint64_t node_id = inv->node_id;
struct ROUTE_BGP* bgp = g_cc.inst->bgp; struct TOPO_BGP* bgp = g_cc.inst->bgp;
if (nodeinfo_find_by_id(bgp, node_id)) { if (nodeinfo_find_by_id(bgp, node_id)) {
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: node 0x%016llx already in BGP, connecting", DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: node 0x%016llx already in BGP, connecting",

4
tools/etcpmon/etcpmon_protocol.h

@ -294,8 +294,8 @@ struct etcpmon_tun_metrics {
uint32_t rt_count; /* Total routes in table */ uint32_t rt_count; /* Total routes in table */
uint32_t rt_local; /* Local routes */ uint32_t rt_local; /* Local routes */
uint32_t rt_learned; /* Learned routes (BGP) */ uint32_t rt_learned; /* Learned routes (BGP) */
uint32_t rt_bgp_senders; /* BGP senders_list count (ROUTE_BGP) */ uint32_t rt_bgp_senders; /* BGP senders_list count (TOPO_BGP) */
uint32_t rt_bgp_nodes; /* BGP nodes count (ROUTE_BGP) */ uint32_t rt_bgp_nodes; /* BGP nodes count (TOPO_BGP) */
}; };
/* Router congestion metrics — aggregated over all router_conns */ /* Router congestion metrics — aggregated over all router_conns */

Loading…
Cancel
Save