Skip to content

Commit

Permalink
feat(config): restrict flows to Paris and Dublin strategies (#1007)
Browse files Browse the repository at this point in the history
  • Loading branch information
fujiapple852 committed Mar 2, 2024
1 parent 9b1aabd commit 6205685
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 20 deletions.
34 changes: 29 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,17 @@ pub enum Mode {
Tui,
/// Display a continuous stream of tracing data
Stream,
/// Generate an pretty text table report for N cycles.
/// Generate a pretty text table report for N cycles.
Pretty,
/// Generate a markdown text table report for N cycles.
/// Generate a Markdown text table report for N cycles.
Markdown,
/// Generate a CSV report for N cycles.
Csv,
/// Generate a JSON report for N cycles.
Json,
/// Generate a Graphviz DOT file for N cycles.
Dot,
/// Display all flows.
/// Display all flows for N cycles.
Flows,
/// Do not generate any tracing output for N cycles.
Silent,
Expand Down Expand Up @@ -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<Self> {
let &Platform {
Expand Down Expand Up @@ -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)?;
Expand Down Expand Up @@ -918,6 +929,17 @@ fn validate_multi(
}
}

/// Validate that flows and dot mode are only used with 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 the 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 {
Expand Down Expand Up @@ -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 the paris or dublin multipath strategy"))); "invalid dot mode")]
#[test_case("trip example.com --mode flows", Err(anyhow!(format!("this mode requires the paris or dublin multipath strategy"))); "invalid flows mode")]
fn test_mode(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
compare(parse_config(cmd), expected);
}
Expand Down
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion test_resources/completions_fish.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
complete -c trip -s c -l config-file -d 'Config file' -r -F
complete -c trip -s m -l mode -d 'Output mode [default: tui]' -r -f -a "{tui 'Display interactive TUI',stream 'Display a continuous stream of tracing data',pretty 'Generate an pretty text table report for N cycles',markdown 'Generate a markdown text table report for N cycles',csv 'Generate a CSV report for N cycles',json 'Generate a JSON report for N cycles',dot 'Generate a Graphviz DOT file for N cycles',flows 'Display all flows',silent 'Do not generate any tracing output for N cycles'}"
complete -c trip -s m -l mode -d 'Output mode [default: tui]' -r -f -a "{tui 'Display interactive TUI',stream 'Display a continuous stream of tracing data',pretty 'Generate a pretty text table report for N cycles',markdown 'Generate a Markdown text table report for N cycles',csv 'Generate a CSV report for N cycles',json 'Generate a JSON report for N cycles',dot 'Generate a Graphviz DOT file for N cycles',flows 'Display all flows for N cycles',silent 'Do not generate any tracing output for N cycles'}"
complete -c trip -s p -l protocol -d 'Tracing protocol [default: icmp]' -r -f -a "{icmp 'Internet Control Message Protocol',udp 'User Datagram Protocol',tcp 'Transmission Control Protocol'}"
complete -c trip -s F -l addr-family -d 'The address family [default: Ipv4thenIpv6]' -r -f -a "{ipv4 'Ipv4 only',ipv6 'Ipv6 only',ipv6-then-ipv4 'Ipv6 with a fallback to Ipv4',ipv4-then-ipv6 'Ipv4 with a fallback to Ipv6'}"
complete -c trip -s P -l target-port -d 'The target port (TCP & UDP only) [default: 80]' -r
Expand Down
12 changes: 6 additions & 6 deletions test_resources/completions_zsh.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ _trip() {
'--config-file=[Config file]:CONFIG_FILE:_files' \
'-m+[Output mode \[default\: tui\]]:MODE:((tui\:"Display interactive TUI"
stream\:"Display a continuous stream of tracing data"
pretty\:"Generate an pretty text table report for N cycles"
markdown\:"Generate a markdown text table report for N cycles"
pretty\:"Generate a pretty text table report for N cycles"
markdown\:"Generate a Markdown text table report for N cycles"
csv\:"Generate a CSV report for N cycles"
json\:"Generate a JSON report for N cycles"
dot\:"Generate a Graphviz DOT file for N cycles"
flows\:"Display all flows"
flows\:"Display all flows for N cycles"
silent\:"Do not generate any tracing output for N cycles"))' \
'--mode=[Output mode \[default\: tui\]]:MODE:((tui\:"Display interactive TUI"
stream\:"Display a continuous stream of tracing data"
pretty\:"Generate an pretty text table report for N cycles"
markdown\:"Generate a markdown text table report for N cycles"
pretty\:"Generate a pretty text table report for N cycles"
markdown\:"Generate a Markdown text table report for N cycles"
csv\:"Generate a CSV report for N cycles"
json\:"Generate a JSON report for N cycles"
dot\:"Generate a Graphviz DOT file for N cycles"
flows\:"Display all flows"
flows\:"Display all flows for N cycles"
silent\:"Do not generate any tracing output for N cycles"))' \
'-p+[Tracing protocol \[default\: icmp\]]:PROTOCOL:((icmp\:"Internet Control Message Protocol"
udp\:"User Datagram Protocol"
Expand Down
6 changes: 3 additions & 3 deletions test_resources/usage_long.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ Options:
Possible values:
- tui: Display interactive TUI
- stream: Display a continuous stream of tracing data
- pretty: Generate an pretty text table report for N cycles
- markdown: Generate a markdown text table report for N cycles
- pretty: Generate a pretty text table report for N cycles
- markdown: Generate a Markdown text table report for N cycles
- csv: Generate a CSV report for N cycles
- json: Generate a JSON report for N cycles
- dot: Generate a Graphviz DOT file for N cycles
- flows: Display all flows
- flows: Display all flows for N cycles
- silent: Do not generate any tracing output for N cycles

-u, --unprivileged
Expand Down
9 changes: 6 additions & 3 deletions trippy-config-sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
# Allowed values are:
# tui - Display interactive Tui [default]
# stream - Display a continuous stream of tracing data
# pretty - Generate an pretty text table report for N cycles
# markdown - Generate a markdown text table report for N cycles
# pretty - Generate a pretty text table report for N cycles
# markdown - Generate a Markdown text table report for N cycles
# csv - Generate a CSV report for N cycles
# json - Generate a JSON report for N cycles
# dot - Generate a Graphviz DOT report for N cycles
# flows - Display all flows
# flows - Display all flows for N cycles
# silent - Do not generate any output for N cycles
#
# Note: the dot and flows modes are only allowed with paris or dublin
# multipath strategy.
mode = "tui"

# Trace without requiring elevated privileges [default: false]
Expand Down

0 comments on commit 6205685

Please sign in to comment.