diff --git a/src/config.rs b/src/config.rs index 70ff7bb..ed6757c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -17,6 +17,7 @@ pub struct Config { pub(crate) endpoint_addr: SocketAddr, pub(crate) source_peer_ip: IpAddr, pub(crate) keepalive_seconds: Option, + pub(crate) max_transmission_unit: usize, pub(crate) log: String, pub(crate) warnings: Vec, } @@ -82,6 +83,13 @@ impl Config { .long("keep-alive") .env("ONETUN_KEEP_ALIVE") .help("Configures a persistent keep-alive for the WireGuard tunnel, in seconds."), + Arg::with_name("max-transmission-unit") + .required(false) + .takes_value(true) + .long("max-transmission-unit") + .env("ONETUN_MTU") + .default_value("1420") + .help("Configures the max-transmission-unit (MTU) of the WireGuard tunnel."), Arg::with_name("log") .required(false) .takes_value(true) @@ -163,6 +171,8 @@ impl Config { .with_context(|| "Invalid source peer IP")?, keepalive_seconds: parse_keep_alive(matches.value_of("keep-alive")) .with_context(|| "Invalid keep-alive value")?, + max_transmission_unit: parse_mtu(matches.value_of("max-transmission-unit")) + .with_context(|| "Invalid max-transmission-unit value")?, log: matches.value_of("log").unwrap_or_default().into(), warnings, }) @@ -209,6 +219,12 @@ fn parse_keep_alive(s: Option<&str>) -> anyhow::Result> { } } +fn parse_mtu(s: Option<&str>) -> anyhow::Result { + s.with_context(|| "Missing MTU")? + .parse() + .with_context(|| "Invalid MTU") +} + #[cfg(unix)] fn is_file_insecurely_readable(path: &str) -> Option<(bool, bool)> { use std::fs::File; diff --git a/src/virtual_device.rs b/src/virtual_device.rs index 02d60f9..d06d7fa 100644 --- a/src/virtual_device.rs +++ b/src/virtual_device.rs @@ -5,9 +5,6 @@ use smoltcp::phy::{Device, DeviceCapabilities, Medium}; use smoltcp::time::Instant; use std::sync::Arc; -/// The max transmission unit for WireGuard. -const WG_MTU: usize = 1420; - /// A virtual device that processes IP packets. IP packets received from the WireGuard endpoint /// are made available to this device using a channel receiver. IP packets sent from this device /// are asynchronously sent out to the WireGuard tunnel. @@ -71,7 +68,7 @@ impl<'a> Device<'a> for VirtualIpDevice { fn capabilities(&self) -> DeviceCapabilities { let mut cap = DeviceCapabilities::default(); cap.medium = Medium::Ip; - cap.max_transmission_unit = WG_MTU; + cap.max_transmission_unit = self.wg.max_transmission_unit; cap } } diff --git a/src/wg.rs b/src/wg.rs index 2dc20d3..ca701f3 100644 --- a/src/wg.rs +++ b/src/wg.rs @@ -30,6 +30,8 @@ pub struct WireGuardTunnel { virtual_port_ip_tx: dashmap::DashMap>>, /// IP packet dispatcher for unroutable packets. `None` if not initialized. sink_ip_tx: RwLock>>>, + /// The max transmission unit for WireGuard. + pub(crate) max_transmission_unit: usize, } impl WireGuardTunnel { @@ -50,6 +52,7 @@ impl WireGuardTunnel { endpoint, virtual_port_ip_tx, sink_ip_tx: RwLock::new(None), + max_transmission_unit: config.max_transmission_unit, }) }