diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-10-14 17:21:09 +0200 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-10-14 17:21:09 +0200 |
commit | 6bc3cc3e92263e256f8fbf554bfb052479348586 (patch) | |
tree | 1be50d05ab2c3cfc307400a01c2debad05f45383 | |
parent | c800e86ece70d28ba463db8c4c5251c0266d11dd (diff) |
switch to tokio
-rw-r--r-- | Cargo.lock | 14 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 56 | ||||
-rw-r--r-- | src/util.rs | 33 |
5 files changed, 38 insertions, 69 deletions
@@ -372,13 +372,13 @@ name = "rsdsl_dhcp6" version = "0.2.0-dev" dependencies = [ "dhcproto", - "libc", "rand", "rsdsl_ip_config", "rsdsl_pd_config", "serde_json", "socket2", "thiserror", + "tokio", "trust-dns-proto", ] @@ -536,10 +536,22 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", + "tokio-macros", "windows-sys", ] [[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] name = "tracing" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7,11 +7,11 @@ edition = "2021" [dependencies] dhcproto = "0.9.0" -libc = "0.2.147" rand = "0.8.5" rsdsl_ip_config = { git = "https://github.com/rsdsl/ip_config.git", version = "0.2.2" } rsdsl_pd_config = { git = "https://github.com/rsdsl/pd_config.git", version = "0.1.0" } serde_json = "1.0" socket2 = "0.5.3" thiserror = "1.0" +tokio = { version = "1.0", features = ["rt", "macros"] } trust-dns-proto = "0.22.0" @@ -1,4 +1,2 @@ mod error; pub use error::*; - -pub mod util; diff --git a/src/main.rs b/src/main.rs index 4c27d26..c753823 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,3 @@ -use rsdsl_dhcp6::util::setsockopt; use rsdsl_dhcp6::{Error, Result}; use std::ffi::CString; @@ -11,7 +10,10 @@ use std::process; use std::str::FromStr; use std::sync::{Arc, Mutex}; use std::thread; -use std::time::{Duration, Instant, SystemTime}; +use std::time::SystemTime; + +use tokio::net::{ToSocketAddrs, UdpSocket}; +use tokio::time::{self, Duration, Instant}; use dhcproto::v6::{duid::Duid, DhcpOption, IAPrefix, Message, MessageType, OptionCode, IAPD, ORO}; use dhcproto::{Decodable, Decoder, Encodable, Encoder, Name}; @@ -20,8 +22,8 @@ use rsdsl_pd_config::PdConfig; use socket2::{Domain, SockAddr, Socket, Type}; use trust_dns_proto::serialize::binary::BinDecodable; -const BUFSIZE: usize = 1500; const DUID_LOCATION: &str = "/data/dhcp6.duid"; +const TICK_INTERVAL: u64 = 60; #[derive(Clone, Debug, Eq, PartialEq)] struct Dhcp6 { @@ -31,8 +33,6 @@ struct Dhcp6 { impl Dhcp6 { fn load_from_disk() -> Result<Self> { - let mut lease_file = File::open(rsdsl_pd_config::LOCATION)?; - Ok(Self { duid: load_or_generate_duid()?, lease: load_lease_optional(), @@ -41,11 +41,11 @@ impl Dhcp6 { } fn load_or_generate_duid() -> Result<Duid> { - match fs::read("/data/dhcp6.duid") { + match fs::read(DUID_LOCATION) { Ok(duid) => Ok(duid.into()), Err(_) => { let duid = Duid::uuid(&rand::random::<u128>().to_be_bytes()); - fs::write("/data/dhcp6.duid", &duid)?; + fs::write(DUID_LOCATION, &duid)?; Ok(duid) } @@ -57,7 +57,8 @@ fn load_lease_optional() -> Option<PdConfig> { serde_json::from_reader(&mut file).ok() } -fn main() -> Result<()> { +#[tokio::main] +async fn main() -> Result<()> { let dhcp6 = Dhcp6::load_from_disk()?; let sock = Socket::new(Domain::IPV6, Type::DGRAM, None)?; @@ -66,38 +67,29 @@ fn main() -> Result<()> { sock.set_reuse_port(true)?; sock.set_reuse_address(true)?; - // Bind socket to interface. - unsafe { - let link_index = CString::new("ppp0")?.into_raw(); - - setsockopt( - sock.as_raw_fd(), - libc::SOL_SOCKET, - libc::SO_BINDTODEVICE, - link_index, - "ppp0".len() as i32, - )?; - - // Prevent memory leak. - let _ = CString::from_raw(link_index); - } - let address = SocketAddr::from_str("[::]:546")?; sock.bind(&address.into())?; - loop { - let mut buf = [MaybeUninit::new(0); BUFSIZE]; - let (n, remote) = sock.recv_from(&mut buf)?; + let sock: std::net::UdpSocket = sock.into(); + let sock: UdpSocket = sock.try_into()?; + + sock.bind_device(Some("ppp0".as_bytes()))?; - // See unstable `MaybeUninit::slice_assume_init_ref`. - let buf = unsafe { &*(&buf as *const [MaybeUninit<u8>] as *const [u8]) }; + let mut interval = time::interval(Duration::from_secs(TICK_INTERVAL)); - let buf = &buf[..n]; + let mut buf = [0; 1500]; + loop { + tokio::select! { + result = sock.recv_from(&mut buf) => { + } + _ = interval.tick() => { + } + } } } -fn send_to_exact(sock: &Socket, buf: &[u8], dst: &SockAddr) -> Result<()> { - let n = sock.send_to(buf, dst)?; +async fn send_to_exact<A: ToSocketAddrs>(sock: &UdpSocket, buf: &[u8], target: A) -> Result<()> { + let n = sock.send_to(buf, target).await?; if n != buf.len() { Err(Error::PartialSend) } else { diff --git a/src/util.rs b/src/util.rs deleted file mode 100644 index 245f755..0000000 --- a/src/util.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::ffi::{c_char, c_int}; -use std::io; - -/// Helper macro to execute a system call that returns an `io::Result`. -macro_rules! syscall { - ($fn: ident ( $($arg: expr),* $(,)* ) ) => {{ - #[allow(unused_unsafe)] - let res = unsafe { libc::$fn($($arg, )*) }; - if res == -1 { - Err(io::Error::last_os_error()) - } else { - Ok(res) - } - }}; -} - -#[allow(clippy::missing_safety_doc)] -pub unsafe fn setsockopt( - fd: c_int, - opt: c_int, - val: c_int, - payload: *const c_char, - optlen: c_int, -) -> io::Result<()> { - syscall!(setsockopt( - fd, - opt, - val, - payload.cast(), - optlen as libc::socklen_t - )) - .map(|_| ()) -} |