# STCP (Secure TCP) — общая часть соединения ## 1. Назначение STCP — потоковый TCP-протокол с X25519-ключеобменом и потоковым AES-CTR шифрованием (stream cipher). Обеспечивает безопасное TCP-соединение: клиент подключается, сервер принимает, выполняется ECDH-рукопожатие с обфускацией публичных ключей, после чего трафик шифруется AES-CTR с контрольными суммами CRC32. Модуль `stcp.c/stcp.h` содержит общие структуры, константы и базовый жизненный цикл соединения `struct stcp_conn`, используемый как клиентской (`stcp_client`), так и серверной (`stcp_server`) сторонами. ## 2. Как пользоваться Типовая схема: вышестоящий код создаёт `struct stcp_conn` (сервер через `stcp_server_create`, клиент — через `stcp_client_connect`), устанавливает очереди приёма/передачи (`stcp_conn_set_tx_queue`, `stcp_conn_set_rx_queue`), коллбэк закрытия (`stcp_conn_set_on_close`). После рукопожатия (`STCP_STATE_DATA`) сообщения передаются через `rx_queue`/`tx_queue`: отправка — через ll_queue с коллбэком `tx_cb`, приём — данные раскладываются в `rx_queue`. Потоковое шифрование (`sc_stream_state`) не требует буферизации целых сообщений — XOR применяется побайтово к потоку, поэтому порядок отправки/приёма критичен. Для каждого направления создаётся отдельный stream (`stream_send`, `stream_recv`). Ключевые нюансы: - Размер сообщения — `uint16_t` в префиксе, макс. 65535 байт. - Каждое сообщение шифруется: 2 байта длины + данные + 4 байта CRC32. - CRC32 проверяется после расшифровки для детектирования повреждений. - При разрыве соединения или ошибке вызывается `on_close`. ## 3. API ### Состояния - `STCP_STATE_INIT` — начальное (на клиенте) - `STCP_STATE_HS_SERVER_WAIT` — сервер ждёт рукопожатия от клиента - `STCP_STATE_DATA` — активный обмен данными (шифрованный) - `STCP_STATE_CLOSED` / `STCP_STATE_ERROR` — завершение ### stcp_conn — структура соединения | Поле | Описание | |------|----------| | `sock` | TCP-сокет | | `ua` | UASYNC event loop | | `state` | Текущее состояние (enum stcp_state) | | `is_server` | 1 = серверная сторона | | `session_key[SC_SESSION_KEY_SIZE]` | Ключ X25519 ECDH (AES-128) | | `stream_send` / `stream_recv` | Состояния потокового AES-CTR для отправки и приёма | | `my_keys` | Локальные ключи X25519 | | `peer_pubkey` | Публичный ключ пира (после рукопожатия) | | `rx_queue` / `tx_queue` | ll_queue для приёма/отправки сообщений | | `tx_cb` | Коллбэк очереди tx_queue | | `recv_buf` | Буфер приёма TCP (динамический, до 128KB) | | `send_buf` | Буфер отправки (для досыла при EAGAIN) | | `hs_expected_len` / `hs_key_processed` | Состояние рукопожатия | | `on_ready` | Вызывается после завершения рукопожатия | | `on_close` | Вызывается при закрытии соединения | ### Функции - `stcp_conn_set_tx_queue(c, q)` — установить очередь отправки, привязывает `tx_cb` как коллбэк - `stcp_conn_set_rx_queue(c, q)` — установить очередь приёма (в неё кладутся расшифрованные сообщения) - `stcp_conn_set_on_close(c, cb, arg)` — установить коллбэк закрытия (err=0 — норма, иначе код ошибки) - `stcp_conn_free(c)` — освободить сокет, буферы, очистить stream-ы. Если `allocated=1` — освободить и саму структуру