fix: stop unbounded memory growth that hangs the OS - #66
Open
abolfazlakbarzadeh wants to merge 5 commits into
Open
fix: stop unbounded memory growth that hangs the OS#66abolfazlakbarzadeh wants to merge 5 commits into
abolfazlakbarzadeh wants to merge 5 commits into
Conversation
Close TCP/UDP flows from Drop so DNS lookups and aborted SOCKS clients release smoltcp sockets instead of leaking buffers forever. Cap per-connection TCP pending with deferral/backpressure, free established sockets on TimeWait, and remove UDP entries when the app channel is closed.
Send post-handshake junk once after the first encapsulated packet instead of spawning a task on every WriteToNetwork under traffic. Run keepalive junk inline on the timer task, and reuse the encrypt and timer output buffers across iterations to cut RSS churn.
Track accepted SOCKS clients in a JoinSet so aborting or dropping the serve task tears down child handlers instead of leaving orphaned relays that keep netstack connections alive across reconnects.
Reset the capsule byte buffer if it would exceed 256 KiB so a malformed or stalled stream cannot grow memory without limit.
Return AbortOnDrop guards from establish_wg and spawn_udp_forwarder so warp-in-warp reconnect drops outer/inner WireGuard tasks and the UDP forwarder pair instead of leaking them across session loops.
This was referenced Jul 28, 2026
Open
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Aether’s RSS climbed during normal use until the machine hung. This PR plugs the main leak and growth paths across netstack, WireGuard obfuscation, SOCKS teardown, MASQUE capsule parsing, and gool reconnect.
Root causes addressed
DNS / SOCKS UDP socket leak (netstack)
Hostname connects open a UDP socket for DNS, then drop the sender without
UdpClose.UdpSender/TcpSenderhad noDropcleanup, andservice_udpdid not remove entries when the app channel died. Each leak held large smoltcp buffers (~64–256 KiB), so browsing many domains grew memory steadily on every protocol.WireGuard obfuscation task storm
jc_after_hsjunk was spawned on every encapsulateWriteToNetwork(every outbound IP packet), not once after handshake. Keepalive junk also spawned a new task on each timer tick. Under traffic this flooded Tokio with short-lived tasks and allocations.Unbounded TCP send staging
App data was drained from the shared
data_inchannel straight into uncapped per-connectionpendingvectors, with no backpressure when the TCP window stalled.Incomplete teardown on reconnect
socks_task.abort()only stopped the accept loop; per-client tasks kept running. In gool,establish_wgand the UDP forwarder were fire-and-forget, so reconnect left orphan tunnels/forwarders behind.CapsuleParser growth
Incomplete/malformed capsule streams could extend the reassembly buffer without a ceiling.
What changed
netstackDrop→ close on TCP/UDP senders & conns; per-conn pending cap + deferral; free sockets onTimeWait; remove UDP when app is gonewireguardsocksJoinSetso server abort tears children downmasquemain(gool)AbortOnDropguards for outer/inner WG tasks and UDP forwardersCommits
fix(netstack): stop socket and pending-buffer memory growthfix(wireguard): prevent obfuscation task and alloc stormsfix(socks): abort client tasks when the proxy server stopsfix(masque): bound CapsuleParser reassembly bufferfix(gool): abort nested tunnels and forwarders on teardownTest plan
cargo build --releasefrom theaether/tree (with siblingquiche/)warp-in-warp): connect, use briefly, let it reconnect; confirm outer/inner tunnels and forwarders are aborted on session end