Add: H3 support - incomplete

This commit is contained in:
DaZuo0122
2026-01-17 13:47:37 +08:00
parent 840ceec38f
commit ccd4a31d21
14 changed files with 1553 additions and 71 deletions

View File

@@ -10,8 +10,8 @@ use x509_parser::oid_registry::{
use std::sync::Arc;
use wtfnet_core::ErrorCode;
use wtfnet_platform::{
CertProvider, DnsConfigSnapshot, ListenSocket, NeighborEntry, NeighProvider, NetInterface,
Platform, PlatformError, PortsProvider, RootCert, RouteEntry, SysProvider,
CertProvider, ConnSocket, DnsConfigSnapshot, ListenSocket, NeighborEntry, NeighProvider,
NetInterface, Platform, PlatformError, PortsProvider, RootCert, RouteEntry, SysProvider,
};
pub fn platform() -> Platform {
@@ -333,6 +333,33 @@ fn parse_windows_listeners() -> Result<Vec<ListenSocket>, PlatformError> {
Ok(sockets)
}
fn parse_windows_connections() -> Result<Vec<ConnSocket>, PlatformError> {
let proc_map = load_windows_process_map();
let output = std::process::Command::new("netstat")
.arg("-ano")
.output()
.map_err(|err| PlatformError::new(ErrorCode::IoError, err.to_string()))?;
if !output.status.success() {
return Err(PlatformError::new(ErrorCode::IoError, "netstat -ano failed"));
}
let text = String::from_utf8_lossy(&output.stdout);
let mut sockets = Vec::new();
for line in text.lines() {
let trimmed = line.trim();
if !trimmed.starts_with("TCP") {
continue;
}
if let Some(mut socket) = parse_netstat_tcp_conn_line(trimmed) {
enrich_conn_socket(&mut socket, &proc_map);
sockets.push(socket);
}
}
Ok(sockets)
}
fn parse_netstat_tcp_line(line: &str) -> Option<ListenSocket> {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() < 5 {
@@ -358,6 +385,32 @@ fn parse_netstat_tcp_line(line: &str) -> Option<ListenSocket> {
})
}
fn parse_netstat_tcp_conn_line(line: &str) -> Option<ConnSocket> {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() < 5 {
return None;
}
let local = parts[1];
let remote = parts[2];
let state = parts[3];
let pid = parts[4].parse::<u32>().ok();
if state == "LISTENING" {
return None;
}
Some(ConnSocket {
proto: "tcp".to_string(),
local_addr: local.to_string(),
remote_addr: remote.to_string(),
state: Some(state.to_string()),
pid,
ppid: None,
process_name: None,
process_path: None,
})
}
fn parse_netstat_udp_line(line: &str) -> Option<ListenSocket> {
let parts: Vec<&str> = line.split_whitespace().collect();
if parts.len() < 4 {
@@ -429,6 +482,17 @@ fn enrich_socket(socket: &mut ListenSocket, map: &HashMap<u32, ProcInfo>) {
}
}
fn enrich_conn_socket(socket: &mut ConnSocket, map: &HashMap<u32, ProcInfo>) {
let pid = match socket.pid {
Some(pid) => pid,
None => return,
};
if let Some(info) = map.get(&pid) {
socket.process_name = info.name.clone();
socket.process_path = info.path.clone();
}
}
#[derive(Clone)]
struct ProcInfo {
name: Option<String>,
@@ -605,6 +669,10 @@ impl PortsProvider for WindowsPortsProvider {
.filter(|socket| extract_port(&socket.local_addr) == Some(port))
.collect())
}
async fn connections(&self) -> Result<Vec<ConnSocket>, PlatformError> {
parse_windows_connections()
}
}
#[async_trait]