mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
refactor(connlib): don't use Tun::new twice in windows since wintun doesn't like it (#4261)
Should fix the problem with #4198 after hooking `set_dns`
This commit is contained in:
@@ -116,9 +116,11 @@ impl Device {
|
||||
dns_config: Vec<IpAddr>,
|
||||
_: &impl Callbacks,
|
||||
) -> Result<(), ConnlibError> {
|
||||
let tun = Tun::new(config, dns_config)?;
|
||||
if self.tun.is_none() {
|
||||
self.tun = Some(Tun::new()?);
|
||||
}
|
||||
|
||||
self.tun = Some(tun);
|
||||
self.tun.as_ref().unwrap().set_config(config, &dns_config)?;
|
||||
|
||||
if let Some(waker) = self.waker.take() {
|
||||
waker.wake();
|
||||
|
||||
@@ -27,7 +27,7 @@ const TUNNEL_NAME: &str = "Firezone";
|
||||
|
||||
// TODO: Double-check that all these get dropped gracefully on disconnect
|
||||
pub struct Tun {
|
||||
_adapter: Arc<wintun::Adapter>,
|
||||
adapter: Arc<wintun::Adapter>,
|
||||
/// The index of our network adapter, we can use this when asking Windows to add / remove routes / DNS rules
|
||||
/// It's stable across app restarts and I'm assuming across system reboots too.
|
||||
iface_idx: u32,
|
||||
@@ -53,7 +53,7 @@ const CREATE_NO_WINDOW: u32 = 0x08000000;
|
||||
const DEFAULT_MTU: u32 = 1280;
|
||||
|
||||
impl Tun {
|
||||
pub fn new(config: &InterfaceConfig, dns_config: Vec<IpAddr>) -> Result<Self> {
|
||||
pub fn new() -> Result<Self> {
|
||||
const TUNNEL_UUID: &str = "e9245bc1-b8c1-44ca-ab1d-c6aad4f13b9c";
|
||||
|
||||
// SAFETY: we're loading a DLL from disk and it has arbitrary C code in it.
|
||||
@@ -73,6 +73,39 @@ impl Tun {
|
||||
}
|
||||
};
|
||||
|
||||
let iface_idx = adapter.get_adapter_index()?;
|
||||
|
||||
// Remove any routes that were previously associated with us
|
||||
// TODO: Pick a more elegant way to do this
|
||||
Command::new("powershell")
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.arg("-Command")
|
||||
.arg(format!(
|
||||
"Remove-NetRoute -InterfaceIndex {iface_idx} -Confirm:$false"
|
||||
))
|
||||
.stdout(Stdio::null())
|
||||
.status()?;
|
||||
|
||||
set_iface_config(adapter.get_luid(), DEFAULT_MTU)?;
|
||||
|
||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY)?);
|
||||
|
||||
let (packet_tx, packet_rx) = mpsc::channel(5);
|
||||
|
||||
let recv_thread = start_recv_thread(packet_tx, Arc::clone(&session))?;
|
||||
let packet_rx = std::sync::Mutex::new(packet_rx);
|
||||
|
||||
Ok(Self {
|
||||
adapter,
|
||||
iface_idx,
|
||||
_recv_thread: recv_thread,
|
||||
packet_rx,
|
||||
session: Arc::clone(&session),
|
||||
routes: HashSet::new(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_config(&self, config: &InterfaceConfig, dns_config: &[IpAddr]) -> Result<()> {
|
||||
tracing::debug!("Setting our IPv4 = {}", config.ipv4);
|
||||
tracing::debug!("Setting our IPv6 = {}", config.ipv6);
|
||||
|
||||
@@ -102,22 +135,9 @@ impl Tun {
|
||||
.stdout(Stdio::null())
|
||||
.status()?;
|
||||
|
||||
tracing::debug!("Our IPs are {:?}", adapter.get_addresses()?);
|
||||
tracing::debug!("Our IPs are {:?}", self.adapter.get_addresses()?);
|
||||
|
||||
let iface_idx = adapter.get_adapter_index()?;
|
||||
|
||||
// Remove any routes that were previously associated with us
|
||||
// TODO: Pick a more elegant way to do this
|
||||
Command::new("powershell")
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.arg("-Command")
|
||||
.arg(format!(
|
||||
"Remove-NetRoute -InterfaceIndex {iface_idx} -Confirm:$false"
|
||||
))
|
||||
.stdout(Stdio::null())
|
||||
.status()?;
|
||||
|
||||
set_iface_config(adapter.get_luid(), DEFAULT_MTU)?;
|
||||
let iface_idx = self.adapter.get_adapter_index()?;
|
||||
|
||||
// Set our DNS IP as the DNS server for our interface
|
||||
// TODO: Known issue where web browsers will keep a connection open to a site,
|
||||
@@ -139,21 +159,7 @@ impl Tun {
|
||||
.stdout(Stdio::null())
|
||||
.status()?;
|
||||
|
||||
let session = Arc::new(adapter.start_session(wintun::MAX_RING_CAPACITY)?);
|
||||
|
||||
let (packet_tx, packet_rx) = mpsc::channel(5);
|
||||
|
||||
let recv_thread = start_recv_thread(packet_tx, Arc::clone(&session))?;
|
||||
let packet_rx = std::sync::Mutex::new(packet_rx);
|
||||
|
||||
Ok(Self {
|
||||
_adapter: adapter,
|
||||
iface_idx,
|
||||
_recv_thread: recv_thread,
|
||||
packet_rx,
|
||||
session: Arc::clone(&session),
|
||||
routes: HashSet::new(),
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// It's okay if this blocks until the route is added in the OS.
|
||||
|
||||
Reference in New Issue
Block a user