From e1de3d62f8d41a91cc8323622b873dee0fc89675 Mon Sep 17 00:00:00 2001 From: FujiApple Date: Mon, 12 Feb 2024 21:34:32 +0800 Subject: [PATCH] feat(config): restrict flows to Paris and Dublin strategies (#1007) --- src/config.rs | 28 ++++++++++++++++++++++++++-- src/main.rs | 4 ++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 419f9aa36..c38ee1905 100644 --- a/src/config.rs +++ b/src/config.rs @@ -334,6 +334,16 @@ impl TrippyConfig { Self::build_config(args, cfg_file, platform) } + /// The maximum number of flows allowed. + /// + /// This is restricted to 1 for the classic strategy. + pub fn max_flows(&self) -> usize { + match self.multipath_strategy { + MultipathStrategy::Classic => 1, + _ => self.tui_max_flows, + } + } + #[allow(clippy::too_many_lines)] fn build_config(args: Args, cfg_file: ConfigFile, platform: &Platform) -> anyhow::Result { let &Platform { @@ -641,6 +651,7 @@ impl TrippyConfig { validate_strategy(multipath_strategy, unprivileged)?; validate_protocol_strategy(protocol, multipath_strategy)?; validate_multi(mode, protocol, &args.targets, dns_resolve_all)?; + validate_flows(mode, multipath_strategy)?; validate_ttl(first_ttl, max_ttl)?; validate_max_inflight(max_inflight)?; validate_read_timeout(read_timeout)?; @@ -918,6 +929,17 @@ fn validate_multi( } } +/// Validate that flows and dot mode are only used with udp protocol and paris +/// or dublin multipath strategy. +fn validate_flows(mode: Mode, strategy: MultipathStrategy) -> anyhow::Result<()> { + match (mode, strategy) { + (Mode::Flows | Mode::Dot, MultipathStrategy::Classic) => Err(anyhow!( + "this mode requires udp protocol with paris or dublin multipath strategy" + )), + _ => Ok(()), + } +} + /// Validate `first_ttl` and `max_ttl`. fn validate_ttl(first_ttl: u8, max_ttl: u8) -> anyhow::Result<()> { if (first_ttl as usize) < 1 || (first_ttl as usize) > MAX_HOPS { @@ -1150,11 +1172,13 @@ mod tests { #[test_case("trip example.com --mode markdown", Ok(cfg().mode(Mode::Markdown).max_rounds(Some(10)).build()); "markdown mode")] #[test_case("trip example.com --mode csv", Ok(cfg().mode(Mode::Csv).max_rounds(Some(10)).build()); "csv mode")] #[test_case("trip example.com --mode json", Ok(cfg().mode(Mode::Json).max_rounds(Some(10)).build()); "json mode")] - #[test_case("trip example.com --mode dot", Ok(cfg().mode(Mode::Dot).max_rounds(Some(10)).build()); "dot mode")] - #[test_case("trip example.com --mode flows", Ok(cfg().mode(Mode::Flows).max_rounds(Some(10)).build()); "flows mode")] + #[test_case("trip example.com --mode dot --udp -R paris", Ok(cfg().mode(Mode::Dot).max_rounds(Some(10)).multipath_strategy(MultipathStrategy::Paris).protocol(Protocol::Udp).port_direction(PortDirection::FixedSrc(Port(1024))).build()); "dot mode")] + #[test_case("trip example.com --mode flows --udp -R paris", Ok(cfg().mode(Mode::Flows).max_rounds(Some(10)).multipath_strategy(MultipathStrategy::Paris).protocol(Protocol::Udp).port_direction(PortDirection::FixedSrc(Port(1024))).build()); "flows mode")] #[test_case("trip example.com --mode silent", Ok(cfg().mode(Mode::Silent).max_rounds(Some(10)).build()); "silent mode")] #[test_case("trip example.com -m tui", Ok(cfg().mode(Mode::Tui).build()); "tui mode short")] #[test_case("trip example.com --mode foo", Err(anyhow!(format!("error: one of the values isn't valid for an argument"))); "invalid mode")] + #[test_case("trip example.com --mode dot", Err(anyhow!(format!("this mode requires udp protocol with paris or dublin multipath strategy"))); "invalid dot mode")] + #[test_case("trip example.com --mode flows", Err(anyhow!(format!("this mode requires udp protocol with paris or dublin multipath strategy"))); "invalid flows mode")] fn test_mode(cmd: &str, expected: anyhow::Result) { compare(parse_config(cmd), expected); } diff --git a/src/main.rs b/src/main.rs index 2690391d1..5c065629a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -218,7 +218,7 @@ fn start_tracer( tracer_config, channel_config, cfg.tui_max_samples, - cfg.tui_max_flows, + cfg.max_flows(), ); let trace_data = backend.trace(); thread::Builder::new() @@ -344,7 +344,7 @@ fn make_tui_config(args: &TrippyConfig) -> TuiConfig { args.tui_geoip_mode, args.tui_max_addrs, args.tui_max_samples, - args.tui_max_flows, + args.max_flows(), args.tui_theme, &args.tui_bindings, &args.tui_custom_columns,