aboutsummaryrefslogtreecommitdiffstats
path: root/src/platform
diff options
context:
space:
mode:
authorMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-24 18:41:43 +0100
committerMathias Hall-Andersen <mathias@hall-andersen.dk>2019-11-24 18:41:43 +0100
commit3bff078e3f1c59454d8db14e5dc7603e6fdbeaba (patch)
treeda301a422eb8aa38ac7960324b8b6fe2d0909302 /src/platform
parentDaemonization (diff)
downloadwireguard-rs-3bff078e3f1c59454d8db14e5dc7603e6fdbeaba.tar.xz
wireguard-rs-3bff078e3f1c59454d8db14e5dc7603e6fdbeaba.zip
Make IO traits suitable for Tun events (up/down)
Diffstat (limited to '')
-rw-r--r--src/platform/dummy/bind.rs8
-rw-r--r--src/platform/dummy/tun.rs35
-rw-r--r--src/platform/linux/mod.rs2
-rw-r--r--src/platform/linux/tun.rs42
-rw-r--r--src/platform/linux/udp.rs24
-rw-r--r--src/platform/mod.rs2
-rw-r--r--src/platform/tun.rs30
-rw-r--r--src/platform/udp.rs (renamed from src/platform/bind.rs)4
8 files changed, 82 insertions, 65 deletions
diff --git a/src/platform/dummy/bind.rs b/src/platform/dummy/bind.rs
index d69e6a4..3146af8 100644
--- a/src/platform/dummy/bind.rs
+++ b/src/platform/dummy/bind.rs
@@ -11,7 +11,7 @@ use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc;
use std::sync::Mutex;
-use super::super::bind::*;
+use super::super::udp::*;
use super::UnitEndpoint;
@@ -82,7 +82,7 @@ impl Writer<UnitEndpoint> for VoidBind {
}
}
-impl Bind for VoidBind {
+impl UDP for VoidBind {
type Error = BindError;
type Endpoint = UnitEndpoint;
@@ -193,7 +193,7 @@ impl PairBind {
}
}
-impl Bind for PairBind {
+impl UDP for PairBind {
type Error = BindError;
type Endpoint = UnitEndpoint;
type Reader = PairReader<Self::Endpoint>;
@@ -216,7 +216,7 @@ impl Owner for VoidOwner {
}
}
-impl PlatformBind for PairBind {
+impl PlatformUDP for PairBind {
type Owner = VoidOwner;
fn bind(_port: u16) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Owner), Self::Error> {
Err(BindError::Disconnected)
diff --git a/src/platform/dummy/tun.rs b/src/platform/dummy/tun.rs
index 569bf1c..6ddf7d5 100644
--- a/src/platform/dummy/tun.rs
+++ b/src/platform/dummy/tun.rs
@@ -10,6 +10,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::Arc;
use std::sync::Mutex;
+use std::thread;
+use std::time::Duration;
use super::super::tun::*;
@@ -83,9 +85,8 @@ pub struct TunWriter {
tx: Mutex<SyncSender<Vec<u8>>>,
}
-#[derive(Clone)]
-pub struct TunMTU {
- mtu: Arc<AtomicUsize>,
+pub struct TunStatus {
+ first: bool,
}
impl Reader for TunReader {
@@ -131,16 +132,25 @@ impl Writer for TunWriter {
}
}
-impl MTU for TunMTU {
- fn mtu(&self) -> usize {
- self.mtu.load(Ordering::Acquire)
+impl Status for TunStatus {
+ type Error = TunError;
+
+ fn event(&mut self) -> Result<TunEvent, Self::Error> {
+ if self.first {
+ self.first = false;
+ return Ok(TunEvent::Up(1420));
+ }
+
+ loop {
+ thread::sleep(Duration::from_secs(60 * 60));
+ }
}
}
impl Tun for TunTest {
type Writer = TunWriter;
type Reader = TunReader;
- type MTU = TunMTU;
+ type Status = TunStatus;
type Error = TunError;
}
@@ -157,7 +167,7 @@ impl TunFakeIO {
}
impl TunTest {
- pub fn create(mtu: usize, store: bool) -> (TunFakeIO, TunReader, TunWriter, TunMTU) {
+ pub fn create(mtu: usize, store: bool) -> (TunFakeIO, TunReader, TunWriter, TunStatus) {
let (tx1, rx1) = if store {
sync_channel(32)
} else {
@@ -184,16 +194,13 @@ impl TunTest {
tx: Mutex::new(tx2),
store,
};
- let mtu = TunMTU {
- mtu: Arc::new(AtomicUsize::new(mtu)),
- };
-
- (fake, reader, writer, mtu)
+ let status = TunStatus { first: true };
+ (fake, reader, writer, status)
}
}
impl PlatformTun for TunTest {
- fn create(_name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error> {
+ fn create(_name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Status), Self::Error> {
Err(TunError::Disconnected)
}
}
diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs
index 82731de..d28391e 100644
--- a/src/platform/linux/mod.rs
+++ b/src/platform/linux/mod.rs
@@ -4,4 +4,4 @@ mod udp;
pub use tun::LinuxTun as Tun;
pub use uapi::LinuxUAPI as UAPI;
-pub use udp::LinuxBind as Bind;
+pub use udp::LinuxUDP as UDP;
diff --git a/src/platform/linux/tun.rs b/src/platform/linux/tun.rs
index 0bbae81..604fad9 100644
--- a/src/platform/linux/tun.rs
+++ b/src/platform/linux/tun.rs
@@ -6,8 +6,8 @@ use std::error::Error;
use std::fmt;
use std::os::raw::c_short;
use std::os::unix::io::RawFd;
-use std::sync::atomic::{AtomicUsize, Ordering};
-use std::sync::Arc;
+use std::thread;
+use std::time::Duration;
const IFNAMSIZ: usize = 16;
const TUNSETIFF: u64 = 0x4004_54ca;
@@ -30,7 +30,9 @@ struct Ifreq {
_pad: [u8; 64],
}
-pub struct LinuxTun {}
+pub struct LinuxTun {
+ events: Vec<TunEvent>,
+}
pub struct LinuxTunReader {
fd: RawFd,
@@ -44,8 +46,8 @@ pub struct LinuxTunWriter {
* announcing an MTU update for the interface
*/
#[derive(Clone)]
-pub struct LinuxTunMTU {
- value: Arc<AtomicUsize>,
+pub struct LinuxTunStatus {
+ first: bool,
}
#[derive(Debug)]
@@ -81,13 +83,6 @@ impl Error for LinuxTunError {
}
}
-impl MTU for LinuxTunMTU {
- #[inline(always)]
- fn mtu(&self) -> usize {
- self.value.load(Ordering::Relaxed)
- }
-}
-
impl Reader for LinuxTunReader {
type Error = LinuxTunError;
@@ -118,15 +113,30 @@ impl Writer for LinuxTunWriter {
}
}
+impl Status for LinuxTunStatus {
+ type Error = LinuxTunError;
+
+ fn event(&mut self) -> Result<TunEvent, Self::Error> {
+ if self.first {
+ self.first = false;
+ return Ok(TunEvent::Up(1420));
+ }
+
+ loop {
+ thread::sleep(Duration::from_secs(60 * 60));
+ }
+ }
+}
+
impl Tun for LinuxTun {
type Error = LinuxTunError;
type Reader = LinuxTunReader;
type Writer = LinuxTunWriter;
- type MTU = LinuxTunMTU;
+ type Status = LinuxTunStatus;
}
impl PlatformTun for LinuxTun {
- fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error> {
+ fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Status), Self::Error> {
// construct request struct
let mut req = Ifreq {
name: [0u8; libc::IFNAMSIZ],
@@ -157,9 +167,7 @@ impl PlatformTun for LinuxTun {
Ok((
vec![LinuxTunReader { fd }], // TODO: enable multi-queue for Linux
LinuxTunWriter { fd },
- LinuxTunMTU {
- value: Arc::new(AtomicUsize::new(1500)), // TODO: fetch and update
- },
+ LinuxTunStatus { first: true },
))
}
}
diff --git a/src/platform/linux/udp.rs b/src/platform/linux/udp.rs
index a291d1a..f871bce 100644
--- a/src/platform/linux/udp.rs
+++ b/src/platform/linux/udp.rs
@@ -1,4 +1,4 @@
-use super::super::bind::*;
+use super::super::udp::*;
use super::super::Endpoint;
use std::io;
@@ -6,7 +6,7 @@ use std::net::{SocketAddr, UdpSocket};
use std::sync::Arc;
#[derive(Clone)]
-pub struct LinuxBind(Arc<UdpSocket>);
+pub struct LinuxUDP(Arc<UdpSocket>);
pub struct LinuxOwner(Arc<UdpSocket>);
@@ -22,7 +22,7 @@ impl Endpoint for SocketAddr {
}
}
-impl Reader<SocketAddr> for LinuxBind {
+impl Reader<SocketAddr> for LinuxUDP {
type Error = io::Error;
fn read(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
@@ -30,7 +30,7 @@ impl Reader<SocketAddr> for LinuxBind {
}
}
-impl Writer<SocketAddr> for LinuxBind {
+impl Writer<SocketAddr> for LinuxUDP {
type Error = io::Error;
fn write(&self, buf: &[u8], dst: &SocketAddr) -> Result<(), Self::Error> {
@@ -56,17 +56,19 @@ impl Owner for LinuxOwner {
}
impl Drop for LinuxOwner {
- fn drop(&mut self) {}
+ fn drop(&mut self) {
+ // TODO: close udp bind
+ }
}
-impl Bind for LinuxBind {
+impl UDP for LinuxUDP {
type Error = io::Error;
type Endpoint = SocketAddr;
- type Reader = LinuxBind;
- type Writer = LinuxBind;
+ type Reader = Self;
+ type Writer = Self;
}
-impl PlatformBind for LinuxBind {
+impl PlatformUDP for LinuxUDP {
type Owner = LinuxOwner;
fn bind(port: u16) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Owner), Self::Error> {
@@ -74,8 +76,8 @@ impl PlatformBind for LinuxBind {
let socket = Arc::new(socket);
Ok((
- vec![LinuxBind(socket.clone())],
- LinuxBind(socket.clone()),
+ vec![LinuxUDP(socket.clone())],
+ LinuxUDP(socket.clone()),
LinuxOwner(socket),
))
}
diff --git a/src/platform/mod.rs b/src/platform/mod.rs
index 99707e3..6b8fa0e 100644
--- a/src/platform/mod.rs
+++ b/src/platform/mod.rs
@@ -1,8 +1,8 @@
mod endpoint;
-pub mod bind;
pub mod tun;
pub mod uapi;
+pub mod udp;
pub use endpoint::Endpoint;
diff --git a/src/platform/tun.rs b/src/platform/tun.rs
index c92304a..fda17fd 100644
--- a/src/platform/tun.rs
+++ b/src/platform/tun.rs
@@ -1,5 +1,18 @@
use std::error::Error;
+pub enum TunEvent {
+ Up(usize), // interface is up (supply MTU)
+ Down, // interface is down
+}
+
+pub trait Status: Send + 'static {
+ type Error: Error;
+
+ /// Returns status updates for the interface
+ /// When the status is unchanged the method blocks
+ fn event(&mut self) -> Result<TunEvent, Self::Error>;
+}
+
pub trait Writer: Send + Sync + 'static {
type Error: Error;
@@ -35,27 +48,14 @@ pub trait Reader: Send + 'static {
fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize, Self::Error>;
}
-pub trait MTU: Send + Sync + Clone + 'static {
- /// Returns the MTU of the device
- ///
- /// This function needs to be efficient (called for every read).
- /// The goto implementation strategy is to .load an atomic variable,
- /// then use e.g. netlink to update the variable in a separate thread.
- ///
- /// # Returns
- ///
- /// The MTU of the interface in bytes
- fn mtu(&self) -> usize;
-}
-
pub trait Tun: Send + Sync + 'static {
type Writer: Writer;
type Reader: Reader;
- type MTU: MTU;
+ type Status: Status;
type Error: Error;
}
/// On some platforms the application can create the TUN device itself.
pub trait PlatformTun: Tun {
- fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::MTU), Self::Error>;
+ fn create(name: &str) -> Result<(Vec<Self::Reader>, Self::Writer, Self::Status), Self::Error>;
}
diff --git a/src/platform/bind.rs b/src/platform/udp.rs
index 9487dfd..3671229 100644
--- a/src/platform/bind.rs
+++ b/src/platform/udp.rs
@@ -13,7 +13,7 @@ pub trait Writer<E: Endpoint>: Send + Sync + Clone + 'static {
fn write(&self, buf: &[u8], dst: &E) -> Result<(), Self::Error>;
}
-pub trait Bind: Send + Sync + 'static {
+pub trait UDP: Send + Sync + 'static {
type Error: Error;
type Endpoint: Endpoint;
@@ -37,7 +37,7 @@ pub trait Owner: Send {
/// On some platforms the application can itself bind to a socket.
/// This enables configuration using the UAPI interface.
-pub trait PlatformBind: Bind {
+pub trait PlatformUDP: UDP {
type Owner: Owner;
/// Bind to a new port, returning the reader/writer and