diff --git a/Cargo.lock b/Cargo.lock index 2f63320..683ae47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2851,6 +2851,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-socks", + "tracing", "url", ] @@ -2871,6 +2872,7 @@ dependencies = [ "serde", "thiserror 2.0.17", "tokio", + "tracing", "url", ] @@ -2927,6 +2929,7 @@ dependencies = [ "thiserror 2.0.17", "tokio", "tokio-socks", + "tracing", "url", "wtfnet-geoip", ] @@ -2942,6 +2945,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-socks", + "tracing", "url", "x509-parser", ] diff --git a/README.md b/README.md index 91674c9..5c41b50 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ wtfn calc summarize 10.0.0.0/24 10.0.1.0/24 Global flags: - `--json` / `--pretty` - `--no-color` / `--quiet` -- `-v` / `-vv` +- `-v` / `-vv` / `--verbose` - `--log-level ` - `--log-format ` - `--log-file ` diff --git a/crates/wtfnet-cli/src/main.rs b/crates/wtfnet-cli/src/main.rs index bb9e5c6..a9a4f07 100644 --- a/crates/wtfnet-cli/src/main.rs +++ b/crates/wtfnet-cli/src/main.rs @@ -24,7 +24,7 @@ struct Cli { no_color: bool, #[arg(long)] quiet: bool, - #[arg(short = 'v', action = clap::ArgAction::Count)] + #[arg(short = 'v', long = "verbose", action = clap::ArgAction::Count)] verbose: u8, #[arg(long)] log_level: Option, diff --git a/crates/wtfnet-dns/Cargo.toml b/crates/wtfnet-dns/Cargo.toml index fa8c855..d0156b9 100644 --- a/crates/wtfnet-dns/Cargo.toml +++ b/crates/wtfnet-dns/Cargo.toml @@ -16,6 +16,7 @@ tokio-rustls = "0.24" tokio-socks = "0.5" url = "2" pnet = { version = "0.34", optional = true } +tracing = "0.1" [features] pcap = ["dep:pnet"] diff --git a/crates/wtfnet-dns/src/lib.rs b/crates/wtfnet-dns/src/lib.rs index 1917d1b..8c7515f 100644 --- a/crates/wtfnet-dns/src/lib.rs +++ b/crates/wtfnet-dns/src/lib.rs @@ -19,6 +19,7 @@ use thiserror::Error; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio_rustls::TlsConnector; use tokio_socks::tcp::Socks5Stream; +use tracing::debug; use url::Url; #[cfg(feature = "pcap")] @@ -169,6 +170,15 @@ pub async fn query( timeout_ms: u64, ) -> Result { let record_type = parse_record_type(record_type)?; + debug!( + domain, + record_type = %record_type, + transport = %transport, + server = ?server.as_ref().map(|value| value.addr), + proxy = ?proxy.as_deref(), + timeout_ms, + "dns query start" + ); if let Some(proxy) = proxy { let server = server.ok_or_else(|| DnsError::MissingServer(transport.to_string()))?; return match transport { @@ -245,6 +255,15 @@ pub async fn detect( repeat: u32, timeout_ms: u64, ) -> Result { + debug!( + domain, + transport = %transport, + servers = servers.len(), + proxy = ?proxy.as_deref(), + repeat, + timeout_ms, + "dns detect start" + ); let mut results = Vec::new(); for server in servers { for _ in 0..repeat.max(1) { @@ -311,6 +330,12 @@ pub async fn watch(_options: DnsWatchOptions) -> Result Result { + debug!( + iface = ?options.iface, + duration_ms = options.duration_ms, + filter = ?options.filter, + "dns watch start" + ); let iface = match select_interface(options.iface.as_deref()) { Some(value) => value, None => { @@ -341,6 +366,15 @@ pub async fn watch(options: DnsWatchOptions) -> Result match rx.next() { Ok(frame) => { if let Some(event) = parse_dns_frame(frame, start, &filter) { + debug!( + src = %event.src, + dst = %event.dst, + query_name = %event.query_name, + query_type = %event.query_type, + rcode = %event.rcode, + is_response = event.is_response, + "dns watch event" + ); events.push(event); } } @@ -435,6 +469,13 @@ async fn doh_query_via_proxy( timeout_ms: u64, proxy: String, ) -> Result { + debug!( + domain, + record_type = %record_type, + server = %server.addr, + proxy = %proxy, + "dns doh via proxy" + ); let tls_name = server .name .clone() @@ -530,6 +571,13 @@ async fn dot_query_via_proxy( timeout_ms: u64, proxy: String, ) -> Result { + debug!( + domain, + record_type = %record_type, + server = %server.addr, + proxy = %proxy, + "dns dot via proxy" + ); let tls_name = server .name .clone() diff --git a/crates/wtfnet-http/Cargo.toml b/crates/wtfnet-http/Cargo.toml index 147de14..fc6dfbc 100644 --- a/crates/wtfnet-http/Cargo.toml +++ b/crates/wtfnet-http/Cargo.toml @@ -9,3 +9,4 @@ serde = { version = "1", features = ["derive"] } thiserror = "2" tokio = { version = "1", features = ["net", "time"] } url = "2" +tracing = "0.1" diff --git a/crates/wtfnet-http/src/lib.rs b/crates/wtfnet-http/src/lib.rs index fd6c7a2..c572340 100644 --- a/crates/wtfnet-http/src/lib.rs +++ b/crates/wtfnet-http/src/lib.rs @@ -4,6 +4,7 @@ use std::net::{IpAddr, SocketAddr}; use std::time::{Duration, Instant}; use tokio::net::lookup_host; use thiserror::Error; +use tracing::debug; use url::Url; #[derive(Debug, Error)] @@ -67,6 +68,16 @@ pub struct HttpRequestOptions { } pub async fn request(url: &str, opts: HttpRequestOptions) -> Result { + debug!( + url, + method = ?opts.method, + timeout_ms = opts.timeout_ms, + follow_redirects = ?opts.follow_redirects, + http1_only = opts.http1_only, + http2_only = opts.http2_only, + proxy = ?opts.proxy, + "http request start" + ); let parsed = Url::parse(url).map_err(|err| HttpError::Url(err.to_string()))?; let host = parsed .host_str() diff --git a/crates/wtfnet-probe/Cargo.toml b/crates/wtfnet-probe/Cargo.toml index 50fd227..be07eff 100644 --- a/crates/wtfnet-probe/Cargo.toml +++ b/crates/wtfnet-probe/Cargo.toml @@ -14,3 +14,4 @@ wtfnet-geoip = { path = "../wtfnet-geoip" } libc = "0.2" tokio-socks = "0.5" url = "2" +tracing = "0.1" diff --git a/crates/wtfnet-probe/src/lib.rs b/crates/wtfnet-probe/src/lib.rs index 6082427..904c08f 100644 --- a/crates/wtfnet-probe/src/lib.rs +++ b/crates/wtfnet-probe/src/lib.rs @@ -21,6 +21,7 @@ use thiserror::Error; use tokio::net::{TcpStream, lookup_host}; use tokio::time::timeout; use tokio_socks::tcp::Socks5Stream; +use tracing::debug; use url::Url; use wtfnet_geoip::GeoIpRecord; @@ -114,7 +115,15 @@ pub async fn ping( timeout_ms: u64, interval_ms: u64, ) -> Result { + debug!( + target, + count, + timeout_ms, + interval_ms, + "probe ping start" + ); let addr = resolve_one(target).await?; + debug!(ip = %addr, "probe ping resolved"); let mut results = Vec::new(); let mut received = 0u32; let mut min = None; @@ -193,6 +202,15 @@ pub async fn tcp_ping( proxy: Option<&str>, prefer_ipv4: bool, ) -> Result { + debug!( + target, + port, + count, + timeout_ms, + proxy = ?proxy, + prefer_ipv4, + "probe tcp ping start" + ); let (report_ip, target_host, proxy_addr) = if let Some(proxy) = proxy { let proxy = parse_socks5_proxy(proxy)?; if proxy.remote_dns { @@ -214,6 +232,12 @@ pub async fn tcp_ping( (Some(addr), addr.to_string(), String::new()) }; let socket_addr = report_ip.map(|addr| SocketAddr::new(addr, port)); + debug!( + report_ip = ?report_ip, + target_host = %target_host, + proxy_addr = %proxy_addr, + "probe tcp ping resolved" + ); let timeout_dur = Duration::from_millis(timeout_ms); let mut results = Vec::new(); let mut received = 0u32; @@ -285,7 +309,15 @@ pub async fn tcp_trace( max_hops: u8, timeout_ms: u64, ) -> Result { + debug!( + target, + port, + max_hops, + timeout_ms, + "probe tcp trace start" + ); let addr = resolve_one(target).await?; + debug!(ip = %addr, "probe tcp trace resolved"); let socket_addr = SocketAddr::new(addr, port); let timeout_dur = Duration::from_millis(timeout_ms); let mut hops = Vec::new(); @@ -341,7 +373,15 @@ pub async fn udp_trace( max_hops: u8, timeout_ms: u64, ) -> Result { + debug!( + target, + port, + max_hops, + timeout_ms, + "probe udp trace start" + ); let addr = resolve_one(target).await?; + debug!(ip = %addr, "probe udp trace resolved"); let timeout_dur = Duration::from_millis(timeout_ms); let mut hops = Vec::new(); diff --git a/crates/wtfnet-tls/Cargo.toml b/crates/wtfnet-tls/Cargo.toml index 7d89c3a..04195b3 100644 --- a/crates/wtfnet-tls/Cargo.toml +++ b/crates/wtfnet-tls/Cargo.toml @@ -13,3 +13,4 @@ tokio-rustls = "0.24" x509-parser = "0.16" tokio-socks = "0.5" url = "2" +tracing = "0.1" diff --git a/crates/wtfnet-tls/src/lib.rs b/crates/wtfnet-tls/src/lib.rs index 33e1f0b..b528e82 100644 --- a/crates/wtfnet-tls/src/lib.rs +++ b/crates/wtfnet-tls/src/lib.rs @@ -8,6 +8,7 @@ use tokio::net::TcpStream; use tokio::time::timeout; use tokio_rustls::TlsConnector; use tokio_socks::tcp::Socks5Stream; +use tracing::debug; use url::Url; use x509_parser::prelude::{FromDer, X509Certificate}; @@ -85,6 +86,15 @@ pub struct TlsOptions { } pub async fn handshake(target: &str, options: TlsOptions) -> Result { + debug!( + target, + sni = ?options.sni, + alpn = ?options.alpn, + proxy = ?options.socks5, + timeout_ms = options.timeout_ms, + prefer_ipv4 = options.prefer_ipv4, + "tls handshake start" + ); let (host, port, server_name) = parse_target(target, options.sni.as_deref())?; let connector = build_connector(options.insecure, &options.alpn)?; let stream = connect( @@ -115,6 +125,15 @@ pub async fn handshake(target: &str, options: TlsOptions) -> Result Result { + debug!( + target, + sni = ?options.sni, + alpn = ?options.alpn, + proxy = ?options.socks5, + timeout_ms = options.timeout_ms, + prefer_ipv4 = options.prefer_ipv4, + "tls verify start" + ); let (host, port, server_name) = parse_target(target, options.sni.as_deref())?; let connector = build_connector(false, &options.alpn)?; match connect( @@ -159,6 +178,15 @@ pub async fn verify(target: &str, options: TlsOptions) -> Result Result { + debug!( + target, + sni = ?options.sni, + alpn = ?options.alpn, + proxy = ?options.socks5, + timeout_ms = options.timeout_ms, + prefer_ipv4 = options.prefer_ipv4, + "tls certs start" + ); let (host, port, server_name) = parse_target(target, options.sni.as_deref())?; let connector = build_connector(options.insecure, &options.alpn)?; let stream = connect( @@ -180,6 +208,15 @@ pub async fn certs(target: &str, options: TlsOptions) -> Result Result { + debug!( + target, + sni = ?options.sni, + alpn = ?options.alpn, + proxy = ?options.socks5, + timeout_ms = options.timeout_ms, + prefer_ipv4 = options.prefer_ipv4, + "tls alpn start" + ); let (host, port, server_name) = parse_target(target, options.sni.as_deref())?; let connector = build_connector(options.insecure, &options.alpn)?; let stream = connect(