bgp/ncd: владение conn через NCD-handle в senders_list; call audio route persist + incoming call sound
This commit is contained in:
1 parent
b11e77e4c0
commit
b483335c06
17 files changed
+185
-48
No files matched your search
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user