etcp_router: sess_id как локальный счётчик переустановок (не в протоколе)
This commit is contained in:
1 parent
2d04bf941b
commit
01ea6913ae
4 files changed
+26
-64
No files matched your search
@@ -202,7 +202,7 @@ static int router_build_packet(struct ETCP_ROUTER_CONN* rconn, const uint8_t* pa
|
||||
hdr->seq = rconn->tx_seq++;
|
||||
hdr->svc_id = rconn->svc_id;
|
||||
{
|
||||
uint8_t f = (rconn->sess_id << ROUTER_SESS_ID_SHIFT);
|
||||
uint8_t f = 0;
|
||||
if (!rconn->start_sent && hdr->seq == 0 && pl_len > 0) f |= ROUTER_FLAG_START;
|
||||
hdr->flags = f;
|
||||
}
|
||||
@@ -232,7 +232,7 @@ static void router_send_ctrl(struct ETCP_ROUTER_CONN* rconn, uint8_t flag_bits)
|
||||
hdr->src_node_id = rconn->inst->node_id;
|
||||
hdr->seq = 0;
|
||||
hdr->svc_id = rconn->svc_id;
|
||||
hdr->flags = (rconn->sess_id << ROUTER_SESS_ID_SHIFT) | flag_bits;
|
||||
hdr->flags = flag_bits;
|
||||
hdr->timestamp = get_current_timestamp();
|
||||
struct ll_entry* entry = queue_entry_new(0);
|
||||
if (!entry) { u_free(hdr); return; }
|
||||
@@ -263,7 +263,7 @@ static void router_send_rst(struct ETCP_ROUTER_CONN* rconn) {
|
||||
hdr->dst_node_id = rconn->remote_node_id;
|
||||
hdr->src_node_id = inst->node_id;
|
||||
hdr->seq = 0;
|
||||
hdr->flags = ROUTER_FLAG_RST | (rconn->sess_id << ROUTER_SESS_ID_SHIFT);
|
||||
hdr->flags = ROUTER_FLAG_RST;
|
||||
hdr->svc_id = rconn->svc_id;
|
||||
hdr->timestamp = get_current_timestamp();
|
||||
struct ll_entry* entry = queue_entry_new(0);
|
||||
@@ -376,7 +376,6 @@ static void router_conn_reset(struct ETCP_ROUTER_CONN* rconn) {
|
||||
|
||||
rconn->tx_seq = 0; rconn->rx_seq = 0; rconn->tx_acked = 0;
|
||||
rconn->last_sent_ack_seq = 0; rconn->last_ack_sent_tb = 0;
|
||||
rconn->peer_sess_id = 0;
|
||||
rconn->send_blocked = 0; rconn->start_sent = 0; rconn->peer_sync_done = 0;
|
||||
rconn->no_route = 0; rconn->no_route_timer = NULL; rconn->no_ack_count = 0; rconn->closed = 0;
|
||||
rconn->c_pkts_sent = 0; rconn->c_pkts_send_err = 0; rconn->c_pkts_rcvd = 0;
|
||||
@@ -741,7 +740,7 @@ static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
|
||||
hdr->src_node_id = inst->node_id;
|
||||
hdr->seq = rconn->rx_seq;
|
||||
hdr->svc_id = rconn->svc_id;
|
||||
hdr->flags = (rconn->sess_id << ROUTER_SESS_ID_SHIFT);
|
||||
hdr->flags = 0;
|
||||
if (rconn->last_recv_updated) {
|
||||
uint64_t now = get_time_tb();
|
||||
hdr->timestamp = rconn->last_recv_pkt_ts + (uint32_t)(now - rconn->last_recv_pkt_local_tb);
|
||||
@@ -1028,17 +1027,13 @@ static void router_forward_transit(struct UTUN_INSTANCE* inst, struct ll_entry*
|
||||
static int router_check_peer_restart(struct UTUN_INSTANCE* inst, struct ETCP_ROUTER_CONN** prconn,
|
||||
struct SVC_ROUTE_HDR* hdr) {
|
||||
struct ETCP_ROUTER_CONN* rconn = *prconn;
|
||||
uint8_t incoming_sess = (hdr->flags >> ROUTER_SESS_ID_SHIFT) & 0x3;
|
||||
if (incoming_sess != rconn->peer_sess_id ||
|
||||
((hdr->flags & ROUTER_FLAG_START) && rconn->rx_seq > 0)) {
|
||||
if ((hdr->flags & ROUTER_FLAG_START) && rconn->rx_seq > 0) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE,
|
||||
"router: peer restart sess_id=%u→%u svc_id=%u from %016llx",
|
||||
rconn->peer_sess_id, incoming_sess, hdr->svc_id,
|
||||
(unsigned long long)hdr->src_node_id);
|
||||
"router: peer restart svc_id=%u from %016llx",
|
||||
hdr->svc_id, (unsigned long long)hdr->src_node_id);
|
||||
etcp_router_conn_restart(inst, hdr->group_id, hdr->src_node_id, hdr->svc_id);
|
||||
*prconn = etcp_router_conn_get(inst, hdr->group_id, hdr->src_node_id, hdr->svc_id);
|
||||
if (!*prconn) return -1;
|
||||
(*prconn)->peer_sess_id = incoming_sess;
|
||||
rconn = *prconn;
|
||||
}
|
||||
return 0;
|
||||
@@ -1121,7 +1116,6 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
||||
if (!rconn) {
|
||||
rconn = etcp_router_conn_get(inst, hdr->group_id, hdr->src_node_id, hdr->svc_id);
|
||||
if (!rconn) { free_entry(entry); return; }
|
||||
rconn->peer_sess_id = (hdr->flags >> ROUTER_SESS_ID_SHIFT) & 0x3;
|
||||
}
|
||||
if (router_check_peer_restart(inst, &rconn, hdr) != 0) { free_entry(entry); return; }
|
||||
|
||||
@@ -1256,8 +1250,8 @@ void etcp_router_conn_restart(struct UTUN_INSTANCE* inst, uint64_t group_id, uin
|
||||
struct ETCP_ROUTER_CONN* rconn = router_conn_find(inst, group_id, remote_node_id, svc_id);
|
||||
if (!rconn) return;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_restart: svc_id=%u remote=%016llx — resetting local state",
|
||||
svc_id, (unsigned long long)remote_node_id);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_restart: svc_id=%u remote=%016llx sess_id=%u→%u — resetting local state",
|
||||
svc_id, (unsigned long long)remote_node_id, rconn->sess_id, rconn->sess_id + 1);
|
||||
|
||||
etcp_recv_fn cb = inst->router_bindings.callbacks[svc_id];
|
||||
if (cb) {
|
||||
@@ -1276,6 +1270,7 @@ void etcp_router_conn_restart(struct UTUN_INSTANCE* inst, uint64_t group_id, uin
|
||||
}
|
||||
|
||||
router_conn_reset(rconn);
|
||||
rconn->sess_id++;
|
||||
}
|
||||
|
||||
void etcp_router_on_send_ready(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t node_id, uint8_t svc_id,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//
|
||||
// Формат SVC_ROUTE пакета:
|
||||
// [cmd:1] [group_id:8] [dst_node_id:8] [src_node_id:8] [seq:4] [svc_id:1] [flags:1] [timestamp:2] [payload...]
|
||||
// flags: bit7=START, bit6=RST, bit5-4=sess_id(0-3), bit3=SIGNED, bit2=ENCRYPTED, bit1=CLOSE
|
||||
// flags: bit7=START, bit6=RST, bit3=SIGNED, bit2=ENCRYPTED, bit1=CLOSE
|
||||
// ACK-пакет: тот же заголовок, seq=rx_seq, payload_len=0
|
||||
#ifndef ETCP_ROUTER_H
|
||||
#define ETCP_ROUTER_H
|
||||
@@ -28,7 +28,7 @@ struct SVC_ROUTE_HDR {
|
||||
uint64_t src_node_id;
|
||||
uint32_t seq; // data: tx_seq; ACK: rx_seq (ожидаемый seq)
|
||||
uint8_t svc_id; // идентификатор сервиса
|
||||
uint8_t flags; // bit7=START, bit6=RST, bit5-4=sess_id, bit2=ENCRYPTED, bit1=CLOSE
|
||||
uint8_t flags; // bit7=START, bit6=RST, bit3=SIGNED, bit2=ENCRYPTED, bit1=CLOSE
|
||||
uint16_t timestamp; // часы отправителя (0.1ms), для RTT; ACK: эхо последнего data-пакета
|
||||
};
|
||||
#pragma pack(pop)
|
||||
@@ -51,8 +51,6 @@ struct SVC_ROUTE_HDR {
|
||||
#define ROUTER_FLAG_ENCRYPTED 0x04 // payload зашифрован AES-128-CCM (nonce+tag+crc)
|
||||
#define ROUTER_FLAG_SIGNED 0x08 // пакет содержит Ed25519 подпись (64 байта после payload)
|
||||
#define ROUTER_FLAG_CLOSE 0x02 // нормальное закрытие conn
|
||||
#define ROUTER_SESS_ID_SHIFT 4
|
||||
#define ROUTER_SESS_ID_MASK 0x30
|
||||
|
||||
// Очередь транзитных пакетов для пары (group_id, src_node_id, dst_node_id)
|
||||
// Создаётся когда не получается отправить пакет в ETCP напрямую,
|
||||
@@ -114,8 +112,7 @@ struct ETCP_ROUTER_CONN {
|
||||
uint8_t closed; // 1 = в процессе закрытия, таймеры игнорируют
|
||||
void* close_callback; // пользовательский коллбэк завершения закрытия
|
||||
void* close_callback_arg; // аргумент для close_callback
|
||||
uint8_t sess_id; // наш session id (0-3)
|
||||
uint8_t peer_sess_id; // последний sess_id от peer'а
|
||||
uint32_t sess_id; // локальный счётчик переустановок (0 при создании, ++ при рестарте; на wire не пишется)
|
||||
uint8_t start_sent; // 0 = нужно отправить START в первом data
|
||||
uint8_t peer_sync_done; // 0 = rx_seq ещё не синхронизирован с удалённым seq (авто-создание/рестарт)
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ etcp_route_send(inst, group_id, dst, e, force, ROUTE_CRYPTO_SIGN | ROUTE_CRYPTO_
|
||||
**SVC_ROUTE_HDR** (33 байта) — заголовок пакета:
|
||||
`cmd(1) + group_id(8) + dst_node_id(8) + src_node_id(8) + seq(4) + svc_id(1) + flags(1) + timestamp(2)`
|
||||
|
||||
Флаги: `ROUTER_FLAG_START` (0x80), `ROUTER_FLAG_RST` (0x40), `ROUTER_FLAG_SIGNED` (0x08), `ROUTER_FLAG_ENCRYPTED` (0x04), `ROUTER_FLAG_CLOSE` (0x02). Sess_id в bits 5-4.
|
||||
Флаги: `ROUTER_FLAG_START` (0x80), `ROUTER_FLAG_RST` (0x40), `ROUTER_FLAG_SIGNED` (0x08), `ROUTER_FLAG_ENCRYPTED` (0x04), `ROUTER_FLAG_CLOSE` (0x02).
|
||||
|
||||
**Формат доставки сервису** (router → callback):
|
||||
`[svc_id:1][src_node_id:8][dst_node_id:8][rx_flags:1][payload...]` (ROUTER_SVC_HDR_SIZE = 18).
|
||||
|
||||
Reference in new issue
Block a user