Preserve datagram bindings and verify optional ICMP behavior
This commit is contained in:
1 parent
bb2ef05157
commit
1ce285c09b
3 files changed
+31
-1
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]));
|
||||
}
|
||||
Reference in new issue
Block a user