Fix: set_ipv6_multicast_hops on unix

This commit is contained in:
DaZuo0122
2026-01-16 21:49:22 +08:00
parent d3ce6b0a93
commit c367ca29e4
3 changed files with 39 additions and 14 deletions

View File

@@ -11,3 +11,4 @@ thiserror = "2"
tokio = { version = "1", features = ["net", "time"] }
surge-ping = "0.8"
wtfnet-geoip = { path = "../wtfnet-geoip" }
libc = "0.2"

View File

@@ -9,9 +9,12 @@ use pnet::transport::{
TransportChannelType, TransportProtocol, icmp_packet_iter, icmpv6_packet_iter,
transport_channel,
};
#[cfg(unix)]
use std::os::unix::io::AsRawFd;
use serde::{Deserialize, Serialize};
use socket2::{Domain, Protocol, Socket, Type};
use std::net::{IpAddr, SocketAddr};
use std::mem::size_of_val;
use std::time::{Duration, Instant};
use thiserror::Error;
use tokio::net::{TcpStream, lookup_host};
@@ -473,9 +476,7 @@ fn udp_trace_hop_v6(
let socket =
std::net::UdpSocket::bind("[::]:0").map_err(|err| ProbeError::Io(err.to_string()))?;
socket
.set_unicast_hops_v6(u32::from(ttl))
.map_err(|err| ProbeError::Io(err.to_string()))?;
set_ipv6_unicast_hops(&socket, ttl)?;
let _ = socket.send_to(&[0u8; 4], addr);
let mut iter = icmpv6_packet_iter(&mut rx);
@@ -491,6 +492,28 @@ fn udp_trace_hop_v6(
}
}
#[cfg(unix)]
fn set_ipv6_unicast_hops(socket: &std::net::UdpSocket, ttl: u8) -> Result<(), ProbeError> {
let fd = socket.as_raw_fd();
let hops: libc::c_int = ttl.into();
let result = unsafe {
libc::setsockopt(
fd,
libc::IPPROTO_IPV6,
libc::IPV6_UNICAST_HOPS,
&hops as *const _ as *const libc::c_void,
size_of_val(&hops) as libc::socklen_t,
)
};
if result == 0 {
Ok(())
} else {
Err(ProbeError::Io(
std::io::Error::last_os_error().to_string(),
))
}
}
#[cfg(unix)]
fn interpret_icmp_v4(packet: &IcmpPacket) -> Option<bool> {
let icmp_type = packet.get_icmp_type();