From 07540b7ff87f208940e04538e2a6afd621638cbe Mon Sep 17 00:00:00 2001 From: Evgeny Date: Tue, 12 May 2026 22:08:30 +0300 Subject: [PATCH] fix icmp: use SOCK_RAW for FreeBSD compat, add socket diagnostic logging --- src/icmp_proxy.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/icmp_proxy.c b/src/icmp_proxy.c index 77f13cfd..a45ef6c9 100644 --- a/src/icmp_proxy.c +++ b/src/icmp_proxy.c @@ -54,10 +54,13 @@ static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id, while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16); icmp_hdr->icmp_cksum = ~(uint16_t)sum; + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: sendto dst=0x%08x id=0x%04x seq=%u len=%zu", + dst_ip, echo_id, echo_seq, icmp_len); struct sockaddr_in addr = {.sin_family = AF_INET, .sin_addr = {.s_addr = dst_ip}}; ssize_t n = sendto(g_icmp_ctx->raw_sock, buf, icmp_len, 0, (struct sockaddr*)&addr, sizeof(addr)); u_free(buf); if (n < 0) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: sendto failed: %s", strerror(errno)); return -1; } + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: sendto sent %zd bytes", n); struct icmp_request* r = u_calloc(1, sizeof(struct icmp_request)); if (!r) return 0; @@ -77,6 +80,7 @@ static void raw_read_cb(socket_t sock, void* arg) { uint8_t buf[65536]; struct sockaddr_in from; socklen_t flen = sizeof(from); ssize_t n = recvfrom(g_icmp_ctx->raw_sock, buf, sizeof(buf), 0, (struct sockaddr*)&from, &flen); + if (n <= 0) { if (n < 0) DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: recvfrom error: %s", strerror(errno)); return; } if (n < (ssize_t)(sizeof(struct ip) + ICMP_MINLEN)) return; struct ip* ip_hdr = (struct ip*)buf; @@ -88,6 +92,8 @@ static void raw_read_cb(socket_t sock, void* arg) { struct icmp_request* r = req_find_by_id(g_icmp_ctx->pending, icmp_hdr->icmp_id, icmp_hdr->icmp_seq); if (!r) return; + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: echo reply id=0x%04x seq=%u from=0x%08x", + icmp_hdr->icmp_id, icmp_hdr->icmp_seq, from.sin_addr.s_addr); size_t payload_len = n - ip_hdr_len - ICMP_MINLEN; if (payload_len > 1500) payload_len = 1500; @@ -125,6 +131,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 if (g_icmp_ctx->test_loopback) { + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: test loopback reply to 0x%08x", dst_ip); struct ll_entry* e = queue_entry_new(0); if (e) { e->dgram = u_malloc(ICMP_PROXY_HDR_SIZE + payload_len); @@ -269,10 +276,11 @@ int icmp_proxy_init(struct UTUN_INSTANCE* inst, struct UASYNC* ua) { g_icmp_ctx = ctx; if (ctx->is_exit) { - ctx->raw_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); + ctx->raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); if (ctx->raw_sock == SOCKET_INVALID) - DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: raw socket failed (need root): %s", strerror(errno)); + DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: raw socket(SOCK_RAW) failed: %s", strerror(errno)); else { + DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: raw socket created fd=%d", ctx->raw_sock); ctx->raw_read_id = uasync_add_socket(ua, ctx->raw_sock, raw_read_cb, NULL, NULL, NULL); if (!ctx->raw_read_id) { socket_close_wrapper(ctx->raw_sock); ctx->raw_sock = SOCKET_INVALID; } }