Preserve datagram bindings and verify optional ICMP behavior

This commit is contained in:
evgeny committed 2026-10-24 13:38:45 +02:00
1 parent bb2ef05157
commit 1ce285c09b
3 files changed
+31 -1

No files matched your search

+3
View File
@@ -379,6 +379,9 @@ int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) {
if (inst->icmp_proxy->ua == ua) return 0;
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "icmp_proxy: init attempted with another event loop"); return -EINVAL;
}
if (inst->router_bindings.callbacks[ETCP_RT_ID_ICMP_PROXY]) {
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "icmp_proxy: service already belongs to another owner"); return -EINVAL;
}
struct icmp_proxy_ctx* ctx = u_calloc(1, sizeof(struct icmp_proxy_ctx));
if (!ctx) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "icmp_proxy: context allocation failed"); return -ENOMEM; }
ctx->inst = inst; ctx->ua = ua; ctx->raw_sock = SOCKET_INVALID;
+3
View File
@@ -305,6 +305,9 @@ int udp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) {
if (inst->udp_proxy->ua == ua) return 0;
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "udp_proxy: init attempted with another event loop"); return -1;
}
if (inst->router_bindings.callbacks[ETCP_RT_ID_UDP_PROXY]) {
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "udp_proxy: service already belongs to another owner"); return -1;
}
struct udp_proxy_ctx* ctx = u_calloc(1, sizeof(struct udp_proxy_ctx));
if (!ctx) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "udp_proxy: context allocation failed"); return -1; }
ctx->inst = inst; ctx->ua = ua;
+25 -1
View File
@@ -1,6 +1,8 @@
/* Отказы реальных UDP-сокетов, атомарный запуск и независимое владение TCP/UDP/ICMP. */
#include "async_regression.h"
#include "../src/utun_instance.h"
#include "../src/transport_layer/etcp.h"
#include "../src/transport_layer/etcp_connections.h"
#include "../src/proxy/udp_proxy.h"
#include "../src/proxy/icmp_proxy.h"
#include "../src/proxy/tcp_proxy_client.h"
@@ -134,6 +136,14 @@ static int icmp_failures(int kind) {
CHECK(f.inst->icmp_proxy == ctx && f.inst->router_bindings.callbacks[ETCP_RT_ID_ICMP_PROXY] == icmp_proxy_recv_cb);
if (kind < 3) {
CHECK(ret < 0); CHECK_EQ(ctx->raw_sock, SOCKET_INVALID); CHECK(!ctx->raw_read_id);
if (kind == 0) {
struct tun_if tun = {0}; tun.input_queue = queue_new(f.ua, 0, 0, 0, "icmp_reply"); CHECK(tun.input_queue);
struct tcp_proxy_client client = {.tun = &tun, .via_node_id = 42}; f.inst->tcp_proxy_client = &client;
struct ll_entry* e = request(1, 0, 4); CHECK(e); e->dgram[ROUTER_SVC_PAYLOAD_OFF] = ICMP_PROXY_SUBCMD_REPLY;
struct ETCP_CONN conn = {.instance = f.inst}; icmp_proxy_recv_cb(&conn, e);
e = queue_data_get(tun.input_queue); CHECK(e && e->len == 33 && e->dgram[0] == 4);
queue_dgram_free(e); queue_entry_free(e); queue_free(tun.input_queue); f.inst->tcp_proxy_client = NULL;
}
deny_raw = 0; mock_raw = 1; CHECK_EQ(icmp_proxy_enable_exit(f.inst), 0);
} else CHECK_EQ(ret, 0);
CHECK_EQ(icmp_proxy_enable_exit(f.inst), 0);
@@ -172,6 +182,12 @@ static int ownership(int unused) {
CHECK(!tcp_proxy_client_create(f.inst, f.ua, NULL, NULL, 1500, 1, NULL, 0, 42, 1, "127.0.0.1:0", 1, "bad"));
CHECK(!f.inst->router_bindings.callbacks[ETCP_RT_ID_TCP_PROXY_CLIENT]);
CHECK(f.inst->udp_proxy == udp && f.inst->icmp_proxy == icmp);
struct tcp_proxy_client_mapping_config maps[2] = {
{.local_port = 80, .remote_port = 80, .remote_ip = "127.0.0.1"},
{.local_port = 80, .remote_port = 81, .remote_ip = "127.0.0.1"}
};
CHECK(!tcp_proxy_client_create(f.inst, f.ua, "proxy_test", "10.0.0.1", 1500, 1, maps, 2, 42, 0, NULL, 0, NULL));
CHECK(!f.inst->router_bindings.callbacks[ETCP_RT_ID_TCP_PROXY_CLIENT]);
CHECK(!tcp_proxy_client_create(f.inst, f.ua, NULL, NULL, 1500, 1, NULL, 0, 42, 1, NULL, 0, NULL));
struct tcp_proxy_client* p = tcp_proxy_client_create(f.inst, f.ua, NULL, NULL, 1500, 1, NULL, 0, 42, 1, "127.0.0.1:0", 0, NULL);
CHECK(p); f.inst->tcp_proxy_client = p; CHECK(socks_proxy_get_port(p->socks_listen));
@@ -194,11 +210,18 @@ static int instance_rollback(int kind) {
struct utun_config* cfg = parse_config_from_buf(text, strlen(text), "proxy-failure"); CHECK(cfg);
if (kind == 0) regression_fault_arm(FAULT_CALLOC, "udp_proxy.c", 1);
else if (kind == 1) regression_fault_arm(FAULT_CALLOC, "icmp_proxy.c", 1);
else if (kind == 3) deny_raw = 1;
else if (kind == 4) { mock_raw = 1; fail_read = 1; }
else {
cfg->global.tcp_proxy_client_socks_enabled = 1;
strcpy(cfg->global.tcp_proxy_client_socks_addr, "invalid");
}
struct UTUN_INSTANCE* inst = utun_instance_create_from_config(ua, cfg);
if (kind == 3) {
CHECK(inst && inst->tcp_proxy_server.enabled && inst->udp_proxy && inst->icmp_proxy);
CHECK_EQ(inst->icmp_proxy->raw_sock, SOCKET_INVALID);
utun_instance_destroy(inst); uasync_destroy(ua, 0); return 0;
}
if (kind < 2) CHECK(regression_fault_hit());
regression_fault_reset(); CHECK(!inst); CHECK_EQ(cfg->global.tcp_proxy_server_enabled, 1);
free_config(cfg); uasync_destroy(ua, 0); return 0;
@@ -216,7 +239,8 @@ int main(int argc, char** argv) {
{"ICMP nonblocking", icmp_failures, 1}, {"ICMP read registration", icmp_failures, 2},
{"ICMP expiry and renewal", icmp_failures, 3}, {"Shared contexts and listener rollback", ownership, 0},
{"Instance UDP rollback", instance_rollback, 0}, {"Instance ICMP rollback", instance_rollback, 1},
{"Instance listener rollback", instance_rollback, 2}
{"Instance listener rollback", instance_rollback, 2}, {"Instance optional ICMP", instance_rollback, 3},
{"Instance raw registration rollback", instance_rollback, 4}
};
return regression_run(argc, argv, cases, sizeof(cases) / sizeof(cases[0]));
}