fix icmp: use SOCK_RAW for FreeBSD compat, add socket diagnostic logging
This commit is contained in:
1 parent
d00996243d
commit
07540b7ff8
1 file changed
+10
-2
+10
-2
@@ -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; }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user