feat(windows): hook WSAConnect and enrich probe summary
This commit is contained in:
1 parent
e3dfb03da1
commit
301b69a480
3 files changed
+88
-4
No files matched your search
@@ -286,6 +286,21 @@ fn build_probe_report(results: Vec<ProbeNode>, timeout: Duration, group: String)
|
||||
let total = results.len();
|
||||
let ok = results.iter().filter(|r| r.ok).count();
|
||||
let fail = total.saturating_sub(ok);
|
||||
let success_rate = if total == 0 {
|
||||
0.0
|
||||
} else {
|
||||
(ok as f64) * 100.0 / (total as f64)
|
||||
};
|
||||
let best_latency_ms = results
|
||||
.iter()
|
||||
.filter(|r| r.ok)
|
||||
.map(|r| r.latency_ms)
|
||||
.min();
|
||||
let worst_latency_ms = results
|
||||
.iter()
|
||||
.filter(|r| r.ok)
|
||||
.map(|r| r.latency_ms)
|
||||
.max();
|
||||
let mut stats = ProbeFailureStats::default();
|
||||
for r in &results {
|
||||
if r.ok {
|
||||
@@ -310,7 +325,14 @@ fn build_probe_report(results: Vec<ProbeNode>, timeout: Duration, group: String)
|
||||
generated_at_iso8601: format_unix_ts_iso8601(generated_at),
|
||||
timeout_ms: timeout.as_millis(),
|
||||
selected_group: group,
|
||||
summary: ProbeSummary { total, ok, fail },
|
||||
summary: ProbeSummary {
|
||||
total,
|
||||
ok,
|
||||
fail,
|
||||
success_rate,
|
||||
best_latency_ms,
|
||||
worst_latency_ms,
|
||||
},
|
||||
failure_stats: stats,
|
||||
nodes: results,
|
||||
}
|
||||
@@ -346,9 +368,15 @@ fn print_probe_report(report: &ProbeReport) {
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"Probe summary: total={}, ok={}, fail={}",
|
||||
report.summary.total, report.summary.ok, report.summary.fail
|
||||
"Probe summary: total={}, ok={}, fail={}, success_rate={:.2}%",
|
||||
report.summary.total, report.summary.ok, report.summary.fail, report.summary.success_rate
|
||||
);
|
||||
if let Some(best) = report.summary.best_latency_ms {
|
||||
println!("Latency: best={} ms", best);
|
||||
}
|
||||
if let Some(worst) = report.summary.worst_latency_ms {
|
||||
println!("Latency: worst={} ms", worst);
|
||||
}
|
||||
println!(
|
||||
"Failure stats: timeout={}, refused={}, reset={}, net_unreach={}, addr_unavail={}, not_connected={}, other={}",
|
||||
report.failure_stats.timeout,
|
||||
@@ -378,6 +406,9 @@ struct ProbeSummary {
|
||||
total: usize,
|
||||
ok: usize,
|
||||
fail: usize,
|
||||
success_rate: f64,
|
||||
best_latency_ms: Option<u128>,
|
||||
worst_latency_ms: Option<u128>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Default)]
|
||||
|
||||
@@ -403,6 +403,20 @@ pub unsafe extern "system" fn hook_connect_impl(
|
||||
SOCKET_ERROR
|
||||
}
|
||||
|
||||
/// Windows WSAConnect hook implementation.
|
||||
#[cfg(windows)]
|
||||
pub unsafe extern "system" fn hook_wsa_connect_impl(
|
||||
sock: usize,
|
||||
name: *const c_void,
|
||||
namelen: i32,
|
||||
_caller_data: *const c_void,
|
||||
_callee_data: *const c_void,
|
||||
_sqos: *const c_void,
|
||||
_gqos: *const c_void,
|
||||
) -> i32 {
|
||||
hook_connect_impl(sock, name, namelen)
|
||||
}
|
||||
|
||||
/// Windows getaddrinfo hook implementation.
|
||||
#[cfg(windows)]
|
||||
pub unsafe extern "system" fn hook_getaddrinfo_impl(
|
||||
|
||||
@@ -15,10 +15,19 @@ use crate::error::{Error, Result};
|
||||
|
||||
use super::hooks_windows::{
|
||||
hook_connect_impl, hook_freeaddrinfo_impl, hook_getaddrinfo_impl, hook_gethostbyname_impl,
|
||||
hook_getnameinfo_impl,
|
||||
hook_getnameinfo_impl, hook_wsa_connect_impl,
|
||||
};
|
||||
|
||||
type ConnectFn = unsafe extern "system" fn(usize, *const c_void, i32) -> i32;
|
||||
type WsaConnectFn = unsafe extern "system" fn(
|
||||
usize,
|
||||
*const c_void,
|
||||
i32,
|
||||
*const c_void,
|
||||
*const c_void,
|
||||
*const c_void,
|
||||
*const c_void,
|
||||
) -> i32;
|
||||
type GetAddrInfoFn =
|
||||
unsafe extern "system" fn(*const i8, *const i8, *const c_void, *mut *mut c_void) -> i32;
|
||||
type FreeAddrInfoFn = unsafe extern "system" fn(*mut c_void);
|
||||
@@ -27,6 +36,7 @@ type GetNameInfoFn =
|
||||
unsafe extern "system" fn(*const c_void, i32, *mut i8, u32, *mut i8, u32, i32) -> i32;
|
||||
|
||||
static ORIGINAL_CONNECT: OnceLock<ConnectFn> = OnceLock::new();
|
||||
static ORIGINAL_WSA_CONNECT: OnceLock<WsaConnectFn> = OnceLock::new();
|
||||
static ORIGINAL_GETADDRINFO: OnceLock<GetAddrInfoFn> = OnceLock::new();
|
||||
static ORIGINAL_FREEADDRINFO: OnceLock<FreeAddrInfoFn> = OnceLock::new();
|
||||
static ORIGINAL_GETHOSTBYNAME: OnceLock<GetHostByNameFn> = OnceLock::new();
|
||||
@@ -56,6 +66,8 @@ impl OriginalFunctions {
|
||||
unsafe {
|
||||
let connect_fn: ConnectFn =
|
||||
install_api_hook("connect", hook_connect_impl as *const () as *mut c_void)?;
|
||||
let wsa_connect_fn: WsaConnectFn =
|
||||
install_api_hook("WSAConnect", hook_wsa_connect_impl as *const () as *mut c_void)?;
|
||||
let getaddrinfo_fn: GetAddrInfoFn = install_api_hook(
|
||||
"getaddrinfo",
|
||||
hook_getaddrinfo_impl as *const () as *mut c_void,
|
||||
@@ -74,6 +86,7 @@ impl OriginalFunctions {
|
||||
)?;
|
||||
|
||||
let _ = ORIGINAL_CONNECT.set(connect_fn);
|
||||
let _ = ORIGINAL_WSA_CONNECT.set(wsa_connect_fn);
|
||||
let _ = ORIGINAL_GETADDRINFO.set(getaddrinfo_fn);
|
||||
let _ = ORIGINAL_FREEADDRINFO.set(freeaddrinfo_fn);
|
||||
let _ = ORIGINAL_GETHOSTBYNAME.set(gethostbyname_fn);
|
||||
@@ -115,6 +128,32 @@ pub unsafe fn original_connect(sock: usize, addr: *const c_void, len: i32) -> i3
|
||||
}
|
||||
}
|
||||
|
||||
/// Call the original WSAConnect function.
|
||||
pub unsafe fn original_wsa_connect(
|
||||
sock: usize,
|
||||
name: *const c_void,
|
||||
namelen: i32,
|
||||
caller_data: *const c_void,
|
||||
callee_data: *const c_void,
|
||||
sqos: *const c_void,
|
||||
gqos: *const c_void,
|
||||
) -> i32 {
|
||||
if let Some(f) = ORIGINAL_WSA_CONNECT.get() {
|
||||
f(
|
||||
sock,
|
||||
name,
|
||||
namelen,
|
||||
caller_data,
|
||||
callee_data,
|
||||
sqos,
|
||||
gqos,
|
||||
)
|
||||
} else {
|
||||
WSASetLastError(WSAECONNREFUSED.0);
|
||||
-1
|
||||
}
|
||||
}
|
||||
|
||||
/// Call the original getaddrinfo function.
|
||||
pub unsafe fn original_getaddrinfo(
|
||||
node: *const i8,
|
||||
|
||||
Reference in new issue
Block a user