feat: add proxy node probe command and docs
This commit is contained in:
1 parent
33dd48d4b4
commit
e70e6c3b4c
3 files changed
+87
-1
No files matched your search
@@ -40,6 +40,7 @@ Recommendation:
|
||||
- Discovery/validation:
|
||||
- `--list-groups`
|
||||
- `--check`
|
||||
- `--probe` (quick per-node reachability/latency check)
|
||||
- DNS:
|
||||
- `proxy_dns`
|
||||
- compatibility aliases: `proxy_dns_old`, `proxy_dns_daemon`
|
||||
@@ -88,6 +89,8 @@ Validate config and groups:
|
||||
```bash
|
||||
proxychains4 -f ./proxychains.conf --list-groups
|
||||
proxychains4 -f ./proxychains.conf --group jp --check
|
||||
proxychains4 -f ./proxychains.conf --group jp --probe
|
||||
proxychains4 -f ./proxychains.conf --probe --probe-timeout-ms 1200
|
||||
```
|
||||
|
||||
## Example Config
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
- 配置发现/校验:
|
||||
- `--list-groups`
|
||||
- `--check`
|
||||
- `--probe`(快速探测每个节点连通性与时延)
|
||||
- DNS:
|
||||
- `proxy_dns`
|
||||
- 兼容别名:`proxy_dns_old`、`proxy_dns_daemon`
|
||||
@@ -88,6 +89,8 @@ proxychains4.exe curl https://ifconfig.me
|
||||
```bash
|
||||
proxychains4 -f ./proxychains.conf --list-groups
|
||||
proxychains4 -f ./proxychains.conf --group jp --check
|
||||
proxychains4 -f ./proxychains.conf --group jp --probe
|
||||
proxychains4 -f ./proxychains.conf --probe --probe-timeout-ms 1200
|
||||
```
|
||||
|
||||
## 示例配置
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
//! - Windows: Uses DLL injection
|
||||
|
||||
use std::env;
|
||||
use std::net::{SocketAddr, SocketAddrV4, TcpStream};
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use clap::Parser;
|
||||
use tracing::{debug, error, info, Level};
|
||||
@@ -47,9 +49,17 @@ struct Args {
|
||||
#[arg(long)]
|
||||
check: bool,
|
||||
|
||||
/// Probe configured proxy nodes and print per-node reachability
|
||||
#[arg(long)]
|
||||
probe: bool,
|
||||
|
||||
/// Probe timeout in milliseconds (default: config tcp_connect_time_out)
|
||||
#[arg(long, value_name = "MS")]
|
||||
probe_timeout_ms: Option<u64>,
|
||||
|
||||
/// The command to run
|
||||
#[arg(
|
||||
required_unless_present_any = ["list_groups", "check"],
|
||||
required_unless_present_any = ["list_groups", "check", "probe"],
|
||||
trailing_var_arg = true
|
||||
)]
|
||||
command: Vec<String>,
|
||||
@@ -121,6 +131,11 @@ fn main() {
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
if args.probe {
|
||||
let failed = run_probe(&config, &args);
|
||||
process::exit(if failed == 0 { 0 } else { 2 });
|
||||
}
|
||||
|
||||
// Execute the command with platform-specific injection
|
||||
match execute_command(&args, &config) {
|
||||
Ok(status) => {
|
||||
@@ -190,6 +205,62 @@ fn print_check_summary(config: &Config, args: &Args) {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_probe(config: &Config, args: &Args) -> usize {
|
||||
let timeout = args
|
||||
.probe_timeout_ms
|
||||
.map(Duration::from_millis)
|
||||
.unwrap_or(config.tcp_connect_timeout);
|
||||
let mut failed = 0usize;
|
||||
|
||||
println!("Proxy probe:");
|
||||
println!(" timeout_ms={}", timeout.as_millis());
|
||||
println!(
|
||||
" group={}",
|
||||
args.group.as_deref().unwrap_or("default/all")
|
||||
);
|
||||
|
||||
for (idx, proxy) in config.proxies.iter().enumerate() {
|
||||
let target_v4 = SocketAddrV4::new(proxy.ip, proxy.port);
|
||||
let target = SocketAddr::V4(target_v4);
|
||||
let start = Instant::now();
|
||||
match TcpStream::connect_timeout(&target, timeout) {
|
||||
Ok(stream) => {
|
||||
let elapsed = start.elapsed().as_millis();
|
||||
let _ = stream.shutdown(std::net::Shutdown::Both);
|
||||
println!(
|
||||
" [{}] OK {:<6} {}:{} {} ms",
|
||||
idx + 1,
|
||||
proxy.proxy_type,
|
||||
proxy.ip,
|
||||
proxy.port,
|
||||
elapsed
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
failed += 1;
|
||||
let elapsed = start.elapsed().as_millis();
|
||||
println!(
|
||||
" [{}] FAIL {:<6} {}:{} {} ms ({})",
|
||||
idx + 1,
|
||||
proxy.proxy_type,
|
||||
proxy.ip,
|
||||
proxy.port,
|
||||
elapsed,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"Probe summary: total={}, ok={}, fail={}",
|
||||
config.proxies.len(),
|
||||
config.proxies.len().saturating_sub(failed),
|
||||
failed
|
||||
);
|
||||
failed
|
||||
}
|
||||
|
||||
/// Set proxychains-specific environment variables
|
||||
fn set_proxychains_env(config: &Config, args: &Args) {
|
||||
if args.quiet {
|
||||
@@ -425,4 +496,13 @@ mod tests {
|
||||
assert!(args.list_groups);
|
||||
assert!(args.command.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_args_probe_without_command() {
|
||||
let args = Args::try_parse_from(["proxychains4", "--probe"]);
|
||||
assert!(args.is_ok());
|
||||
let args = args.unwrap();
|
||||
assert!(args.probe);
|
||||
assert!(args.command.is_empty());
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user