Skip to content

Commit 6b50b9a

Browse files
committed
Refactor stuff in macOS routing thingy
1 parent b551094 commit 6b50b9a

File tree

1 file changed

+70
-96
lines changed

1 file changed

+70
-96
lines changed

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

+70-96
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::{
1111
};
1212

1313
use super::data::{Destination, RouteMessage};
14+
use system_configuration::core_foundation::string::CFStringRef;
1415
use system_configuration::{
1516
core_foundation::{
1617
array::CFArray,
@@ -212,62 +213,29 @@ impl PrimaryInterfaceMonitor {
212213
}
213214

214215
fn get_primary_interface(&self, family: Family) -> Option<NetworkServiceDetails> {
215-
let global_name = if family == Family::V4 {
216+
let key = if family == Family::V4 {
216217
STATE_IPV4_KEY
217218
} else {
218219
STATE_IPV6_KEY
219220
};
220-
let global_dict = self
221+
let ip_dict = self
221222
.store
222-
.get(CFString::new(global_name))
223+
.get(key)
223224
.and_then(|v| v.downcast_into::<CFDictionary>())?;
224-
let name = global_dict
225-
.find(unsafe { kSCDynamicStorePropNetPrimaryInterface }.to_void())
226-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
227-
.and_then(|s| s.downcast::<CFString>())
228-
.map(|s| s.to_string())
229-
.or_else(|| {
230-
log::debug!("Missing name for primary interface ({family})");
231-
None
232-
})?;
233-
234-
let router_key = if family == Family::V4 {
235-
unsafe { kSCPropNetIPv4Router.to_void() }
236-
} else {
237-
unsafe { kSCPropNetIPv6Router.to_void() }
238-
};
239-
240-
let router_ip = global_dict
241-
.find(router_key)
242-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
243-
.and_then(|s| s.downcast::<CFString>())
244-
.and_then(|ip| ip.to_string().parse().ok())
245-
.or_else(|| {
246-
log::debug!("Missing router IP for primary interface \"{name}\"");
247-
None
248-
})?;
249-
250-
let ip_key = if family == Family::V4 {
251-
unsafe { kSCPropNetIPv4Addresses.to_void() }
252-
} else {
253-
unsafe { kSCPropNetIPv6Addresses.to_void() }
254-
};
255-
256-
let first_ip = global_dict
257-
.find(ip_key)
258-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
259-
.and_then(|s| s.downcast::<CFArray>())
260-
.and_then(|ips| {
261-
ips.get(0)
262-
.map(|ip| unsafe { CFType::wrap_under_get_rule(*ip) })
263-
})
264-
.and_then(|s| s.downcast::<CFString>())
265-
.and_then(|ip| ip.to_string().parse().ok())
266-
.or_else(|| {
267-
log::debug!("Missing IP for primary interface \"{name}\"");
268-
None
269-
})?;
270-
225+
let name =
226+
get_dict_elem_as_string(&ip_dict, unsafe { kSCDynamicStorePropNetPrimaryInterface })
227+
.or_else(|| {
228+
log::debug!("Missing name for primary interface ({family})");
229+
None
230+
})?;
231+
let router_ip = get_service_router_ip(&ip_dict, family).or_else(|| {
232+
log::debug!("Missing router IP for primary interface ({name}, {family})");
233+
None
234+
})?;
235+
let first_ip = get_service_first_ip(&ip_dict, family).or_else(|| {
236+
log::debug!("Missing IP for primary interface ({name}, {family})");
237+
None
238+
})?;
271239
Some(NetworkServiceDetails {
272240
name,
273241
router_ip,
@@ -276,67 +244,33 @@ impl PrimaryInterfaceMonitor {
276244
}
277245

278246
fn network_services(&self, family: Family) -> Vec<NetworkServiceDetails> {
279-
let router_key = if family == Family::V4 {
280-
unsafe { kSCPropNetIPv4Router.to_void() }
281-
} else {
282-
unsafe { kSCPropNetIPv6Router.to_void() }
283-
};
284-
285247
SCNetworkSet::new(&self.prefs)
286248
.service_order()
287249
.iter()
288250
.filter_map(|service_id| {
289251
let service_id_s = service_id.to_string();
290-
let key = if family == Family::V4 {
252+
let service_key = if family == Family::V4 {
291253
format!("State:/Network/Service/{service_id_s}/IPv4")
292254
} else {
293255
format!("State:/Network/Service/{service_id_s}/IPv6")
294256
};
295-
296257
let ip_dict = self
297258
.store
298-
.get(CFString::new(&key))
259+
.get(CFString::new(&service_key))
299260
.and_then(|v| v.downcast_into::<CFDictionary>())?;
300-
let name = ip_dict
301-
.find(unsafe { kSCPropInterfaceName }.to_void())
302-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
303-
.and_then(|s| s.downcast::<CFString>())
304-
.map(|s| s.to_string())
261+
let name = get_dict_elem_as_string(&ip_dict, unsafe { kSCPropInterfaceName })
305262
.or_else(|| {
306-
log::debug!("Missing name for service {service_id_s} ({family})");
263+
log::debug!("Missing name for service {service_key} ({family})");
307264
None
308265
})?;
309-
let router_ip = ip_dict
310-
.find(router_key)
311-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
312-
.and_then(|s| s.downcast::<CFString>())
313-
.and_then(|ip| ip.to_string().parse().ok())
314-
.or_else(|| {
315-
log::debug!("Missing router IP for {service_id_s} ({name}, {family})");
316-
None
317-
})?;
318-
319-
let ip_key = if family == Family::V4 {
320-
unsafe { kSCPropNetIPv4Addresses.to_void() }
321-
} else {
322-
unsafe { kSCPropNetIPv6Addresses.to_void() }
323-
};
324-
325-
let first_ip = ip_dict
326-
.find(ip_key)
327-
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
328-
.and_then(|s| s.downcast::<CFArray>())
329-
.and_then(|ips| {
330-
ips.get(0)
331-
.map(|ip| unsafe { CFType::wrap_under_get_rule(*ip) })
332-
})
333-
.and_then(|s| s.downcast::<CFString>())
334-
.and_then(|ip| ip.to_string().parse().ok())
335-
.or_else(|| {
336-
log::debug!("Missing IP for primary interface \"{name}\"");
337-
None
338-
})?;
339-
266+
let router_ip = get_service_router_ip(&ip_dict, family).or_else(|| {
267+
log::debug!("Missing router IP for {service_key} ({name}, {family})");
268+
None
269+
})?;
270+
let first_ip = get_service_first_ip(&ip_dict, family).or_else(|| {
271+
log::debug!("Missing IP for \"{service_key}\" ({name}, {family})");
272+
None
273+
})?;
340274
Some(NetworkServiceDetails {
341275
name,
342276
router_ip,
@@ -406,3 +340,43 @@ fn is_routable_v6(addr: &Ipv6Addr) -> bool {
406340
fn is_link_local_v6(addr: &Ipv6Addr) -> bool {
407341
(addr.segments()[0] & 0xffc0) == 0xfe80
408342
}
343+
344+
fn get_service_router_ip(ip_dict: &CFDictionary, family: Family) -> Option<IpAddr> {
345+
let router_key = if family == Family::V4 {
346+
unsafe { kSCPropNetIPv4Router }
347+
} else {
348+
unsafe { kSCPropNetIPv6Router }
349+
};
350+
get_dict_elem_as_string(ip_dict, router_key).and_then(|ip| ip.parse().ok())
351+
}
352+
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+
372+
fn get_dict_elem_as_string(dict: &CFDictionary, key: CFStringRef) -> Option<String> {
373+
dict.find(key.to_void())
374+
.map(|s| unsafe { CFType::wrap_under_get_rule(*s) })
375+
.and_then(|s| s.downcast::<CFArray>())
376+
.and_then(|ips| {
377+
ips.get(0)
378+
.map(|ip| unsafe { CFType::wrap_under_get_rule(*ip) })
379+
})
380+
.and_then(|s| s.downcast::<CFString>())
381+
.map(|s| s.to_string())
382+
}

0 commit comments

Comments
 (0)