wstunnel icon indicating copy to clipboard operation
wstunnel copied to clipboard

Optimize hot paths: DNS resolution, UDP cleanup, buffer management, and HTTP2 allocations

Open Copilot opened this issue 3 months ago • 0 comments

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() in sort_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() with drain() 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.

Copilot avatar Oct 29 '25 12:10 Copilot