diff --git a/doc/etcp_protocol.txt b/doc/etcp_protocol.txt index 7bfa10a2..69400f9c 100644 --- a/doc/etcp_protocol.txt +++ b/doc/etcp_protocol.txt @@ -259,6 +259,15 @@ link_state: 0=just init, 1=handshake, 2=reconnect, 3=connected. При получении INIT получатель создаёт или переиспользует ETCP_CONN и подходящий линк; для существующего соединения проверяет совпадение ключа пира. Эпоха из INIT учитывается через etcp_conn_apply_peer_reset_id, без немедленного сброса потока при смене известной эпохи. +Принятый INIT обновляет recv_keepalive, время последнего RX и входной remote_keepalive=flag_up +до переиспользования буфера для ответа. INIT с flag_up=0 снимает прежний UP UDP-линка: +получение запроса доказывает только входящую достижимость, обратный путь ещё не подтверждён. +Ответ и keepalive отправляются и при DOWN, чтобы холодное подключение и восстановление +могли завершить двустороннюю проверку. При DOWN одного линка соединение остаётся UP, +если есть другой работоспособный линк. Повтор неизменного состояния не создаёт нового DOWN/UP. +INIT_RESPONSE должен содержать полное обязательное тело (64 байта без timestamp/flag_up) +и node_id, соответствующий аутентифицированному ключу пира. Усечённый ответ или чужой node_id +отклоняются до изменения живости, эпохи и параметров линка. Дополнительный padding разрешён. приём кодограмм из UDP выглядит так: uasync select -> etcp_connection.c etcp_connections_read_callback: memory_pool_alloc, decrypt (or init) -> etcp_conn_input (etcp.c/h - сам tcp механизм) -> ETCP_CONN output_queue diff --git a/src/transport_layer/etcp_connections.h b/src/transport_layer/etcp_connections.h index e974b879..d76454e4 100644 --- a/src/transport_layer/etcp_connections.h +++ b/src/transport_layer/etcp_connections.h @@ -111,7 +111,8 @@ struct ETCP_INIT_REQUEST_PKT { #define ETCP_INIT_REQ_SIZE sizeof(struct ETCP_INIT_REQUEST_PKT) -// INIT RESPONSE: server → client +// INIT RESPONSE: server → client. Обязательное тело — 64 байта без timestamp/flag_up и padding. +// Полнота тела и node_id проверяются до изменения RX/эпохи/параметров линка. struct ETCP_INIT_RESPONSE_PKT { uint8_t code; // 0: ETCP_INIT_RESPONSE (0x03) или ETCP_INIT_RESPONSE_NOINIT (0x05) uint8_t node_id[8]; // 1: server node_id (big-endian) @@ -440,6 +441,7 @@ void etcp_tcp_link_start_connect(struct ETCP_LINK *link, struct sockaddr_storage void etcp_tcp_link_start_reconnect(struct ETCP_LINK *link); /* Принять plaintext установленного линка: session/формат проверяются до соответствующей обработки RX. + * pkt_len включает timestamp/flag_up; длина тела после этих трёх байт записывается в pkt->data_len. * 0 — pkt потреблён; ненулевой код — pkt остаётся вызывающему. RX/handshake callbacks могут запросить close; * callbacks_running удерживает teardown до выхода, сброс сессии прекращает обработку старого потока. */ int etcp_packet_decrypted(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt,