Skip to content

Commit a991c00

Browse files
committed
Simplify interface filtering
1 parent 00bab2a commit a991c00

File tree

2 files changed

+37
-54
lines changed

2 files changed

+37
-54
lines changed

talpid-routing/src/unix/macos/interface.rs

+35-53
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use system_configuration::{
2424
network_configuration::SCNetworkSet,
2525
preferences::SCPreferences,
2626
sys::schema_definitions::{
27-
kSCDynamicStorePropNetPrimaryInterface, kSCPropInterfaceName, kSCPropNetIPv4Addresses,
28-
kSCPropNetIPv4Router, kSCPropNetIPv6Addresses, kSCPropNetIPv6Router,
27+
kSCDynamicStorePropNetPrimaryInterface, kSCPropInterfaceName, kSCPropNetIPv4Router,
28+
kSCPropNetIPv6Router,
2929
},
3030
};
3131

@@ -168,19 +168,15 @@ impl PrimaryInterfaceMonitor {
168168
let (iface, index) = ifaces
169169
.into_iter()
170170
.filter_map(|iface| {
171-
let index = if_nametoindex(iface.name.as_str()).map_err(|error| {
172-
log::error!("Failed to retrieve interface index for \"{}\": {error}", iface.name);
173-
error
174-
}).ok()?;
175-
176-
let active = is_active_interface(&iface.name, family).unwrap_or_else(|error| {
177-
log::error!("is_active_interface() returned an error for interface \"{}\", assuming active. Error: {error}", iface.name);
178-
true
179-
});
180-
if !active {
181-
log::debug!("Skipping inactive interface {}, router IP {}", iface.name, iface.router_ip);
182-
return None;
183-
}
171+
let index = if_nametoindex(iface.name.as_str())
172+
.map_err(|error| {
173+
log::error!(
174+
"Failed to retrieve interface index for \"{}\": {error}",
175+
iface.name
176+
);
177+
error
178+
})
179+
.ok()?;
184180
Some((iface, index))
185181
})
186182
.next()?;
@@ -232,10 +228,11 @@ impl PrimaryInterfaceMonitor {
232228
log::debug!("Missing router IP for primary interface ({name}, {family})");
233229
None
234230
})?;
235-
let first_ip = get_service_first_ip(&ip_dict, family).or_else(|| {
231+
let first_ip = find_first_ip(&name, family).or_else(|| {
236232
log::debug!("Missing IP for primary interface ({name}, {family})");
237233
None
238234
})?;
235+
239236
Some(NetworkServiceDetails {
240237
name,
241238
router_ip,
@@ -267,7 +264,7 @@ impl PrimaryInterfaceMonitor {
267264
log::debug!("Missing router IP for {service_key} ({name}, {family})");
268265
None
269266
})?;
270-
let first_ip = get_service_first_ip(&ip_dict, family).or_else(|| {
267+
let first_ip = find_first_ip(&name, family).or_else(|| {
271268
log::debug!("Missing IP for \"{service_key}\" ({name}, {family})");
272269
None
273270
})?;
@@ -307,26 +304,30 @@ pub fn get_interface_link_addresses() -> io::Result<BTreeMap<String, SockaddrSto
307304
Ok(gateway_link_addrs)
308305
}
309306

310-
/// Return whether the given interface has an assigned (unicast) IP address.
311-
fn is_active_interface(interface_name: &str, family: Family) -> io::Result<bool> {
307+
/// Return the first assigned (unicast) IP address for the given interface
308+
fn find_first_ip(interface_name: &str, family: Family) -> Option<IpAddr> {
312309
let required_link_flags: InterfaceFlags = InterfaceFlags::IFF_UP | InterfaceFlags::IFF_RUNNING;
313-
let has_ip_addr = nix::ifaddrs::getifaddrs()?
310+
nix::ifaddrs::getifaddrs()
311+
.ok()?
314312
.filter(|addr| (addr.flags & required_link_flags) == required_link_flags)
315313
.filter(|addr| addr.interface_name == interface_name)
316-
.any(|addr| {
317-
if let Some(addr) = addr.address {
318-
// Check if family matches; ignore if link-local address
319-
match family {
320-
Family::V4 => matches!(addr.as_sockaddr_in(), Some(addr_in) if is_routable_v4(&addr_in.ip())),
321-
Family::V6 => {
322-
matches!(addr.as_sockaddr_in6(), Some(addr_in) if is_routable_v6(&addr_in.ip()))
323-
}
324-
}
325-
} else {
326-
false
327-
}
328-
});
329-
Ok(has_ip_addr)
314+
.filter_map(|addr| addr.address)
315+
.find_map(|addr| match family {
316+
Family::V4 => addr
317+
.as_sockaddr_in()
318+
.map(|addr_in| IpAddr::from(addr_in.ip())),
319+
Family::V6 => addr
320+
.as_sockaddr_in6()
321+
.map(|addr_in| IpAddr::from(addr_in.ip())),
322+
})
323+
.filter(is_routable)
324+
}
325+
326+
fn is_routable(addr: &IpAddr) -> bool {
327+
match addr {
328+
IpAddr::V4(ip) => is_routable_v4(ip),
329+
IpAddr::V6(ip) => is_routable_v6(ip),
330+
}
330331
}
331332

332333
fn is_routable_v4(addr: &Ipv4Addr) -> bool {
@@ -350,25 +351,6 @@ fn get_service_router_ip(ip_dict: &CFDictionary, family: Family) -> Option<IpAdd
350351
get_dict_elem_as_string(ip_dict, router_key).and_then(|ip| ip.parse().ok())
351352
}
352353

353-
fn get_service_first_ip(ip_dict: &CFDictionary, family: Family) -> Option<IpAddr> {
354-
let ip_key = if family == Family::V4 {
355-
unsafe { kSCPropNetIPv4Addresses }
356-
} else {
357-
unsafe { kSCPropNetIPv6Addresses }
358-
};
359-
ip_dict
360-
.find(ip_key.to_void())
361-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
362-
.and_then(|s| s.downcast::<CFArray>())
363-
.and_then(|ips| {
364-
ips.get(0)
365-
.map(|ip| unsafe { CFType::wrap_under_get_rule(*ip) })
366-
})
367-
.and_then(|s| s.downcast::<CFString>())
368-
.map(|s| s.to_string())
369-
.and_then(|ip| ip.parse().ok())
370-
}
371-
372354
fn get_dict_elem_as_string(dict: &CFDictionary, key: CFStringRef) -> Option<String> {
373355
dict.find(key.to_void())
374356
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })

talpid-routing/src/unix/macos/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ impl RouteManagerImpl {
601601
async fn add_route_with_record(&mut self, route: RouteMessage) -> Result<()> {
602602
let destination = RouteDestination::try_from(&route).map_err(Error::InvalidData)?;
603603

604-
let add_result = self.routing_table
604+
let add_result = self
605+
.routing_table
605606
.add_route(&route)
606607
.await
607608
.map_err(Error::AddRoute)?;

0 commit comments

Comments
 (0)