Skip to content

Commit 7162395

Browse files
authored
Always add route to endpoint through default gateway (#97)
1 parent 947c88e commit 7162395

File tree

4 files changed

+117
-126
lines changed

4 files changed

+117
-126
lines changed

Cargo.lock

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "defguard_wireguard_rs"
3-
version = "0.7.7"
3+
version = "0.7.8"
44
edition = "2024"
55
rust-version = "1.85"
66
description = "A unified multi-platform high-level API for managing WireGuard interfaces"

src/bsd/mod.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,7 @@ pub fn get_gateway(ip_version: IpVersion) -> Result<Option<IpAddr>, IoError> {
458458

459459
/// Add routing gateway.
460460
pub fn add_gateway(dest: &IpAddrMask, gateway: IpAddr, is_blackhole: bool) -> Result<(), IoError> {
461-
debug!(
462-
"Adding gateway, destination: {dest}, gateway: {gateway}, is blackhole: {is_blackhole}..."
463-
);
461+
debug!("Adding gateway: destination {dest}, gateway {gateway}, is blackhole {is_blackhole}.");
464462
match (dest.ip, dest.mask(), gateway) {
465463
(IpAddr::V4(ip), IpAddr::V4(mask), IpAddr::V4(gw)) => {
466464
let payload = DestAddrMask::<SockAddrIn>::new(ip.into(), mask.into(), gw.into());
@@ -481,7 +479,7 @@ pub fn add_gateway(dest: &IpAddrMask, gateway: IpAddr, is_blackhole: bool) -> Re
481479

482480
/// Remove routing gateway.
483481
pub fn delete_gateway(dest: &IpAddrMask) -> Result<(), IoError> {
484-
debug!("Deleting gateway with destination {dest}...");
482+
debug!("Deleting gateway with destination {dest}.");
485483
match (dest.ip, dest.mask()) {
486484
(IpAddr::V4(ip), IpAddr::V4(mask)) => {
487485
let payload =
@@ -504,7 +502,7 @@ pub fn delete_gateway(dest: &IpAddrMask) -> Result<(), IoError> {
504502

505503
/// Add link layer address gateway.
506504
pub fn add_linked_route(dest: &IpAddrMask, if_name: &str) -> Result<(), IoError> {
507-
debug!("Adding link layer gateway, destination: {dest}, interface: {if_name}");
505+
debug!("Adding link layer gateway: destination {dest}, interface {if_name}");
508506
let name = CString::new(if_name).unwrap();
509507
let if_index = unsafe { libc::if_nametoindex(name.as_ptr()) as u16 };
510508
if if_index == 0 {

src/utils.rs

Lines changed: 104 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -323,21 +323,26 @@ pub(crate) fn add_peer_routing(
323323

324324
use crate::bsd::{IoError, delete_gateway};
325325

326+
let gateway_v4 = get_gateway(IpVersion::IPv4);
327+
if let Ok(Some(gateway)) = gateway_v4 {
328+
debug!("Default gateway for IPv4: {gateway}");
329+
}
330+
let gateway_v6 = get_gateway(IpVersion::IPv6);
331+
if let Ok(Some(gateway)) = gateway_v6 {
332+
debug!("Default gateway for IPv4: {gateway}");
333+
}
334+
326335
debug!("Adding peer routing for interface: {ifname}");
327336
for peer in peers {
328337
debug!("Processing peer: {}", peer.public_key);
329-
let mut default_route_v4 = false;
330-
let mut default_route_v6 = false;
331-
let mut gateway_v4 = Ok(None);
332-
let mut gateway_v6 = Ok(None);
333338
for addr in &peer.allowed_ips {
334339
debug!("Processing route for allowed IP: {addr}, interface: {ifname}");
335340
// FIXME: currently it is impossible to add another default route, so use the hack from
336341
// wg-quick for Darwin.
337342
if addr.ip.is_unspecified() && addr.cidr == 0 {
338343
debug!(
339344
"Found following default route in the allowed IPs: {addr}, interface: \
340-
{ifname}, proceeding with default route initial setup..."
345+
{ifname}, proceeding with default route initial setup."
341346
);
342347
let default1;
343348
let default2;
@@ -346,36 +351,29 @@ pub(crate) fn add_peer_routing(
346351
default1 = IpAddrMask::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 1);
347352
// 128.0.0.0/1
348353
default2 = IpAddrMask::new(IpAddr::V4(Ipv4Addr::new(128, 0, 0, 0)), 1);
349-
gateway_v4 = get_gateway(IpVersion::IPv4);
350-
debug!("Default gateway for IPv4 value: {gateway_v4:?}");
351-
default_route_v4 = true;
352354
} else {
353355
// ::/1
354356
default1 = IpAddrMask::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 1);
355357
// 8000::/1
356358
default2 =
357359
IpAddrMask::new(IpAddr::V6(Ipv6Addr::new(0x8000, 0, 0, 0, 0, 0, 0, 0)), 1);
358-
gateway_v6 = get_gateway(IpVersion::IPv6);
359-
debug!("Default gateway for IPv6 value: {gateway_v6:?}");
360-
default_route_v6 = true;
361360
}
362361
match add_linked_route(&default1, ifname) {
363362
Ok(()) => debug!("Route to {default1} has been added for interface {ifname}"),
364363
Err(err) => match err {
365364
IoError::WriteIo(Errno::ENETUNREACH) => {
366365
warn!(
367-
"Failed to add default route {default1} for interface \
368-
{ifname}: Network is unreachable. This may happen if your \
369-
interface's IP address is not the same IP version as the \
370-
default gateway ({default1}) that was tried to be set, in this \
371-
case this warning can be ignored. Otherwise, there may be some \
372-
other issues with your network configuration."
366+
"Failed to add default route {default1} for interface {ifname}: \
367+
Network is unreachable. This may happen if interface's IP address \
368+
is not the same IP version as the default gateway ({default1}) \
369+
that was tried to be set, in this case this warning can be \
370+
ignored. Otherwise, there may be some other issues with network \
371+
configuration."
373372
);
374373
}
375374
_ => {
376375
error!(
377-
"Failed to add route to {default1} for interface {ifname}: \
378-
{err}"
376+
"Failed to add route to {default1} for interface {ifname}: {err}"
379377
);
380378
}
381379
},
@@ -385,18 +383,17 @@ pub(crate) fn add_peer_routing(
385383
Err(err) => match err {
386384
IoError::WriteIo(Errno::ENETUNREACH) => {
387385
warn!(
388-
"Failed to add default route {default2} for interface \
389-
{ifname}: Network is unreachable. This may happen if your \
390-
interface's IP address is not the same IP version as the \
391-
default gateway ({default2}) that was tried to be set, in this \
392-
case this warning can be ignored. Otherwise, there may be some \
393-
other issues with your network configuration."
386+
"Failed to add default route {default2} for interface {ifname}: \
387+
Network is unreachable. This may happen if interface's IP address \
388+
is not the same IP version as the default gateway ({default2}) \
389+
that was tried to be set, in this case this warning can be \
390+
ignored. Otherwise, there may be some other issues with network \
391+
configuration."
394392
);
395393
}
396394
_ => {
397395
error!(
398-
"Failed to add route to {default2} for interface {ifname}: \
399-
{err}"
396+
"Failed to add route to {default2} for interface {ifname}: {err}"
400397
);
401398
}
402399
},
@@ -412,107 +409,103 @@ pub(crate) fn add_peer_routing(
412409
}
413410
}
414411

415-
if default_route_v4 || default_route_v6 {
416-
if let Some(endpoint) = peer.endpoint {
417-
debug!("Default routes have been set, proceeding with further configuration...");
418-
let host = IpAddrMask::host(endpoint.ip());
419-
let localhost = if endpoint.is_ipv4() {
420-
IpAddr::V4(Ipv4Addr::LOCALHOST)
421-
} else {
422-
IpAddr::V6(Ipv6Addr::LOCALHOST)
423-
};
424-
debug!("Cleaning up old route to {host}, if it exists...");
425-
match delete_gateway(&host) {
426-
Ok(()) => {
427-
debug!(
428-
"Previously existing route to {host} has been removed, if it existed"
429-
);
430-
}
431-
Err(err) => {
432-
debug!("Previously existing route to {host} has not been removed: {err}");
433-
}
434-
}
435-
if endpoint.is_ipv6() && default_route_v6 {
412+
// Logic below is valid only in case an endpoint has been configured for the peer.
413+
let Some(endpoint) = peer.endpoint else {
414+
continue;
415+
};
416+
417+
let endpoint_ip = IpAddrMask::host(endpoint.ip());
418+
let localhost = if endpoint.is_ipv4() {
419+
IpAddr::V4(Ipv4Addr::LOCALHOST)
420+
} else {
421+
IpAddr::V6(Ipv6Addr::LOCALHOST)
422+
};
423+
424+
match delete_gateway(&endpoint_ip) {
425+
Ok(()) => {
426+
debug!("Former route to {endpoint_ip} has been removed, if it existed.");
427+
}
428+
Err(err) => {
429+
debug!("Former route to {endpoint_ip} has not been removed: {err}");
430+
}
431+
}
432+
433+
debug!("Default routes have been set, proceeding with further configuration.");
434+
if endpoint.is_ipv6() {
435+
debug!(
436+
"Endpoint is an IPv6 address and a default IPv6 route is present in the allowed \
437+
IPs; proceeding with further configuration."
438+
);
439+
match gateway_v6 {
440+
Ok(Some(gateway)) => {
436441
debug!(
437-
"Endpoint is an IPv6 address and a default route (IPv6) is present in \
438-
the alloweds IPs, proceeding with further configuration..."
442+
"Default gateway for IPv6 has been found before: {gateway}, routing the \
443+
traffic destined to {endpoint_ip} through it."
439444
);
440-
match gateway_v6 {
441-
Ok(Some(gateway)) => {
442-
debug!(
443-
"Default gateway for IPv4 has been found before: {gateway}, \
444-
routing the traffic destined to {host} through it..."
445-
);
446-
match add_gateway(&host, gateway, false) {
447-
Ok(()) => {
448-
debug!("Route to {host} has been added for gateway {gateway}");
449-
}
450-
Err(err) => {
451-
error!(
452-
"Failed to add route to {host} for gateway {gateway}: \
453-
{err}"
454-
);
455-
}
456-
}
445+
match add_gateway(&endpoint_ip, gateway, false) {
446+
Ok(()) => {
447+
debug!("Route to {endpoint_ip} has been added for gateway {gateway}");
457448
}
458-
Ok(None) => {
459-
debug!(
460-
"Default gateway for IPv6 has not been found, routing the \
461-
traffic destined to {host} through localhost as a blackhole \
462-
route..."
449+
Err(err) => {
450+
error!(
451+
"Failed to add route to {endpoint_ip} for gateway {gateway}: {err}"
463452
);
464-
match add_gateway(&host, localhost, true) {
465-
Ok(()) => debug!("Blackhole route to {host} has been added"),
466-
Err(err) => {
467-
error!("Failed to add blackhole route to {host}: {err}");
468-
}
469-
}
470453
}
454+
}
455+
}
456+
Ok(None) => {
457+
debug!(
458+
"Default gateway for IPv6 has not been found, routing the traffic destined \
459+
to {endpoint_ip} through localhost as a blackhole route."
460+
);
461+
match add_gateway(&endpoint_ip, localhost, true) {
462+
Ok(()) => debug!("Blackhole route to {endpoint_ip} has been added"),
471463
Err(err) => {
472-
error!("Failed to get gateway for {host}: {err}");
464+
error!("Failed to add blackhole route to {endpoint_ip}: {err}");
473465
}
474466
}
475-
} else if default_route_v4 {
467+
}
468+
Err(ref err) => {
469+
error!("Failed to get gateway for {endpoint_ip}: {err}");
470+
}
471+
}
472+
} else {
473+
debug!(
474+
"Endpoint is an IPv4 address and a default IPv4 route is present in the allowed \
475+
IPs; proceeding with further configuration."
476+
);
477+
match gateway_v4 {
478+
Ok(Some(gateway)) => {
476479
debug!(
477-
"Endpoint is an IPv4 address and a default route (IPv4) is present in \
478-
the alloweds IPs, proceeding with further configuration..."
480+
"Default gateway for IPv4 has been found before: {gateway}, routing the \
481+
traffic destined to {endpoint_ip} through it."
479482
);
480-
match gateway_v4 {
481-
Ok(Some(gateway)) => {
482-
debug!(
483-
"Default gateway for IPv4 has been found before: {gateway}, \
484-
routing the traffic destined to {host} through it..."
485-
);
486-
match add_gateway(&host, gateway, false) {
487-
Ok(()) => {
488-
debug!("Added route to {host} for gateway {gateway}");
489-
}
490-
Err(err) => {
491-
error!(
492-
"Failed to add route to {host} for gateway {gateway}: \
493-
{err}"
494-
);
495-
}
496-
}
483+
match add_gateway(&endpoint_ip, gateway, false) {
484+
Ok(()) => {
485+
debug!("Added route to {endpoint_ip} for gateway {gateway}");
497486
}
498-
Ok(None) => {
499-
debug!(
500-
"Default gateway for IPv4 has not been found, routing the \
501-
traffic destined to {host} through localhost as a blackhole \
502-
route..."
487+
Err(err) => {
488+
error!(
489+
"Failed to add route to {endpoint_ip} for gateway {gateway}: {err}"
503490
);
504-
match add_gateway(&host, localhost, true) {
505-
Ok(()) => debug!("Blackhole route to {host} has been added"),
506-
Err(err) => {
507-
error!("Failed to add blackhole route to {host}: {err}");
508-
}
509-
}
510491
}
492+
}
493+
}
494+
Ok(None) => {
495+
debug!(
496+
"Default gateway for IPv4 has not been found, routing the traffic destined \
497+
to {endpoint_ip} through localhost as a blackhole route."
498+
);
499+
match add_gateway(&endpoint_ip, localhost, true) {
500+
Ok(()) => debug!("Blackhole route to {endpoint_ip} has been added"),
511501
Err(err) => {
512-
error!("Failed to get gateway for {host}: {err}");
502+
error!("Failed to add blackhole route to {endpoint_ip}: {err}");
513503
}
514504
}
515505
}
506+
Err(ref err) => {
507+
error!("Failed to get gateway for {endpoint_ip}: {err}");
508+
}
516509
}
517510
}
518511
}

0 commit comments

Comments
 (0)