mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
refactor(connlib): don't recreate the tun device for Apple and Windows (#4260)
This is done to fix a bug where the file descriptor is unregistered from the reactor after the new `Tun` struct is created if the old one is dropped after.
This commit is contained in:
@@ -212,7 +212,7 @@ where
|
||||
|
||||
let callbacks = self.callbacks.clone();
|
||||
|
||||
self.io.device_mut().initialize(
|
||||
self.io.device_mut().set_config(
|
||||
&config,
|
||||
// We can just sort in here because sentinel ips are created in order
|
||||
dns_mapping.left_values().copied().sorted().collect(),
|
||||
|
||||
@@ -63,8 +63,8 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
pub(crate) fn initialize(
|
||||
#[cfg(any(target_os = "android", target_os = "linux"))]
|
||||
pub(crate) fn set_config(
|
||||
&mut self,
|
||||
config: &Interface,
|
||||
dns_config: Vec<IpAddr>,
|
||||
@@ -83,8 +83,34 @@ impl Device {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
pub(crate) fn set_config(
|
||||
&mut self,
|
||||
config: &Interface,
|
||||
dns_config: Vec<IpAddr>,
|
||||
callbacks: &impl Callbacks,
|
||||
) -> Result<(), ConnlibError> {
|
||||
// For macos the filedescriptor is the same throughout its lifetime.
|
||||
// If we reinitialzie tun, we might drop the old tun after the new one is created
|
||||
// this unregisters the file descriptor with the reactor so we never wake up
|
||||
// in case an event is triggered.
|
||||
if self.tun.is_none() {
|
||||
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() {
|
||||
waker.wake();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_family = "windows")]
|
||||
pub(crate) fn initialize(
|
||||
pub(crate) fn set_config(
|
||||
&mut self,
|
||||
config: &Interface,
|
||||
dns_config: Vec<IpAddr>,
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::device_channel::{ipv4, ipv6};
|
||||
use connlib_shared::{messages::Interface as InterfaceConfig, Callbacks, Error, Result};
|
||||
use connlib_shared::{Callbacks, Error, Result};
|
||||
use ip_network::IpNetwork;
|
||||
use libc::{
|
||||
ctl_info, fcntl, getpeername, getsockopt, ioctl, iovec, msghdr, recvmsg, sendmsg, sockaddr_ctl,
|
||||
socklen_t, AF_INET, AF_INET6, AF_SYSTEM, CTLIOCGINFO, F_GETFL, F_SETFL, IF_NAMESIZE,
|
||||
O_NONBLOCK, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
|
||||
};
|
||||
use std::net::IpAddr;
|
||||
use std::task::{Context, Poll};
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
@@ -70,11 +69,7 @@ impl Tun {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
config: &InterfaceConfig,
|
||||
dns_config: Vec<IpAddr>,
|
||||
callbacks: &impl Callbacks,
|
||||
) -> Result<Self> {
|
||||
pub fn new() -> Result<Self> {
|
||||
let mut info = ctl_info {
|
||||
ctl_id: 0,
|
||||
ctl_name: [0; 96],
|
||||
@@ -131,8 +126,6 @@ impl Tun {
|
||||
}
|
||||
|
||||
if addr.sc_id == info.ctl_id {
|
||||
callbacks.on_set_interface_config(config.ipv4, config.ipv6, dns_config);
|
||||
|
||||
set_non_blocking(fd)?;
|
||||
|
||||
return Ok(Self {
|
||||
|
||||
@@ -50,7 +50,7 @@ where
|
||||
let callbacks = self.callbacks.clone();
|
||||
self.io
|
||||
.device_mut()
|
||||
.initialize(config, vec![], &callbacks)?;
|
||||
.set_config(config, vec![], &callbacks)?;
|
||||
self.io.device_mut().set_routes(
|
||||
HashSet::from([PEERS_IPV4.parse().unwrap(), PEERS_IPV6.parse().unwrap()]),
|
||||
&callbacks,
|
||||
|
||||
Reference in New Issue
Block a user