Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Release build not working with raw socket
I am writing small async ping collector, using non-blocking raw socket. The is code is wokring perfectly fine with debug build, but it gives error for release build at sent_to call.
2025-08-28T12:39:04.010149Z ERROR socket-manager::sender: failed to sent data: Address family not supported by protocol (os error 97)
2025-08-28T12:39:04.010199Z ERROR socket-manager::sender: for task_id: 1, failed to send payload: Io(Os { code: 97, kind: Uncategorized, message: "Address family not supported by protocol" })
2025-08-28T12:39:04.012623Z ERROR socket-manager::sender: failed to sent data: Address family not supported by protocol (os error 97)
2025-08-28T12:39:04.012677Z ERROR socket-manager::sender: for task_id: 2, failed to send payload: Io(Os { code: 97, kind: Uncategorized, message: "Address family not supported by protocol" })
2025-08-28T12:39:04.015837Z ERROR socket-manager::sender: failed to sent data: Address family not supported by protocol (os error 97)
2025-08-28T12:39:04.015976Z ERROR socket-manager::sender: for task_id: 3, failed to send payload: Io(Os { code: 97, kind: Uncategorized, message: "Address family not supported by protocol" })
2025-08-28T12:39:04.511229Z ERROR socket-manager::sender: failed to sent data: Address family not supported by protocol (os error 97)
pub fn new(family: AddressFamily) -> Result<Self> {
tracing::debug!("creating_raw socket with: {:?}", family);
let fd = match family {
AddressFamily::Ipv4 => unsafe {
libc::socket(libc::AF_INET, libc::SOCK_RAW, libc::IPPROTO_ICMP)
},
AddressFamily::Ipv6 => unsafe {
libc::socket(libc::AF_INET6, libc::SOCK_RAW, libc::IPPROTO_ICMPV6)
},
};
if fd < 0 {
tracing::error!(
"failed to create socket: {}",
std::io::Error::last_os_error()
);
return Err(std::io::Error::last_os_error().into());
}
Ok(RawSocket {
family,
fd: AsyncFd::new(fd)?,
})
}
pub async fn send_to(&self, buf: &[u8], dst: IpAddr) -> Result<()> {
// Use a loop to handle non-blocking send
loop {
let mut guard = self.fd.writable().await?;
let check = guard.try_io(|inner| {
let addr = match (&self.family, dst) {
(AddressFamily::Ipv4, IpAddr::V4(ip)) => {
let sockaddr_in = libc::sockaddr_in {
sin_family: libc::AF_INET as u16,
sin_port: 0,
sin_addr: libc::in_addr {
s_addr: u32::from_ne_bytes(ip.octets()),
},
sin_zero: [0; 8],
};
&sockaddr_in as *const _ as *const libc::sockaddr
}
(AddressFamily::Ipv6, IpAddr::V6(ip)) => {
let sockaddr_in6 = libc::sockaddr_in6 {
sin6_family: libc::AF_INET6 as u16,
sin6_port: 0,
sin6_flowinfo: 0,
sin6_addr: libc::in6_addr {
s6_addr: ip.octets(),
},
sin6_scope_id: 0,
};
&sockaddr_in6 as *const _ as *const libc::sockaddr
}
(_, _) => {
return Err(std::io::Error::other(Error::SocketAndPacketMismatch));
}
};
let addr_len = match self.family {
AddressFamily::Ipv4 => std::mem::size_of::<libc::sockaddr_in>() as u32,
AddressFamily::Ipv6 => std::mem::size_of::<libc::sockaddr_in6>() as u32,
};
let fd = inner.as_raw_fd();
let result = unsafe {
libc::sendto(fd, buf.as_ptr() as *const _, buf.len(), 0, addr, addr_len)
};
if result < 0 {
if std::io::Error::last_os_error().raw_os_error() != Some(libc::EAGAIN) {
tracing::error!("failed to sent data: {}", std::io::Error::last_os_error());
}
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
});
match check {
Ok(result) => return Ok(result?),
Err(_) => {
guard.clear_ready();
continue;
}
}
}
}
3 posts - 3 participants
🏷️ Rust_feed