Protect REALITY STCP traffic with authenticated TLS-like records

This commit is contained in:
evgeny committed 2026-10-07 12:30:45 +02:00
1 parent a49cf5434e
commit a069d11ef9
33 files changed
+1786 -421

No files matched your search

+1 -1
View File
@@ -197,7 +197,7 @@ void cm_candidate_ping_timer_cb(void* arg) {
struct stcp_client** slot = NULL;
for (uint8_t i = 0; i < CONN_MGR_MAX_CANDIDATES; i++)
if (!mgr->cand_tcp_pings[i]) { slot = &mgr->cand_tcp_pings[i]; break; }
if (slot) etcp_send_tcp_ping(mgr->instance, ni->public_key, &link->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_cand_tcp_ping_cb, slot, slot);
if (slot) etcp_send_tcp_ping(mgr->instance, ni->public_key, &link->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_cand_tcp_ping_cb, slot, slot, link->reality_set ? &link->reality : NULL);
} else
etcp_send_ping(mgr->instance, ni->public_key, &link->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL, NULL, 0);
}
+19 -1
View File
@@ -52,6 +52,8 @@ struct conn_probe_ctx {
uint16_t min_rtt; // min RTT в текущей серии
uint16_t timeout_ms;
void* ping_timer;
uint8_t reality_set;
struct reality_client_config reality;
struct stcp_client* tcp_cli; // хендл влётного TCP-пинга (для отмены), NULL для UDP
};
@@ -147,7 +149,7 @@ static int conn_match_candidate_sockets(struct UTUN_INSTANCE* instance,
static int conn_probe_send(struct conn_probe_ctx* ctx) {
if (ctx->is_tcp) {
return etcp_send_tcp_ping(ctx->instance, ctx->peer_pubkey, &ctx->target_addr,
ctx->timeout_ms, conn_probe_single_cb, ctx, &ctx->tcp_cli);
ctx->timeout_ms, conn_probe_single_cb, ctx, &ctx->tcp_cli, ctx->reality_set ? &ctx->reality : NULL);
}
struct ETCP_SOCKET* sock = ctx->candidate_sockets[ctx->candidate_index];
return etcp_send_ping_to_socket(ctx->instance, sock, ctx->peer_pubkey,
@@ -333,6 +335,14 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
ctx->timeout_ms = g_probe_timeout_ms; ctx->best_across_sockets = 65535;
if (a->protocol & TOPO_PROTO_TCP) {
const struct TOPO_REALITY_SOCK *rs = topo_node_find_reality_sock(ni, a->socket_id);
if (a->protocol & TOPO_PROTO_REALITY) {
if (!rs) {
DEBUG_WARN(DEBUG_CATEGORY_REALITY, "probe rejected: REALITY parameters missing for socket=%u", a->socket_id);
u_free(ctx); continue;
}
}
if (rs) { topo_node_reality_config(&ctx->reality, rs); ctx->reality_set = 1; }
ctx->is_tcp = 1;
ctx->candidate_count = 1; ctx->candidate_index = 0; ctx->count_total = 1;
} else {
@@ -371,6 +381,14 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
ctx->timeout_ms = g_probe_timeout_ms; ctx->best_across_sockets = 65535;
if (a6->protocol & TOPO_PROTO_TCP) {
const struct TOPO_REALITY_SOCK *rs = topo_node_find_reality_sock(ni, a6->socket_id);
if (a6->protocol & TOPO_PROTO_REALITY) {
if (!rs) {
DEBUG_WARN(DEBUG_CATEGORY_REALITY, "probe rejected: REALITY parameters missing for socket=%u", a6->socket_id);
u_free(ctx); continue;
}
}
if (rs) { topo_node_reality_config(&ctx->reality, rs); ctx->reality_set = 1; }
ctx->is_tcp = 1;
ctx->candidate_count = 1; ctx->candidate_index = 0; ctx->count_total = 1;
} else {
+9 -5
View File
@@ -73,13 +73,17 @@ const struct TOPO_REALITY_SOCK* topo_node_find_reality_sock(const struct TOPO_NO
}
/* Копирует reality-параметры узла в link->reality и поднимает флаг reality_set. */
void topo_node_reality_config(struct reality_client_config *cfg, const struct TOPO_REALITY_SOCK *rs) {
memcpy(cfg->server_static_pubkey, rs->server_pubkey, REALITY_AUTH_KEY_SIZE);
memcpy(cfg->short_id, rs->short_id, REALITY_SHORT_ID_SIZE);
memcpy(cfg->version, rs->version, REALITY_VERSION_SIZE);
snprintf(cfg->server_name, sizeof(cfg->server_name), "%s", rs->server_name);
cfg->fingerprint = REALITY_FP_OPENSSL;
}
void topo_node_apply_reality(struct ETCP_LINK* link, const struct TOPO_REALITY_SOCK* rs) {
if (!link || !rs) return;
memcpy(link->reality.server_static_pubkey, rs->server_pubkey, REALITY_AUTH_KEY_SIZE);
memcpy(link->reality.short_id, rs->short_id, REALITY_SHORT_ID_SIZE);
memcpy(link->reality.version, rs->version, REALITY_VERSION_SIZE);
snprintf(link->reality.server_name, sizeof(link->reality.server_name), "%s", rs->server_name);
link->reality.fingerprint = REALITY_FP_CHROME;
topo_node_reality_config(&link->reality, rs);
link->reality_set = 1;
}
+1
View File
@@ -289,6 +289,7 @@ static inline const struct TOPO_SUBNET6* topo_v6_subnets(const struct TOPO_NOD
const struct TOPO_REALITY_SOCK* topo_node_find_reality_sock(const struct TOPO_NODE* ni, uint8_t socket_id);
/* Заполнить link->reality из reality-инфо пира (rs из BGP). link->reality_set = 1. */
void topo_node_reality_config(struct reality_client_config *cfg, const struct TOPO_REALITY_SOCK *rs);
void topo_node_apply_reality(struct ETCP_LINK* link, const struct TOPO_REALITY_SOCK* rs);
#ifdef __cplusplus