bgp/ncd: владение conn через NCD-handle в senders_list; call audio route persist + incoming call sound

This commit is contained in:
evgeny committed 2026-09-16 13:29:28 +03:00
1 parent b11e77e4c0
commit b483335c06
17 files changed
+185 -48

No files matched your search

+47 -3
View File
@@ -23,6 +23,7 @@
#include "route_connectivity.h"
#include "control_server.h"
#include "conn_mgr.h"
#include "../transport_layer/node_conn_direct.h"
#include "topo_group_connect.h"
#include "topo_recovery.h"
#include "broadcast.h"
@@ -324,7 +325,11 @@ static void topo_group_destroy(struct TOPO_GROUP* group) {
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 2b broadcast_destroy done");
struct ll_entry* e;
while ((e = queue_data_get(group->senders_list)) != NULL) queue_entry_free(e);
while ((e = queue_data_get(group->senders_list)) != NULL) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e;
if (item->handle) { node_conn_direct_close(item->handle); item->handle = NULL; }
queue_entry_free(e);
}
queue_free(group->senders_list);
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 3 senders_list done");
@@ -597,6 +602,24 @@ void topo_group_new_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
}
topo_group_add_to_senders(group, conn);
/* BGP — владелец conn: держим NCD-handle (если ещё нет), чтобы соединение
* не рвалось другими владельцами (conn_mgr) при их закрытии. cb=NULL —
* события BGP уже получает через conn-status callback. */
{ 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->conn == conn) {
if (item->handle == NULL) {
node_conn_direct_open(conn->instance, conn->peer_node_id, NULL, NULL, &item->handle, NULL);
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "topo_group_new_conn: BGP handle acquired node=0x%016llx h=%p",
(unsigned long long)conn->peer_node_id, (void*)item->handle);
}
break;
}
se = se->next;
}
}
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "topo_group_new_conn: peer=%016llx group=%016llx type=%d ch=%s", (unsigned long long)conn->peer_node_id, (unsigned long long)group->group_id, group->group_type, group->channel_id);
topo_group_send_table_request(group, conn);
@@ -658,8 +681,24 @@ void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
node_entry = next;
}
/* освобождаем владение BGP: сначала убираем item из senders_list (чтобы
ре-ентрантный remove_conn от conn DOWN не нашёл его), затем закрываем handle. */
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; }
while (e) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)e->data;
if (item->conn == conn) {
struct NODE_CONN_DIRECT* h = item->handle;
item->handle = NULL;
queue_remove_data(group->senders_list, e);
queue_entry_free(e);
if (h) {
node_conn_direct_close(h);
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "topo_group_remove_conn: BGP handle released node=0x%016llx", (unsigned long long)conn->peer_node_id);
}
break;
}
e = e->next;
}
if (cascaded > 0) topo_recovery_start(group);
@@ -1019,7 +1058,12 @@ static void topo_group_add_to_senders(struct TOPO_GROUP* group, struct ETCP_CONN
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_GROUP_CONN_ITEM));
if (item_entry) { ((struct TOPO_GROUP_CONN_ITEM*)item_entry->data)->conn = conn; queue_data_put(group->senders_list, item_entry); }
if (item_entry) {
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)item_entry->data;
item->conn = conn;
item->handle = NULL;
queue_data_put(group->senders_list, item_entry);
}
}
}
+1
View File
@@ -164,6 +164,7 @@ struct TOPOMSG_ERR_GROUP_MISMATCH {
struct TOPO_GROUP_CONN_ITEM {
struct ll_entry ll;
struct ETCP_CONN* conn;
struct NODE_CONN_DIRECT* handle; // владение BGP этим conn (NCD-handle)
};
struct ETCP_LINK;
+15 -5
View File
@@ -275,6 +275,18 @@ void topo_group_connect_on_down(struct TOPO_GROUP* group, struct ETCP_CONN* conn
* В Phase 2/3 — успех завершает цикл; провал закрывает handle (чтобы не оставить
* залипшее состояние) и ставит паузу перед следующей попыткой.
*/
/* Передача владения: после topo_group_new_conn (который взял свой NCD-handle)
* закрываем connect-фазу handle, чтобы владельцем conn остался один BGP-хэндл
* (в senders_list), без двойного счёта. */
static void tgc_release_handle(struct TOPO_GROUP_CONNECT* gc, struct NODE_CONN_DIRECT* h) {
if (!gc || !h) return;
for (int i = 0; i < gc->handle_count; i++) {
if (gc->handles[i] == h) { gc->handles[i] = NULL; node_conn_direct_close(h); return; }
}
if (gc->cur_handle == h) { gc->cur_handle = NULL; node_conn_direct_close(h); return; }
node_conn_direct_close(h);
}
static void tgc_callback(struct NODE_CONN_DIRECT* h, enum ncd_event event, void* arg) {
struct TOPO_GROUP_CONNECT* gc = (struct TOPO_GROUP_CONNECT*)arg;
struct ETCP_CONN* conn = node_conn_direct_get_conn(h);
@@ -283,10 +295,9 @@ static void tgc_callback(struct NODE_CONN_DIRECT* h, enum ncd_event event, void*
int ok = (event == NCD_EVENT_UP);
if (ok) {
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(gc->group, node_id);
if (nq) nq->handle = h;
/* запуск BGP: узел соединён с группой */
/* запуск BGP: узел соединён с группой (topo_group_new_conn берёт владение NCD-handle) */
if (conn) topo_group_new_conn(gc->group, conn);
tgc_release_handle(gc, h);
} else if (event == NCD_EVENT_TIMEOUT) {
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(gc->group, node_id);
if (nq) nq->handle = NULL;
@@ -540,10 +551,9 @@ static void tgc_once_cb(struct NODE_CONN_DIRECT* h, enum ncd_event ev, void* arg
struct ETCP_CONN* conn = node_conn_direct_get_conn(h);
if (ev == NCD_EVENT_UP && conn) {
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(c->group, c->node_id);
if (nq) nq->handle = h;
node_conn_direct_set_callback(h, NULL, NULL);
topo_group_new_conn(c->group, conn);
node_conn_direct_close(h); /* владение перешло к topo_group_new_conn */
DEBUG_INFO(DEBUG_CATEGORY_BGP, "%s: once-connect UP node=0x%016llx ch=%s",
TGC_ID, (unsigned long long)c->node_id, c->group->channel_id);
} else if (ev == NCD_EVENT_TIMEOUT) {
+11 -9
View File
@@ -343,15 +343,16 @@ static void tgi_handle_info_resp(struct ETCP_CONN* conn, const uint8_t* data, si
topo_group_new_conn(bgp_grp, conn);
}
/* ── успех: переводим ncd-handle во владение узла, доставляем JOIN ── */
/* ── успех: владение conn перешло к topo_group_new_conn (item->handle),
закрываем connect-фазу handle и доставляем JOIN ── */
{
uint64_t node_id = inv->node_id, group_id = inv->group_id;
tgi_cb_t cb = inv->cb; void* cb_arg = inv->cb_arg;
if (inv->ncd_handle) node_conn_direct_set_callback(inv->ncd_handle, NULL, NULL);
struct TOPO_GROUP* g = topo_groups_find(inv->inst->topo_groups, group_id);
struct TOPO_GROUP_NODE* nq = g ? topo_node_find_by_id(g, node_id) : NULL;
if (nq) nq->handle = inv->ncd_handle;
inv->ncd_handle = NULL; /* не закрываем — соединение переходит узлу */
if (inv->ncd_handle) {
node_conn_direct_set_callback(inv->ncd_handle, NULL, NULL);
node_conn_direct_close(inv->ncd_handle);
inv->ncd_handle = NULL;
}
inv->temp_nq = NULL; /* не удаляем узел из группы */
tgi_cancel(inv);
if (cb) cb(node_id, group_id, TGI_EVENT_JOIN, cb_arg);
@@ -511,10 +512,11 @@ struct tgi_conn_ctx { struct UTUN_INSTANCE* inst; uint64_t node_id, group_id; };
static void tgi_to_channel_cb(struct NODE_CONN_DIRECT* h, enum ncd_event ev, void* arg) {
struct tgi_conn_ctx* c = (struct tgi_conn_ctx*)arg;
if (ev == NCD_EVENT_UP) {
struct ETCP_CONN* conn = node_conn_direct_get_conn(h);
struct TOPO_GROUP* g = topo_groups_find(c->inst->topo_groups, c->group_id);
struct TOPO_GROUP_NODE* nq = g ? topo_node_find_by_id(g, c->node_id) : NULL;
if (nq) nq->handle = h;
node_conn_direct_set_callback(h, NULL, NULL);
/* владение переходит к topo_group_new_conn (item->handle), connect-фазу закрываем */
if (g && conn) topo_group_new_conn(g, conn);
node_conn_direct_close(h);
u_free(c);
} else if (ev == NCD_EVENT_TIMEOUT) {
node_conn_direct_force_close(h);
+3 -3
View File
@@ -68,9 +68,9 @@ static void topo_recovery_callback(struct NODE_CONN_DIRECT* h, enum ncd_event ev
ctx->current_node_id = 0;
ctx->current_handle = NULL;
if (event == NCD_EVENT_UP) {
struct TOPO_GROUP_NODE* nq = topo_node_find_by_id(ctx->group, node_id);
if (nq) nq->handle = h;
node_conn_direct_set_callback(h, NULL, NULL);
/* владение переходит к topo_group_new_conn (item->handle), connect-фазу закрываем */
if (conn) topo_group_new_conn(ctx->group, conn);
node_conn_direct_close(h);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "recovery: next=%016llx reconnected to %016llx", (unsigned long long)ctx->next_hop_id, (unsigned long long)node_id);
} else {
node_conn_direct_close(h);