Browse Source

etcp: единый реестр svc_id + убрать коллизию CHAT/CONN_MGR (0x11)

Все ETCP_ID_*/ETCP_RT_ID_* сведены в etcp_api.h (единственное место
определения) с реестром и предупреждением про коллизии в пределах одного
пространства имён. Убраны локальные define из topo_group.h,
topo_group_invite.h, db_sync.h, chat_sync.h, chat_join.h; хардкод 0x31 в
member_sync.c заменён на ETCP_RT_ID_MEMBER_SYNC.

Коллизия: chatgui-десктоп биндил мёртвый ETCP_RT_ID_CHAT 0x11 поверх
ETCP_RT_ID_CONN_MGR 0x11 — затирался conn_mgr_router_recv_handler, из-за
чего INDIRECT-обмен conn_mgr не работал и голос звонка не устанавливался.
Удалён мёртвый код recvCallback/messageReceived/send в utun_node.{cpp,h}.
proxy
evgeny 2 weeks ago
parent
commit
734a414186
  1. 3
      src/chat/chat_join.h
  2. 5
      src/chat/chat_sync.h
  3. 3
      src/chat/db_sync.h
  4. 2
      src/chat/member_sync.c
  5. 3
      src/routing_layer/topo_group.h
  6. 3
      src/routing_layer/topo_group_invite.h
  7. 1
      src/transport_layer/etcp.c
  8. 63
      src/transport_layer/etcp_api.h
  9. 30
      tools/chatgui/transport/utun_node.cpp
  10. 4
      tools/chatgui/transport/utun_node.h

3
src/chat/chat_join.h

