diff options
| author | David Lönnhager <david.l@mullvad.net> | 2025-05-28 17:37:36 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-06-09 14:52:36 +0200 |
| commit | a6f99ee822d4ec40594bb2ce89498526bc0cf453 (patch) | |
| tree | e7b77f3df6b61ccc538b221b8d209bfe70246d06 /talpid-macos | |
| parent | bcca08c804560b4d2413fdfd3e3df8413330fae9 (diff) | |
| download | mullvadvpn-a6f99ee822d4ec40594bb2ce89498526bc0cf453.tar.xz mullvadvpn-a6f99ee822d4ec40594bb2ce89498526bc0cf453.zip | |
Set SO_REUSEADDR on local DNS resolver socket
This fixes an issue where bind() fails due to other sockets
Co-authored-by: Joakim Hulthe <joakim.hulthe@mullvad.net>
Diffstat (limited to 'talpid-macos')
| -rw-r--r-- | talpid-macos/Cargo.toml | 4 | ||||
| -rw-r--r-- | talpid-macos/src/lib.rs | 3 | ||||
| -rw-r--r-- | talpid-macos/src/net.rs | 45 |
3 files changed, 51 insertions, 1 deletions
diff --git a/talpid-macos/Cargo.toml b/talpid-macos/Cargo.toml index 7b910f5e6d..0b4caa4258 100644 --- a/talpid-macos/Cargo.toml +++ b/talpid-macos/Cargo.toml @@ -11,5 +11,7 @@ rust-version.workspace = true workspace = true [target.'cfg(target_os="macos")'.dependencies] +anyhow.workspace = true +log.workspace = true libc = "0.2.172" -log = { workspace = true } +tokio = { workspace = true, features = ["process"] } diff --git a/talpid-macos/src/lib.rs b/talpid-macos/src/lib.rs index 5a282660d3..1dad718685 100644 --- a/talpid-macos/src/lib.rs +++ b/talpid-macos/src/lib.rs @@ -9,3 +9,6 @@ pub mod process; /// OS bindings generated by 'generate_bindings.rs' #[allow(non_camel_case_types)] mod bindings; + +/// Networking utilities +pub mod net; diff --git a/talpid-macos/src/net.rs b/talpid-macos/src/net.rs new file mode 100644 index 0000000000..5eff2f6878 --- /dev/null +++ b/talpid-macos/src/net.rs @@ -0,0 +1,45 @@ +use anyhow::{anyhow, bail, Context}; +use std::net::IpAddr; +use tokio::process::Command; + +/// Adds an alias to a network interface. +pub async fn add_alias(interface: &str, addr: IpAddr) -> anyhow::Result<()> { + let context = || anyhow!("Failed to add interface {interface} alias {addr}"); + let output = Command::new("ifconfig") + .args([interface, "alias", &format!("{addr}"), "up"]) + .output() + .await + .context("Failed to spawn ifconfig") + .with_context(context)?; + + if !output.status.success() { + bail!( + "{}: Non-zero exit code from ifconfig: {}", + context(), + output.status + ); + } + + Ok(()) +} + +/// Removes an alias from a network interface. +pub async fn remove_alias(interface: &str, addr: IpAddr) -> anyhow::Result<()> { + let context = || anyhow!("Failed to remove interface {interface} alias {addr}"); + let output = Command::new("ifconfig") + .args([interface, "delete", &format!("{addr}")]) + .output() + .await + .context("Failed to spawn ifconfig") + .with_context(context)?; + + if !output.status.success() { + bail!( + "{}: Non-zero exit code from ifconfig: {}", + context(), + output.status + ); + } + + Ok(()) +} |
