chore(connlib): remove MTU refreshing (#4698)

This did not do anything other than limit the size of the buffer that we
pass in for reading. This has no effect whatsoever. We only ever read a
single packet anyway and we get told how big it is as a result of
`poll_read`.

Resolves: #4469.
This commit is contained in:
Thomas Eizinger
2024-04-19 15:09:02 +10:00
committed by GitHub
parent bc22fb2bf2
commit 4ee37d6cce
3 changed files with 8 additions and 94 deletions

View File

@@ -34,14 +34,11 @@ use std::collections::HashSet;
use std::io;
use std::net::IpAddr;
use std::task::{Context, Poll, Waker};
use std::time::{Duration, Instant};
use tun::Tun;
pub struct Device {
mtu: usize,
tun: Option<Tun>,
waker: Option<Waker>,
mtu_refreshed_at: Instant,
}
#[allow(dead_code)]
@@ -64,9 +61,7 @@ impl Device {
pub(crate) fn new() -> Self {
Self {
tun: None,
mtu: 1_280,
waker: None,
mtu_refreshed_at: Instant::now(),
}
}
@@ -77,11 +72,7 @@ impl Device {
dns_config: Vec<IpAddr>,
callbacks: &impl Callbacks,
) -> Result<(), ConnlibError> {
let tun = Tun::new(config, dns_config, callbacks)?;
let mtu = ioctl::interface_mtu_by_name(tun.name())?;
self.tun = Some(tun);
self.mtu = mtu;
self.tun = Some(Tun::new(config, dns_config, callbacks)?);
if let Some(waker) = self.waker.take() {
waker.wake();
@@ -105,8 +96,6 @@ impl Device {
self.tun = Some(Tun::new()?);
}
self.mtu = ioctl::interface_mtu_by_name(self.tun.as_ref().unwrap().name())?;
callbacks.on_set_interface_config(config.ipv4, config.ipv6, dns_config);
if let Some(waker) = self.waker.take() {
@@ -144,20 +133,14 @@ impl Device {
buf: &'b mut [u8],
cx: &mut Context<'_>,
) -> Poll<io::Result<MutableIpPacket<'b>>> {
use pnet_packet::Packet as _;
let Some(tun) = self.tun.as_mut() else {
self.waker = Some(cx.waker().clone());
return Poll::Pending;
};
use pnet_packet::Packet as _;
if self.mtu_refreshed_at.elapsed() > Duration::from_secs(30) {
let mtu = ioctl::interface_mtu_by_name(tun.name())?;
self.mtu = mtu;
self.mtu_refreshed_at = Instant::now();
}
let n = std::task::ready!(tun.poll_read(&mut buf[..self.mtu], cx))?;
let n = std::task::ready!(tun.poll_read(buf, cx))?;
if n == 0 {
return Poll::Ready(Err(io::Error::new(
@@ -184,18 +167,14 @@ impl Device {
buf: &'b mut [u8],
cx: &mut Context<'_>,
) -> Poll<io::Result<MutableIpPacket<'b>>> {
use pnet_packet::Packet as _;
let Some(tun) = self.tun.as_mut() else {
self.waker = Some(cx.waker().clone());
return Poll::Pending;
};
use pnet_packet::Packet as _;
if self.mtu_refreshed_at.elapsed() > Duration::from_secs(30) {
// TODO
}
let n = std::task::ready!(tun.poll_read(&mut buf[..self.mtu], cx))?;
let n = std::task::ready!(tun.poll_read(buf, cx))?;
if n == 0 {
return Poll::Ready(Err(io::Error::new(
@@ -254,23 +233,10 @@ fn io_error_not_initialized() -> io::Error {
io::Error::new(io::ErrorKind::NotConnected, "device is not initialized yet")
}
#[cfg(target_family = "unix")]
#[cfg(any(target_os = "linux", target_os = "android"))]
mod ioctl {
use super::*;
use std::os::fd::RawFd;
use tun::SIOCGIFMTU;
pub(crate) fn interface_mtu_by_name(name: &str) -> io::Result<usize> {
let socket = Socket::ip4()?;
let mut request = Request::<GetInterfaceMtuPayload>::new(name)?;
// Safety: The file descriptor is open.
unsafe {
exec(socket.fd, SIOCGIFMTU, &mut request)?;
}
Ok(request.payload.mtu as usize)
}
/// Executes the `ioctl` syscall on the given file descriptor with the provided request.
///
@@ -299,52 +265,4 @@ mod ioctl {
pub(crate) name: [std::ffi::c_uchar; libc::IF_NAMESIZE],
pub(crate) payload: P,
}
/// A socket newtype which closes the file descriptor on drop.
struct Socket {
fd: RawFd,
}
impl Socket {
fn ip4() -> io::Result<Socket> {
// Safety: All provided parameters are constants.
let fd = unsafe { libc::socket(libc::AF_INET, libc::SOCK_STREAM, libc::IPPROTO_IP) };
if fd == -1 {
return Err(io::Error::last_os_error());
}
Ok(Self { fd })
}
}
impl Drop for Socket {
fn drop(&mut self) {
// Safety: This is the only call to `close` and it happens when `Guard` is being dropped.
unsafe { libc::close(self.fd) };
}
}
impl Request<GetInterfaceMtuPayload> {
fn new(name: &str) -> io::Result<Self> {
if name.len() > libc::IF_NAMESIZE {
return Err(io::ErrorKind::InvalidInput.into());
}
let mut request = Request {
name: [0u8; libc::IF_NAMESIZE],
payload: Default::default(),
};
request.name[..name.len()].copy_from_slice(name.as_bytes());
Ok(request)
}
}
#[derive(Default)]
#[repr(C)]
struct GetInterfaceMtuPayload {
mtu: libc::c_int,
}
}

View File

@@ -17,8 +17,6 @@ use std::{
use tokio::io::unix::AsyncFd;
const CTL_NAME: &[u8] = b"com.apple.net.utun_control";
/// `libc` for darwin doesn't define this constant so we declare it here.
pub(crate) const SIOCGIFMTU: u64 = 0x0000_0000_c020_6933;
#[derive(Debug)]
pub(crate) struct Tun {

View File

@@ -32,8 +32,6 @@ use std::{
};
use tokio::io::unix::AsyncFd;
pub(crate) const SIOCGIFMTU: libc::c_ulong = libc::SIOCGIFMTU;
const IFACE_NAME: &str = "tun-firezone";
const TUNSETIFF: libc::c_ulong = 0x4004_54ca;
const TUN_DEV_MAJOR: u32 = 10;