Merge remote-tracking branch 'origin/feature/probe-ports-test' into feature/probe-ports-test
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use clap::{ArgGroup, Args, Parser, Subcommand, ValueEnum};
|
||||
use nym_bin_common::bin_info;
|
||||
use nym_config::defaults::setup_env;
|
||||
use nym_gateway_probe::config::{CredentialArgs, CredentialMode, NetstackArgs, ProbeConfig};
|
||||
use nym_gateway_probe::{
|
||||
NymApiDirectory, PortCheckResult, ProbeResult, RunPortsConfig, query_gateway_by_ip,
|
||||
DirectPortCheckProtocol, NymApiDirectory, PortCheckResult, ProbeResult, RunPortsConfig,
|
||||
query_gateway_by_ip,
|
||||
};
|
||||
use nym_sdk::mixnet::NodeIdentity;
|
||||
use serde::Serialize;
|
||||
@@ -93,11 +94,19 @@ enum Commands {
|
||||
config_dir: Option<PathBuf>,
|
||||
|
||||
/// Bonded gateway identity.
|
||||
#[arg(long, short = 'g', alias = "gateway")]
|
||||
entry_gateway: NodeIdentity,
|
||||
/// Cannot be used with --gateway-ip.
|
||||
#[arg(long, short = 'g', alias = "gateway", conflicts_with = "gateway_ip")]
|
||||
entry_gateway: Option<NodeIdentity>,
|
||||
|
||||
/// Gateway queried directly by IP address (unannounced/local gateways)
|
||||
/// Cannot be used with --gateway/--entry-gateway.
|
||||
/// Cannot be used with --mnemonic or --use-mock-ecash.
|
||||
#[arg(long, conflicts_with = "entry_gateway", conflicts_with = "gateway")]
|
||||
gateway_ip: Option<String>,
|
||||
|
||||
/// Separate exit gateway to test (entry_gateway is used for mixnet entry)
|
||||
#[arg(long)]
|
||||
/// Cannot be used with --gateway-ip.
|
||||
#[arg(long, conflicts_with = "gateway_ip")]
|
||||
exit_gateway: Option<NodeIdentity>,
|
||||
|
||||
/// Test every port in the canonical exit policy (network-tunnel-manager.sh PORT_MAPPINGS).
|
||||
@@ -105,9 +114,14 @@ enum Commands {
|
||||
#[arg(long)]
|
||||
check_all_ports: bool,
|
||||
|
||||
/// Credential arguments (required).
|
||||
/// Specify the protocol used for tests with --gateway-ip.
|
||||
#[arg(long, value_enum, default_value_t = PortCheckProtocol::Auto)]
|
||||
check_protocol: PortCheckProtocol,
|
||||
|
||||
/// Optional credential arguments.
|
||||
/// Required only in bonded mode (when using --gateway/--entry-gateway).
|
||||
#[command(flatten)]
|
||||
credential_mode: CredentialMode,
|
||||
credential_mode: OptionalCredentialMode,
|
||||
|
||||
#[command(flatten)]
|
||||
probe_config: RunPortsProbeConfig,
|
||||
@@ -128,6 +142,45 @@ enum Commands {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
|
||||
enum PortCheckProtocol {
|
||||
Auto,
|
||||
Tcp,
|
||||
Udp,
|
||||
}
|
||||
|
||||
#[derive(Debug, Args, Clone)]
|
||||
#[command(group(
|
||||
ArgGroup::new("run_ports_credential_mode")
|
||||
.args(["use_mock_ecash","mnemonic"])
|
||||
.required(false)
|
||||
.multiple(false)
|
||||
))]
|
||||
struct OptionalCredentialMode {
|
||||
/// Use mock ecash credentials for testing
|
||||
#[arg(long, action = clap::ArgAction::SetTrue, conflicts_with = "gateway_ip")]
|
||||
use_mock_ecash: bool,
|
||||
|
||||
/// Mnemonic to get credentials from the blockchain
|
||||
#[arg(long, conflicts_with = "gateway_ip")]
|
||||
mnemonic: Option<String>,
|
||||
}
|
||||
|
||||
impl OptionalCredentialMode {
|
||||
fn into_required(self) -> anyhow::Result<CredentialMode> {
|
||||
if self.use_mock_ecash || self.mnemonic.is_some() {
|
||||
Ok(CredentialMode {
|
||||
use_mock_ecash: self.use_mock_ecash,
|
||||
mnemonic: self.mnemonic,
|
||||
})
|
||||
} else {
|
||||
anyhow::bail!(
|
||||
"missing credentials for bonded run-ports mode: provide --mnemonic <MNEMONIC> or --use-mock-ecash"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Args, Clone)]
|
||||
struct RunPortsProbeConfig {
|
||||
/// Only choose gateway with that minimum performance
|
||||
@@ -272,9 +325,11 @@ pub(crate) async fn run() -> anyhow::Result<ProbeOutput> {
|
||||
}
|
||||
Commands::RunPorts {
|
||||
entry_gateway,
|
||||
gateway_ip,
|
||||
exit_gateway,
|
||||
config_dir,
|
||||
check_all_ports,
|
||||
check_protocol,
|
||||
credential_mode,
|
||||
probe_config,
|
||||
} => {
|
||||
@@ -294,6 +349,47 @@ pub(crate) async fn run() -> anyhow::Result<ProbeOutput> {
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(gateway_ip) = gateway_ip {
|
||||
info!("Using direct IP-only port check mode for gateway: {gateway_ip}");
|
||||
if entry_gateway.is_some() {
|
||||
anyhow::bail!("--gateway/--entry-gateway cannot be used with --gateway-ip");
|
||||
}
|
||||
|
||||
let target_ip: std::net::IpAddr = gateway_ip.parse().map_err(|_| {
|
||||
anyhow::anyhow!(
|
||||
"invalid --gateway-ip value '{gateway_ip}': expected plain IP address"
|
||||
)
|
||||
})?;
|
||||
|
||||
let direct_protocol = match check_protocol {
|
||||
PortCheckProtocol::Auto => DirectPortCheckProtocol::Auto,
|
||||
PortCheckProtocol::Tcp => DirectPortCheckProtocol::Tcp,
|
||||
PortCheckProtocol::Udp => DirectPortCheckProtocol::Udp,
|
||||
};
|
||||
|
||||
return Box::pin(nym_gateway_probe::Probe::probe_run_ports_direct_ip(
|
||||
&gateway_ip,
|
||||
target_ip,
|
||||
&run_ports_config,
|
||||
direct_protocol,
|
||||
))
|
||||
.await
|
||||
.map(ProbeOutput::PortCheck);
|
||||
}
|
||||
|
||||
if check_protocol == PortCheckProtocol::Udp {
|
||||
anyhow::bail!(
|
||||
"--check-protocol udp is only supported with --gateway-ip direct mode"
|
||||
);
|
||||
}
|
||||
if check_protocol == PortCheckProtocol::Auto {
|
||||
info!(
|
||||
"Bonded run-ports mode uses TCP checks; treating --check-protocol auto as tcp"
|
||||
);
|
||||
}
|
||||
|
||||
let credential_mode = credential_mode.into_required()?;
|
||||
|
||||
let api_url = network
|
||||
.endpoints
|
||||
.first()
|
||||
@@ -301,6 +397,11 @@ pub(crate) async fn run() -> anyhow::Result<ProbeOutput> {
|
||||
.ok_or(anyhow::anyhow!("missing api url"))?;
|
||||
|
||||
let directory = NymApiDirectory::new(api_url).await?;
|
||||
let entry_gateway = entry_gateway.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"missing gateway selection: provide --gateway <ID> or --gateway-ip <IP[:PORT]>"
|
||||
)
|
||||
})?;
|
||||
|
||||
let entry_details = directory
|
||||
.entry_gateway(&entry_gateway)?
|
||||
|
||||
Reference in New Issue
Block a user