Finding available utun name for MacOS

This commit is contained in:
Maxime Van Hees authored and Lee Smet committed 2024-08-30 13:31:43 +02:00
1 parent 78b45a16f1
commit 5bfc5ff7e0
3 files changed
+146 -8

No files matched your search

Generated
+107
View File
@@ -1044,6 +1044,15 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "ipnetwork"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
dependencies = [
"serde",
]
[[package]]
name = "is-terminal"
version = "0.4.12"
@@ -1254,6 +1263,7 @@ dependencies = [
"netdev",
"nix 0.29.0",
"openssl",
"pnet",
"quinn",
"rand",
"rcgen",
@@ -1435,6 +1445,12 @@ dependencies = [
"memoffset",
]
[[package]]
name = "no-std-net"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65"
[[package]]
name = "nom"
version = "7.1.3"
@@ -1668,6 +1684,97 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "pnet"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "682396b533413cc2e009fbb48aadf93619a149d3e57defba19ff50ce0201bd0d"
dependencies = [
"ipnetwork",
"pnet_base",
"pnet_datalink",
"pnet_packet",
"pnet_sys",
"pnet_transport",
]
[[package]]
name = "pnet_base"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffc190d4067df16af3aba49b3b74c469e611cad6314676eaf1157f31aa0fb2f7"
dependencies = [
"no-std-net",
]
[[package]]
name = "pnet_datalink"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e79e70ec0be163102a332e1d2d5586d362ad76b01cec86f830241f2b6452a7b7"
dependencies = [
"ipnetwork",
"libc",
"pnet_base",
"pnet_sys",
"winapi",
]
[[package]]
name = "pnet_macros"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13325ac86ee1a80a480b0bc8e3d30c25d133616112bb16e86f712dcf8a71c863"
dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 2.0.48",
]
[[package]]
name = "pnet_macros_support"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eed67a952585d509dd0003049b1fc56b982ac665c8299b124b90ea2bdb3134ab"
dependencies = [
"pnet_base",
]
[[package]]
name = "pnet_packet"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c96ebadfab635fcc23036ba30a7d33a80c39e8461b8bd7dc7bb186acb96560f"
dependencies = [
"glob",
"pnet_base",
"pnet_macros",
"pnet_macros_support",
]
[[package]]
name = "pnet_sys"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d4643d3d4db6b08741050c2f3afa9a892c4244c085a72fcda93c9c2c9a00f4b"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "pnet_transport"
version = "0.35.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f604d98bc2a6591cf719b58d3203fd882bdd6bf1db696c4ac97978e9f4776bf"
dependencies = [
"libc",
"pnet_base",
"pnet_packet",
"pnet_sys",
]
[[package]]
name = "polyval"
version = "0.6.1"
+1
View File
@@ -46,6 +46,7 @@ netdev = "0.30.0"
openssl = { version = "0.10.66", optional = true }
tokio-openssl = { version = "0.6.4", optional = true }
arc-swap = "1.7.1"
pnet = "0.35.0"
[target.'cfg(target_os = "linux")'.dependencies]
rtnetlink = "0.14.1"
+38 -8
View File
@@ -81,13 +81,9 @@ pub async fn new(
),
Box<dyn std::error::Error>,
> {
if !validate_utun_name(&tun_config.name) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"TUN device name must be of the form 'utunXXX...' where X is a digit",
))?;
}
let mut tun = match create_tun_interface(&tun_config.name) {
let tun_name = find_available_utun_name(&tun_config.name)?;
let mut tun = match create_tun_interface(&tun_name) {
Ok(tun) => tun,
Err(e) => {
error!(
@@ -97,7 +93,7 @@ pub async fn new(
return Err(e);
}
};
let iface = Iface::by_name(&tun_config.name)?;
let iface = Iface::by_name(&tun_name)?;
iface.add_address(tun_config.node_subnet, tun_config.route_subnet)?;
let (tun_sink, mut sink_receiver) = mpsc::channel::<PacketBuffer>(1000);
@@ -174,6 +170,40 @@ fn validate_utun_name(input: &str) -> bool {
.is_ok()
}
/// Find an available utun interface name
fn find_available_utun_name(preferred_name: &str) -> Result<String, Box<dyn std::error::Error>> {
let interfaces = datalink::interfaces();
let utun_interfaces: Vec<_> = interfaces
.iter()
.filter(|iface| iface.name.starts_with("utun"))
.collect();
if !preferred_name.is_empty() && validate_utun_name(preferred_name) {
if !utun_interfaces
.iter()
.any(|iface| iface.name == preferred_name)
{
return Ok(preferred_name.to_string());
}
error!("Preferred utun name '{}' is already in use", preferred_name);
}
let max_utun_number = utun_interfaces
.iter()
.filter_map(|iface| iface.name[4..].parse::<u64>().ok())
.max()
.unwrap_or(0);
let new_utun_number = max_utun_number + 1;
let new_utun_name = format!("utun{}", new_utun_number);
if validate_utun_name(&new_utun_name) {
Ok(new_utun_name)
} else {
Err("Could not find an available utun interface name".into())
}
}
/// Create a new TUN interface
fn create_tun_interface(name: &str) -> Result<tun::AsyncDevice, Box<dyn std::error::Error>> {
let mut config = tun::Configuration::default();