Skip to content

Commit

Permalink
Make SocketPool non-optional for Pinger
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasz-grz committed Jan 20, 2025
1 parent 0c14764 commit ce97ddd
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .unreleased/LLT-5886_protected_pinger
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Use the SocketPool component in order to bind the Pinger raw socket to the tunnel interface on macOS.
LinkDetection component was also updated to use the new Pinger.
2 changes: 1 addition & 1 deletion crates/telio-nurse/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ telio-sockets.workspace = true
once_cell.workspace = true

[dev-dependencies]
telio-sockets.workspace = true
telio-sockets = { workspace = true, features = ["mockall"] }
telio-wg = { workspace = true, features = ["mockall"] }
tokio = { workspace = true, features = ["net", "sync", "test-util"] }
telio-nurse = { workspace = true, features = ["mockall"] }
Expand Down
15 changes: 6 additions & 9 deletions crates/telio-nurse/src/qos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ impl Analytics {
let (ping_channel_tx, ping_channel_rx) = mpsc::channel(1);

let ping_backend = if config.rtt_types.contains(&RttType::Ping) {
Arc::new(Pinger::new(config.rtt_tries, ipv6_enabled, Some(socket_pool)).ok())
Arc::new(Pinger::new(config.rtt_tries, ipv6_enabled, socket_pool).ok())
} else {
Arc::new(None)
};
Expand Down Expand Up @@ -607,7 +607,7 @@ mod tests {
collections::HashSet,
net::{Ipv4Addr, Ipv6Addr},
};
use telio_sockets::NativeProtector;
use telio_sockets::protector::MockProtector;
use telio_task::{
io::{mc_chan::Tx, McChan},
task_exec, Task,
Expand Down Expand Up @@ -939,13 +939,10 @@ mod tests {
rtt_types: vec![RttType::Ping],
buckets: 5,
};
let socket_pool = Arc::new(SocketPool::new(
NativeProtector::new(
#[cfg(target_os = "macos")]
true,
)
.expect("Failed to create NativeProtector"),
));

let mut protect = MockProtector::default();
protect.expect_make_internal().returning(|_| Ok(()));
let socket_pool = Arc::new(SocketPool::new(protect));

(
Analytics::new(config, io, true, socket_pool),
Expand Down
1 change: 1 addition & 0 deletions crates/telio-pinger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ tracing.workspace = true

[dev-dependencies]
tokio = { workspace = true, features = ["net", "sync", "test-util"] }
telio-sockets = { workspace = true, features = ["mockall"] }
39 changes: 16 additions & 23 deletions crates/telio-pinger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,24 +53,20 @@ impl Pinger {
pub fn new(
no_of_tries: u32,
ipv6: bool,
socket_pool: Option<Arc<SocketPool>>,
socket_pool: Arc<SocketPool>,
) -> std::io::Result<Self> {
let client_v6 = if ipv6 {
let client_v6 = Arc::new(Self::build_client(ICMP::V6)?);
if let Some(ref socket_pool) = socket_pool {
telio_log_trace!("Making pinger IPv6 socket internal");
socket_pool.make_internal(client_v6.get_socket().get_native_sock())?;
}
telio_log_trace!("Making pinger IPv6 socket internal");
socket_pool.make_internal(client_v6.get_socket().get_native_sock())?;
Some(client_v6)
} else {
None
};

let client_v4 = Arc::new(Self::build_client(ICMP::V4)?);
if let Some(ref socket_pool) = socket_pool {
telio_log_trace!("Making pinger IPv4 socket internal");
socket_pool.make_internal(client_v4.get_socket().get_native_sock())?;
}
telio_log_trace!("Making pinger IPv4 socket internal");
socket_pool.make_internal(client_v4.get_socket().get_native_sock())?;

Ok(Self {
client_v4,
Expand Down Expand Up @@ -203,12 +199,16 @@ impl Pinger {
#[cfg(test)]
mod tests {
use super::*;
use telio_sockets::NativeProtector;
use telio_sockets::protector::MockProtector;

// Basic constructor test
#[tokio::test]
async fn test_pinger_new_v6_sock_pool() {
let pinger = Pinger::new(1, true, None).expect("Failed to create Pinger");
let mut protect = MockProtector::default();
protect.expect_make_internal().returning(|_| Ok(()));

let pinger = Pinger::new(1, true, Arc::new(SocketPool::new(protect)))
.expect("Failed to create Pinger");
assert!(pinger.client_v4.get_socket().get_native_sock() > 0);
assert!(pinger.client_v6.is_some());
assert_eq!(pinger.no_of_tries, 1);
Expand All @@ -217,18 +217,11 @@ mod tests {
// Basic ping test
#[tokio::test]
async fn test_ping_localhost() {
let pinger = Pinger::new(
2,
false,
Some(Arc::new(SocketPool::new(
NativeProtector::new(
#[cfg(target_os = "macos")]
true,
)
.expect("Failed to create Protector"),
))),
)
.expect("Failed to create Pinger");
let mut protect = MockProtector::default();
protect.expect_make_internal().returning(|_| Ok(()));

let pinger = Pinger::new(2, false, Arc::new(SocketPool::new(protect)))
.expect("Failed to create Pinger");

let target =
DualTarget::new(("127.0.0.1".parse().ok(), None)).expect("Failed to create target");
Expand Down
1 change: 1 addition & 0 deletions crates/telio-sockets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ parking_lot.workspace = true
socket2.workspace = true
thiserror.workspace = true
tokio = { workspace = true, features = ["full"] }
mockall = { workspace = true, optional = true }

telio-utils.workspace = true
once_cell.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/telio-sockets/src/protector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub use platform::NativeProtector;

pub type Protect = Arc<dyn Fn(NativeSocket) + Send + Sync + RefUnwindSafe + 'static>;

#[cfg_attr(any(test, feature = "mockall"), mockall::automock)]
pub trait Protector: Send + Sync {
fn make_external(&self, socket: NativeSocket) -> io::Result<()>;

Expand Down
17 changes: 4 additions & 13 deletions crates/telio-sockets/src/socket_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,26 +235,17 @@ mod tests {
sync::Mutex,
};

use mockall::mock;
use rstest::rstest;

use crate::{native::NativeSocket, protector::make_external_protector, Protect};
use crate::{
protector::{make_external_protector, MockProtector},
Protect,
};

use super::*;

const PACKET: [u8; 8] = *b"libtelio";

mock! {
Protector {}
impl Protector for Protector {
fn make_external(&self, socket: NativeSocket) -> io::Result<()>;
fn clean(&self, socket: NativeSocket);
fn set_fwmark(&self, fwmark: u32);
fn set_tunnel_interface(&self, interface: u64);
fn make_internal(&self, interface: NativeSocket) -> Result<(), std::io::Error>;
}
}

#[tokio::test]
async fn test_external_drops_protector() {
let mut protect = MockProtector::default();
Expand Down
3 changes: 2 additions & 1 deletion crates/telio-wg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ tokio = { workspace = true, features = ["full"] }

telio-crypto.workspace = true
telio-model.workspace = true
telio-sockets.workspace = true
telio-sockets = { workspace = true, features = ["mockall"] }
telio-task.workspace = true
telio-utils.workspace = true
telio-pinger.workspace = true
Expand All @@ -47,6 +47,7 @@ tokio = { workspace = true, features = ["test-util"] }

telio-firewall.workspace = true
telio-task = { workspace = true, features = ["test-util"] }
telio-sockets = { workspace = true, features = ["mockall"] }
telio-test.workspace = true
proptest.workspace = true

Expand Down
2 changes: 1 addition & 1 deletion crates/telio-wg/src/link_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl LinkDetection {
pub fn new(
cfg: FeatureLinkDetection,
ipv6_enabled: bool,
socket_pool: Option<Arc<SocketPool>>,
socket_pool: Arc<SocketPool>,
) -> Self {
let ping_channel = Chan::default();
let enhanced_detection = if cfg.no_of_pings != 0 {
Expand Down
4 changes: 2 additions & 2 deletions crates/telio-wg/src/link_detection/enhanced_detection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl EnhancedDetection {
ping_channel: chan::Rx<(Vec<IpAddr>, Option<IpStack>)>,
no_of_pings: u32,
ipv6_enabled: bool,
socket_pool: Option<Arc<SocketPool>>,
socket_pool: Arc<SocketPool>,
) -> std::io::Result<Self> {
Ok(Self {
task: Task::start(State::new(
Expand All @@ -46,7 +46,7 @@ impl State {
ping_channel: chan::Rx<(Vec<IpAddr>, Option<IpStack>)>,
no_of_pings: u32,
ipv6_enabled: bool,
socket_pool: Option<Arc<SocketPool>>,
socket_pool: Arc<SocketPool>,
) -> std::io::Result<Self> {
Ok(State {
ping_channel,
Expand Down
14 changes: 5 additions & 9 deletions crates/telio-wg/src/wg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,15 +347,15 @@ impl DynamicWg {
link_detection,
cfg.try_clone()?,
ipv6_enabled,
Some(cfg.socket_pool),
cfg.socket_pool,
));
#[cfg(windows)]
return Ok(Self::start_with(
io,
adapter,
link_detection,
ipv6_enabled,
None,
cfg.socket_pool,
));
}

Expand All @@ -365,7 +365,7 @@ impl DynamicWg {
link_detection: Option<FeatureLinkDetection>,
#[cfg(unix)] cfg: Config,
ipv6_enabled: bool,
socket_pool: Option<Arc<SocketPool>>,
socket_pool: Arc<SocketPool>,
) -> Self {
let interval = interval(Duration::from_millis(POLL_MILLIS));
Self {
Expand Down Expand Up @@ -1111,7 +1111,7 @@ pub mod tests {
use mockall::predicate;
use rand::{Rng, RngCore, SeedableRng};
use telio_crypto::PresharedKey;
use telio_sockets::NativeProtector;
use telio_sockets::protector::MockProtector;
use telio_utils::Hidden;
use tokio::{runtime::Handle, sync::Mutex, task, time::sleep};

Expand Down Expand Up @@ -1266,11 +1266,7 @@ pub mod tests {
})
});

// Tests and windows don't have a cfg
#[cfg(any(all(unix, test), not(unix)))]
let socket_pool = None;
#[cfg(all(unix, not(test)))]
let socket_pool = Some(cfg.socket_pool.clone());
let socket_pool = Arc::new(SocketPool::new(MockProtector::default()));

let wg = DynamicWg::start_with(
Io {
Expand Down

0 comments on commit ce97ddd

Please sign in to comment.