Roll back required TUN mappings and verify instance startup failures
This commit is contained in:
1 parent
c4eddfe50e
commit
bb2ef05157
2 files changed
+39
-4
No files matched your search
@@ -752,6 +752,9 @@ struct tcp_proxy_client* tcp_proxy_client_create(struct UTUN_INSTANCE* inst, str
|
||||
}
|
||||
|
||||
int need_tun = tun_name && tun_name[0] && tun_ip && tun_ip[0];
|
||||
if ((tun_name && tun_name[0]) != (tun_ip && tun_ip[0])) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: TUN requires both name and IP"); return NULL;
|
||||
}
|
||||
if (!need_tun && !socks_enabled && !http_proxy_enabled) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "no proxy mode enabled"); return NULL;
|
||||
}
|
||||
@@ -784,10 +787,20 @@ struct tcp_proxy_client* tcp_proxy_client_create(struct UTUN_INSTANCE* inst, str
|
||||
int j; for (j = 0; j < mapping_count; j++) {
|
||||
uint16_t port_net = htons(mappings[j].local_port);
|
||||
struct tcp_pcb *lpcb = tcp_new(p->lwip);
|
||||
if (!lpcb) continue;
|
||||
tcp_bind(lpcb, INADDR_ANY, port_net);
|
||||
if (!lpcb) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: mapping PCB allocation failed port=%u", mappings[j].local_port);
|
||||
tcp_proxy_client_destroy(p); return NULL;
|
||||
}
|
||||
if (tcp_bind(lpcb, INADDR_ANY, port_net) != LERR_OK) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: mapping bind failed port=%u", mappings[j].local_port);
|
||||
tcp_abort(lpcb); tcp_proxy_client_destroy(p); return NULL;
|
||||
}
|
||||
struct tcp_pcb *listen_pcb = tcp_listen(lpcb);
|
||||
if (listen_pcb) { tcp_arg(listen_pcb, p); tcp_accept(listen_pcb, tcp_proxy_client_accept_cb); }
|
||||
if (!listen_pcb) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: mapping listen failed port=%u", mappings[j].local_port);
|
||||
tcp_abort(lpcb); tcp_proxy_client_destroy(p); return NULL;
|
||||
}
|
||||
tcp_arg(listen_pcb, p); tcp_accept(listen_pcb, tcp_proxy_client_accept_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +184,26 @@ static int ownership(int unused) {
|
||||
CHECK_EQ(tcp_proxy_server_init(f.inst), 0); cleanup(&f); return 0;
|
||||
}
|
||||
|
||||
// Конструктор instance сам откатывает proxy-ресурсы, сохраняя заимствованный config при отказе.
|
||||
static int instance_rollback(int kind) {
|
||||
struct UASYNC* ua = uasync_create(); CHECK(ua);
|
||||
const char* text = "[global]\ntun_enabled=no\n"
|
||||
"my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n"
|
||||
"my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n"
|
||||
"[server: s1]\naddr=127.0.0.1:0\ntype=public\n[tcp_proxy_server]\nconnect_timeout=2000\n";
|
||||
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 {
|
||||
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 < 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;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
const struct regression_case cases[] = {
|
||||
{"UDP flow allocation", udp_failures, 0}, {"UDP socket", udp_failures, 1},
|
||||
@@ -194,7 +214,9 @@ int main(int argc, char** argv) {
|
||||
{"UDP empty datagram", udp_failures, 10}, {"UDP context OOM", context_oom, 0},
|
||||
{"ICMP context OOM", context_oom, 1}, {"ICMP unavailable raw", icmp_failures, 0},
|
||||
{"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}
|
||||
{"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}
|
||||
};
|
||||
return regression_run(argc, argv, cases, sizeof(cases) / sizeof(cases[0]));
|
||||
}
|
||||
Reference in new issue
Block a user