Protect REALITY STCP traffic with authenticated TLS-like records
This commit is contained in:
1 parent
a49cf5434e
commit
a069d11ef9
33 files changed
+1786
-421
No files matched your search
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user