wstunnel
wstunnel copied to clipboard
Optimize hot paths: DNS resolution, UDP cleanup, buffer management, and HTTP2 allocations
Identified and fixed performance bottlenecks in network I/O hot paths causing unnecessary allocations, redundant iterations, and lock contention.
DNS Resolver (protocols/dns/resolver.rs)
- Replace multi-pass iterator chains with single-pass
partition()insort_socket_addrs - Eliminates redundant traversals when interleaving IPv4/IPv6 addresses per RFC8305
Before:
let mut v6 = socket_addrs.iter().filter(|s| matches!(s, SocketAddr::V6(_)));
let mut v4 = socket_addrs.iter().filter(|s| matches!(s, SocketAddr::V4(_)));
// Two separate iterator chains, multiple passes
After:
let (v6_addrs, v4_addrs): (Vec<SocketAddr>, Vec<SocketAddr>) =
socket_addrs.iter().partition(|s| matches!(s, SocketAddr::V6(_)));
// Single pass, then direct iteration
UDP Server (protocols/udp/server.rs)
- Replace
iter()+clear()withdrain()in dead key cleanup - Reduces write lock hold time under high connection churn
Websocket Transport (tunnel/transport/websocket.rs)
- Fix buffer growth:
reserve()adds to capacity, not sets it - Previous code:
reserve(capacity + capacity/4)→ actual growth ~56% - Fixed code:
reserve(capacity/4)→ correct 25% growth - Update misleading comment (claimed "1.25%" was actually 25%)
HTTP2 Transport (tunnel/transport/http2.rs)
- Use static
LazyLock<Arc<Notify>>instead of allocating per tunnel - HTTP2 doesn't use pending operations; shared dummy is sufficient
Original prompt
Identify and suggest improvements to slow or inefficient code
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.