@ -35,8 +35,7 @@ struct UTUN_INSTANCE;
extern "C" {
#endif
/* etcp_router service id (connection ↔ инвайтер) */
#define ETCP_RT_ID_JOIN 0x33
/* etcp_router service id (connection ↔ инвайтер): ETCP_RT_ID_JOIN (см. etcp_api.h) */
/* subcommands (первый байт payload etcp_router) */
#define JOIN_SUBCMD_KEY_REGISTER 0x01 /* инвайтер → connection: {join_key:8} */

5
src/chat/chat_sync.h

@ -35,9 +35,8 @@ extern "C" {
struct UTUN_INSTANCE;
struct UASYNC;
/* etcp service ID (direct P2P) */
#define ETCP_RT_ID_CHAT_SYNC 0x30
#define ETCP_RT_ID_MEMBER_SYNC 0x31
/* etcp service IDs (direct P2P): ETCP_RT_ID_CHAT_SYNC / ETCP_RT_ID_MEMBER_SYNC
* (etcp_bind, см. etcp_api.h) */
/* Message types */
#define CS_MSG_INIT_SYNC 0x01

3
src/chat/db_sync.h

@ -50,8 +50,7 @@ extern "C" {
struct UTUN_INSTANCE;
struct DB_SYNC_INSTANCE;
// etcp_router service ID
#define ETCP_RT_ID_DB_SYNC 0x20
// etcp service ID: ETCP_RT_ID_DB_SYNC (etcp_bind, см. etcp_api.h)
// Message types
#define DB_MSG_INIT_SYNC 0x01

2
src/chat/member_sync.c

@ -911,7 +911,7 @@ void member_sync_subscribe_group(struct UTUN_INSTANCE* inst, struct TOPO_GROUP*
int member_sync_init(struct UTUN_INSTANCE* inst) {
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_MEMBER_SYNC, "%s: init — inst is NULL", MS_ID); return -1; }
int rc = merkle_sync_init(inst, 0x31, &g_member_ops, inst);
int rc = merkle_sync_init(inst, ETCP_RT_ID_MEMBER_SYNC, &g_member_ops, inst);
if (rc != 0) return rc;
/* очистка битых записей во всех каналах перед построением дерева */
member_sync_verify_and_purge_all(inst);

3
src/routing_layer/topo_group.h

@ -87,8 +87,7 @@ void utun_remove_nodeinfo_cbk(struct UTUN_INSTANCE* instance, nodeinfo_cbk_fn fn
void topo_fire_nodeinfo_cbk(struct UTUN_INSTANCE* instance, struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* node);
// ETCP ID для пакетов топологии
#define ETCP_ID_TOPO_ENTRY 0x01
// ETCP ID для пакетов топологии: ETCP_ID_TOPO_ENTRY (см. etcp_api.h)
// Sub-команды
#define TOPO_SUBCMD_NODEINFO 0x04 // полная информация об узле + подсети

3
src/routing_layer/topo_group_invite.h

@ -31,8 +31,7 @@ struct ETCP_CONN;
struct ll_entry;
struct NODE_CONN_DIRECT;
/* service id протокола invite (etcp_bind) */
#define ETCP_RT_ID_GROUP_INVITE 0x13
/* service id протокола invite: ETCP_RT_ID_GROUP_INVITE (etcp_bind, см. etcp_api.h) */
#define TGI_SUBCMD_INFO_REQ 0x01
#define TGI_SUBCMD_INFO_RESP 0x02

1
src/transport_layer/etcp.c

@ -1,6 +1,7 @@
// etcp.c - ETCP Protocol Implementation (refactored and expanded based on etcp_protocol.txt)
#include "etcp.h"
#include "etcp_api.h"
#include "etcp_connect.h"
#include "etcp_debug.h"
#include "etcp_loadbalancer.h"

63
src/transport_layer/etcp_api.h

@ -27,29 +27,62 @@ extern "C" {
#define ETCP_MAX_BINDINGS 256
// ═══════════════════════════════════════════════════════════════════════════
// ЕДИНЫЙ РЕЕСТР ETCP-идентификаторов. Единственное место определения.
//
// Два независимых пространства имён (отдельные таблицы биндинга):
// • ETCP_ID_* — raw ETCP: etcp_bind() / etcp_send()
// • ETCP_RT_ID_* — router-сервисы: etcp_router_bind() / etcp_route_send()
//
// Одинаковое значение в РАЗНЫХ пространствах — НЕ коллизия (напр. 0x00 =
// ETCP_ID_DATA и ETCP_RT_ID_DATA). Коллизия — дубль значения В ПРЕДЕЛАХ одного
// пространства: последний bind затирает предыдущий обработчик и молча ломает
// сервис (реальный случай: ETCP_RT_ID_CHAT 0x11 затирал ETCP_RT_ID_CONN_MGR
// 0x11 → переставал работать conn_mgr).
//
// Часть констант ETCP_RT_ID_* исторически биндится через etcp_bind()
// (raw-пространство) — помечены «(raw)»; их значения занимают raw-реестр.
//
// raw: 0x00 DATA, 0x01 TOPO_ENTRY, 0x02 NAT_DETECTION, 0x03 SVC_ROUTE,
// 0x04 NTP_TIME, 0x05 BROADCAST, 0x12 NCD_CONTROL, 0x13 GROUP_INVITE,
// 0x20 DB_SYNC, 0x30 CHAT_SYNC, 0x31 MEMBER_SYNC
// router: 0x00 DATA, 0x02 NAT, 0x04 TCP_PROXY_SERVER, 0x05 UDP_PROXY,
// 0x06 ICMP_PROXY, 0x07 MEDIA_DELIVERY, 0x08 TCP_PROXY_CLIENT,
// 0x11 CONN_MGR, 0x32 ADMIN_KEY, 0x33 JOIN, 0x34 DM,
// 0x35 DM_MAILBOX, 0x36 CALL
//
// !!! Новый ID: впиши его в нужный реестр выше и убедись, что значение
// не занято в том же пространстве.
// ═══════════════════════════════════════════════════════════════════════════
// === Raw ETCP packet IDs (etcp_bind/etcp_send) ===
#define ETCP_ID_DATA 0x00 // Пакет для передачи адресату
#define ETCP_ID_NAT_DETECTION 0x02 // NAT-детекция (STUN-like ping через третий узел)
#define ETCP_ID_SVC_ROUTE 0x03 // Транспорт роутера (etcp_router)
#define ETCP_ID_DATA 0x00 // пакет для передачи адресату
#define ETCP_ID_TOPO_ENTRY 0x01 // BGP-топология (topo_group)
#define ETCP_ID_NAT_DETECTION 0x02 // NAT-детекция (STUN-like ping)
#define ETCP_ID_SVC_ROUTE 0x03 // транспорт роутера (etcp_router)
#define ETCP_ID_NTP_TIME 0x04 // NTP time sync P2P
#define ETCP_ID_BROADCAST 0x05 // Broadcast messages between peers
#define ETCP_ID_BROADCAST 0x05 // broadcast-сообщения между пирами
// === Router-сервисы (etcp_router_bind/etcp_route_send) ===
#define ETCP_RT_ID_DATA 0x00 // routing.c — маршрутизация данных
#define ETCP_RT_ID_NAT 0x02 // NAT трафик между узлами
#define ETCP_RT_ID_SVC_ROUTE 0x03 // etcp_router — транспорт роутера
#define ETCP_RT_ID_TCP_PROXY_SERVER 0x04 // TCP proxy server: принимает CONNECT/DATA от клиентов
#define ETCP_RT_ID_TCP_PROXY_CLIENT 0x08 // TCP proxy client: принимает DATA/CLOSE/ERROR/FIN от сервера
#define ETCP_RT_ID_NAT 0x02 // NAT-трафик между узлами
#define ETCP_RT_ID_SVC_ROUTE 0x03 // транспорт роутера (raw, = ETCP_ID_SVC_ROUTE)
#define ETCP_RT_ID_TCP_PROXY_SERVER 0x04 // TCP proxy server (CONNECT/DATA от клиентов)
#define ETCP_RT_ID_UDP_PROXY 0x05 // UDP datagram прокси (client ↔ exit)
#define ETCP_RT_ID_ICMP_PROXY 0x06 // ICMP echo прокси (ping через exit)
#define ETCP_RT_ID_MEDIA_DELIVERY 0x07 // распространение медиа (аудио/видео стриминг)
#define ETCP_RT_ID_MEDIA_DELIVERY 0x07 // распространение медиа (аудио/видео)
#define ETCP_RT_ID_TCP_PROXY_CLIENT 0x08 // TCP proxy client (DATA/CLOSE/ERROR/FIN)
#define ETCP_RT_ID_CONN_MGR 0x11 // Connection Manager — management connections
#define ETCP_RT_ID_NCD_CONTROL 0x12 // node_conn_direct — CLOSE / KEEP_ALIVE control
#define ETCP_RT_ID_ADMIN_KEY 0x32 // chat_admin — передача канального приватного ключа (encrypted+signed)
#define ETCP_RT_ID_DM 0x34 // dm_core — прямой p2p чат (msg/ack/hello)
#define ETCP_RT_ID_DM_MAILBOX 0x35 // dm_mailbox — offline-хранение на storage-узлах (put/pull/ack)
#define ETCP_RT_ID_CALL 0x36 // call — P2P аудио-звонок (сигналинг + медиа)
#define ETCP_RT_ID_NCD_CONTROL 0x12 // node_conn_direct CLOSE/KEEP_ALIVE (raw)
#define ETCP_RT_ID_GROUP_INVITE 0x13 // topo_group_invite (raw)
#define ETCP_RT_ID_DB_SYNC 0x20 // db_sync (raw)
#define ETCP_RT_ID_CHAT_SYNC 0x30 // chat_sync (raw)
#define ETCP_RT_ID_MEMBER_SYNC 0x31 // member_sync/merkle_sync (raw)
#define ETCP_RT_ID_ADMIN_KEY 0x32 // chat_admin — канальный приватный ключ
#define ETCP_RT_ID_JOIN 0x33 // chat_join — join-протокол
#define ETCP_RT_ID_DM 0x34 // dm_core — прямой p2p чат
#define ETCP_RT_ID_DM_MAILBOX 0x35 // dm_mailbox — offline-хранение
#define ETCP_RT_ID_CALL 0x36 // call — P2P аудио-звонок
// Connection status events (instance-level callback)
#define ETCP_CONN_STATUS_NEW 0 // соединение создано

30
tools/chatgui/transport/utun_node.cpp

@ -29,10 +29,6 @@ extern "C" {
#include "topo_group.h"
}
#define ETCP_RT_ID_CHAT 0x11
static UtunNode* g_currentNode = nullptr;
UtunNode::UtunNode(QObject* parent) : QObject(parent) {}
UtunNode::~UtunNode() {
@ -97,14 +93,6 @@ void UtunNode::finalize() {
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "finalize: cleanup done");
}
void UtunNode::send(uint64_t dstNodeId, const QByteArray& data) {
if (!m_instance) return;
struct ll_entry* entry = queue_entry_new(data.size());
if (!entry) return;
memcpy(entry->data, data.constData(), data.size());
etcp_route_send(m_instance, TOPO_GROUP_UTUN, dstNodeId, entry, 0, 0);
}
QString UtunNode::nodeIdHex() const {
if (!m_instance) return {};
char buf[32];
@ -129,19 +117,7 @@ bool UtunNode::ntpEnabled() const {
return m_instance ? m_instance->ntp.enabled : false;
}
void UtunNode::recvCallback(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!g_currentNode || !entry || !entry->dgram || entry->len < ROUTER_SVC_HDR_SIZE) return;
uint64_t src;
memcpy(&src, entry->dgram + ROUTER_SVC_SRC_OFF, 8);
QByteArray data((const char*)(entry->dgram + ROUTER_SVC_PAYLOAD_OFF), (int)(entry->len - ROUTER_SVC_PAYLOAD_OFF));
QMetaObject::invokeMethod(g_currentNode, [=] {
emit g_currentNode->messageReceived(src, data);
}, Qt::QueuedConnection);
}
void UtunNode::runLoop() {
g_currentNode = this;
debug_config_init();
debug_enable_function_name(0);
@ -201,7 +177,6 @@ void UtunNode::runLoop() {
struct UASYNC* ua = uasync_create();
if (!ua) {
QMetaObject::invokeMethod(this, [this] { emit error("uasync_create failed"); });
g_currentNode = nullptr;
return;
}
m_ua = ua;
@ -214,7 +189,6 @@ void UtunNode::runLoop() {
QMetaObject::invokeMethod(this, [this] { emit error("parse_config failed"); });
uasync_destroy(ua, 0);
m_ua = nullptr;
g_currentNode = nullptr;
return;
}
cfg->global.db_sync_enabled = 1;
@ -227,7 +201,6 @@ void UtunNode::runLoop() {
QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_create_from_config failed"); });
uasync_destroy(ua, 0);
m_ua = nullptr;
g_currentNode = nullptr;
return;
}
@ -243,7 +216,6 @@ void UtunNode::runLoop() {
m_instance = nullptr;
uasync_destroy(ua, 0);
m_ua = nullptr;
g_currentNode = nullptr;
return;
}
@ -251,8 +223,6 @@ void UtunNode::runLoop() {
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "utun_node: after instance_init, etcp_sockets=%d conns=%d",
sock_count, queue_entry_count(m_instance->connections)); }
etcp_router_bind(m_instance, ETCP_RT_ID_CHAT, recvCallback);
utun_add_nodeinfo_cbk(m_instance, gui_nodeinfo_cb_impl, nullptr);
/* Bridge chat events to GUI via gui_bridge */

4
tools/chatgui/transport/utun_node.h

@ -30,8 +30,6 @@ public:
struct UTUN_INSTANCE* instance() const { return m_instance; }
void send(uint64_t dstNodeId, const QByteArray& data);
QString nodeIdHex() const;
QString pubKeyHex() const;
int64_t ntpOffsetUs() const;
@ -42,11 +40,9 @@ signals:
void started();
void stopped();
void error(const QString& msg);
void messageReceived(uint64_t src, const QByteArray& data);
private:
void runLoop();
static void recvCallback(struct ETCP_CONN* conn, struct ll_entry* entry);
UTUN_INSTANCE* m_instance = nullptr;
struct UASYNC* m_ua = nullptr;

Loading…
Cancel
Save