Attempt changing to socket2

This commit is contained in:
Nils Andreas Svee committed 2022-10-13 18:03:56 +02:00
1 parent 8e0a03b408
commit 6119408e1f
3 files changed
+47 -40

No files matched your search

+30 -34
View File
@@ -2,12 +2,8 @@ use crate::MeasurementType;
use etherparse::ReadError;
use log::{debug, error};
use nix::errno::Errno;
use nix::sys::socket::{
recvfrom, sendto, socket, AddressFamily, MsgFlags, SockFlag, SockProtocol, SockType,
SockaddrIn, SockaddrIn6, SockaddrLike,
};
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
use std::os::unix::io::RawFd;
use std::str::FromStr;
use std::sync::mpsc::Sender;
use std::sync::{Arc, RwLock};
@@ -47,30 +43,34 @@ pub struct PingReply {
pub last_receive_time_s: f64,
}
fn open_socket(type_: MeasurementType) -> nix::Result<RawFd> {
fn open_socket(type_: MeasurementType) -> std::io::Result<Socket> {
match type_ {
MeasurementType::ICMP | MeasurementType::ICMPTimestamps => {
socket(
AddressFamily::Inet,
SockType::Raw,
SockFlag::empty(), /* value */
SockProtocol::ICMP,
)
}
MeasurementType::NTP => {
socket(
AddressFamily::Inet,
SockType::Datagram,
SockFlag::empty(), /* value */
SockProtocol::Udp,
)
Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::ICMPV4))
}
MeasurementType::NTP => Socket::new(Domain::IPV4, Type::DGRAM, None),
_ => {
unimplemented!()
}
}
}
trait ReadFrom {
fn read_from(&mut self) -> io::Result<(Vec<u8>, SockAddr)>;
}
impl ReadFrom for Socket {
fn read_from(&mut self) -> io::Result<(Vec<u8>, SockAddr)> {
let mut buffer = Vec::with_capacity(4096);
let (received, addr) = self.recv_from(buffer.spare_capacity_mut())?;
unsafe {
buffer.set_len(received);
}
Ok((buffer, addr))
}
}
pub trait PingListener {
fn listen(
&mut self,
@@ -79,30 +79,26 @@ pub trait PingListener {
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
stats_sender: Sender<PingReply>,
) -> anyhow::Result<()> {
let socket = open_socket(type_)?;
let socket = &mut open_socket(type_)?;
loop {
let mut v: Vec<u8> = vec![0; 40];
let mut buf = v.as_mut_slice();
let (size, sender) = match recvfrom::<SockaddrIn>(socket, buf) {
let (buf, sender) = match socket.read_from() {
Ok(val) => val,
Err(_) => continue,
};
// etherparse doesn't like when the size in the header doesn't match the buffer
// so resize the buffer when actual packet size is known
buf = buf[..size].as_mut();
//buf = buf[..size].as_mut();
let addr_bytes = sender.expect("Should be an address here").ip();
let addr = IpAddr::from(addr_bytes.to_be_bytes());
let addr: IpAddr = sender.as_socket().unwrap().ip();
let reflectors = reflectors_lock.read().unwrap();
if !reflectors.contains(&addr) {
continue;
}
let reply = match self.parse_packet(id, addr, buf) {
let reply = match self.parse_packet(id, addr, buf.as_slice()) {
Ok(val) => val,
Err(_) => {
// parse_packet will throw an error if it's an unknown protocol etc.
@@ -126,7 +122,7 @@ pub trait PingSender {
type_: MeasurementType,
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
) -> anyhow::Result<()> {
let socket = open_socket(type_)?;
let socket = &open_socket(type_)?;
let mut seq: u16 = 0;
let tick_duration_ms: u16 = 500;
@@ -138,25 +134,25 @@ pub trait PingSender {
drop(reflectors_unlocked);
for reflector in reflectors.iter() {
let addr: Box<dyn SockaddrLike>;
let addr: SockAddr;
match reflector.is_ipv4() {
true => {
let ip4 = Ipv4Addr::from_str(&*reflector.to_string()).unwrap();
let sock4 = SocketAddrV4::new(ip4, 0);
addr = Box::new(SockaddrIn::from(sock4));
addr = sock4.into();
}
false => {
let ip6 = Ipv6Addr::from_str(&*reflector.to_string()).unwrap();
let sock6 = SocketAddrV6::new(ip6, 0, 0, 0);
addr = Box::new(SockaddrIn6::from(sock6));
addr = sock6.into();
}
}
let buf_v = self.craft_packet(id, seq);
let buf = buf_v.as_slice();
sendto(socket, buf, addr.as_ref(), MsgFlags::empty()).expect("Couldn't send ping");
socket.send_to(buf, &addr)?;
}
thread::sleep(sleep_duration);