chat: invite-ссылки с выбором достижимого узла + tcp_io фикс half-close FIN
- Общий модуль invite_build: сборка utun://-ссылок, авто-выбор лучшего достижимого узла, список кандидатов (вынесено из android jni_bridge) - chatgui: диалог invite с выбором узла (комбобокс), события INVITE_CANDIDATES / INVITE_LINK_READY через gui_bridge - headless/chatcli: invite <ch_id> [node_id], команда invite_nodes - tcp_io: error_cb отличает грациозный EPOLLHUP (SO_ERROR==0) от реальной ошибки — при приостановленном чтении FIN не роняет недослейные данные (фикс flaky half-close) - run_test.sh: half-close echo на выделенном порту 19190 + отдельный DNAT (был недостижим)
This commit is contained in:
1 parent
a17a85a383
commit
1345f44e10
23 files changed
+872
-539
No files matched your search
@@ -46,6 +46,8 @@ static gui_member_updated_fn g_member_updated_cb = nullptr;
|
||||
static gui_member_removed_fn g_member_removed_cb = nullptr;
|
||||
static gui_bgp_info_fn g_bgp_info_cb = nullptr;
|
||||
static gui_admin_key_received_fn g_admin_key_received_cb = nullptr;
|
||||
static gui_invite_link_ready_fn g_invite_link_ready_cb = nullptr;
|
||||
static gui_invite_candidates_fn g_invite_candidates_cb = nullptr;
|
||||
static struct UASYNC* g_ua = nullptr;
|
||||
|
||||
/* ── GuiBridgeReceiver implementation ── */
|
||||
@@ -210,6 +212,29 @@ void GuiBridgeReceiver::processPost(int eventType, QByteArray data) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GUI_EVT_INVITE_LINK_READY:
|
||||
if (dlen >= 3) {
|
||||
uint8_t chLen = d[0];
|
||||
uint16_t linkLen = 0; memcpy(&linkLen, d + 1 + chLen, 2);
|
||||
if (dlen >= 1 + chLen + 2 + linkLen) {
|
||||
if (linkLen == 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "gui_bridge: INVITE_LINK_READY ch=%.*s — empty link (build failed)",
|
||||
chLen, (const char*)d + 1);
|
||||
if (g_invite_link_ready_cb) g_invite_link_ready_cb((const char*)d + 1, chLen, "");
|
||||
} else {
|
||||
if (g_invite_link_ready_cb) g_invite_link_ready_cb((const char*)d + 1, chLen, (const char*)(d + 1 + chLen + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GUI_EVT_INVITE_CANDIDATES:
|
||||
if (dlen >= 2) {
|
||||
uint8_t chLen = d[0];
|
||||
if (dlen >= 1 + chLen + 10) {
|
||||
if (g_invite_candidates_cb) g_invite_candidates_cb((const char*)d + 1, chLen, d + 1 + chLen, dlen - 1 - chLen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "gui_bridge: unknown event type %d", eventType);
|
||||
break;
|
||||
@@ -335,6 +360,14 @@ void gui_bridge_set_admin_key_received_cb(gui_admin_key_received_fn cb) {
|
||||
g_admin_key_received_cb = cb;
|
||||
}
|
||||
|
||||
void gui_bridge_set_invite_link_ready_cb(gui_invite_link_ready_fn cb) {
|
||||
g_invite_link_ready_cb = cb;
|
||||
}
|
||||
|
||||
void gui_bridge_set_invite_candidates_cb(gui_invite_candidates_fn cb) {
|
||||
g_invite_candidates_cb = cb;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
/* ── uTun nodeinfo callback (called from uasync thread) ── */
|
||||
|
||||
Reference in new issue
Block a user