diff --git a/src/icmp_proxy.c b/src/icmp_proxy.c index 0bf9d97a..77f13cfd 100644 --- a/src/icmp_proxy.c +++ b/src/icmp_proxy.c @@ -124,8 +124,7 @@ static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry) if (g_icmp_ctx->raw_sock != SOCKET_INVALID) { exit_send_echo(inst, client_node_id, dst_ip, echo_id, echo_seq, payload, payload_len); - } else { - // No raw socket (e.g. no root): send simulated echo reply back to client + } else if (g_icmp_ctx->test_loopback) { struct ll_entry* e = queue_entry_new(0); if (e) { e->dgram = u_malloc(ICMP_PROXY_HDR_SIZE + payload_len); @@ -141,6 +140,8 @@ static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry) etcp_route_send(inst, client_node_id, e); } else queue_entry_free(e); } + } else { + DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: no raw socket, dropping echo request to 0x%08x", dst_ip); } drop: @@ -240,6 +241,11 @@ int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst, return 0; } +void icmp_proxy_set_test_loopback(struct UTUN_INSTANCE* inst, int enabled) { + (void)inst; + if (g_icmp_ctx) g_icmp_ctx->test_loopback = enabled; +} + static void req_expire(struct icmp_proxy_ctx* ctx) { uint64_t now = get_time_tb(); struct icmp_request** prev = &ctx->pending; while (*prev) { @@ -259,6 +265,7 @@ int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) { ctx->inst = inst; ctx->ua = ua; ctx->raw_sock = SOCKET_INVALID; ctx->request_timeout_tb = ICMP_TIMEOUT_TB; ctx->is_exit = inst->remote_proxy.enabled; + ctx->test_loopback = 0; g_icmp_ctx = ctx; if (ctx->is_exit) { diff --git a/src/icmp_proxy.h b/src/icmp_proxy.h index 3c79df6b..3886f4d6 100644 --- a/src/icmp_proxy.h +++ b/src/icmp_proxy.h @@ -40,6 +40,7 @@ struct icmp_proxy_ctx { void* raw_read_id; struct icmp_request* pending; uint64_t request_timeout_tb; + int test_loopback; // 1 = virtual loopback when no raw socket (test only) }; int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua); @@ -57,4 +58,6 @@ int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst, uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq, const uint8_t* payload, size_t payload_len); +void icmp_proxy_set_test_loopback(struct UTUN_INSTANCE* inst, int enabled); + #endif // ICMP_PROXY_H diff --git a/tests/test_icmp_proxy.c b/tests/test_icmp_proxy.c index be1b1ff1..8c1ac937 100644 --- a/tests/test_icmp_proxy.c +++ b/tests/test_icmp_proxy.c @@ -154,6 +154,8 @@ int main(void) { if (utun_instance_init(cli) < 0) { printf("[FAIL] client init\n"); goto done; } if (utun_instance_init(exit_node) < 0) { printf("[FAIL] exit init\n"); goto done; } + icmp_proxy_set_test_loopback(exit_node, 1); + g_to_id = uasync_set_timeout(ua, 100, NULL, monitor, "mon"); void* to_id = uasync_set_timeout(ua, TEST_TIMEOUT_MS * 10, NULL, test_timeout, "to");