Close a UDP proxy backend that becomes active after eviction#2019
Open
devops-thiago wants to merge 1 commit into
Open
Close a UDP proxy backend that becomes active after eviction#2019devops-thiago wants to merge 1 commit into
devops-thiago wants to merge 1 commit into
Conversation
UDPProxyBackend.close() returned early when the backend channel had not finished binding, leaving the socket open. The frontend calls close() on whichever backend the LRU cache evicts, so a backend evicted inside the bind window was never closed: channelActive then adopted the channel, and because the ProxyContext had already been dropped from the cache, no reference remained that could close it. The socket stayed open for the lifetime of the process. Record the close request in the backend state and have channelActive honour it, closing the channel instead of adopting it. Both paths run on the event loop the backend is bootstrapped on, so the flag needs no additional synchronisation. UDPProxyBackend becomes internal so the regression test can drive the eviction ordering directly. Fixes apple#2015
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.
Type of Change
Motivation and Context
Fixes #2015.
UDPProxyFrontendkeeps at most 256 backends in an LRU cache and closes whichever one is evicted.UDPProxyBackend.close()returned early when the backend channel had not finished binding:state.channelis nil from construction untilchannelActiveruns, which happens afterbindcompletes. A backend evicted inside that window is never closed.channelActivethen adopts the channel, and because theProxyContexthas already been dropped from the cache, no reference remains that could close it. The socket stays open for the lifetime of the process.The existing warning shows the case was anticipated, but the early return leaves the socket open rather than deferring the close.
This change records the close request in the backend state and has
channelActivehonour it, closing the channel instead of adopting it and discarding any queued payloads. Both paths run on the event loop the backend is bootstrapped on, sinceDatagramBootstrap(group: context.eventLoop)andNIOLoopBound(proxy, eventLoop: context.eventLoop)bind them to that loop, so the flag needs no further synchronisation.UDPProxyBackendchanges from file-private to internal so the test can drive the ordering directly. Nothing outside the module references it.Testing
testBackendClosedBeforeChannelActiveClosesTheChannelcallsclose()before the channel becomes active, then activates it through anEmbeddedChanneland asserts the channel is no longer active. The test fails against the current code and passes with this change.testUDPForwarderandtestLRUCachecontinue to pass.