diff --git a/src/Makefile.am b/src/Makefile.am index 9b94a1ba..bdbf0a55 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ utun_CORE_SOURCES = \ config_updater.c \ route_lib.c \ route6_lib.c \ - topo_bgp.c \ + topo_group.c \ route_ping.c \ topo_node.c \ topo_node_lmdb.c \ @@ -62,7 +62,7 @@ libutun_a_SOURCES = \ config_updater.c \ route_lib.c \ route6_lib.c \ - topo_bgp.c \ + topo_group.c \ route_ping.c \ topo_node.c \ topo_node_lmdb.c \ diff --git a/src/conn_mgr.c b/src/conn_mgr.c index d69619d2..af6db62a 100644 --- a/src/conn_mgr.c +++ b/src/conn_mgr.c @@ -18,7 +18,7 @@ #include "config_parser.h" #include "secure_channel.h" #include "topo_node.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_ping.h" #include "route_connectivity.h" #include "conn_mgr.h" @@ -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) { - struct TOPO_BGP* bgp = entry->mgr->instance->bgp; - if (!bgp) return; - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, entry->node_id); + struct TOPO_GROUP* group = topo_groups_get_default(entry->mgr->instance->topo_groups); + if (!group) return; + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, entry->node_id); if (!nq) return; nq->conn_mgr_type = entry->conn_type; 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) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), node_id); if (!nq) return; nq->conn_mgr_type = CONN_TYPE_NONE; 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, conn_mgr_connect_callback_t cb, void* cb_arg) { if (!mgr) return CONN_MGR_ERR_INTERNAL; - 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; } - struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, node_id); + struct TOPO_GROUP* group = topo_groups_get_default(mgr->instance->topo_groups); + if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "conn_mgr_connect: BGP not initialized"); return CONN_MGR_ERR_INTERNAL; } + struct TOPO_NODEQ* target = topo_node_find_by_id(group, 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; } struct CONN_MGR_ENTRY* entry = cm_find_entry(mgr, node_id); 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; } return CONN_MGR_OK; } - struct ETCP_CONN* existing = topo_bgp_find_conn_for_node(bgp, node_id); + struct ETCP_CONN* existing = topo_group_find_conn_for_node(group, node_id); if (existing && existing->peer_node_id == node_id && existing->links) { struct ETCP_LINK* l = existing->links; while (l) { if (l->link_status && l->initialized) break; l = l->next; } @@ -223,7 +223,7 @@ int conn_mgr_connect_node(struct CONN_MGR* mgr, uint64_t node_id, uint32_t idle_ entry->main.phase = 0; entry->main.timer = NULL; entry->main.request_id = 0; - int has_our_local = cm_has_local_addr(bgp->local_node); + int has_our_local = cm_has_local_addr(group->local_node); int has_target_local = cm_has_local_addr(target); if (has_our_local && has_target_local) { entry->local_scan_state = CM_TRY_PENDING; cm_start_local_scan(entry); } entry->main_connect_state = CM_TRY_PENDING; @@ -271,11 +271,11 @@ 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) { if (!mgr || !nodeinfo_data || len < sizeof(struct TOPO_NODE)) return CONN_MGR_ERR_INTERNAL; - struct TOPO_BGP* bgp = mgr->instance->bgp; - if (!bgp) return CONN_MGR_ERR_INTERNAL; + struct TOPO_GROUP* group = topo_groups_get_default(mgr->instance->topo_groups); + if (!group) return CONN_MGR_ERR_INTERNAL; const struct TOPO_NODE* src = (const struct TOPO_NODE*)nodeinfo_data; uint64_t node_id = src->node_id; - struct TOPO_NODEQ* existing = topo_node_find_by_id(bgp, node_id); + struct TOPO_NODEQ* existing = topo_node_find_by_id(group, 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; } struct TOPO_NODE* ni = u_calloc(1, sizeof(struct TOPO_NODE)); if (!ni) return CONN_MGR_ERR_INTERNAL; @@ -287,7 +287,7 @@ int conn_mgr_add_alien_node(struct CONN_MGR* mgr, const uint8_t* nodeinfo_data, nq->hash_node_id = ni->node_id; nq->alien = 1; nq->dirty = 0; nq->last_ver = ni->ver; nq->connectivity.ping_req_time = 0; - if (bgp->nodes) queue_data_put_with_index(bgp->nodes, &nq->ll); + if (group->nodes) queue_data_put_with_index(group->nodes, &nq->ll); DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: added alien node 0x%016llx", (unsigned long long)node_id); return CONN_MGR_OK; } @@ -426,8 +426,8 @@ struct cm_ping_ctx { }; static void cm_start_local_scan(struct CONN_MGR_ENTRY* entry) { - struct TOPO_BGP* bgp = entry->mgr->instance->bgp; - struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id); + struct TOPO_GROUP* group = topo_groups_get_default(entry->mgr->instance->topo_groups); + struct TOPO_NODEQ* target = topo_node_find_by_id(group, entry->node_id); if (!target || !target->node) { entry->local_scan_state = CM_TRY_FAILED; return; } for (const struct TOPO_ADDR4* a = target->node->v4_addrs; a; a = a->next) { if (a->type != TOPO_ADDR_INTERFACE) continue; @@ -454,8 +454,8 @@ static void cm_start_local_scan(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->local_scan_state == CM_TRY_OK) return; - struct TOPO_BGP* bgp = entry->mgr->instance->bgp; - struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id); + struct TOPO_GROUP* group = topo_groups_get_default(entry->mgr->instance->topo_groups); + struct TOPO_NODEQ* target = topo_node_find_by_id(group, entry->node_id); if (!target || !target->node) { cm_deliver_result(entry, CONN_MGR_ERR_NOT_FOUND); return; } uint8_t priority_order[] = { TOPO_ADDR_REAL, TOPO_ADDR_NAT, TOPO_ADDR_INTERFACE }; for (int pri = 0; pri < 3; pri++) { @@ -484,7 +484,7 @@ static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) { } } } - int has_our = cm_has_direct_ip(bgp->local_node); + int has_our = cm_has_direct_ip(group->local_node); int has_target = cm_has_direct_ip(target); if (has_our && !has_target) { cm_start_phase_reverse(entry); return; } cm_start_phase_indirect(entry); @@ -493,9 +493,9 @@ static void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry) { static void cm_direct_timeout_cb(void* arg) { struct CONN_MGR_ENTRY* entry = (struct CONN_MGR_ENTRY*)arg; entry->main.timer = NULL; - struct TOPO_BGP* bgp = entry->mgr->instance->bgp; - struct TOPO_NODEQ* target = topo_node_find_by_id(bgp, entry->node_id); - int has_our = cm_has_direct_ip(bgp->local_node); + struct TOPO_GROUP* group = topo_groups_get_default(entry->mgr->instance->topo_groups); + struct TOPO_NODEQ* target = topo_node_find_by_id(group, entry->node_id); + int has_our = cm_has_direct_ip(group->local_node); int has_target = target ? cm_has_direct_ip(target) : 0; if (entry->local_scan_state != CM_TRY_OK) { if (has_our && !has_target) { cm_start_phase_reverse(entry); return; } @@ -542,7 +542,7 @@ static void cm_ping_cb(int success, uint16_t rtt, void* arg, uint64_t nonce, ctx->attempt++; if (ctx->attempt < CONN_MGR_LOCAL_SCAN_ATTEMPTS && ctx->phase == 0) { etcp_send_ping_to_socket(entry->mgr->instance, ctx->sock, - topo_node_find_by_id(entry->mgr->instance->bgp, entry->node_id)->node->public_key, + topo_node_find_by_id(topo_groups_get_default(entry->mgr->instance->topo_groups), entry->node_id)->node->public_key, &ctx->addr, CONN_MGR_LOCAL_SCAN_TIMEOUT_MS, cm_ping_cb, ctx, NULL, 0); return; } @@ -553,8 +553,8 @@ 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) { - struct TOPO_BGP* bgp = entry->mgr->instance->bgp; - struct TOPO_NODEQ* local = bgp->local_node; + struct TOPO_GROUP* group = topo_groups_get_default(entry->mgr->instance->topo_groups); + struct TOPO_NODEQ* local = group->local_node; if (!local || !local->node) { cm_deliver_result(entry, CONN_MGR_ERR_INTERNAL); return; } uint32_t req_id = ++entry->mgr->next_request_id; entry->main.request_id = req_id; entry->main.phase = 2; @@ -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++) { uint64_t id = resp->my_candidates[i].node_id; - struct TOPO_NODEQ* nq = topo_node_find_by_id(entry->mgr->instance->bgp, id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(entry->mgr->instance->topo_groups), id); uint16_t our_rtt = nq ? cm_get_node_min_rtt(nq) : 0; if (our_rtt == 0xFFFF) our_rtt = 0; 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++) { pkt.selected[i].node_id = all[i].node_id; pkt.selected[i].rtt = 0; - struct TOPO_NODEQ* nq = topo_node_find_by_id(entry->mgr->instance->bgp, all[i].node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(entry->mgr->instance->topo_groups), all[i].node_id); if (nq) pkt.selected[i].rtt = cm_get_node_min_rtt(nq); } 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; uint64_t now_tb = get_time_tb(); for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), ep->cached_resp.my_candidates[i].node_id); if (!nq || !cm_is_rtt_fresh(nq, now_tb)) { need_probe++; break; } } 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; uint64_t now_tb = get_time_tb(); for (uint8_t i = 0; i < ep->cached_resp.my_count && i < 4; i++) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, ep->cached_resp.my_candidates[i].node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), 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 (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)); struct ETCP_CONN* new_conn = etcp_connection_create(conn->instance, NULL); if (new_conn) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(conn->instance->bgp, src_node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(conn->instance->topo_groups), src_node_id); 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)); 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(); for (uint8_t i = 0; i < req->candidate_count && i < 4; i++) { uint64_t cand_id = req->candidates[i].node_id; - struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, cand_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), cand_id); if (nq && cm_is_rtt_fresh(nq, now_tb)) continue; 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; for (uint8_t i = 0; i < resp.your_count; i++) { resp.your_candidates[i].node_id = req->candidates[i].node_id; - struct TOPO_NODEQ* nq2 = topo_node_find_by_id(mgr->instance->bgp, req->candidates[i].node_id); + struct TOPO_NODEQ* nq2 = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), req->candidates[i].node_id); uint16_t rtt = nq2 ? cm_get_node_min_rtt(nq2) : 0; resp.your_candidates[i].rtt = rtt; } @@ -913,13 +913,13 @@ static void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) { static void cm_bg_ping_timer_cb(void* arg) { struct CONN_MGR* mgr = (struct CONN_MGR*)arg; - struct TOPO_BGP* bgp = mgr->instance->bgp; - if (!bgp || !bgp->nodes) { + struct TOPO_GROUP* group = topo_groups_get_default(mgr->instance->topo_groups); + if (!group || !group->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"); return; } uint64_t now_tb = get_time_tb(); - struct ll_entry* e = bgp->nodes->head; + struct ll_entry* e = group->nodes->head; size_t total = 0; while (e) { total++; e = e->next; } if (total == 0) { @@ -936,13 +936,13 @@ static void cm_bg_ping_timer_cb(void* arg) { mgr->bg_ping_cycle_start_tb = now_tb; } size_t cursor = 0; - e = bgp->nodes->head; + e = group->nodes->head; while (e && cursor < mgr->bg_ping_cursor) { cursor++; e = e->next; } if (e) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; uint64_t node_id = nq->node->node_id; if (node_id != mgr->instance->node_id) { - struct ETCP_CONN* dconn = topo_bgp_find_conn_for_node(bgp, node_id); + struct ETCP_CONN* dconn = topo_group_find_conn_for_node(group, node_id); int has_active = 0; if (dconn && 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(); for (uint8_t i = 0; i < mgr->best_candidate_count; i++) { uint64_t cand_id = mgr->best_candidates[i].node_id; - struct TOPO_NODEQ* nq = topo_node_find_by_id(mgr->instance->bgp, cand_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(mgr->instance->topo_groups), cand_id); if (!nq) { 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; @@ -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])); mgr->best_candidate_count--; i--; continue; } - struct ETCP_CONN* dconn = topo_bgp_find_conn_for_node(mgr->instance->bgp, cand_id); + struct ETCP_CONN* dconn = topo_group_find_conn_for_node(topo_groups_get_default(mgr->instance->topo_groups), cand_id); int has_active = 0; if (dconn && dconn->links) { struct ETCP_LINK* l = dconn->links; diff --git a/src/conn_mgr.h b/src/conn_mgr.h index 43f4a4be..2e68e80c 100644 --- a/src/conn_mgr.h +++ b/src/conn_mgr.h @@ -16,7 +16,7 @@ extern "C" { struct UTUN_INSTANCE; struct ETCP_CONN; struct TOPO_NODEQ; -struct TOPO_BGP; +struct TOPO_GROUP; /** * @file conn_mgr.h diff --git a/src/control_server.c b/src/control_server.c index 6cb9e366..039db141 100644 --- a/src/control_server.c +++ b/src/control_server.c @@ -10,7 +10,7 @@ #include "etcp_connections.h" #include "tun_if.h" #include "route_lib.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "etcp_router.h" #include "topo_node.h" #include "pkt_normalizer.h" @@ -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; if (strncmp(cmd->action, "nat", 3) == 0) { DEBUG_INFO(DEBUG_CATEGORY_CONTROL, "Action 'nat' received, requesting NAT check for all links"); - topo_bgp_request_nat_check_all(server->instance->bgp); + topo_group_request_nat_check_all(topo_groups_get_default(server->instance->topo_groups)); } else if (strncmp(cmd->action, "nodes", 5) == 0) { 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; char* text = (char*)u_malloc(text_max); if (text) { - int text_len = topo_node_format_all(server->instance->bgp, text, text_max); + int text_len = topo_node_format_all(topo_groups_get_default(server->instance->topo_groups), text, text_max); if (text_len < 0) text_len = 0; text[text_len] = '\0'; uint16_t rsp_size = ETCPMON_ACTION_RESULT_SIZE(text_len); @@ -1188,13 +1188,14 @@ static void send_metrics(struct control_server* server, struct control_client* c } /* BGP routing */ - if (instance->bgp) { - rsp->tun.rt_bgp_senders = (uint32_t)queue_entry_count(instance->bgp->senders_list); - rsp->tun.rt_bgp_nodes = (uint32_t)queue_entry_count(instance->bgp->nodes); + { struct TOPO_GROUP* g = topo_groups_get_default(instance->topo_groups); + if (g) { + rsp->tun.rt_bgp_senders = (uint32_t)queue_entry_count(g->senders_list); + rsp->tun.rt_bgp_nodes = (uint32_t)queue_entry_count(g->nodes); } else { rsp->tun.rt_bgp_senders = 0; rsp->tun.rt_bgp_nodes = 0; - } + } } } else { memset(&rsp->tun, 0, sizeof(rsp->tun)); } @@ -1388,7 +1389,7 @@ static struct ETCP_CONN* find_connection_by_peer_id(struct UTUN_INSTANCE* instan static void send_single_node_info(struct control_server* server, struct control_client* client, struct TOPO_NODEQ* nq) { if (!server || !nq || !nq->node) return; uint8_t buf[8192]; - int ser_len = topo_node_serialize(server->instance->bgp, nq, buf + 2, sizeof(buf) - 2); + int ser_len = topo_node_serialize(topo_groups_get_default(server->instance->topo_groups), nq, buf + 2, sizeof(buf) - 2); 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; size_t data_size = 2 + (size_t)ser_len; @@ -1405,14 +1406,14 @@ 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) { - struct TOPO_BGP* bgp = server->instance->bgp; - if (!bgp) { send_error(client, ETCPMON_ERR_SERVER_BUSY, "BGP not available", seq_id); return; } + struct TOPO_GROUP* group = topo_groups_get_default(server->instance->topo_groups); + if (!group) { send_error(client, ETCPMON_ERR_SERVER_BUSY, "BGP not available", seq_id); return; } /* Send local node first */ - if (bgp->local_node) send_single_node_info(server, client, bgp->local_node); + if (group->local_node) send_single_node_info(server, client, group->local_node); /* Send all known remote nodes */ - struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; + struct ll_entry* e = group->nodes ? group->nodes->head : NULL; while (e) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; send_single_node_info(server, client, nq); diff --git a/src/db_sync.c b/src/db_sync.c index 21b485f6..443372d7 100644 --- a/src/db_sync.c +++ b/src/db_sync.c @@ -5,7 +5,7 @@ #include "etcp.h" #include "etcp_router.h" #include "utun_instance.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "../lib/debug_config.h" #include "../lib/mem.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) { struct DB_SYNC* db = (struct DB_SYNC*)arg; if (!db || !db->enabled) return; - 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; } + struct TOPO_GROUP* group = topo_groups_get_default(db->inst->topo_groups); + if (!group) { 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 - struct ll_entry* e = bgp->senders_list->head; + struct ll_entry* e = group->senders_list->head; while (e) { - struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data; + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; if (item->conn && item->conn->peer_node_id != 0 && item->conn->links_up) { uint64_t pid = item->conn->peer_node_id; if (pid != db->inst->node_id) { diff --git a/src/etcp.c b/src/etcp.c index f90e1fbb..ddeb8fc0 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -5,7 +5,7 @@ #include "etcp_loadbalancer.h" #include "etcp_router.h" #include "routing.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_ping.h" #include "../lib/u_async.h" #include "../lib/ll_queue.h" @@ -506,8 +506,8 @@ void etcp_conn_reinit(struct ETCP_CONN* etcp) {// Если сбой в обме etcp->initialized = 0;// еще раз придёт conn_ready_callback // Отменяем висящие NAT-ping'и для этого соединения - if (etcp->instance && etcp->instance->bgp) { - route_ping_cancel_for_conn(etcp->instance->bgp, etcp); + if (etcp->instance && etcp->instance->topo_groups) { + route_ping_cancel_for_conn(topo_groups_get_default(etcp->instance->topo_groups), etcp); } // Сбрасываем NAT-статус у всех линков этого соединения diff --git a/src/etcp_connections.c b/src/etcp_connections.c index ca62f806..389dcecd 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -18,7 +18,7 @@ #include "etcp.h" #include "stcp_link.h" #include "topo_node.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_ping.h" #include "../lib/memory_pool.h" #include "../lib/u_async.h" @@ -1288,8 +1288,8 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk { link->nat_type = NAT_TYPE_DIRECT; link->nat_check_status = NAT_CHECK_EIM; - if (link->etcp->instance->bgp) { - topo_bgp_send_nat_info(link->etcp, link->remote_socket_id, + if (link->etcp->instance->topo_groups) { + topo_group_send_nat_info(link->etcp, link->remote_socket_id, link->nat_ip, link->nat_port, NAT_TYPE_DIRECT); } DEBUG_INFO(DEBUG_CATEGORY_BGP, "DIRECT IP: %s:%u for %s", @@ -1310,19 +1310,20 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk nat_sin->sin_family = AF_INET; nat_sin->sin_addr.s_addr = my_ip; nat_sin->sin_port = ((struct sockaddr_in*)&e_sock->interface_addr)->sin_port; - if (link->etcp->instance->bgp) { - topo_bgp_update_my_nodeinfo(link->etcp->instance->bgp->instance, link->etcp->instance->bgp); - struct TOPO_BGP* bgp = link->etcp->instance->bgp; - if (bgp->local_node && bgp->senders_list) { - bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1; - bgp->local_node->dirty = 1; - struct ll_entry* se = bgp->senders_list->head; + { struct TOPO_GROUP* g = topo_groups_get_default(link->etcp->instance->topo_groups); + if (g) { + topo_group_update_my_nodeinfo(g->instance, g); + if (g->local_node && g->senders_list) { + g->local_node->node->ver = (g->local_node->node->ver % 255) + 1; + g->local_node->dirty = 1; + struct ll_entry* se = g->senders_list->head; 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); + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; + if (item && item->conn) topo_group_send_nodeinfo(g, g->local_node, item->conn); se = se->next; } } + } } DEBUG_INFO(DEBUG_CATEGORY_NAT, "Self-detected PUBLIC: socket=%s ip=%s port=%u sock_id=%d", e_sock->name, ip_to_str(&my_ip, AF_INET).str, @@ -1368,9 +1369,8 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk start_keepalive_timer(link); loadbalancer_link_ready(link); // Restart NAT check after link is up (e.g. after address change or reinit) - if (link->etcp->instance->bgp) { - if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_bgp_start_link_nat_check(link->etcp->instance->bgp, link); - } + { struct TOPO_GROUP* g = topo_groups_get_default(link->etcp->instance->topo_groups); + if (g && link->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_group_start_link_nat_check(g, link); } } static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, struct ETCP_LINK* link, uint8_t pkt_code, size_t pkt_len) { @@ -1697,9 +1697,8 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) { goto ec_fr; } // Cancel pending NAT check and reset status - if (link->etcp->instance->bgp) { - route_ping_cancel_for_conn(link->etcp->instance->bgp, link->etcp); - } + { struct TOPO_GROUP* g = topo_groups_get_default(link->etcp->instance->topo_groups); + if (g) route_ping_cancel_for_conn(g, link->etcp); } link->nat_check_status = NAT_CHECK_NONE; link->nat_type = NAT_TYPE_UNKNOWN; } @@ -1839,7 +1838,7 @@ ec_fr: } // Initialize only sockets (servers for incoming connections) -// Called before topo_bgp_init() to populate etcp_sockets for nodeinfo +// Called before topo_group_init() to populate etcp_sockets for nodeinfo // Returns: 0 = all OK, 1 = partial success (some sockets failed), -1 = fatal error (no sockets) int init_sockets(struct UTUN_INSTANCE* instance) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); diff --git a/src/etcp_router.c b/src/etcp_router.c index 67807ada..60869b1e 100644 --- a/src/etcp_router.c +++ b/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.h" #include "utun_instance.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "../lib/debug_config.h" #include "../lib/mem.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); struct ETCP_CONN* conn = NULL; - struct TOPO_BGP* bgp = inst->bgp; - if (bgp) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, rconn->remote_node_id); + struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); + if (group) { + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, rconn->remote_node_id); 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++) { - conn = topo_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]); + conn = topo_group_find_conn_for_node(group, nq->conn_mgr_intermediaries[i]); if (conn) break; } } } - if (!conn) conn = topo_bgp_find_conn_for_node(bgp, rconn->remote_node_id); + if (!conn) conn = topo_group_find_conn_for_node(group, rconn->remote_node_id); if (!conn) { 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); @@ -259,7 +259,7 @@ static int router_send_one_flags(struct ETCP_ROUTER_CONN* rconn, const uint8_t* // Отправка без conn (RST для неизвестного src) static void router_send_to(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t svc_id, uint8_t flag_bits) { - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, dst); + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), dst); if (!conn) return; struct SVC_ROUTE_HDR* hdr = (struct SVC_ROUTE_HDR*)u_malloc(SVC_ROUTE_HDR_SIZE); if (!hdr) return; @@ -314,7 +314,7 @@ static void router_close_and_notify(struct ETCP_ROUTER_CONN* rconn) { rconn->closed = 1; router_send_close_to_service(rconn); // Отправляем CLOSE удалённой стороне - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), rconn->remote_node_id); 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; } @@ -389,7 +389,7 @@ static void router_no_route_retry_cb(void* arg) { struct ETCP_ROUTER_CONN* rconn = (struct ETCP_ROUTER_CONN*)arg; if (rconn->closed) return; rconn->no_route_timer = NULL; - struct ETCP_CONN* c = topo_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id); + struct ETCP_CONN* c = topo_group_find_conn_for_node(topo_groups_get_default(rconn->inst->topo_groups), rconn->remote_node_id);; if (c) { 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)); @@ -420,17 +420,17 @@ static void router_retransmit_one(struct ETCP_ROUTER_CONN* rconn, struct ROUTER_ hdr->timestamp = get_current_timestamp(); struct ETCP_CONN* conn = NULL; - struct TOPO_BGP* bgp = inst->bgp; - if (bgp) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, rconn->remote_node_id); + struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); + if (group) { + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, rconn->remote_node_id); 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++) { - conn = topo_bgp_find_conn_for_node(bgp, nq->conn_mgr_intermediaries[i]); + conn = topo_group_find_conn_for_node(group, nq->conn_mgr_intermediaries[i]); if (conn) break; } } } - if (!conn) conn = topo_bgp_find_conn_for_node(bgp, rconn->remote_node_id); + if (!conn) conn = topo_group_find_conn_for_node(group, rconn->remote_node_id); if (!conn) { DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_retransmit: no route to %016llx svc_id=%u", (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) { struct UTUN_INSTANCE* inst = rconn->inst; - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), rconn->remote_node_id); if (!conn) { DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_ack: no route to %016llx svc_id=%u", (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); - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(rconn->inst->bgp, rconn->remote_node_id); + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(rconn->inst->topo_groups), rconn->remote_node_id);; if (seq == rconn->rx_seq) router_try_assembly(rconn, conn); router_schedule_ack(rconn); 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; uint8_t* sig = (uint8_t*)entry->dgram + SVC_ROUTE_HDR_SIZE + actual_payload; - struct TOPO_BGP* bgp = inst->bgp; - struct TOPO_NODEQ* nq = bgp ? topo_node_find_by_id(bgp, hdr->src_node_id) : NULL; + struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); + struct TOPO_NODEQ* nq = group ? topo_node_find_by_id(group, hdr->src_node_id) : NULL; if (!nq) { DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router: SIGNED packet from unknown node %016llx — dropping", (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, struct SVC_ROUTE_HDR* hdr) { - struct ETCP_CONN* next = topo_bgp_find_conn_for_node(inst->bgp, hdr->dst_node_id); + struct ETCP_CONN* next = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), hdr->dst_node_id); if (!next) { 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); @@ -1088,7 +1088,7 @@ int etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t dst_node_id, struct ll_ return 0; } - struct ETCP_CONN* etcp_conn = topo_bgp_find_conn_for_node(inst->bgp, dst_node_id); + struct ETCP_CONN* etcp_conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), dst_node_id); if (!etcp_conn) { 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; } @@ -1119,8 +1119,8 @@ 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) { - if (!inst || !inst->bgp) return -1; - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, node_id); + if (!inst || !topo_groups_get_default(inst->topo_groups)) return -1; + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), node_id); if (!conn || !conn->normalizer || !conn->normalizer->input) return -1; return queue_entry_count(conn->normalizer->input); } @@ -1128,16 +1128,16 @@ int etcp_router_input_q_count(struct UTUN_INSTANCE* inst, uint64_t node_id) { void etcp_router_waiter_register(struct UTUN_INSTANCE* inst, uint64_t peer_node_id, struct queue_waiter_handle* h, queue_threshold_callback_fn callback, void* arg) { - if (!inst || !inst->bgp || !h) return; - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, peer_node_id); + if (!inst || !topo_groups_get_default(inst->topo_groups) || !h) return; + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), peer_node_id); if (!conn || !conn->normalizer || !conn->normalizer->input) return; queue_waiter_wait(conn->normalizer->input, h, callback, arg); } void etcp_router_waiter_cancel(struct UTUN_INSTANCE* inst, uint64_t peer_node_id, struct queue_waiter_handle* h) { - if (!inst || !inst->bgp || !h) return; - struct ETCP_CONN* conn = topo_bgp_find_conn_for_node(inst->bgp, peer_node_id); + if (!inst || !topo_groups_get_default(inst->topo_groups) || !h) return; + struct ETCP_CONN* conn = topo_group_find_conn_for_node(topo_groups_get_default(inst->topo_groups), peer_node_id); if (!conn || !conn->normalizer || !conn->normalizer->input) return; queue_waiter_cancel(conn->normalizer->input, h); } diff --git a/src/msg_transport.c b/src/msg_transport.c index 666157c6..62ac4c5b 100644 --- a/src/msg_transport.c +++ b/src/msg_transport.c @@ -10,7 +10,7 @@ #include "etcp_router.h" #include "etcp.h" #include "secure_channel.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "../lib/u_async.h" #include "../lib/debug_config.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: { uint64_t peer_id = hdr->id; - struct TOPO_BGP* bgp = t->instance->bgp; - if (!bgp) { + struct TOPO_GROUP* group = topo_groups_get_default(t->instance->topo_groups); + if (!group) { send_error(client, MSG_ERR_PEER_NOT_FOUND, "BGP not initialized"); break; } - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, peer_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, peer_id); if (!nq) { send_error(client, MSG_ERR_PEER_NOT_FOUND, "peer not found"); DEBUG_WARN(DEBUG_CATEGORY_MSGTRANSPORT, "GET_PEER_INFO: peer=%016llx not found", diff --git a/src/route_connectivity.c b/src/route_connectivity.c index caac0a9c..ab5706e2 100644 --- a/src/route_connectivity.c +++ b/src/route_connectivity.c @@ -14,7 +14,7 @@ #include "etcp.h" #include "etcp_connections.h" #include "topo_node.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_connectivity.h" #define CONN_MAX_SOCKET_CANDIDATES 8 @@ -387,9 +387,10 @@ void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct TOPO_ } void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance) { - if (!instance || !instance->bgp || !instance->bgp->nodes) return; + struct TOPO_GROUP* group = topo_groups_get_default(instance->topo_groups); + if (!instance || !group || !group->nodes) return; int count = 0; - struct ll_entry* e = instance->bgp->nodes->head; + struct ll_entry* e = group->nodes->head; while (e) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; nq->connectivity.probe_status = PROBE_STATUS_NONE; diff --git a/src/route_ping.c b/src/route_ping.c index 50fd862c..78fd0755 100644 --- a/src/route_ping.c +++ b/src/route_ping.c @@ -15,7 +15,7 @@ #include "etcp.h" #include "etcp_connections.h" #include "topo_node.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_ping.h" #include "../lib/u_async.h" @@ -36,7 +36,7 @@ struct route_ping_series_ctx { struct route_ping_pending { struct route_ping_pending* next; - struct TOPO_BGP* bgp; + struct TOPO_GROUP* group; uint32_t request_id; route_ping_callback_t callback; void* arg; @@ -54,8 +54,8 @@ static void route_ping_pending_timeout(void* arg) { u_free(p); return; } - struct TOPO_BGP* bgp = p->bgp; - struct route_ping_pending** cur = &bgp->ping_pending; + struct TOPO_GROUP* group = p->group; + struct route_ping_pending** cur = &group->ping_pending; while (*cur) { if (*cur == p) { *cur = p->next; @@ -70,8 +70,8 @@ static void route_ping_pending_timeout(void* arg) { } // прошел ответ "серия пигнов на удаленном узле завершена" -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 TOPO_PING_RESP)) { +void route_ping_handle_resp(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { + if (!group || !from_conn || !data || len < sizeof(struct TOPO_PING_RESP)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); return; } @@ -80,13 +80,13 @@ void route_ping_handle_resp(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, c from_conn->log_name, (unsigned)resp->request_id, (unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt); - struct route_ping_pending** cur = &bgp->ping_pending; + struct route_ping_pending** cur = &group->ping_pending; while (*cur) { struct route_ping_pending* p = *cur; if (p->request_id == resp->request_id) { *cur = p->next; if (p->timeout_timer) { - uasync_cancel_timeout(bgp->instance->ua, p->timeout_timer); + uasync_cancel_timeout(group->instance->ua, p->timeout_timer); p->timeout_timer = NULL; } if (p->callback) { @@ -102,10 +102,10 @@ void route_ping_handle_resp(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, c (unsigned)resp->request_id); } -void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn) return; +void route_ping_cancel_for_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) return; - if (!bgp->ping_pending) { + if (!group->ping_pending) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "cancel_for_conn: ping_pending is NULL for %s", conn->log_name); return; } @@ -113,7 +113,7 @@ void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "cancel_for_conn: checking pending for %s", conn->log_name); int cancelled = 0; - struct route_ping_pending** cur = &bgp->ping_pending; + struct route_ping_pending** cur = &group->ping_pending; while (*cur) { struct route_ping_pending* p = *cur; struct nat_check_arg* na = (struct nat_check_arg*)p->arg; @@ -126,7 +126,7 @@ void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { if ((na && na->link && na->link->etcp == conn) || p->via_conn == conn) { *cur = p->next; if (p->timeout_timer) { - uasync_cancel_timeout(bgp->instance->ua, p->timeout_timer); + uasync_cancel_timeout(group->instance->ua, p->timeout_timer); p->timeout_timer = NULL; } p->cancelled = 1; @@ -148,12 +148,12 @@ void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { // ======================================================================== -int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn, +int route_ping_send_req_addr(struct TOPO_GROUP* group, struct ETCP_CONN* to_conn, uint32_t target_ip, uint16_t target_port, uint8_t count, uint16_t interval_ms, uint16_t timeout_ms, uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg, const uint8_t* pubkey) { - if (!bgp || !to_conn || count == 0 || timeout_ms == 0) { + if (!group || !to_conn || count == 0 || timeout_ms == 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args"); return -1; } @@ -165,7 +165,7 @@ int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn, } req_pkt->cmd = ETCP_ID_TOPO_ENTRY; req_pkt->subcmd = TOPO_SUBCMD_PING_REQ; - uint32_t new_req_id = bgp->next_ping_req_id++; + uint32_t new_req_id = group->next_ping_req_id++; req_pkt->request_id = new_req_id; req_pkt->count = count; req_pkt->interval_ms = interval_ms; @@ -203,15 +203,15 @@ int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn, DEBUG_ERROR(DEBUG_CATEGORY_BGP, "pending alloc failed"); return -5; } - pending->bgp = bgp; + pending->group = group; pending->request_id = new_req_id; // req_pkt may be freed by etcp_send callback pending->callback = cb; pending->arg = arg; pending->via_conn = to_conn; - pending->next = bgp->ping_pending; - bgp->ping_pending = pending; + pending->next = group->ping_pending; + group->ping_pending = pending; - pending->timeout_timer = uasync_set_timeout(bgp->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping"); + pending->timeout_timer = uasync_set_timeout(group->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping"); return 0; } @@ -303,11 +303,11 @@ static void route_ping_single_cb(int success, } // Обработчик PING_REQ (нам запросили "пропингуй узел и верни результат") -void route_ping_handle_req(struct TOPO_BGP* bgp, +void route_ping_handle_req(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { - if (!bgp || !from_conn || !data || len < offsetof(struct TOPO_PING_REQ, pubkey)) { + if (!group || !from_conn || !data || len < offsetof(struct TOPO_PING_REQ, pubkey)) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "ping req: bad args len=%zu", len); return; } @@ -327,7 +327,7 @@ void route_ping_handle_req(struct TOPO_BGP* bgp, ctx->timeout_ms = req_pkt->timeout_ms; { - struct TOPO_NODEQ* req_nq = topo_node_find_by_id(bgp, from_conn->peer_node_id); + struct TOPO_NODEQ* req_nq = topo_node_find_by_id(group, from_conn->peer_node_id); if (req_nq) req_nq->connectivity.ping_req_time = get_time_tb(); } if (len >= sizeof(struct TOPO_PING_REQ)) { @@ -356,7 +356,7 @@ void route_ping_handle_req(struct TOPO_BGP* bgp, */ /* Ищем первый IPv4-сокет (как в старом коде) */ - struct ETCP_SOCKET* ls = bgp->instance->etcp_sockets; + struct ETCP_SOCKET* ls = group->instance->etcp_sockets; while (ls) { if (ls->local_addr.ss_family == AF_INET) { ctx->local_sock = ls; @@ -377,7 +377,7 @@ void route_ping_handle_req(struct TOPO_BGP* bgp, /* Запускаем первый пинг (дальше цепочка через callback) */ int ret = etcp_send_ping_to_socket( - bgp->instance, + group->instance, ctx->local_sock, ctx->pubkey, &ctx->target_addr, diff --git a/src/route_ping.h b/src/route_ping.h index 950e4574..dff7730c 100644 --- a/src/route_ping.h +++ b/src/route_ping.h @@ -8,7 +8,7 @@ extern "C" { #include #include -#include "topo_bgp.h" +#include "topo_group.h" #define TOPO_SUBCMD_PING_REQ 0x07 #define TOPO_SUBCMD_PING_RESP 0x08 @@ -42,21 +42,21 @@ typedef void (*route_ping_callback_t)(int success, uint16_t avg_rtt, uint8_t cou // Отправить запрос пинга по произвольному IP:port (используется для NAT-детекции) // Если target_ip == 0, используется node_id из списка известных узлов // Если pubkey != NULL, он передается в пакете (для пинга без локального nodeinfo) -int route_ping_send_req_addr(struct TOPO_BGP* bgp, struct ETCP_CONN* to_conn, +int route_ping_send_req_addr(struct TOPO_GROUP* group, struct ETCP_CONN* to_conn, uint32_t target_ip, uint16_t target_port, uint8_t count, uint16_t interval_ms, uint16_t timeout_ms, uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg, const uint8_t* pubkey); // Очистить список ожидающих запросов (при уничтожении BGP) -void route_ping_destroy_pending(struct TOPO_BGP* bgp); +void route_ping_destroy_pending(struct TOPO_GROUP* group); // Отменить pending запросы для указанного соединения (при удалении conn) -void route_ping_cancel_for_conn(struct TOPO_BGP* bgp, struct ETCP_CONN* conn); +void route_ping_cancel_for_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn); -// Обработчики, вызываемые из topo_bgp_receive_cbk -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 TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); +// Обработчики, вызываемые из topo_group_receive_cbk +void route_ping_handle_req(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); +void route_ping_handle_resp(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); #ifdef __cplusplus diff --git a/src/topo_bgp.c b/src/topo_group.c similarity index 54% rename from src/topo_bgp.c rename to src/topo_group.c index dffa6899..294ae9ea 100644 --- a/src/topo_bgp.c +++ b/src/topo_group.c @@ -1,6 +1,6 @@ /** - * @file topo_bgp.c - * @brief BGP-like обмен топологией узлов + * @file topo_group.c + * @brief BGP-like обмен топологией узлов (группы) */ #include #include @@ -18,18 +18,21 @@ #include "topo_node.h" #include "topo_node_lmdb.h" #include "route_lib.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_ping.h" #include "route_connectivity.h" #include "control_server.h" +#define TOPO_GROUP_UTUN 0x8000000000000000ULL + + // ============================================================================ // Вспомогательные функции // ============================================================================ -static void topo_bgp_send_table_request(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn) return; +static void topo_group_send_table_request(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) return; DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending table request to %s", conn->log_name); struct TOPOMSG_TABLE_REQ* req = u_calloc(1, sizeof(struct TOPOMSG_TABLE_REQ)); if (!req) return; @@ -41,8 +44,8 @@ static void topo_bgp_send_table_request(struct TOPO_BGP* bgp, struct ETCP_CONN* if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); } } -static void topo_bgp_send_table_complete(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn) return; +static void topo_group_send_table_complete(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) return; struct TOPOMSG_TABLE_REQ* req = u_calloc(1, sizeof(struct TOPOMSG_TABLE_REQ)); if (!req) return; req->cmd = ETCP_ID_TOPO_ENTRY; @@ -53,10 +56,10 @@ static void topo_bgp_send_table_complete(struct TOPO_BGP* bgp, struct ETCP_CONN* if (etcp_send(conn, e) != 0) { u_free(req); queue_entry_free(e); } } -static void topo_bgp_add_to_senders(struct TOPO_BGP* bgp, struct ETCP_CONN* conn); -static bool topo_bgp_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id); -static void topo_bgp_send_full_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn); -static void topo_bgp_handle_request_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn); +static void topo_group_add_to_senders(struct TOPO_GROUP* group, struct ETCP_CONN* conn); +static bool topo_group_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id); +static void topo_group_send_full_table(struct TOPO_GROUP* group, struct ETCP_CONN* conn); +static void topo_group_handle_request_table(struct TOPO_GROUP* group, struct ETCP_CONN* conn); static void nodeinfo_dump_log(const uint8_t* data, size_t len) { if (!data || len < sizeof(struct TOPOMSG_NODEINFO_PKT)) return; @@ -99,7 +102,7 @@ static char* nodeinfo_format(const uint8_t* data, size_t len) { return buf; } -static const char* bgp_subcmd_name(uint8_t subcmd) { +static const char* group_subcmd_name(uint8_t subcmd) { switch (subcmd) { case TOPO_SUBCMD_NODEINFO: return "NODEINFO"; case TOPO_SUBCMD_REQUEST_TABLE: return "REQ_TABLE"; @@ -118,15 +121,15 @@ static const char* bgp_subcmd_name(uint8_t subcmd) { // Broadcast / Withdraw // ============================================================================ -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; } +static void topo_group_broadcast_withdraw(struct TOPO_GROUP* group, uint64_t node_id, uint64_t wd_source, struct ETCP_CONN* exclude) { + if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "group is NULL"); return; } struct TOPOMSG_WITHDRAW_PKT* pkt = u_calloc(1, sizeof(struct TOPOMSG_WITHDRAW_PKT)); if (!pkt) return; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_WITHDRAW; 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 = group->senders_list ? group->senders_list->head : NULL; while (e) { - struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)e->data; + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; if (item && item->conn && item->conn != exclude) { 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); } @@ -141,26 +144,27 @@ static void topo_bgp_broadcast_withdraw(struct TOPO_BGP* bgp, uint64_t node_id, // Приём пакетов // ============================================================================ -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 topo_bgp_handle_nat_check_req(struct TOPO_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); +static void topo_group_handle_nat_info(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); +static void topo_group_handle_nat_check_req(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len); -static void topo_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* entry) { +static void topo_group_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; } struct UTUN_INSTANCE* instance = from_conn->instance; - 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 TOPO_BGP* bgp = instance->bgp; + if (!instance || !instance->topo_groups) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_receive_cbk: invalid instance/topo_groups"); queue_dgram_free(entry); queue_entry_free(entry); return; } + struct TOPO_GROUP* group = topo_groups_get_default(instance->topo_groups); + if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_receive_cbk: no default group"); queue_dgram_free(entry); queue_entry_free(entry); return; } uint8_t* data = entry->dgram; uint8_t cmd = data[0]; uint8_t subcmd = data[1]; 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", group_subcmd_name(subcmd), from_conn->log_name, 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 == TOPO_SUBCMD_WITHDRAW) topo_bgp_process_withdraw(bgp, from_conn, data, entry->len); - else if (subcmd == TOPO_SUBCMD_REQUEST_TABLE) topo_bgp_handle_request_table(bgp, from_conn); - else if (subcmd == TOPO_SUBCMD_PING_REQ) route_ping_handle_req(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 == TOPO_SUBCMD_NAT_INFO) topo_bgp_handle_nat_info(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); + if (subcmd == TOPO_SUBCMD_NODEINFO) { nodeinfo_dump_log(data, entry->len); topo_group_process_nodeinfo(group, from_conn, data, entry->len); } + else if (subcmd == TOPO_SUBCMD_WITHDRAW) topo_group_process_withdraw(group, from_conn, data, entry->len); + else if (subcmd == TOPO_SUBCMD_REQUEST_TABLE) topo_group_handle_request_table(group, from_conn); + else if (subcmd == TOPO_SUBCMD_PING_REQ) route_ping_handle_req(group, from_conn, data, entry->len); + else if (subcmd == TOPO_SUBCMD_PING_RESP) route_ping_handle_resp(group, from_conn, data, entry->len); + else if (subcmd == TOPO_SUBCMD_NAT_INFO) topo_group_handle_nat_info(group, from_conn, data, entry->len); + else if (subcmd == TOPO_SUBCMD_NAT_CHECK_REQ) topo_group_handle_nat_check_req(group, from_conn, data, entry->len); 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); @@ -171,143 +175,204 @@ static void topo_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry* e // Init / Destroy / New / Remove conn // ============================================================================ -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); topo_bgp_new_conn(conn); } +static void topo_group_on_conn_up(struct ETCP_CONN* conn, void* arg) { + (void)arg; + if (conn && conn->instance && conn->instance->topo_groups) { + struct TOPO_GROUP* group = topo_groups_get_default(conn->instance->topo_groups); + if (group) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer UP: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); topo_group_new_conn(group, conn); } + } } -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); topo_bgp_remove_conn(conn); } +static void topo_group_on_conn_down(struct ETCP_CONN* conn, void* arg) { + (void)arg; + if (conn && conn->instance && conn->instance->topo_groups) { + struct TOPO_GROUP* group = topo_groups_get_default(conn->instance->topo_groups); + if (group) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP peer DOWN: %s peer=%016llx", conn->log_name, (unsigned long long)conn->peer_node_id); topo_group_remove_conn(group, conn); } + } } -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, topo_bgp_on_conn_up, conn->instance->bgp); etcp_conn_add_down_cbk(conn, topo_bgp_on_conn_down, conn->instance->bgp); } +static void topo_group_etcp_conn_cbk(struct ETCP_CONN* conn, void* arg) { + (void)arg; + if (conn && conn->instance && conn->instance->topo_groups) { + struct TOPO_GROUP* group = topo_groups_get_default(conn->instance->topo_groups); + if (group) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP set callbacks: %s", conn->log_name); etcp_conn_add_up_cbk(conn, topo_group_on_conn_up, group); etcp_conn_add_down_cbk(conn, topo_group_on_conn_down, group); } + } } -struct TOPO_BGP* topo_bgp_init(struct UTUN_INSTANCE* instance) { - if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: instance is NULL"); return NULL; } - DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_init: node_id=%016llx", (unsigned long long)instance->node_id); +static struct TOPO_GROUP* topo_group_create(struct UTUN_INSTANCE* instance, uint64_t group_id) { + if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_create: instance is NULL"); return NULL; } + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group_create: group_id=%016llx node_id=%016llx", (unsigned long long)group_id, (unsigned long long)instance->node_id); - struct TOPO_BGP* bgp = u_calloc(1, sizeof(struct TOPO_BGP)); - if (!bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_init: alloc failed"); return NULL; } - bgp->instance = instance; - bgp->ping_pending = NULL; bgp->next_ping_req_id = 1; - bgp->nodeinfo_env = NULL; bgp->nodeinfo_dbi = 0; + struct TOPO_GROUP* group = u_calloc(1, sizeof(struct TOPO_GROUP)); + if (!group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_create: alloc failed"); return NULL; } + group->group_id = group_id; + group->instance = instance; + group->ping_pending = NULL; group->next_ping_req_id = 1; + group->nodeinfo_env = NULL; group->nodeinfo_dbi = 0; - sc_derive_ed25519_pubkey(instance->my_keys.private_key, bgp->ed25519_public_key); + sc_derive_ed25519_pubkey(instance->my_keys.private_key, group->ed25519_public_key); DEBUG_INFO(DEBUG_CATEGORY_BGP, "Ed25519 pubkey derived from X25519 private key"); - if (instance->config && instance->config->global.db_path[0]) topo_node_lmdb_init(bgp, instance->config->global.db_path); + if (instance->config && instance->config->global.db_path[0]) topo_node_lmdb_init(group, instance->config->global.db_path); + + group->nodes = queue_new(instance->ua, BGP_NODES_HASH_SIZE, offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "group_nodes"); + if (!group->nodes) { u_free(group); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_create: nodes queue creation failed"); return NULL; } + + group->senders_list = queue_new(instance->ua, 0, 0, 0, "group_senders"); + if (!group->senders_list) { queue_free(group->nodes); u_free(group); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_create: senders_list queue creation failed"); return NULL; } + + group->local_node = NULL; + topo_group_update_my_nodeinfo(instance, group); + + DEBUG_INFO(DEBUG_CATEGORY_BGP, "TOPO group created: group_id=%016llx", (unsigned long long)group_id); + return group; +} + +static void topo_group_destroy(struct TOPO_GROUP* group) { + if (!group) return; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group_destroy: group_id=%016llx", (unsigned long long)group->group_id); + + struct ll_entry* e; + while ((e = queue_data_get(group->senders_list)) != NULL) queue_entry_free(e); + queue_free(group->senders_list); + + if (group->local_node) { topo_node_free_lists(group, group->local_node); u_free(group->local_node); } - 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, "topo_bgp_init: nodes queue creation failed"); return NULL; } + topo_node_lmdb_destroy(group); - 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, "topo_bgp_init: senders_list queue creation failed"); return NULL; } + if (group->nodes) queue_free(group->nodes); - bgp->v4_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA4), "to_v4sock"); - bgp->v4_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR4), "to_v4addr"); - bgp->v6_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA6), "to_v6sock"); - bgp->v6_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR6), "to_v6addr"); - bgp->v4_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET4), "to_v4sub"); - bgp->v6_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET6), "to_v6sub"); + u_free(group); +} + +struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance) { + if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_init: instance is NULL"); return NULL; } + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_groups_init: node_id=%016llx", (unsigned long long)instance->node_id); + + struct TOPO_GROUPS* g = u_calloc(1, sizeof(struct TOPO_GROUPS)); + if (!g) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_init: alloc failed"); return NULL; } + g->instance = instance; + + g->group_list = queue_new(instance->ua, 0, 0, 0, "topo_groups"); + if (!g->group_list) { u_free(g); DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_init: group_list queue creation failed"); return NULL; } - bgp->local_node = NULL; - topo_bgp_update_my_nodeinfo(instance, bgp); + g->v4_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA4), "to_v4sock"); + g->v4_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR4), "to_v4addr"); + g->v6_sock_meta_pool = memory_pool_init(sizeof(struct TOPO_SOCKMETA6), "to_v6sock"); + g->v6_addr_pool = memory_pool_init(sizeof(struct TOPO_ADDR6), "to_v6addr"); + g->v4_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET4), "to_v4sub"); + g->v6_subnet_pool = memory_pool_init(sizeof(struct TOPO_SUBNET6), "to_v6sub"); + + instance->topo_groups = g; + + struct TOPO_GROUP* default_group = topo_group_create(instance, TOPO_GROUP_UTUN); + if (!default_group) { + memory_pool_destroy(g->v4_sock_meta_pool); memory_pool_destroy(g->v4_addr_pool); + memory_pool_destroy(g->v6_sock_meta_pool); memory_pool_destroy(g->v6_addr_pool); + memory_pool_destroy(g->v4_subnet_pool); memory_pool_destroy(g->v6_subnet_pool); + queue_free(g->group_list); u_free(g); + DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_init: failed to create default group"); + return NULL; + } + { struct ll_entry* e = queue_entry_new(sizeof(struct TOPO_GROUP)); if (e) { *(struct TOPO_GROUP**)e->data = default_group; queue_data_put(g->group_list, e); } } - etcp_bind(instance, ETCP_ID_TOPO_ENTRY, topo_bgp_receive_cbk); - etcp_add_new_conn_cbk(instance, topo_bgp_etcp_conn_cbk, NULL); + etcp_bind(instance, ETCP_ID_TOPO_ENTRY, topo_group_receive_cbk); + etcp_add_new_conn_cbk(instance, topo_group_etcp_conn_cbk, NULL); - DEBUG_INFO(DEBUG_CATEGORY_BGP, "TOPO BGP module initialized"); - return bgp; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "TOPO groups initialized (with default group)"); + return g; } -void topo_bgp_destroy(struct UTUN_INSTANCE* instance) { - if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: instance is NULL"); return; } - if (!instance->bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: bgp is NULL"); return; } - DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_destroy: node_id=%016llx", (unsigned long long)instance->node_id); +void topo_groups_destroy(struct UTUN_INSTANCE* instance) { + if (!instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_destroy: instance is NULL"); return; } + if (!instance->topo_groups) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_groups_destroy: topo_groups is NULL"); return; } + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_groups_destroy: node_id=%016llx", (unsigned long long)instance->node_id); etcp_unbind(instance, ETCP_ID_TOPO_ENTRY); route_connectivity_cancel_all(instance); - struct ll_entry* e; - while ((e = queue_data_get(instance->bgp->senders_list)) != NULL) queue_entry_free(e); - queue_free(instance->bgp->senders_list); - - if (instance->bgp->local_node) { topo_node_free_lists(instance->bgp, instance->bgp->local_node); u_free(instance->bgp->local_node); } + struct TOPO_GROUPS* g = instance->topo_groups; + struct ll_entry* ge; + while ((ge = queue_data_get(g->group_list)) != NULL) { topo_group_destroy(*(struct TOPO_GROUP**)ge->data); queue_entry_free(ge); } + queue_free(g->group_list); - topo_node_lmdb_destroy(instance->bgp); + memory_pool_destroy(g->v4_sock_meta_pool); + memory_pool_destroy(g->v4_addr_pool); + memory_pool_destroy(g->v6_sock_meta_pool); + memory_pool_destroy(g->v6_addr_pool); + memory_pool_destroy(g->v4_subnet_pool); + memory_pool_destroy(g->v6_subnet_pool); - if (instance->bgp->nodes) queue_free(instance->bgp->nodes); + u_free(g); instance->topo_groups = NULL; +} - memory_pool_destroy(instance->bgp->v4_sock_meta_pool); - memory_pool_destroy(instance->bgp->v4_addr_pool); - memory_pool_destroy(instance->bgp->v6_sock_meta_pool); - memory_pool_destroy(instance->bgp->v6_addr_pool); - memory_pool_destroy(instance->bgp->v4_subnet_pool); - memory_pool_destroy(instance->bgp->v6_subnet_pool); +struct TOPO_GROUP* topo_groups_get_default(struct TOPO_GROUPS* g) { + return topo_groups_find(g, TOPO_GROUP_UTUN); +} - u_free(instance->bgp); instance->bgp = NULL; +struct TOPO_GROUP* topo_groups_find(struct TOPO_GROUPS* g, uint64_t group_id) { + if (!g || !g->group_list) return NULL; + struct ll_entry* e = g->group_list->head; + while (e) { struct TOPO_GROUP* grp = *(struct TOPO_GROUP**)e->data; if (grp && grp->group_id == group_id) return grp; e = e->next; } + return NULL; } -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 topo_group_set_nat_check_local(struct TOPO_GROUP* group, int allow) { if (!group) return; group->allow_nat_check_local = allow ? 1 : 0; } -void topo_bgp_new_conn(struct ETCP_CONN* conn) { - if (!conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn 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, "topo_bgp_new_conn: conn->instance->bgp is NULL"); return; } - if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_new_conn: conn->instance->rt is NULL"); return; } +void topo_group_new_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_new_conn: invalid args"); return; } + if (!conn->instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_new_conn: conn->instance is NULL"); return; } + if (!conn->instance->rt) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_new_conn: conn->instance->rt is NULL"); return; } - struct TOPO_BGP* bgp = conn->instance->bgp; - struct TOPO_NODEQ* peer_nq = topo_node_find_by_id(bgp, conn->peer_node_id); - topo_bgp_add_to_senders(bgp, conn); - 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 TOPO_NODEQ* peer_nq = topo_node_find_by_id(group, conn->peer_node_id); + topo_group_add_to_senders(group, conn); + if (peer_nq && peer_nq->alien) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group_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; - 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; } + while (c) { struct ETCP_LINK* l = c->links; while (l) { if (l->initialized && l->conn && l->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_group_start_link_nat_check(group, l); l = l->next; } c = c->next; } - topo_bgp_send_table_request(bgp, conn); + topo_group_send_table_request(group, conn); } -void topo_bgp_remove_conn(struct ETCP_CONN* conn) { - 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, "topo_bgp_remove_conn: invalid instance/bgp"); return; } - struct TOPO_BGP* bgp = conn->instance->bgp; +void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_remove_conn: invalid args"); return; } + if (!conn->instance) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_remove_conn: invalid instance"); return; } bool found_in_list = false; - struct ll_entry* e = bgp->senders_list->head; - 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, "topo_bgp_remove_conn: conn already removed or not in list, skipping"); return; } + struct ll_entry* e = group->senders_list->head; + while (e) { struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_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, "topo_group_remove_conn: conn already removed or not in list, skipping"); return; } - DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_bgp_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id); + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group_remove_conn: peer=%016llx", (unsigned long long)conn->peer_node_id); - route_ping_cancel_for_conn(bgp, conn); + route_ping_cancel_for_conn(group, 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 ROUTE_TABLE* rt = conn->instance->rt; int nodes_removed = 0; - struct ll_entry* node_entry = bgp->nodes ? bgp->nodes->head : NULL; + struct ll_entry* node_entry = group->nodes ? group->nodes->head : NULL; while (node_entry) { struct ll_entry* next = node_entry->next; struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)node_entry; - if (topo_bgp_remove_path(nq, conn) == 1) { + if (topo_group_remove_path(nq, conn) == 1) { 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); nq->dirty = 1; route_connectivity_cancel_node(conn->instance, nq); if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } uint64_t key = nq->hash_node_id; - topo_node_free_lists(bgp, nq); + topo_node_free_lists(group, nq); struct ll_entry* entry = node_entry; - if (entry) { queue_remove_data(bgp->nodes, entry); queue_entry_free(entry); } + if (entry) { queue_remove_data(group->nodes, entry); queue_entry_free(entry); } nodes_removed++; - etcp_router_conn_close_all_for_node(bgp->instance, key); + etcp_router_conn_close_all_for_node(group->instance, key); uint64_t wd_src = (key == conn->peer_node_id) ? conn->instance->node_id : conn->peer_node_id; - topo_bgp_broadcast_withdraw(bgp, key, wd_src, NULL); + topo_group_broadcast_withdraw(group, key, wd_src, NULL); DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "Removed node %016llx after link down", (unsigned long long)key); } node_entry = next; } - e = bgp->senders_list->head; - 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; } + e = group->senders_list->head; + while (e) { struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data; if (item->conn == conn) { queue_remove_data(group->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); } @@ -317,9 +382,9 @@ void topo_bgp_remove_conn(struct ETCP_CONN* conn) { // NODEINFO BASED IMPLEMENTATION // ============================================================================ -struct ETCP_CONN* topo_bgp_find_conn_for_node(struct TOPO_BGP* bgp, uint64_t node_id) { - if (!bgp) return NULL; - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, node_id); +struct ETCP_CONN* topo_group_find_conn_for_node(struct TOPO_GROUP* group, uint64_t node_id) { + if (!group) return NULL; + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, node_id); if (!nq || !nq->paths || !nq->paths->head) return NULL; struct ll_entry* e = nq->paths->head; struct TOPO_NODEPATH* best_live = NULL; uint8_t best_live_hops = 255; @@ -333,7 +398,7 @@ struct ETCP_CONN* topo_bgp_find_conn_for_node(struct TOPO_BGP* bgp, uint64_t nod return best_live ? best_live->conn : (best_any ? best_any->conn : NULL); } -int topo_bgp_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count) { +int topo_group_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->paths) { nq->paths = queue_new(conn->instance->ua, 0, 0, 0, "node_paths"); if (!nq->paths) return -1; } size_t path_size = sizeof(struct TOPO_NODEPATH) - sizeof(struct ll_entry) + hop_count * 8; @@ -345,7 +410,7 @@ int topo_bgp_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* h return 0; } -int topo_bgp_remove_path_by_hop(struct TOPO_NODEQ* nq, uint64_t wd_source) { +static int topo_group_remove_path_by_hop(struct TOPO_NODEQ* nq, uint64_t wd_source) { if (!nq || !nq->paths) return 0; int removed = 0; struct ll_entry* e = nq->paths->head; @@ -360,7 +425,7 @@ int topo_bgp_remove_path_by_hop(struct TOPO_NODEQ* nq, uint64_t wd_source) { return removed; } -int topo_bgp_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn) { +int topo_group_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn) { if (!nq || !conn || !nq->paths) return -1; struct ll_entry* e = nq->paths->head; 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; } @@ -378,45 +443,45 @@ 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; } link->nat_type = success ? NAT_TYPE_EIM : NAT_TYPE_STRICT; link->nat_check_status = success ? NAT_CHECK_EIM : NAT_CHECK_STRICT; - if (link->etcp) topo_bgp_send_nat_info(link->etcp, link->remote_socket_id, na->nat_ip, na->nat_port, link->nat_type); + if (link->etcp) topo_group_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); u_free(na); } -static struct ETCP_CONN* topo_bgp_find_third_node(struct TOPO_BGP* bgp, struct ETCP_CONN* exclude) { - if (!bgp || !bgp->senders_list) return NULL; - struct ll_entry* e = bgp->senders_list->head; - 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; } +static struct ETCP_CONN* topo_group_find_third_node(struct TOPO_GROUP* group, struct ETCP_CONN* exclude) { + if (!group || !group->senders_list) return NULL; + struct ll_entry* e = group->senders_list->head; + while (e) { struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_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; } -void topo_bgp_start_link_nat_check(struct TOPO_BGP* bgp, struct ETCP_LINK* link) { - if (!bgp || !link || !link->conn || !link->etcp) return; +void topo_group_start_link_nat_check(struct TOPO_GROUP* group, struct ETCP_LINK* link) { + if (!group || !link || !link->conn || !link->etcp) return; if (link->nat_type == NAT_TYPE_DIRECT) 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; } - struct ETCP_CONN* third_conn = topo_bgp_find_third_node(bgp, link->etcp); + struct ETCP_CONN* third_conn = topo_group_find_third_node(group, link->etcp); if (!third_conn) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no third node found for link"); return; } uint32_t target_ip; uint16_t target_port; if (link->nat_ip != 0 && link->nat_port != 0) { target_ip = link->nat_ip; target_port = link->nat_port; } else { struct sockaddr_in* sin = (struct sockaddr_in*)&link->remote_addr; target_ip = sin->sin_addr.s_addr; target_port = ntohs(sin->sin_port); } - if (!bgp->allow_nat_check_local && is_local_subnet(target_ip)) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local connection: %s, skip nat check", ip_to_str(&target_ip, AF_INET).str); return; } + if (!group->allow_nat_check_local && is_local_subnet(target_ip)) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local connection: %s, skip nat check", ip_to_str(&target_ip, AF_INET).str); return; } struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg)); if (!arg) return; arg->link = link; arg->nat_ip = target_ip; arg->nat_port = target_port; const uint8_t* pubkey = link->etcp->crypto_ctx.peer_key_set ? link->etcp->crypto_ctx.peer_public_key : NULL; if (!pubkey) { u_free(arg); DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "no peer pubkey for link=%p", (void*)link); return; } - int ret = route_ping_send_req_addr(bgp, third_conn, target_ip, target_port, 3, 500, 1000, 5000, nat_link_check_cb, arg, pubkey); + int ret = route_ping_send_req_addr(group, third_conn, target_ip, target_port, 3, 500, 1000, 5000, nat_link_check_cb, arg, pubkey); if (ret == 0) { link->nat_check_status = NAT_CHECK_IN_PROGRESS; DEBUG_INFO(DEBUG_CATEGORY_BGP, "ping remote request via=%s (%s:%d)", third_conn->log_name, ip_to_str(&target_ip, AF_INET).str, target_port); } else { u_free(arg); DEBUG_WARN(DEBUG_CATEGORY_BGP, "failed to start for link=%s (%s:%d)", third_conn->log_name, ip_to_str(&target_ip, AF_INET).str, target_port); } } // ===== NODEINFO process ===== -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 TOPOMSG_NODEINFO_PKT)) return -1; +int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from, const uint8_t* data, size_t len) { + if (!group || !from || len < sizeof(struct TOPOMSG_NODEINFO_PKT)) return -1; struct TOPOMSG_NODEINFO_PKT* pkt = (struct TOPOMSG_NODEINFO_PKT*)data; struct TOPOMSG_NODE* ni = &pkt->node; @@ -425,9 +490,9 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons 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 (node_id == bgp->instance->node_id) return 0; + if (node_id == group->instance->node_id) return 0; - struct TOPO_NODEQ* nodeinfo1 = topo_node_find_by_id(bgp, node_id); + struct TOPO_NODEQ* nodeinfo1 = topo_node_find_by_id(group, node_id); uint8_t new_ver = ni->ver; if (nodeinfo1 && (int8_t)(nodeinfo1->last_ver - new_ver) >= 0) { @@ -437,8 +502,8 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons 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); hop_list[ni->hop_count] = from->peer_node_id; - topo_bgp_remove_path(nodeinfo1, from); - topo_bgp_add_path(nodeinfo1, from, hop_list, new_hops); + topo_group_remove_path(nodeinfo1, from); + topo_group_add_path(nodeinfo1, from, hop_list, new_hops); } return 0; } @@ -450,20 +515,19 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons struct ll_queue* paths = NULL; int is_new_node = 0; if (nodeinfo1) { - topo_node_free_lists(bgp, nodeinfo1); + topo_node_free_lists(group, nodeinfo1); paths = nodeinfo1->paths; nodeinfo1->paths = NULL; } else { is_new_node = 1; } - // deserialize from protocol const uint8_t* ser_data = data + 2; size_t ser_len = len - 2; struct TOPO_NODE* new_ni = NULL; struct TOPO_NODESUBNETS* new_subnets = NULL; struct TOPOMSG_TRANZIT* new_tranzit = NULL; uint8_t new_tranzit_count = 0; uint64_t* new_hop_list = NULL; uint8_t 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) { + if (topo_node_deserialize(group, 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); - if (nodeinfo1) { queue_remove_data(bgp->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); } + if (nodeinfo1) { queue_remove_data(group->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); } return -1; } @@ -491,12 +555,11 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons nodeinfo1->connectivity.real_status = PROBE_RESULT_UNKNOWN; nodeinfo1->connectivity.ping_req_time = 0; nodeinfo1->alien = 0; - queue_data_put_with_index(bgp->nodes, &nodeinfo1->ll); + queue_data_put_with_index(group->nodes, &nodeinfo1->ll); } nodeinfo1->paths = paths; nodeinfo1->last_ver = new_ver; - // add this hop uint64_t hop_list[MAX_HOPS]; if (nodeinfo1->hop_count > 0) memcpy(hop_list, nodeinfo1->hop_list, nodeinfo1->hop_count * 8); hop_list[nodeinfo1->hop_count] = from->peer_node_id; @@ -506,22 +569,22 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons nodeinfo1->hop_list = u_malloc(nodeinfo1->hop_count * 8); memcpy(nodeinfo1->hop_list, hop_list, nodeinfo1->hop_count * 8); - topo_bgp_remove_path_by_hop(nodeinfo1, from->peer_node_id); - topo_bgp_add_path(nodeinfo1, from, hop_list, nodeinfo1->hop_count); + topo_group_remove_path_by_hop(nodeinfo1, from->peer_node_id); + topo_group_add_path(nodeinfo1, from, hop_list, nodeinfo1->hop_count); - if (bgp->instance->rt) route_insert(bgp->instance->rt, 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 (group->instance->rt) route_insert(group->instance->rt, nodeinfo1); + if (node_id != group->instance->node_id) topo_node_lmdb_put(group, nodeinfo1); + if (group->instance->control_srv) control_server_notify_node_change(group->instance->control_srv, nodeinfo1); int hop_count = nodeinfo1->hop_count; - struct ll_entry* se = bgp->senders_list ? bgp->senders_list->head : NULL; + struct ll_entry* se = group->senders_list ? group->senders_list->head : NULL; while (se) { - struct TOPO_BGP_CONN_ITEM* item = (struct TOPO_BGP_CONN_ITEM*)se->data; + struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; if (item->conn) { uint64_t id = item->conn->peer_node_id; if (id != node_id) { int found = 0; for (int i = 0; i < hop_count; i++) if (hop_list[i] == id) found = 1; - if (found == 0) topo_bgp_send_nodeinfo(nodeinfo1, item->conn); + if (found == 0) topo_group_send_nodeinfo(group, nodeinfo1, item->conn); } } se = se->next; @@ -530,39 +593,39 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons int 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 != group->instance->node_id && (is_new_node || socks_changed)) { int v4a = topo_list_count((struct _topo_head*)nodeinfo1->node->v4_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(group->instance, nodeinfo1); } return 0; } -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 TOPOMSG_WITHDRAW_PKT)) return -1; +int topo_group_process_withdraw(struct TOPO_GROUP* group, struct ETCP_CONN* sender, const uint8_t* data, size_t len) { + if (!group || len < sizeof(struct TOPOMSG_WITHDRAW_PKT)) return -1; struct TOPOMSG_WITHDRAW_PKT* wp = (struct TOPOMSG_WITHDRAW_PKT*)data; uint64_t node_id = wp->node_id, wd_source = wp->wd_source; - struct TOPO_NODEQ* nq = topo_node_find_by_id(bgp, node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(group, node_id); if (!nq) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "node not found"); return 0; } - int ret = topo_bgp_remove_path_by_hop(nq, wd_source); + int ret = topo_group_remove_path_by_hop(nq, wd_source); if (ret == 1) { - 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 (group->instance && group->instance->rt) route_delete(group->instance->rt, nq); + if (group->instance->control_srv) control_server_notify_node_removed(group->instance->control_srv, node_id); nq->dirty = 1; - route_connectivity_cancel_node(bgp->instance, nq); + route_connectivity_cancel_node(group->instance, nq); if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; } - topo_node_free_lists(bgp, nq); - 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); } - topo_bgp_broadcast_withdraw(bgp, node_id, wd_source, sender); + topo_node_free_lists(group, nq); + struct ll_entry* entry = queue_find_data_by_index(group->nodes, &node_id); + if (entry) { queue_remove_data(group->nodes, entry); queue_entry_free(entry); } + topo_group_broadcast_withdraw(group, node_id, wd_source, sender); } return 0; } -void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* node, struct ETCP_CONN* conn) { - if (!node || !conn) return; +void topo_group_send_nodeinfo(struct TOPO_GROUP* group, struct TOPO_NODEQ* node, struct ETCP_CONN* conn) { + if (!group || !node || !conn) return; size_t max_sz = sizeof(struct TOPOMSG_NODEINFO_PKT) + 4096; uint8_t* p = u_malloc(max_sz); @@ -570,7 +633,7 @@ void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* node, struct ETCP_CONN* conn) { p[0] = ETCP_ID_TOPO_ENTRY; p[1] = TOPO_SUBCMD_NODEINFO; - int ser_len = topo_node_serialize(conn->instance->bgp, node, p + 2, max_sz - 2); + int ser_len = topo_node_serialize(group, node, p + 2, max_sz - 2); if (ser_len < 0) { u_free(p); return; } struct ll_entry* e = queue_entry_new(0); @@ -580,18 +643,18 @@ void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* 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); } } -static void topo_bgp_add_to_senders(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn || !bgp->senders_list) return; +static void topo_group_add_to_senders(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn || !group->senders_list) return; bool already = false; - struct ll_entry* e = bgp->senders_list->head; - while (e) { if (((struct TOPO_BGP_CONN_ITEM*)e->data)->conn == conn) { already = true; break; } e = e->next; } + struct ll_entry* e = group->senders_list->head; + while (e) { if (((struct TOPO_GROUP_CONN_ITEM*)e->data)->conn == conn) { already = true; break; } e = e->next; } if (!already) { - struct ll_entry* item_entry = queue_entry_new(sizeof(struct TOPO_BGP_CONN_ITEM)); - if (item_entry) { ((struct TOPO_BGP_CONN_ITEM*)item_entry->data)->conn = conn; queue_data_put(bgp->senders_list, item_entry); } + struct ll_entry* item_entry = queue_entry_new(sizeof(struct TOPO_GROUP_CONN_ITEM)); + if (item_entry) { ((struct TOPO_GROUP_CONN_ITEM*)item_entry->data)->conn = conn; queue_data_put(group->senders_list, item_entry); } } } -static bool topo_bgp_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id) { +static bool topo_group_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target_id) { if (!nq || !nq->node || !nq->paths) return false; if (target_id == nq->node->node_id) return false; struct ll_entry* e = nq->paths->head; @@ -605,29 +668,29 @@ static bool topo_bgp_should_send_to(const struct TOPO_NODEQ* nq, uint64_t target return false; } -static void topo_bgp_send_full_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn) return; +static void topo_group_send_full_table(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) return; uint64_t target = conn->peer_node_id; - struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL; + struct ll_entry* e = group->nodes ? group->nodes->head : NULL; while (e) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; 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 (topo_bgp_should_send_to(nq, target)) topo_bgp_send_nodeinfo(nq, conn); + if (topo_group_should_send_to(nq, target)) topo_group_send_nodeinfo(group, nq, conn); e = e->next; } } -static void topo_bgp_handle_request_table(struct TOPO_BGP* bgp, struct ETCP_CONN* conn) { - if (!bgp || !conn) return; - topo_bgp_send_nodeinfo(bgp->local_node, conn); - topo_bgp_send_full_table(bgp, conn); - topo_bgp_add_to_senders(bgp, conn); - topo_bgp_send_table_complete(bgp, conn); +static void topo_group_handle_request_table(struct TOPO_GROUP* group, struct ETCP_CONN* conn) { + if (!group || !conn) return; + topo_group_send_nodeinfo(group, group->local_node, conn); + topo_group_send_full_table(group, conn); + topo_group_add_to_senders(group, conn); + topo_group_send_table_complete(group, conn); } -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 TOPOMSG_NAT_INFO) || !bgp->local_node || !bgp->local_node->node) return; +static void topo_group_handle_nat_info(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { + if (!group || !from_conn || !data || len < sizeof(struct TOPOMSG_NAT_INFO) || !group->local_node || !group->local_node->node) return; 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]; @@ -640,43 +703,43 @@ static void topo_bgp_handle_nat_info(struct TOPO_BGP* bgp, struct ETCP_CONN* fro else verified_type = NAT_VERIFIED_UNKNOWN; int data_changed = 0; - { 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 TOPO_SOCKMETA4* sm = group->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 = group->instance->etcp_sockets; while (es) { if (es->sock_id == socket_id) { if (verified_type == NAT_VERIFIED_STRICT) { struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; nat_sin->sin_family = AF_INET; nat_sin->sin_addr.s_addr = nat_ip; nat_sin->sin_port = htons(nat_port); es->nat_type = verified_type; } else { struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; uint32_t old_nat_ip = nat_sin->sin_addr.s_addr; uint16_t old_nat_port = ntohs(nat_sin->sin_port); nat_sin->sin_family = AF_INET; nat_sin->sin_addr.s_addr = nat_ip; nat_sin->sin_port = htons(nat_port); if (old_nat_ip != nat_ip || old_nat_port != nat_port) data_changed = 1; es->nat_type = verified_type; } break; } es = es->next; } if (data_changed) { - int prev_v4a = topo_list_count((struct _topo_head*)bgp->local_node->node->v4_addrs); - topo_bgp_update_my_nodeinfo(bgp->instance, bgp); - if (topo_list_count((struct _topo_head*)bgp->local_node->node->v4_addrs) != prev_v4a) { - bgp->local_node->dirty = 1; - bgp->local_node->node->ver = (bgp->local_node->node->ver % 255) + 1; - bgp->local_node->last_ver = bgp->local_node->node->ver; + int prev_v4a = topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs); + topo_group_update_my_nodeinfo(group->instance, group); + if (topo_list_count((struct _topo_head*)group->local_node->node->v4_addrs) != prev_v4a) { + group->local_node->dirty = 1; + group->local_node->node->ver = (group->local_node->node->ver % 255) + 1; + group->local_node->last_ver = group->local_node->node->ver; } - if (bgp->local_node->dirty && bgp->senders_list) { - struct ll_entry* se = bgp->senders_list->head; - 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; } + if (group->local_node->dirty && group->senders_list) { + struct ll_entry* se = group->senders_list->head; + while (se) { struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; if (item && item->conn) topo_group_send_nodeinfo(group, group->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; } } -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 TOPOMSG_NAT_CHECK_REQ)) return; +static void topo_group_handle_nat_check_req(struct TOPO_GROUP* group, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) { + if (!group || !from_conn || !data || len < sizeof(struct TOPOMSG_NAT_CHECK_REQ)) return; const struct TOPOMSG_NAT_CHECK_REQ* req = (const struct TOPOMSG_NAT_CHECK_REQ*)data; uint8_t socket_id = req->socket_id; 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; } if (!target_link) return; if (target_link->nat_check_status == NAT_CHECK_IN_PROGRESS) return; - topo_bgp_start_link_nat_check(bgp, target_link); + topo_group_start_link_nat_check(group, target_link); } -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) { +void topo_group_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; struct TOPOMSG_NAT_INFO* pkt = u_calloc(1, sizeof(struct TOPOMSG_NAT_INFO)); if (!pkt) return; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_NAT_INFO; @@ -689,7 +752,7 @@ void topo_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t if (etcp_send(conn, e) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send NAT_INFO failed"); u_free(pkt); queue_entry_free(e); } } -void topo_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { +void topo_group_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { if (!conn) return; struct TOPOMSG_NAT_CHECK_REQ* pkt = u_calloc(1, sizeof(struct TOPOMSG_NAT_CHECK_REQ)); if (!pkt) return; pkt->cmd = ETCP_ID_TOPO_ENTRY; pkt->subcmd = TOPO_SUBCMD_NAT_CHECK_REQ; pkt->socket_id = socket_id; @@ -699,8 +762,14 @@ void topo_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id) { 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 topo_bgp_request_nat_check_all(struct TOPO_BGP* bgp) { - if (!bgp || !bgp->instance) return; +void topo_group_request_nat_check_all(struct TOPO_GROUP* group) { + if (!group || !group->instance) return; 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) topo_bgp_start_link_nat_check(bgp, link); count++; link = link->next; } conn = conn->next; } + struct ETCP_CONN* conn = group->instance->connections; while (conn) { struct ETCP_LINK* link = conn->links; while (link) { if (link->nat_check_status < NAT_CHECK_IN_PROGRESS) topo_group_start_link_nat_check(group, link); count++; link = link->next; } conn = conn->next; } +} + +void topo_group_send_withdraw(struct TOPO_GROUP* group, uint64_t node_id) { + if (!group) return; + DEBUG_INFO(DEBUG_CATEGORY_BGP, "topo_group_send_withdraw: node=%016llx", (unsigned long long)node_id); + topo_group_broadcast_withdraw(group, node_id, group->instance->node_id, NULL); } diff --git a/src/topo_bgp.h b/src/topo_group.h similarity index 71% rename from src/topo_bgp.h rename to src/topo_group.h index 48e4caa8..46aa9a7f 100644 --- a/src/topo_bgp.h +++ b/src/topo_group.h @@ -1,5 +1,5 @@ -#ifndef TOPO_BGP_H -#define TOPO_BGP_H +#ifndef TOPO_GROUP_H +#define TOPO_GROUP_H #ifdef __cplusplus extern "C" { @@ -57,7 +57,7 @@ struct TOPOMSG_TABLE_REQ { uint8_t subcmd; } __attribute__((packed)); -struct TOPO_BGP_CONN_ITEM { +struct TOPO_GROUP_CONN_ITEM { struct ll_entry ll; struct ETCP_CONN* conn; }; @@ -88,7 +88,11 @@ struct TOPOMSG_NAT_CHECK_REQ { struct route_ping_pending; struct ETCP_LINK; -struct TOPO_BGP { +/** + * @brief Группа топологии (одна на каждый group_id: utun, чат-группа, …) + */ +struct TOPO_GROUP { + uint64_t group_id; // уникальный идентификатор группы struct UTUN_INSTANCE* instance; struct ll_queue* senders_list; struct ll_queue* nodes; @@ -99,6 +103,14 @@ struct TOPO_BGP { uint8_t ed25519_public_key[SC_PUBKEY_SIZE]; MDB_env* nodeinfo_env; MDB_dbi nodeinfo_dbi; +}; + +/** + * @brief Контейнер всех групп топологии экземпляра + */ +struct TOPO_GROUPS { + struct UTUN_INSTANCE* instance; + struct ll_queue* group_list; // ll_queue of TOPO_GROUP entries struct memory_pool* v4_sock_meta_pool; struct memory_pool* v4_addr_pool; struct memory_pool* v6_sock_meta_pool; @@ -108,36 +120,43 @@ struct TOPO_BGP { }; /** - * @brief Инициализирует модуль топологии BGP. - * - * Создает очереди, local_node из подсетей конфига, привязывает к ETCP_ID_TOPO_ENTRY, - * устанавливает коллбеки new_conn для on_up/on_down. + * @brief Создаёт контейнер групп и группу utun по умолчанию (group_id=1). * * @param instance экземпляр utun с node_id и конфигом - * @return TOPO_BGP или NULL при ошибке + * @return TOPO_GROUPS или NULL при ошибке */ -struct TOPO_BGP* topo_bgp_init(struct UTUN_INSTANCE* instance); +struct TOPO_GROUPS* topo_groups_init(struct UTUN_INSTANCE* instance); /** - * @brief Освобождает ресурсы BGP (очереди, local_node, снимает привязку ETCP). + * @brief Освобождает все группы и контейнер. * * @param instance экземпляр utun */ -void topo_bgp_destroy(struct UTUN_INSTANCE* instance); +void topo_groups_destroy(struct UTUN_INSTANCE* instance); + +/** + * @brief Возвращает группу по умолчанию (group_id=TOPO_GROUP_UTUN=0x8000000000000000). + */ +struct TOPO_GROUP* topo_groups_get_default(struct TOPO_GROUPS* g); + +/** + * @brief Находит группу по id. + */ +struct TOPO_GROUP* topo_groups_find(struct TOPO_GROUPS* g, uint64_t group_id); /** * @brief Добавляет conn в senders_list (если нет), отправляет запрос таблицы (nodeinfo). * * Вызывается при ETCP on_up. */ -void topo_bgp_new_conn(struct ETCP_CONN* conn); +void topo_group_new_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn); /** * @brief Удаляет conn из senders_list, очищает paths во всех nodes, отправляет withdraw если node unreachable. * * Вызывается при ETCP on_down. */ -void topo_bgp_remove_conn(struct ETCP_CONN* conn); +void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn); /** * @brief Обрабатывает пакет NODEINFO. @@ -147,8 +166,8 @@ void topo_bgp_remove_conn(struct ETCP_CONN* conn); * * @return 0 при успехе */ +int topo_group_process_nodeinfo(struct TOPO_GROUP* group, 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. * @@ -156,42 +175,42 @@ int topo_bgp_process_nodeinfo(struct TOPO_BGP* bgp, struct ETCP_CONN* from, cons * * @return 0 при успехе */ -int topo_bgp_process_withdraw(struct TOPO_BGP* bgp, struct ETCP_CONN* sender, const uint8_t* data, size_t len); +int topo_group_process_withdraw(struct TOPO_GROUP* group, struct ETCP_CONN* sender, const uint8_t* data, size_t len); /** * @brief Отправляет NODEINFO пакет одному conn (всегда local_node). */ -void topo_bgp_send_nodeinfo(struct TOPO_NODEQ* node, struct ETCP_CONN* conn); +void topo_group_send_nodeinfo(struct TOPO_GROUP* group, struct TOPO_NODEQ* node, struct ETCP_CONN* conn); /** * @brief Отправляет WITHDRAW для node_id (вызывает broadcast_withdraw). */ -void topo_bgp_send_withdraw(struct TOPO_BGP* bgp, uint64_t node_id); +void topo_group_send_withdraw(struct TOPO_GROUP* group, uint64_t node_id); /** * @brief Поиск оптимального ETCP соединения для указанного node_id. * * Перебирает paths узла, выбирает путь с минимальным hop_count. * - * @param bgp указатель на TOPO_BGP + * @param group указатель на TOPO_GROUP * @param node_id целевой узел * @return оптимальный ETCP_CONN* или NULL */ -struct ETCP_CONN* topo_bgp_find_conn_for_node(struct TOPO_BGP* bgp, uint64_t node_id); +struct ETCP_CONN* topo_group_find_conn_for_node(struct TOPO_GROUP* group, uint64_t node_id); /** * @brief Добавляет путь (conn) в paths узла. * * @return 0 при успехе */ -int topo_bgp_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count); +int topo_group_add_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn, uint64_t* hop_list, uint8_t hop_count); /** * @brief Удаляет conn из paths узла. * * @return 1 если путей не осталось (unreachable) */ -int topo_bgp_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn); +int topo_group_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn); /** * @brief Отправляет NAT_INFO клиенту с его типом NAT. @@ -201,7 +220,7 @@ int topo_bgp_remove_path(struct TOPO_NODEQ* nq, struct ETCP_CONN* conn); * @param nat_port порт клиента (network byte order) * @param nat_type NAT_TYPE_EIM или NAT_TYPE_STRICT */ -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); +void topo_group_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 серверу. @@ -209,23 +228,23 @@ void topo_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t * @param conn соединение к серверу * @param socket_id ID сокета для проверки */ -void topo_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id); +void topo_group_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id); /** * @brief Разрешить/запретить NAT check для локальных подсетей (127.0.0.1, 10.x.x.x и т.д.) * По умолчанию запрещено. Полезно для тестов. */ -void topo_bgp_set_nat_check_local(struct TOPO_BGP* bgp, int allow); +void topo_group_set_nat_check_local(struct TOPO_GROUP* group, int allow); /** * @brief Запускает NAT check для всех линков всех соединений. */ -void topo_bgp_request_nat_check_all(struct TOPO_BGP* bgp); +void topo_group_request_nat_check_all(struct TOPO_GROUP* group); /** * @brief Запускает NAT check для одного линка. */ -void topo_bgp_start_link_nat_check(struct TOPO_BGP* bgp, struct ETCP_LINK* link); +void topo_group_start_link_nat_check(struct TOPO_GROUP* group, struct ETCP_LINK* link); /* Аргумент callback NAT check */ struct nat_check_arg { @@ -238,4 +257,4 @@ struct nat_check_arg { #ifdef __cplusplus } #endif -#endif // TOPO_BGP_H +#endif // TOPO_GROUP_H diff --git a/src/topo_node.c b/src/topo_node.c index 3e847d82..4f97957b 100644 --- a/src/topo_node.c +++ b/src/topo_node.c @@ -10,7 +10,7 @@ #include "etcp.h" #include "config_parser.h" #include "topo_node.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "route_lib.h" #include "etcp_debug.h" @@ -46,21 +46,21 @@ static void free_v6_sub_list(struct memory_pool* pool, struct TOPO_SUBNET6* head while (head) { struct TOPO_SUBNET6* next = head->next; memory_pool_free(pool, head); head = next; } } -void topo_node_free_lists(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq) { - if (!bgp || !nq) return; +void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq) { + if (!group || !nq) return; if (nq->node) { - free_v4_sock_list(bgp->v4_sock_meta_pool, nq->node->v4_sock_meta); - free_v4_addr_list(bgp->v4_addr_pool, nq->node->v4_addrs); - free_v6_sock_list(bgp->v6_sock_meta_pool, nq->node->v6_sock_meta); - free_v6_addr_list(bgp->v6_addr_pool, nq->node->v6_addrs); + free_v4_sock_list(group->instance->topo_groups->v4_sock_meta_pool, nq->node->v4_sock_meta); + free_v4_addr_list(group->instance->topo_groups->v4_addr_pool, nq->node->v4_addrs); + free_v6_sock_list(group->instance->topo_groups->v6_sock_meta_pool, nq->node->v6_sock_meta); + free_v6_addr_list(group->instance->topo_groups->v6_addr_pool, nq->node->v6_addrs); nq->node->v4_sock_meta = NULL; nq->node->v4_addrs = NULL; nq->node->v6_sock_meta = NULL; nq->node->v6_addrs = NULL; topo_node_unref(nq->node); nq->node = NULL; } if (nq->subnets) { - free_v4_sub_list(bgp->v4_subnet_pool, nq->subnets->v4_subnets); - free_v6_sub_list(bgp->v6_subnet_pool, nq->subnets->v6_subnets); + free_v4_sub_list(group->instance->topo_groups->v4_subnet_pool, nq->subnets->v4_subnets); + free_v6_sub_list(group->instance->topo_groups->v6_subnet_pool, nq->subnets->v6_subnets); u_free(nq->subnets); nq->subnets = NULL; } @@ -83,8 +83,8 @@ int topo_node_dyn_size(const struct TOPOMSG_NODE* msg) { + msg->hop_count * 8; } -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; +int topo_node_serialize(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max) { + if (!group || !nq || !nq->node || !out) return -1; struct TOPO_NODE* ni = nq->node; struct TOPOMSG_NODE msg; @@ -154,10 +154,10 @@ int topo_node_serialize(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq, uint8_t* ou // ===== deserialization ===== -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, +int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t len, struct TOPO_NODE** out_ni, struct TOPO_NODESUBNETS** out_subnets, struct TOPOMSG_TRANZIT** out_tranzit, uint8_t* out_tranzit_count, uint64_t** out_hop_list, uint8_t* out_hop_count) { - if (!bgp || !data || len < TOPOMSG_NODE_HDR_SIZE || !out_ni) return -1; + if (!group || !data || len < TOPOMSG_NODE_HDR_SIZE || !out_ni) return -1; const struct TOPOMSG_NODE* msg = (const struct TOPOMSG_NODE*)data; int dyn = topo_node_dyn_size(msg); @@ -183,28 +183,28 @@ int topo_node_deserialize(struct TOPO_BGP* bgp, const uint8_t* data, size_t len, for (int i = 0; i < msg->local_v4_sockets; i++) { const struct TOPOMSG_SOCKMETA4* w = (const struct TOPOMSG_SOCKMETA4*)dp; dp += sizeof(*w); - struct TOPO_SOCKMETA4* e = memory_pool_alloc(bgp->v4_sock_meta_pool); + struct TOPO_SOCKMETA4* e = memory_pool_alloc(group->instance->topo_groups->v4_sock_meta_pool); 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->next = ni->v4_sock_meta; ni->v4_sock_meta = e; } for (int i = 0; i < msg->local_v4_addrs; i++) { const struct TOPOMSG_ADDR4* w = (const struct TOPOMSG_ADDR4*)dp; dp += sizeof(*w); - struct TOPO_ADDR4* e = memory_pool_alloc(bgp->v4_addr_pool); + struct TOPO_ADDR4* e = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); 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; e->next = ni->v4_addrs; ni->v4_addrs = e; } for (int i = 0; i < msg->local_v6_sockets; i++) { const struct TOPOMSG_SOCKMETA6* w = (const struct TOPOMSG_SOCKMETA6*)dp; dp += sizeof(*w); - struct TOPO_SOCKMETA6* e = memory_pool_alloc(bgp->v6_sock_meta_pool); + struct TOPO_SOCKMETA6* e = memory_pool_alloc(group->instance->topo_groups->v6_sock_meta_pool); 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->next = ni->v6_sock_meta; ni->v6_sock_meta = e; } for (int i = 0; i < msg->local_v6_addrs; i++) { const struct TOPOMSG_ADDR6* w = (const struct TOPOMSG_ADDR6*)dp; dp += sizeof(*w); - struct TOPO_ADDR6* e = memory_pool_alloc(bgp->v6_addr_pool); + struct TOPO_ADDR6* e = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool); 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; e->next = ni->v6_addrs; ni->v6_addrs = e; @@ -215,14 +215,14 @@ int topo_node_deserialize(struct TOPO_BGP* bgp, const uint8_t* data, size_t len, if (!r) { topo_node_unref(ni); return -1; } for (int i = 0; i < msg->local_v4_subnets; i++) { const struct TOPOMSG_SUBNET4* w = (const struct TOPOMSG_SUBNET4*)dp; dp += sizeof(*w); - struct TOPO_SUBNET4* e = memory_pool_alloc(bgp->v4_subnet_pool); + struct TOPO_SUBNET4* e = memory_pool_alloc(group->instance->topo_groups->v4_subnet_pool); if (!e) { u_free(r); topo_node_unref(ni); return -1; } memcpy(e->addr, w->addr, 4); e->prefix_length = w->prefix_length; e->next = r->v4_subnets; r->v4_subnets = e; } for (int i = 0; i < msg->local_v6_subnets; i++) { const struct TOPOMSG_SUBNET6* w = (const struct TOPOMSG_SUBNET6*)dp; dp += sizeof(*w); - struct TOPO_SUBNET6* e = memory_pool_alloc(bgp->v6_subnet_pool); + struct TOPO_SUBNET6* e = memory_pool_alloc(group->instance->topo_groups->v6_subnet_pool); if (!e) { u_free(r); topo_node_unref(ni); return -1; } memcpy(e->addr, w->addr, 16); e->prefix_length = w->prefix_length; e->next = r->v6_subnets; r->v6_subnets = e; @@ -255,10 +255,10 @@ int topo_node_deserialize(struct TOPO_BGP* bgp, const uint8_t* data, size_t len, return 0; } -struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_BGP* bgp, uint64_t node_id) { - if (!bgp || !bgp->nodes) return NULL; +struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t node_id) { + if (!group || !group->nodes) return NULL; 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(group->nodes, &key); return e ? (struct TOPO_NODEQ*)e : NULL; } @@ -283,18 +283,18 @@ 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"; } } -void topo_node_dump_all(struct TOPO_BGP* bgp) { - if (!bgp || !bgp->nodes) return; +void topo_node_dump_all(struct TOPO_GROUP* group) { + if (!group || !group->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(group->nodes)); int idx = 0; - struct ll_entry* e = bgp->nodes->head; + struct ll_entry* e = group->nodes->head; while (e) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; struct TOPO_NODE* ni = nq->node; if (!ni) { e = e->next; continue; } - int is_local = (bgp->local_node == nq); + int is_local = (group->local_node == nq); const char* name_s = ni->node_name ? ni->node_name : ""; DEBUG_INFO(DEBUG_CATEGORY_BGP, "--- Node #%d: id=%016llx name=\"%s\" ver=%u dirty=%u alien=%u grp=%llu%s ---", @@ -377,20 +377,20 @@ void topo_node_dump_all(struct TOPO_BGP* bgp) { } } -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; +int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) { + if (!group || !group->nodes || !buf || buf_size == 0) return 0; int pos = 0; pos += snprintf(buf + pos, buf_size > (size_t)pos ? buf_size - pos : 0, - "=== BGP Nodes dump: %d nodes ===\n", queue_entry_count(bgp->nodes)); + "=== BGP Nodes dump: %d nodes ===\n", queue_entry_count(group->nodes)); int idx = 0; - struct ll_entry* e = bgp->nodes->head; + struct ll_entry* e = group->nodes->head; while (e && (size_t)pos < buf_size) { struct TOPO_NODEQ* nq = (struct TOPO_NODEQ*)e; struct TOPO_NODE* ni = nq->node; if (!ni) { e = e->next; continue; } - int is_local = (bgp->local_node == nq); + int is_local = (group->local_node == nq); const char* name_s = ni->node_name ? ni->node_name : ""; #define FMT_ADD(fmt, ...) pos += snprintf(buf + pos, buf_size > (size_t)pos ? buf_size - pos : 0, fmt, ##__VA_ARGS__) @@ -474,8 +474,8 @@ int topo_node_format_all(struct TOPO_BGP* bgp, char* buf, size_t buf_size) { // ===== update my nodeinfo ===== -int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* bgp) { - if (!instance || !bgp) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_bgp_update_my_nodeinfo: invalid args"); return -1; } +int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GROUP* group) { + if (!instance || !group) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "topo_group_update_my_nodeinfo: invalid args"); return -1; } size_t name_len = 0; if (instance->name[0]) { name_len = strlen(instance->name); if (name_len > 63) name_len = 63; } int vc = 0, vc6 = 0; @@ -501,42 +501,42 @@ int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* } int changed = 1; uint8_t old_ver = 0; - if (bgp->local_node && bgp->local_node->node) { - struct TOPO_NODE* oni = bgp->local_node->node; + if (group->local_node && group->local_node->node) { + struct TOPO_NODE* oni = group->local_node->node; old_ver = oni->ver; - changed = (vc != (bgp->local_node->subnets ? topo_list_count((struct _topo_head*)bgp->local_node->subnets->v4_subnets) : 0)) + changed = (vc != (group->local_node->subnets ? topo_list_count((struct _topo_head*)group->local_node->subnets->v4_subnets) : 0)) || (sock_count != topo_list_count((struct _topo_head*)oni->v4_sock_meta)) || (addr_count != topo_list_count((struct _topo_head*)oni->v4_addrs)) || (name_len != (oni->node_name ? strlen(oni->node_name) : 0)) || (memcmp(oni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE) != 0) - || (vc6 != (bgp->local_node->subnets ? topo_list_count((struct _topo_head*)bgp->local_node->subnets->v6_subnets) : 0)) + || (vc6 != (group->local_node->subnets ? topo_list_count((struct _topo_head*)group->local_node->subnets->v6_subnets) : 0)) || (sock6_count != topo_list_count((struct _topo_head*)oni->v6_sock_meta)) || (addr6_count != topo_list_count((struct _topo_head*)oni->v6_addrs)); - 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 (group->local_node && group->instance && group->instance->topo_groups) + if (memcmp(oni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE) != 0) changed = 1; } if (changed) { - if (bgp->local_node) { - if (instance->rt) route_delete(instance->rt, bgp->local_node); - topo_node_free_lists(bgp, bgp->local_node); - u_free(bgp->local_node); - bgp->local_node = NULL; + if (group->local_node) { + if (instance->rt) route_delete(instance->rt, group->local_node); + topo_node_free_lists(group, group->local_node); + u_free(group->local_node); + group->local_node = NULL; } - bgp->local_node = u_calloc(1, sizeof(struct TOPO_NODEQ)); - if (!bgp->local_node) return -1; - struct TOPO_NODEQ* lq = bgp->local_node; + group->local_node = u_calloc(1, sizeof(struct TOPO_NODEQ)); + if (!group->local_node) return -1; + struct TOPO_NODEQ* lq = group->local_node; 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); group->local_node = NULL; return -1; } ni->ref_count = 1; ni->flags = TOPO_FLAG_SEND_SUBNETS; ni->group_id = TOPO_GROUP_UTUN; ni->node_id = instance->node_id; ni->ver = (old_ver % 255) + 1; memcpy(ni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE); - memcpy(ni->ed25519_public_key, bgp->ed25519_public_key, SC_PUBKEY_SIZE); + memcpy(ni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE); if (name_len) { ni->node_name = u_malloc(name_len + 1); if (ni->node_name) { memcpy(ni->node_name, instance->name, name_len); ni->node_name[name_len] = 0; } } lq->node = ni; @@ -549,35 +549,35 @@ int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* 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->local_addr.ss_family == AF_INET) { - { struct TOPO_SOCKMETA4* sm = memory_pool_alloc(bgp->v4_sock_meta_pool); + { struct TOPO_SOCKMETA4* sm = memory_pool_alloc(group->instance->topo_groups->v4_sock_meta_pool); 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; } 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 TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool); + { struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port); 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; } if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 && e_sock->nat_type != NAT_VERIFIED_STRICT) { - struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool); + struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port); 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; } 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 TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool); + struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, &if_sin->sin_addr.s_addr, 4); a->port = ntohs(if_sin->sin_port); 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; } } else if (e_sock->local_addr.ss_family == AF_INET6) { - { struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(bgp->v6_sock_meta_pool); + { struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(group->instance->topo_groups->v6_sock_meta_pool); 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; } struct sockaddr_in6* if_sin6 = (struct sockaddr_in6*)&e_sock->interface_addr; - { struct TOPO_ADDR6* a6 = memory_pool_alloc(bgp->v6_addr_pool); + { struct TOPO_ADDR6* a6 = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool); memcpy(a6->addr, &if_sin6->sin6_addr, 16); a6->port = ntohs(if_sin6->sin6_port); 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; } @@ -587,13 +587,13 @@ int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* { struct CFG_SERVER* srv = instance->config->servers; while (srv) { if (srv->transport && srv->ip.ss_family == AF_INET) { struct sockaddr_in* tcp_sin = (struct sockaddr_in*)&srv->ip; - struct TOPO_ADDR4* a = memory_pool_alloc(bgp->v4_addr_pool); + struct TOPO_ADDR4* a = memory_pool_alloc(group->instance->topo_groups->v4_addr_pool); memcpy(a->addr, &tcp_sin->sin_addr.s_addr, 4); a->port = ntohs(tcp_sin->sin_port); a->type = TOPO_ADDR_INTERFACE; a->socket_id = 0; a->protocol = TOPO_PROTO_TCP; a->next = ni->v4_addrs; ni->v4_addrs = a; } else if (srv->transport && srv->ip.ss_family == AF_INET6) { struct sockaddr_in6* tcp_sin6 = (struct sockaddr_in6*)&srv->ip; - struct TOPO_ADDR6* a6 = memory_pool_alloc(bgp->v6_addr_pool); + struct TOPO_ADDR6* a6 = memory_pool_alloc(group->instance->topo_groups->v6_addr_pool); memcpy(a6->addr, &tcp_sin6->sin6_addr, 16); a6->port = ntohs(tcp_sin6->sin6_port); a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = 0; a6->protocol = TOPO_PROTO_TCP; a6->next = ni->v6_addrs; ni->v6_addrs = a6; @@ -605,11 +605,11 @@ int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* s = instance->config->my_subnets; while (s) { if (s->ip.family == AF_INET) { - struct TOPO_SUBNET4* sub = memory_pool_alloc(bgp->v4_subnet_pool); + struct TOPO_SUBNET4* sub = memory_pool_alloc(group->instance->topo_groups->v4_subnet_pool); memcpy(sub->addr, &s->ip.addr.v4, 4); sub->prefix_length = s->netmask; sub->next = r->v4_subnets; r->v4_subnets = sub; } else if (s->ip.family == AF_INET6) { - struct TOPO_SUBNET6* sub6 = memory_pool_alloc(bgp->v6_subnet_pool); + struct TOPO_SUBNET6* sub6 = memory_pool_alloc(group->instance->topo_groups->v6_subnet_pool); memcpy(sub6->addr, &s->ip.addr.v6, 16); sub6->prefix_length = s->netmask; sub6->next = r->v6_subnets; r->v6_subnets = sub6; } @@ -621,9 +621,9 @@ int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* 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); if (instance->rt && !route_insert(instance->rt, lq)) - DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "topo_bgp_update_my_nodeinfo: failed to insert local routes"); + DEBUG_WARN(DEBUG_CATEGORY_ROUTING, "topo_group_update_my_nodeinfo: failed to insert local routes"); } else { - bgp->local_node->last_ver = bgp->local_node->node->ver; + group->local_node->last_ver = group->local_node->node->ver; } return vc; } diff --git a/src/topo_node.h b/src/topo_node.h index 0d46c96d..14037093 100644 --- a/src/topo_node.h +++ b/src/topo_node.h @@ -10,7 +10,7 @@ extern "C" { #include "../lib/ll_queue.h" #include "secure_channel.h" -struct TOPO_BGP; +struct TOPO_GROUP; struct ETCP_SOCKET; struct UTUN_INSTANCE; @@ -51,7 +51,7 @@ struct UTUN_INSTANCE; #define TOPO_FLAG_SEND_SUBNETS 0x01 // ---- group_id по умолчанию ---- -#define TOPO_GROUP_UTUN 1 +#define TOPO_GROUP_UTUN 0x8000000000000000ULL // ---- состояние связности с удалённым узлом (локальное, не передаётся по BGP) ---- @@ -217,11 +217,11 @@ struct TOPO_NODEQ { // API // ======================================================================= -struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_BGP* bgp, uint64_t node_id); +struct TOPO_NODEQ* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t node_id); void topo_node_ref(struct TOPO_NODE* ni); void topo_node_unref(struct TOPO_NODE* ni); -void topo_node_free_lists(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq); +void topo_node_free_lists(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq); int topo_node_dyn_size(const struct TOPOMSG_NODE* msg); // convenience accessors @@ -232,14 +232,14 @@ static inline const struct TOPO_ADDR6* topo_v6_addrs(const struct TOPO_NODE* static inline const struct TOPO_SUBNET4* topo_v4_subnets(const struct TOPO_NODESUBNETS* r) { return r ? r->v4_subnets : NULL; } static inline const struct TOPO_SUBNET6* topo_v6_subnets(const struct TOPO_NODESUBNETS* r) { return r ? r->v6_subnets : NULL; } -int topo_node_serialize(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max); -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, +int topo_node_serialize(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq, uint8_t* out, size_t out_max); +int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t len, struct TOPO_NODE** out_ni, struct TOPO_NODESUBNETS** out_subnets, struct TOPOMSG_TRANZIT** out_tranzit, uint8_t* out_tranzit_count, uint64_t** out_hop_list, uint8_t* out_hop_count); -int topo_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_BGP* bgp); +int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GROUP* group); -void topo_node_dump_all(struct TOPO_BGP* bgp); -int topo_node_format_all(struct TOPO_BGP* bgp, char* buf, size_t buf_size); +void topo_node_dump_all(struct TOPO_GROUP* group); +int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size); #ifdef __cplusplus } diff --git a/src/topo_node_lmdb.c b/src/topo_node_lmdb.c index f9cba9ee..63fc5f5b 100644 --- a/src/topo_node_lmdb.c +++ b/src/topo_node_lmdb.c @@ -3,13 +3,13 @@ #include #include #include "topo_node_lmdb.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "../lib/debug_config.h" #include "../lib/mem.h" #define NODEINFO_DB_MAPSIZE (10UL * 1024 * 1024) -int topo_node_lmdb_init(struct TOPO_BGP* bgp, const char* db_path) { +int topo_node_lmdb_init(struct TOPO_GROUP* bgp, const char* db_path) { if (!bgp || !db_path || !db_path[0]) return -1; 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; } @@ -29,12 +29,12 @@ int topo_node_lmdb_init(struct TOPO_BGP* bgp, const char* db_path) { return 0; } -void topo_node_lmdb_destroy(struct TOPO_BGP* bgp) { +void topo_node_lmdb_destroy(struct TOPO_GROUP* bgp) { 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"); } } -int topo_node_lmdb_put(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq) { +int topo_node_lmdb_put(struct TOPO_GROUP* bgp, struct TOPO_NODEQ* nq) { if (!bgp || !bgp->nodeinfo_env || !nq || !nq->node) return -1; uint8_t buf[8192]; int ser_len = topo_node_serialize(bgp, nq, buf, sizeof(buf)); @@ -53,7 +53,7 @@ int topo_node_lmdb_put(struct TOPO_BGP* bgp, struct TOPO_NODEQ* nq) { return 0; } -int topo_node_lmdb_del(struct TOPO_BGP* bgp, uint64_t node_id) { +int topo_node_lmdb_del(struct TOPO_GROUP* bgp, uint64_t node_id) { if (!bgp || !bgp->nodeinfo_env) return -1; 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); diff --git a/src/topo_node_lmdb.h b/src/topo_node_lmdb.h index 12682be1..a0f8ba65 100644 --- a/src/topo_node_lmdb.h +++ b/src/topo_node_lmdb.h @@ -9,12 +9,12 @@ extern "C" { #include #include "topo_node.h" -struct TOPO_BGP; +struct TOPO_GROUP; -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); +int topo_node_lmdb_init(struct TOPO_GROUP* group, const char* db_path); +void topo_node_lmdb_destroy(struct TOPO_GROUP* group); +int topo_node_lmdb_put(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq); +int topo_node_lmdb_del(struct TOPO_GROUP* group, uint64_t node_id); #ifdef __cplusplus diff --git a/src/utun_instance.c b/src/utun_instance.c index 70609f05..77f56138 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -8,7 +8,7 @@ #include "topo_node.h" #include "route_lib.h" #include "routing.h" -#include "topo_bgp.h" +#include "topo_group.h" #include "etcp_connections.h" #include "etcp.h" #include "conn_mgr.h" @@ -159,13 +159,14 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u if (socket_result == 1) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "Partial socket initialization - some servers failed to bind"); } - instance->bgp = topo_bgp_init(instance); - if (!instance->bgp) { + instance->topo_groups = topo_groups_init(instance); + if (!instance->topo_groups) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "Failed to initialize BGP module"); } else { DEBUG_INFO(DEBUG_CATEGORY_BGP, "BGP module initialized"); - if (instance->rt && instance->bgp->local_node) { - topo_bgp_update_my_nodeinfo(instance, instance->bgp); + struct TOPO_GROUP* g = topo_groups_get_default(instance->topo_groups); + if (instance->rt && g && g->local_node) { + topo_group_update_my_nodeinfo(instance, g); } } @@ -454,10 +455,9 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) { if (instance->conn_mgr) { conn_mgr_destroy(instance->conn_mgr); instance->conn_mgr = NULL; } // Cleanup BGP module - if (instance->bgp) { + if (instance->topo_groups) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "Destroying BGP module"); - topo_bgp_destroy(instance); - instance->bgp = NULL; + topo_groups_destroy(instance); } // Cleanup firewall diff --git a/src/utun_instance.h b/src/utun_instance.h index 3866dad6..18b8d2fa 100644 --- a/src/utun_instance.h +++ b/src/utun_instance.h @@ -34,7 +34,8 @@ struct ETCP_SOCKET; struct tun_if; struct ETCP_BINDINGS; struct ETCP_ROUTER_BINDINGS; -struct TOPO_BGP; +struct TOPO_GROUP; +struct TOPO_GROUPS; struct control_server; struct msg_transport; struct PING_CONTEXT; @@ -64,7 +65,7 @@ struct UTUN_INSTANCE { struct CFG_ROUTE_ENTRY* route_subnets; struct ROUTE_TABLE* rt; - struct TOPO_BGP* bgp; // BGP module for topology exchange + struct TOPO_GROUPS* topo_groups; // Groups module for topology exchange // Identification uint64_t node_id; diff --git a/tests/test_bgp_route_exchange.c b/tests/test_bgp_route_exchange.c index b834a55f..21da299e 100644 --- a/tests/test_bgp_route_exchange.c +++ b/tests/test_bgp_route_exchange.c @@ -39,7 +39,7 @@ #include "../src/utun_instance.h" #include "../src/routing.h" #include "../src/route_lib.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/dummynet.h" #include "../src/tun_if.h" #include "../src/secure_channel.h" diff --git a/tests/test_bgp_triangle.c b/tests/test_bgp_triangle.c index c5421798..5c3ea308 100644 --- a/tests/test_bgp_triangle.c +++ b/tests/test_bgp_triangle.c @@ -43,7 +43,7 @@ #include "../src/utun_instance.h" #include "../src/routing.h" #include "../src/route_lib.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/topo_node.h" #include "../src/dummynet.h" #include "../src/tun_if.h" @@ -121,18 +121,18 @@ 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) { - if (!inst || !inst->bgp || !inst->bgp->nodes) return 0; - return topo_node_find_by_id(inst->bgp, node_id) != NULL; + if (!inst || !topo_groups_get_default(inst->topo_groups) || !topo_groups_get_default(inst->topo_groups)->nodes) return 0; + return topo_node_find_by_id(topo_groups_get_default(inst->topo_groups), node_id) != NULL; } static int node_path_count(struct UTUN_INSTANCE* inst, uint64_t node_id) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(inst->topo_groups), node_id); if (!nq || !nq->paths) return 0; return queue_entry_count(nq->paths); } static int node_path_has_peer(struct UTUN_INSTANCE* inst, uint64_t node_id, uint64_t peer_id) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(inst->topo_groups), node_id); if (!nq || !nq->paths) return 0; struct ll_entry* e = nq->paths->head; while (e) { @@ -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) { - struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, node_id); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(inst->topo_groups), node_id); return nq ? nq->last_ver : -1; } diff --git a/tests/test_conn_mgr.c b/tests/test_conn_mgr.c index 7e598dbe..aa77239d 100644 --- a/tests/test_conn_mgr.c +++ b/tests/test_conn_mgr.c @@ -26,7 +26,7 @@ #include "../src/config_parser.h" #include "../src/config_updater.h" #include "../src/utun_instance.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/conn_mgr.h" #include "../lib/u_async.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) { (void)arg; if (result) return; - if (!topo_node_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(topo_groups_get_default(g_a->topo_groups), 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); conn_mgr_connect_node(g_a->conn_mgr, NID_B, 0, ccb, NULL); uasync_set_timeout(ua, 50, NULL, (timeout_callback_t)test2, "t2a"); @@ -93,7 +93,7 @@ static void test3(void* arg) { uint64_t aid = 0xEEEE000000000001ULL; 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)); - struct TOPO_NODEQ* nq = topo_node_find_by_id(g_a->bgp, aid); + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(g_a->topo_groups), aid); 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"); else { fail("alien flag not set"); return; } diff --git a/tests/test_etcp_connect.c b/tests/test_etcp_connect.c index 1ee26b70..eb089d88 100644 --- a/tests/test_etcp_connect.c +++ b/tests/test_etcp_connect.c @@ -14,7 +14,7 @@ #include "../src/config_parser.h" #include "../src/config_updater.h" #include "../src/utun_instance.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/topo_node.h" #include "../src/secure_channel.h" #include "../lib/u_async.h" @@ -84,7 +84,7 @@ static struct TOPO_NODEQ* mknode(uint64_t nid, const uint8_t pubkey[32], static void test1(void* arg) { (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; } - struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B); + struct TOPO_NODEQ* nb = topo_node_find_by_id(topo_groups_get_default(g_a->topo_groups), NID_B); 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); cb_type = 0; cb_conn_ok = 0; cb_count = 0; @@ -110,7 +110,7 @@ static void test3(void* arg) { uint64_t fnid = 0xF000000000000001ULL; struct TOPO_NODEQ* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49999); if (!fn) { fail("mknode failed"); return; } - queue_data_put_with_index(g_a->bgp->nodes, &fn->ll); + queue_data_put_with_index(topo_groups_get_default(g_a->topo_groups)->nodes, &fn->ll); g_a->etcp_connect_timeout_tb = 2000; cb_type = -1; cb_conn_ok = -1; cb_count = 0; int r = etcp_connect(g_a, fn, connect_ccb, NULL, ETCP_CONNECT_EARLY | ETCP_CONNECT_LATE); @@ -140,7 +140,7 @@ static void test5(void* arg) { uint64_t fnid = 0xF000000000000002ULL; struct TOPO_NODEQ* fn = mknode(fnid, fk.public_key, 127,0,0,1, 49998); if (!fn) { fail("mknode failed"); return; } - queue_data_put_with_index(g_a->bgp->nodes, &fn->ll); + queue_data_put_with_index(topo_groups_get_default(g_a->topo_groups)->nodes, &fn->ll); g_a->etcp_connect_timeout_tb = 2000; t5_cb_count = 0; int r1 = etcp_connect(g_a, fn, t5_ccb, NULL, ETCP_CONNECT_EARLY | ETCP_CONNECT_LATE); @@ -159,7 +159,7 @@ static void test6(void* arg) { /* ======================== Test 7: EARLY-only flag ======================== */ static void test7(void* arg) { (void)arg; if (result) return; - struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B); + struct TOPO_NODEQ* nb = topo_node_find_by_id(topo_groups_get_default(g_a->topo_groups), NID_B); 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); cb_type = 0; cb_conn_ok = 0; cb_count = 0; @@ -179,7 +179,7 @@ static void test8(void* arg) { /* ======================== Test 9: LATE-only flag ======================== */ static void test9(void* arg) { (void)arg; if (result) return; - struct TOPO_NODEQ* nb = topo_node_find_by_id(g_a->bgp, NID_B); + struct TOPO_NODEQ* nb = topo_node_find_by_id(topo_groups_get_default(g_a->topo_groups), NID_B); 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); cb_type = 0; cb_conn_ok = 0; cb_count = 0; diff --git a/tests/test_etcp_router.c b/tests/test_etcp_router.c index 826c21ed..be97e9b5 100644 --- a/tests/test_etcp_router.c +++ b/tests/test_etcp_router.c @@ -30,7 +30,7 @@ #include "../src/tun_if.h" #include "../src/secure_channel.h" #include "../src/pkt_normalizer.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../lib/u_async.h" #include "../lib/ll_queue.h" #include "../lib/debug_config.h" diff --git a/tests/test_etcp_router_reconnect.c b/tests/test_etcp_router_reconnect.c index 93a1f8e6..9fb998fe 100644 --- a/tests/test_etcp_router_reconnect.c +++ b/tests/test_etcp_router_reconnect.c @@ -20,7 +20,7 @@ #include "../src/etcp_connections.h" #include "../src/etcp_router.h" #include "../src/etcp_api.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/topo_node.h" #include "../src/config_parser.h" #include "../src/utun_instance.h" @@ -172,7 +172,7 @@ static void state_step(void) { switch (g_state) { case ST_INIT: if (g_bgp_ready_mask == 3) { - struct ETCP_CONN* rc = topo_bgp_find_conn_for_node(g_a->bgp, node_c); + struct ETCP_CONN* rc = topo_group_find_conn_for_node(topo_groups_get_default(g_a->topo_groups), node_c); if (rc) g_state=ST_PHASE1_SEND; } break; @@ -204,7 +204,7 @@ static void state_step(void) { etcp_connect(g_b,nq_c,connect_bgp_ready_cb,&cc_c,ETCP_CONNECT_BGP_READY); } if (g_bgp_ready_mask == 3) { - struct ETCP_CONN* rc = topo_bgp_find_conn_for_node(g_a->bgp, node_c); + struct ETCP_CONN* rc = topo_group_find_conn_for_node(topo_groups_get_default(g_a->topo_groups), node_c); if (rc) { g_phase_sent=0; g_state=ST_PHASE3_SEND; } } break; diff --git a/tests/test_etcp_router_unit.c b/tests/test_etcp_router_unit.c index c4a3a338..6da04c9d 100644 --- a/tests/test_etcp_router_unit.c +++ b/tests/test_etcp_router_unit.c @@ -11,7 +11,7 @@ #include "../src/etcp.h" #include "../src/etcp_api.h" #include "../src/etcp_router.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/utun_instance.h" #include "../lib/u_async.h" #include "../lib/ll_queue.h" @@ -140,13 +140,18 @@ static int setup_sign_keys(void) { } static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519_key) { - struct TOPO_BGP* bgp = u_calloc(1, sizeof(struct TOPO_BGP)); - if (!bgp) { printf(" setup_bgp: u_calloc failed\n"); return; } - bgp->instance = inst; - bgp->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE, - 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; } - inst->bgp = bgp; + inst->topo_groups = u_calloc(1, sizeof(struct TOPO_GROUPS)); + if (!inst->topo_groups) { printf(" setup_bgp: topo_groups alloc failed\n"); return; } + inst->topo_groups->group_list = queue_new(inst->ua, 0, 0, 0, "group_list_test"); + struct TOPO_GROUP* group = u_calloc(1, sizeof(struct TOPO_GROUP)); + if (!group) { printf(" setup_bgp: u_calloc failed\n"); return; } + group->instance = inst; + group->group_id = TOPO_GROUP_UTUN; + group->nodes = queue_new(inst->ua, BGP_NODES_HASH_SIZE, + offsetof(struct TOPO_NODEQ, hash_node_id) - sizeof(struct ll_entry), 8, "group_nodes_test"); + if (!group->nodes) { printf(" setup_bgp: queue_new failed\n"); u_free(group); return; } + { struct ll_entry* e = queue_entry_new(sizeof(struct TOPO_GROUP)); + if (e) { *(struct TOPO_GROUP**)e->data = group; queue_data_put(inst->topo_groups->group_list, e); } } struct TOPO_NODEQ* nq = u_calloc(1, sizeof(struct TOPO_NODEQ)); if (!nq) { printf(" setup_bgp: nq alloc failed\n"); return; } @@ -156,18 +161,22 @@ static void setup_bgp_for_sign_test(struct UTUN_INSTANCE* inst, int with_ed25519 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); nq->node = ni; nq->hash_node_id = ni->node_id; - queue_data_put_with_index(bgp->nodes, &nq->ll); + queue_data_put_with_index(group->nodes, &nq->ll); } static void teardown_bgp_for_sign_test(struct UTUN_INSTANCE* inst) { - if (!inst || !inst->bgp) return; - if (inst->bgp->nodes) { + if (!inst || !inst->topo_groups) return; + struct TOPO_GROUP* group = topo_groups_get_default(inst->topo_groups); + if (!group) return; + if (group->nodes) { struct ll_entry* e; - while ((e = queue_data_get(inst->bgp->nodes)) != NULL) queue_entry_free(e); - queue_free(inst->bgp->nodes); + while ((e = queue_data_get(group->nodes)) != NULL) queue_entry_free(e); + queue_free(group->nodes); } - u_free(inst->bgp); - inst->bgp = NULL; + u_free(group); + queue_free(inst->topo_groups->group_list); + u_free(inst->topo_groups); + inst->topo_groups = NULL; } static void inject_signed(etcp_recv_fn recv_cb, struct UTUN_INSTANCE* inst, diff --git a/tests/test_ipv6_sockets.c b/tests/test_ipv6_sockets.c index 55aa744f..f0b9d161 100644 --- a/tests/test_ipv6_sockets.c +++ b/tests/test_ipv6_sockets.c @@ -34,7 +34,7 @@ #include "../src/utun_instance.h" #include "../src/routing.h" #include "../src/route_lib.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/topo_node.h" #include "../src/tun_if.h" #include "../src/secure_channel.h" @@ -136,11 +136,11 @@ static int is_connection_established(struct UTUN_INSTANCE* inst) { static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* inst, int expect_socks, int expect_addrs, int expect_subnets) { - if (!inst || !inst->bgp || !inst->bgp->local_node || !inst->bgp->local_node->node) { + if (!inst || !topo_groups_get_default(inst->topo_groups) || !topo_groups_get_default(inst->topo_groups)->local_node || !topo_groups_get_default(inst->topo_groups)->local_node->node) { printf("FAIL [%s]: no bgp/local_node\n", name); return 0; } - struct TOPO_NODE* ni = inst->bgp->local_node->node; + struct TOPO_NODE* ni = topo_groups_get_default(inst->topo_groups)->local_node->node; struct ETCP_SOCKET* es = inst->etcp_sockets; int v6_sock_found = 0; @@ -156,7 +156,7 @@ static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* in 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); - int v6sub = inst->bgp->local_node->subnets ? topo_list_count((struct _topo_head*)inst->bgp->local_node->subnets->v6_subnets) : 0; + int v6sub = topo_groups_get_default(inst->topo_groups)->local_node->subnets ? topo_list_count((struct _topo_head*)topo_groups_get_default(inst->topo_groups)->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; } printf("PASS [%s]: v6_subnets=%d\n", name, v6sub); @@ -175,8 +175,8 @@ static int verify_ipv6_local_nodeinfo(const char* name, struct UTUN_INSTANCE* in i++; a = a->next; } } - if (expect_subnets > 0 && inst->bgp->local_node->subnets) { - const struct TOPO_SUBNET6* subs = inst->bgp->local_node->subnets->v6_subnets; + if (expect_subnets > 0 && topo_groups_get_default(inst->topo_groups)->local_node->subnets) { + const struct TOPO_SUBNET6* subs = topo_groups_get_default(inst->topo_groups)->local_node->subnets->v6_subnets; if (subs) { 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; } @@ -188,8 +188,8 @@ 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) { - if (!inst || !inst->bgp) { printf("FAIL [%s]: no bgp\n", name); return 0; } - struct TOPO_NODEQ* nq = topo_node_find_by_id(inst->bgp, peer_node_id); + if (!inst || !topo_groups_get_default(inst->topo_groups)) { printf("FAIL [%s]: no bgp\n", name); return 0; } + struct TOPO_NODEQ* nq = topo_node_find_by_id(topo_groups_get_default(inst->topo_groups), 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; } printf("PASS [%s]: remote node %016llx found\n", name, (unsigned long long)peer_node_id); diff --git a/tests/test_nat_detection.c b/tests/test_nat_detection.c index 202ae3de..f08a41ab 100644 --- a/tests/test_nat_detection.c +++ b/tests/test_nat_detection.c @@ -21,7 +21,7 @@ #include "../src/config_updater.h" #include "../src/utun_instance.h" #include "../src/routing.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/route_ping.h" #include "../src/topo_node.h" #include "../src/tun_if.h" @@ -216,7 +216,7 @@ int main(void) { } // Разрешаем NAT check для localhost (для теста) - if (inst_s->bgp) topo_bgp_set_nat_check_local(inst_s->bgp, 1); + if (topo_groups_get_default(inst_s->topo_groups)) topo_group_set_nat_check_local(topo_groups_get_default(inst_s->topo_groups), 1); 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"); @@ -244,16 +244,16 @@ int main(void) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for BGP exchange (S learns C1 and C2)..."); int bgp_wait_cycles = 0; while (!test_timed_out && bgp_wait_cycles < 500) { - if (inst_s->bgp && topo_node_find_by_id(inst_s->bgp, NODE_ID_C1) != NULL && - topo_node_find_by_id(inst_s->bgp, NODE_ID_C2) != NULL) { + if (topo_groups_get_default(inst_s->topo_groups) && topo_node_find_by_id(topo_groups_get_default(inst_s->topo_groups), NODE_ID_C1) != NULL && + topo_node_find_by_id(topo_groups_get_default(inst_s->topo_groups), NODE_ID_C2) != NULL) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "S learned about C1 and C2"); break; } uasync_poll(ua, 10); bgp_wait_cycles++; } - if (!inst_s->bgp || topo_node_find_by_id(inst_s->bgp, NODE_ID_C1) == NULL || - topo_node_find_by_id(inst_s->bgp, NODE_ID_C2) == NULL) { + if (!topo_groups_get_default(inst_s->topo_groups) || topo_node_find_by_id(topo_groups_get_default(inst_s->topo_groups), NODE_ID_C1) == NULL || + topo_node_find_by_id(topo_groups_get_default(inst_s->topo_groups), NODE_ID_C2) == NULL) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "S did not learn about C1/C2 in time"); goto cleanup; } @@ -313,7 +313,7 @@ int main(void) { } // 5. Verify all NAT fields on server - struct TOPO_NODEQ* node_c1 = topo_node_find_by_id(inst_s->bgp, NODE_ID_C1); + struct TOPO_NODEQ* node_c1 = topo_node_find_by_id(topo_groups_get_default(inst_s->topo_groups), NODE_ID_C1); if (!node_c1) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "TOPO_NODEQ for C1 disappeared"); goto cleanup; @@ -361,9 +361,9 @@ int main(void) { } // 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 (topo_groups_get_default(inst_c1->topo_groups) && topo_groups_get_default(inst_c1->topo_groups)->local_node && topo_groups_get_default(inst_c1->topo_groups)->local_node->node) { int found = 0; - for (const struct TOPO_SOCKMETA4* m = inst_c1->bgp->local_node->node->v4_sock_meta; m; m = m->next) { + for (const struct TOPO_SOCKMETA4* m = topo_groups_get_default(inst_c1->topo_groups)->local_node->node->v4_sock_meta; m; m = m->next) { if (m->id == sock_c1->sock_id) { 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); @@ -375,7 +375,7 @@ int main(void) { 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 int nat_found = 0; - for (const struct TOPO_ADDR4* a = inst_c1->bgp->local_node->node->v4_addrs; a; a = a->next) { + for (const struct TOPO_ADDR4* a = topo_groups_get_default(inst_c1->topo_groups)->local_node->node->v4_addrs; a; a = a->next) { if (a->type == TOPO_ADDR_NAT && a->socket_id == sock_c1->sock_id) { uint32_t addr_ip; memcpy(&addr_ip, a->addr, 4); if (addr_ip != link_sc1->nat_ip || a->port != link_sc1->nat_port) { @@ -395,7 +395,7 @@ int main(void) { bgp_wait_cycles = 0; int c2_verified_nat = 0; while (!test_timed_out && bgp_wait_cycles < 500) { - struct TOPO_NODEQ* node_c1_on_c2 = inst_c2->bgp ? topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) : NULL; + struct TOPO_NODEQ* node_c1_on_c2 = topo_groups_get_default(inst_c2->topo_groups) ? topo_node_find_by_id(topo_groups_get_default(inst_c2->topo_groups), NODE_ID_C1) : NULL; if (node_c1_on_c2 && node_c1_on_c2->node) { 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; } @@ -429,7 +429,7 @@ int main(void) { uint32_t target_ip_net = link_sc1->nat_ip; DEBUG_INFO(DEBUG_CATEGORY_BGP, "TEST: sending ping with pubkey, nat_ip_net=0x%08x nat_port=%u", link_sc1->nat_ip, link_sc1->nat_port); - int ret = route_ping_send_req_addr(inst_s->bgp, conn_sc2, + int ret = route_ping_send_req_addr(topo_groups_get_default(inst_s->topo_groups), conn_sc2, target_ip_net, link_sc1->nat_port, 3, 10, 200, 3000, nat_ping_resp_cb, NULL, node_c1->node->public_key); @@ -459,14 +459,14 @@ int main(void) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "Waiting for C2 to learn C1 nodeinfo..."); bgp_wait_cycles = 0; while (!test_timed_out && bgp_wait_cycles < 500) { - if (inst_c2->bgp && topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) != NULL) { + if (topo_groups_get_default(inst_c2->topo_groups) && topo_node_find_by_id(topo_groups_get_default(inst_c2->topo_groups), NODE_ID_C1) != NULL) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "C2 learned C1 nodeinfo"); break; } uasync_poll(ua, 10); bgp_wait_cycles++; } - if (!inst_c2->bgp || topo_node_find_by_id(inst_c2->bgp, NODE_ID_C1) == NULL) { + if (!topo_groups_get_default(inst_c2->topo_groups) || topo_node_find_by_id(topo_groups_get_default(inst_c2->topo_groups), NODE_ID_C1) == NULL) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "FAIL: C2 did not learn C1 nodeinfo in time"); goto cleanup; } @@ -477,7 +477,7 @@ int main(void) { target_ip_net = link_sc1->nat_ip; DEBUG_INFO(DEBUG_CATEGORY_BGP, "TEST: sending ping NO pubkey, nat_ip_net=0x%08x nat_port=%u", link_sc1->nat_ip, link_sc1->nat_port); - ret = route_ping_send_req_addr(inst_s->bgp, conn_sc2, + ret = route_ping_send_req_addr(topo_groups_get_default(inst_s->topo_groups), conn_sc2, target_ip_net, link_sc1->nat_port, 3, 10, 200, 3000, nat_ping_resp_cb, NULL, node_c1->node->public_key); diff --git a/tests/test_nat_transport.c b/tests/test_nat_transport.c index 9905b6c6..15a57720 100644 --- a/tests/test_nat_transport.c +++ b/tests/test_nat_transport.c @@ -21,7 +21,7 @@ #include "../src/config_updater.h" #include "../src/utun_instance.h" #include "../src/routing.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/tun_if.h" #include "../src/nat_transport.h" #include "../src/eim_nat.h" @@ -565,8 +565,8 @@ int main(void) { DEBUG_INFO(DEBUG_CATEGORY_NAT, "Waiting for BGP..."); int bgp_cycles = 0; while (!test_timed_out && bgp_cycles < 500) { - if (inst_provider->bgp && topo_node_find_by_id(inst_provider->bgp, NODE_ID_CLIENT) && - inst_client->bgp && topo_node_find_by_id(inst_client->bgp, NODE_ID_PROVIDER)) { + if (topo_groups_get_default(inst_provider->topo_groups) && topo_node_find_by_id(topo_groups_get_default(inst_provider->topo_groups), NODE_ID_CLIENT) && + topo_groups_get_default(inst_client->topo_groups) && topo_node_find_by_id(topo_groups_get_default(inst_client->topo_groups), NODE_ID_PROVIDER)) { DEBUG_INFO(DEBUG_CATEGORY_NAT, "BGP exchanged"); break; } diff --git a/tests/test_route_lib.c b/tests/test_route_lib.c index d613ce69..77c4295e 100644 --- a/tests/test_route_lib.c +++ b/tests/test_route_lib.c @@ -37,7 +37,7 @@ struct ETCP_CONN { struct UTUN_INSTANCE { uint64_t node_id; struct ROUTE_TABLE* rt; - struct TOPO_BGP* bgp; + struct TOPO_GROUP* group; }; /* Helper to create test TOPO_NODEQ with subnet in linked list */ diff --git a/tests/test_route_ping.c b/tests/test_route_ping.c index 2f20990c..9a3d30ef 100644 --- a/tests/test_route_ping.c +++ b/tests/test_route_ping.c @@ -21,7 +21,7 @@ #include "../src/config_updater.h" #include "../src/utun_instance.h" #include "../src/routing.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/route_ping.h" #include "../src/tun_if.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)..."); int bgp_wait_cycles = 0; while (!test_timed_out && bgp_wait_cycles < 500) { - if (inst_b->bgp && topo_node_find_by_id(inst_b->bgp, NODE_ID_C) != NULL) { + if (topo_groups_get_default(inst_b->topo_groups) && topo_node_find_by_id(topo_groups_get_default(inst_b->topo_groups), NODE_ID_C) != NULL) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "B learned about C"); break; } uasync_poll(ua, 10); bgp_wait_cycles++; } - if (!inst_b->bgp || topo_node_find_by_id(inst_b->bgp, NODE_ID_C) == NULL) { + if (!topo_groups_get_default(inst_b->topo_groups) || topo_node_find_by_id(topo_groups_get_default(inst_b->topo_groups), NODE_ID_C) == NULL) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "B did not learn about C in time"); goto cleanup; } @@ -271,7 +271,7 @@ int main(void) { /* addr[] в network byte order, port в host byte order */ uint32_t target_ip = 0; uint16_t target_port = 0; - struct TOPO_NODEQ* nq = inst_b->bgp ? topo_node_find_by_id(inst_b->bgp, NODE_ID_C) : NULL; + struct TOPO_NODEQ* nq = topo_groups_get_default(inst_b->topo_groups) ? topo_node_find_by_id(topo_groups_get_default(inst_b->topo_groups), NODE_ID_C) : NULL; if (nq && nq->node) { const struct TOPO_ADDR4* a = nq->node->v4_addrs; if (a) { @@ -287,7 +287,7 @@ int main(void) { DEBUG_INFO(DEBUG_CATEGORY_BGP, "Sending route ping request A->B for C (%s:%u)", ip_to_str(&target_ip, AF_INET).str, (unsigned)target_port); memset(&ping_result, 0, sizeof(ping_result)); - int ret = route_ping_send_req_addr(inst_a->bgp, conn_ab, target_ip, target_port, + int ret = route_ping_send_req_addr(topo_groups_get_default(inst_a->topo_groups), conn_ab, target_ip, target_port, 3, // count 10, // interval_ms 200, // timeout_ms diff --git a/tests/test_stcp_traffic.c b/tests/test_stcp_traffic.c index 50a5c115..a1a72669 100644 --- a/tests/test_stcp_traffic.c +++ b/tests/test_stcp_traffic.c @@ -4,7 +4,7 @@ #include "../src/etcp.h" #include "../src/secure_channel.h" #include "../src/etcp_connections.h" -#include "../src/topo_bgp.h" +#include "../src/topo_group.h" #include "../src/topo_node.h" #include "../src/utun_instance.h" #include "../lib/u_async.h" @@ -167,7 +167,7 @@ int main(void) { TASSERT(etcp_bind(srv_inst, 1, srv_recv_cb) >= 0); TASSERT(etcp_bind(cli_inst, 2, cli_recv_cb) >= 0); - struct TOPO_NODEQ *srv_node = srv_inst->bgp ? srv_inst->bgp->local_node : NULL; + struct TOPO_NODEQ *srv_node = topo_groups_get_default(srv_inst->topo_groups) ? topo_groups_get_default(srv_inst->topo_groups)->local_node : NULL; TASSERT(srv_node); // Increase timeout for TCP STCP handshake cli_inst->etcp_connect_timeout_tb = 100000; // 10 seconds diff --git a/tools/chatgui/libutun/CMakeLists.txt b/tools/chatgui/libutun/CMakeLists.txt index 015da858..66ab5649 100644 --- a/tools/chatgui/libutun/CMakeLists.txt +++ b/tools/chatgui/libutun/CMakeLists.txt @@ -56,7 +56,7 @@ set(UTUN_COMMON_SOURCES ${SRC_DIR}/config_updater.c ${SRC_DIR}/route_lib.c ${SRC_DIR}/route6_lib.c - ${SRC_DIR}/topo_bgp.c + ${SRC_DIR}/topo_group.c ${SRC_DIR}/route_ping.c ${SRC_DIR}/topo_node.c ${SRC_DIR}/topo_node_lmdb.c diff --git a/tools/chatgui/transport/chat_core.c b/tools/chatgui/transport/chat_core.c index f9bdb79a..641fecfb 100644 --- a/tools/chatgui/transport/chat_core.c +++ b/tools/chatgui/transport/chat_core.c @@ -12,7 +12,7 @@ #include "../../../src/utun_instance.h" #include "../../../src/etcp_router.h" #include "../../../src/etcp_api.h" -#include "../../../src/topo_bgp.h" +#include "../../../src/topo_group.h" #include "../../../src/topo_node.h" #include "../../../src/conn_mgr.h" #include "../../../src/secure_channel.h" @@ -616,7 +616,8 @@ static void connect_result_cb(int result, uint64_t node_id, void* arg) { void chat_core_connect_from_invite(struct chat_invite* inv) { if (!g_cc.initialized || !g_cc.inst || !inv) return; - if (!g_cc.inst->bgp || !g_cc.inst->conn_mgr) { + struct TOPO_GROUP* group = topo_groups_get_default(g_cc.inst->topo_groups); + if (!group || !g_cc.inst->conn_mgr) { DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "%s: bgp/conn_mgr not available", CC_ID); uint8_t err[12]; int r = -7; memcpy(err, &inv->node_id, 8); memcpy(err + 8, &r, 4); @@ -625,9 +626,8 @@ void chat_core_connect_from_invite(struct chat_invite* inv) { } uint64_t node_id = inv->node_id; - struct TOPO_BGP* bgp = g_cc.inst->bgp; - if (nodeinfo_find_by_id(bgp, node_id)) { + if (nodeinfo_find_by_id(group, node_id)) { DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: node 0x%016llx already in BGP, connecting", CC_ID, (unsigned long long)node_id); conn_mgr_connect_node(g_cc.inst->conn_mgr, node_id, 30000, @@ -688,7 +688,7 @@ void chat_core_connect_from_invite(struct chat_invite* inv) { memset(&nq->connectivity, 0, sizeof(nq->connectivity)); nq->best_socket = NULL; - queue_data_put_with_index(bgp->nodes, &nq->ll); + queue_data_put_with_index(group->nodes, &nq->ll); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: created NODEINFO for 0x%016llx, %d addrs, connecting", CC_ID, (unsigned long long)node_id, inv->addr_count);