Attempt changing to socket2
This commit is contained in:
1 parent
8e0a03b408
commit
6119408e1f
3 files changed
+47
-40
No files matched your search
Generated
+14
-1
@@ -305,8 +305,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
source = "git+https://github.com/Lochnair/nix?branch=add-icmp_proto#19e59985cdca5ded0eac9ad30bcc8ff39219c097"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -459,6 +461,16 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqm-autorate-rust"
|
name = "sqm-autorate-rust"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -473,6 +485,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rust-uci",
|
"rust-uci",
|
||||||
"serde",
|
"serde",
|
||||||
|
"socket2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|||||||
+3
-5
@@ -26,6 +26,7 @@ etherparse = "0.12.0"
|
|||||||
neli = "0.6.2"
|
neli = "0.6.2"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
rust-uci = { version = "0.1.5", optional = true }
|
rust-uci = { version = "0.1.5", optional = true }
|
||||||
|
socket2 = { version = "0.4", features = ["all"] }
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
|
|
||||||
[dependencies.log]
|
[dependencies.log]
|
||||||
@@ -33,7 +34,7 @@ features = ["std"]
|
|||||||
version = "0.4.17"
|
version = "0.4.17"
|
||||||
|
|
||||||
[dependencies.nix]
|
[dependencies.nix]
|
||||||
features = ["net", "socket", "time"]
|
features = ["time"]
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
@@ -45,7 +46,4 @@ features = ["formatting", "macros"]
|
|||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
uci = ["dep:rust-uci"]
|
uci = ["dep:rust-uci"]
|
||||||
|
|
||||||
[patch.crates-io]
|
|
||||||
nix = { git = "https://github.com/Lochnair/nix", branch = "add-icmp_proto" }
|
|
||||||
+30
-34
@@ -2,12 +2,8 @@ use crate::MeasurementType;
|
|||||||
use etherparse::ReadError;
|
use etherparse::ReadError;
|
||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use nix::errno::Errno;
|
use nix::errno::Errno;
|
||||||
use nix::sys::socket::{
|
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
||||||
recvfrom, sendto, socket, AddressFamily, MsgFlags, SockFlag, SockProtocol, SockType,
|
|
||||||
SockaddrIn, SockaddrIn6, SockaddrLike,
|
|
||||||
};
|
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddrV4, SocketAddrV6};
|
||||||
use std::os::unix::io::RawFd;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
@@ -47,30 +43,34 @@ pub struct PingReply {
|
|||||||
pub last_receive_time_s: f64,
|
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_ {
|
match type_ {
|
||||||
MeasurementType::ICMP | MeasurementType::ICMPTimestamps => {
|
MeasurementType::ICMP | MeasurementType::ICMPTimestamps => {
|
||||||
socket(
|
Socket::new(Domain::IPV4, Type::RAW, Some(Protocol::ICMPV4))
|
||||||
AddressFamily::Inet,
|
|
||||||
SockType::Raw,
|
|
||||||
SockFlag::empty(), /* value */
|
|
||||||
SockProtocol::ICMP,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
MeasurementType::NTP => {
|
|
||||||
socket(
|
|
||||||
AddressFamily::Inet,
|
|
||||||
SockType::Datagram,
|
|
||||||
SockFlag::empty(), /* value */
|
|
||||||
SockProtocol::Udp,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
MeasurementType::NTP => Socket::new(Domain::IPV4, Type::DGRAM, None),
|
||||||
_ => {
|
_ => {
|
||||||
unimplemented!()
|
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 {
|
pub trait PingListener {
|
||||||
fn listen(
|
fn listen(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -79,30 +79,26 @@ pub trait PingListener {
|
|||||||
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
|
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
|
||||||
stats_sender: Sender<PingReply>,
|
stats_sender: Sender<PingReply>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let socket = open_socket(type_)?;
|
let socket = &mut open_socket(type_)?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut v: Vec<u8> = vec![0; 40];
|
let (buf, sender) = match socket.read_from() {
|
||||||
let mut buf = v.as_mut_slice();
|
|
||||||
|
|
||||||
let (size, sender) = match recvfrom::<SockaddrIn>(socket, buf) {
|
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(_) => continue,
|
Err(_) => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
// etherparse doesn't like when the size in the header doesn't match the buffer
|
// 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
|
// 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 = sender.as_socket().unwrap().ip();
|
||||||
let addr = IpAddr::from(addr_bytes.to_be_bytes());
|
|
||||||
|
|
||||||
let reflectors = reflectors_lock.read().unwrap();
|
let reflectors = reflectors_lock.read().unwrap();
|
||||||
if !reflectors.contains(&addr) {
|
if !reflectors.contains(&addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let reply = match self.parse_packet(id, addr, buf) {
|
let reply = match self.parse_packet(id, addr, buf.as_slice()) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
// parse_packet will throw an error if it's an unknown protocol etc.
|
// parse_packet will throw an error if it's an unknown protocol etc.
|
||||||
@@ -126,7 +122,7 @@ pub trait PingSender {
|
|||||||
type_: MeasurementType,
|
type_: MeasurementType,
|
||||||
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
|
reflectors_lock: Arc<RwLock<Vec<IpAddr>>>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let socket = open_socket(type_)?;
|
let socket = &open_socket(type_)?;
|
||||||
|
|
||||||
let mut seq: u16 = 0;
|
let mut seq: u16 = 0;
|
||||||
let tick_duration_ms: u16 = 500;
|
let tick_duration_ms: u16 = 500;
|
||||||
@@ -138,25 +134,25 @@ pub trait PingSender {
|
|||||||
drop(reflectors_unlocked);
|
drop(reflectors_unlocked);
|
||||||
|
|
||||||
for reflector in reflectors.iter() {
|
for reflector in reflectors.iter() {
|
||||||
let addr: Box<dyn SockaddrLike>;
|
let addr: SockAddr;
|
||||||
|
|
||||||
match reflector.is_ipv4() {
|
match reflector.is_ipv4() {
|
||||||
true => {
|
true => {
|
||||||
let ip4 = Ipv4Addr::from_str(&*reflector.to_string()).unwrap();
|
let ip4 = Ipv4Addr::from_str(&*reflector.to_string()).unwrap();
|
||||||
let sock4 = SocketAddrV4::new(ip4, 0);
|
let sock4 = SocketAddrV4::new(ip4, 0);
|
||||||
addr = Box::new(SockaddrIn::from(sock4));
|
addr = sock4.into();
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
let ip6 = Ipv6Addr::from_str(&*reflector.to_string()).unwrap();
|
let ip6 = Ipv6Addr::from_str(&*reflector.to_string()).unwrap();
|
||||||
let sock6 = SocketAddrV6::new(ip6, 0, 0, 0);
|
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_v = self.craft_packet(id, seq);
|
||||||
let buf = buf_v.as_slice();
|
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);
|
thread::sleep(sleep_duration);
|
||||||
|
|||||||
Reference in new issue
Block a user