chat: автоподключение к узлам группы (вкл/выкл) + ручной connect к узлу (desktop+android); фикс reinit при QR-join
This commit is contained in:
1 parent
9ef501a2fb
commit
d7bb58c6fb
20 files changed
+241
-5
No files matched your search
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "chat_core_priv.h"
|
||||
#include "chat_event.h"
|
||||
#include "chat_setting.h"
|
||||
|
||||
#include "../utun_instance.h"
|
||||
#include "../ntp_time.h"
|
||||
@@ -224,6 +225,12 @@ void chat_core_connect_channel(const char* ch_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!chat_setting_get_int("group_autoconnect", 1)) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: connect_channel ch=%s — group_autoconnect disabled, skip auto-connect loop",
|
||||
CC_ID, ch_id);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: connect_channel ch=%s gid=%016llx group_type=%d — starting connect_init", CC_ID, ch_id, (unsigned long long)gid, group->group_type);
|
||||
topo_group_connect_init(group);
|
||||
}
|
||||
@@ -235,3 +242,56 @@ void chat_core_connect_channel_trampoline(void* arg) {
|
||||
chat_core_connect_channel(ch_id);
|
||||
u_free(ch_id);
|
||||
}
|
||||
|
||||
/* ─── однократное подключение к конкретному узлу канала (GUI → uasync) ─── */
|
||||
|
||||
void chat_core_connect_node(const char* ch_id, uint64_t node_id) {
|
||||
if (!g_cc.initialized || !g_cc.inst || !ch_id || !ch_id[0] || !node_id) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "%s: connect_node — skip (not ready or invalid args)", CC_ID);
|
||||
return;
|
||||
}
|
||||
if (node_id == g_cc.inst->node_id) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "%s: connect_node — skip self node=0x%016llx", CC_ID, (unsigned long long)node_id);
|
||||
return;
|
||||
}
|
||||
|
||||
chat_core_ensure_channel_ready(ch_id);
|
||||
|
||||
uint64_t gid = strtoull(ch_id, NULL, 10);
|
||||
struct TOPO_GROUP* group = topo_groups_find(g_cc.inst->topo_groups, gid);
|
||||
if (!group) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "%s: connect_node — group not found ch=%s", CC_ID, ch_id);
|
||||
return;
|
||||
}
|
||||
|
||||
topo_group_connect_node_once(group, node_id);
|
||||
}
|
||||
|
||||
void chat_core_connect_node_trampoline(void* arg) {
|
||||
struct chat_connect_node_req* r = (struct chat_connect_node_req*)arg;
|
||||
if (!r) return;
|
||||
chat_core_connect_node(r->ch_id, r->node_id);
|
||||
u_free(r);
|
||||
}
|
||||
|
||||
/* ─── применение настройки group_autoconnect ко всем CHAT-группам ─── */
|
||||
|
||||
void chat_core_apply_group_autoconnect(void) {
|
||||
int enabled = chat_setting_get_int("group_autoconnect", 1);
|
||||
struct UTUN_INSTANCE* inst = g_cc.inst;
|
||||
if (!inst || !inst->topo_groups || !inst->topo_groups->group_list) return;
|
||||
|
||||
struct ll_entry* e = inst->topo_groups->group_list->head;
|
||||
while (e) {
|
||||
struct TOPO_GROUP* g = (struct TOPO_GROUP*)e;
|
||||
if (g->group_type == TOPO_GROUP_TYPE_CHAT) {
|
||||
if (enabled && !g->connect) {
|
||||
topo_group_connect_init(g);
|
||||
} else if (!enabled && g->connect) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "%s: group_autoconnect OFF — stop auto-connect ch=%s", CC_ID, g->channel_id);
|
||||
topo_group_connect_destroy(g);
|
||||
}
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
@@ -260,6 +260,7 @@ int chat_core_is_initialized(void) { return g_cc.initialized; }
|
||||
|
||||
void chat_core_set_setting(const char* name, const char* value) {
|
||||
chat_setting_set(name, value);
|
||||
if (name && strcmp(name, "group_autoconnect") == 0) chat_core_apply_group_autoconnect();
|
||||
}
|
||||
|
||||
struct chat_setting_arg { char data[256]; };
|
||||
|
||||
@@ -96,6 +96,15 @@ void chat_core_set_setting_trampoline(void* arg);
|
||||
void chat_core_connect_channel(const char* ch_id);
|
||||
void chat_core_connect_channel_trampoline(void* arg);
|
||||
|
||||
/* Однократная попытка подключения к конкретному узлу канала (GUI → uasync) */
|
||||
void chat_core_connect_node(const char* ch_id, uint64_t node_id);
|
||||
void chat_core_connect_node_trampoline(void* arg);
|
||||
|
||||
struct chat_connect_node_req {
|
||||
char ch_id[64];
|
||||
uint64_t node_id;
|
||||
};
|
||||
|
||||
/* Трамплин для gui_bridge_post_uasync (GUI → uasync) */
|
||||
void chat_core_submit_trampoline(void* arg);
|
||||
|
||||
|
||||
@@ -105,4 +105,8 @@ void si_register(struct DB_SYNC_INSTANCE* si, const char* ch_id);
|
||||
|
||||
void on_msg_inserted(struct DB_SYNC_INSTANCE* si, uint64_t record_ts, const char* data, size_t len, uint64_t author, void* arg);
|
||||
|
||||
/* ── применить настройку group_autoconnect ко всем CHAT-группам (chat_channel.c) ── */
|
||||
|
||||
void chat_core_apply_group_autoconnect(void);
|
||||
|
||||
#endif /* CHAT_CORE_PRIV_H */
|
||||
@@ -53,6 +53,7 @@ static const struct chat_setting_def g_setting_defs[] = {
|
||||
{"join_policy", CHAT_SETTING_INT, 1, 0, 2}, /* 0=autojoin, 1=ask, 2=deny */
|
||||
{"whisper_enabled", CHAT_SETTING_BOOL, 0, 0, 1},
|
||||
{"whisper_model_path", CHAT_SETTING_STRING, 0, 0, 0},
|
||||
{"group_autoconnect", CHAT_SETTING_BOOL, 1, 0, 1},
|
||||
};
|
||||
|
||||
#define CHAT_SETTING_COUNT (sizeof(g_setting_defs) / sizeof(g_setting_defs[0]))
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "topo_group_connect.h"
|
||||
#include "topo_recovery.h"
|
||||
#include "broadcast.h"
|
||||
#include "../chat/chat_setting.h"
|
||||
|
||||
#define TOPO_GROUP_UTUN 0x8000000000000000ULL
|
||||
|
||||
@@ -522,7 +523,7 @@ struct TOPO_GROUP* topo_groups_create_group(struct TOPO_GROUPS* g, uint64_t grou
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Group created: group_id=%016llx type=%u ch_id=%s", (unsigned long long)group_id, group_type, group->channel_id);
|
||||
if (group_type == TOPO_GROUP_TYPE_CHAT) topo_group_connect_init(group);
|
||||
if (group_type == TOPO_GROUP_TYPE_CHAT && chat_setting_get_int("group_autoconnect", 1)) topo_group_connect_init(group);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "topo_group.h"
|
||||
#include "topo_node.h"
|
||||
#include "topo_node_sqlite.h"
|
||||
#include "../utun_instance.h"
|
||||
#include "../transport_layer/node_conn_direct.h"
|
||||
#include "../lib/debug_config.h"
|
||||
#include "../lib/mem.h"
|
||||
@@ -523,3 +524,59 @@ static void tgc_cycle_restart(struct TOPO_GROUP_CONNECT* gc) {
|
||||
gc->phase_timer = uasync_set_timeout(gc->group->instance->ua,
|
||||
TGC_DIRECT_TIMEOUT_MS * 10, gc, tgc_phase1_timeout, "tgc_phase1");
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
* Однократное подключение к конкретному узлу (ручной "Connect" из GUI)
|
||||
* ══════════════════════════════════════════════════════════════════════ */
|
||||
|
||||
struct tgc_once_ctx {
|
||||
struct TOPO_GROUP* group;
|
||||
uint64_t node_id;
|
||||
struct NODE_CONN_DIRECT* h;
|
||||
};
|
||||
|
||||
static void tgc_once_cb(struct NODE_CONN_DIRECT* h, enum ncd_event ev, void* arg) {
|
||||
struct tgc_once_ctx* c = (struct tgc_once_ctx*)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);
|
||||
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) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "%s: once-connect TIMEOUT node=0x%016llx ch=%s",
|
||||
TGC_ID, (unsigned long long)c->node_id, c->group->channel_id);
|
||||
node_conn_direct_close(h);
|
||||
} else if (ev == NCD_EVENT_DOWN) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "%s: once-connect DOWN node=0x%016llx ch=%s",
|
||||
TGC_ID, (unsigned long long)c->node_id, c->group->channel_id);
|
||||
node_conn_direct_close(h);
|
||||
}
|
||||
u_free(c);
|
||||
}
|
||||
|
||||
int topo_group_connect_node_once(struct TOPO_GROUP* group, uint64_t node_id) {
|
||||
if (!group || group->group_type != TOPO_GROUP_TYPE_CHAT || !node_id) return -1;
|
||||
if (node_id == group->instance->node_id) return -1;
|
||||
|
||||
struct ETCP_CONN* ex = instance_find_conn(group->instance, node_id);
|
||||
if (ex && ex->links_up && ex->initialized) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "%s: once-connect node=0x%016llx already connected — add to group ch=%s",
|
||||
TGC_ID, (unsigned long long)node_id, group->channel_id);
|
||||
topo_group_new_conn(group, ex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tgc_once_ctx* c = u_calloc(1, sizeof(*c));
|
||||
if (!c) return -1;
|
||||
c->group = group; c->node_id = node_id;
|
||||
|
||||
int r = node_conn_direct_open(group->instance, node_id, tgc_once_cb, c, &c->h, NULL);
|
||||
if (r == NCD_ERR || !c->h) { u_free(c); return -1; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "%s: once-connect node=0x%016llx ch=%s started (rc=%d)",
|
||||
TGC_ID, (unsigned long long)node_id, group->channel_id, r);
|
||||
return 0;
|
||||
}
|
||||
@@ -33,4 +33,9 @@ void topo_group_connect_on_down(struct TOPO_GROUP* group, struct ETCP_CONN* conn
|
||||
int topo_group_connect_active_count(struct TOPO_GROUP* group);
|
||||
void topo_group_connect_restart(struct TOPO_GROUP* group);
|
||||
|
||||
/* Однократная попытка подключения к конкретному узлу группы (без бесконечного
|
||||
* цикла). При успехе соединение добавляется в BGP-группу (topo_group_new_conn),
|
||||
* handle сохраняется в nq->handle. Используется для ручного "Connect" из GUI. */
|
||||
int topo_group_connect_node_once(struct TOPO_GROUP* group, uint64_t node_id);
|
||||
|
||||
#endif
|
||||
@@ -640,10 +640,11 @@ void etcp_conn_reinit_id(struct ETCP_CONN* etcp, const char* reason, uint64_t re
|
||||
// Применение чужого reset_id (эпохи ресета пира). Симметрично:
|
||||
// если uid пира изменился — сбрасываем своё состояние (свой uid сохраняем).
|
||||
void etcp_conn_apply_peer_reset_id(struct ETCP_CONN* conn, uint64_t peer_reset_id) {
|
||||
if (!conn) return;
|
||||
if (!conn || peer_reset_id == 0) return; /* 0 = неизвестно (STCP-сервер ещё не создал conn) */
|
||||
if (peer_reset_id == conn->peer_reset_id) return; // uid пира не изменился
|
||||
uint64_t old = conn->peer_reset_id;
|
||||
conn->peer_reset_id = peer_reset_id;
|
||||
if (conn->got_initial_pkt) {
|
||||
if (old != 0 && conn->got_initial_pkt) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] peer reset id changed to %016llx — resetting self",
|
||||
conn->log_name, (unsigned long long)peer_reset_id);
|
||||
etcp_conn_reinit(conn, "peer reset epoch");
|
||||
|
||||
Reference in new issue
Block a user