You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3.8 KiB
3.8 KiB
STCP Server — приём и рукопожатие соединений
1. Назначение
STCP Server — серверная сторона протокола STCP. Создаёт слушающий TCP-сокет на указанном порту, принимает входящие соединения, выполняет серверную часть X25519-рукопожатия и поднимает зашифрованный канал AES-CTR для обмена сообщениями.
Использует общую структуру struct stcp_conn из stcp.h.
2. Как пользоваться
struct stcp_server *srv = stcp_server_create(ua, port, &my_keys,
on_connect_cb, conn_arg, // вызывается после успешного рукопожатия
on_close_cb, close_arg); // вызывается при закрытии/ошибке
// ... use ...
stcp_server_destroy(srv);
После завершения рукопожатия соединение переходит в STCP_STATE_DATA, вызывается connect_cb. Вышестоящий код может слать сообщения через tx_queue — они будут зашифрованы с CRC32 и отправлены. Входящие расшифрованные сообщения попадают в rx_queue.
Ключевые нюансы:
- Сервер принимает клиентский pubkey+salt (обфусцированный), извлекает pubkey через
sc_obfuscate_pubkey, выполняет ECDH. - Отправляет ответ: статус OK + padding + CRC32, всё зашифровано AES-CTR.
- После рукопожатая трафик шифруется потоковым AES-CTR (XOR), для каждого направления — свой stream.
- Рукопожатие обрабатывается в два этапа:
process_client_handshake(извлечение ключа, дешифровка) →finish_client_handshake(отправка ответа, переход в DATA).
3. API
stcp_server — внутренняя структура
Слушающий сокет, ключи сервера, коллбэки connect_cb / close_cb. Не экспортируется, создаётся только через stcp_server_create.
Функции
stcp_server_create(ua, port, keys, connect_cb, arg, close_cb, close_arg)— создать сервер: открыть TCP-сокет, bind к порту (IPV4, INADDR_ANY), listen(16), зарегистрировать accept-коллбэк. При приёме соединения создаётstruct stcp_connв состоянииSTCP_STATE_HS_SERVER_WAIT.stcp_server_destroy(srv)— закрыть слушающий сокет, освободить память.
Протокол рукопожатия (серверная сторона)
- Сервер читает
SC_PUBKEY_ENC_SIZE + STCP_HS_ENC_CLIENTбайт (pubkey+salt + зашифрованные padding_size + CRC32). - Деобфусцирует клиентский pubkey (
sc_obfuscate_pubkey, salt XOR с SHA256(salt||server_pubkey)). - Выполняет ECDH (
sc_init_ctx+sc_set_peer_public_key) → получаетsession_key, инициализируетstream_send/stream_recv. - Расшифровывает padding_size, проверяет CRC32, ожидает padding-байты.
- Формирует ответ: salt2(8) + обфусцированный серверный pubkey(32) + status=OK(1) + padding_size(2) + CRC32(4) + padding(8). Всё кроме salt2 зашифровано
sc_stream_xor. - Переходит в
STCP_STATE_DATA, вызываетon_ready(==connect_cb).