enforce timeout on initial socks5 proxy connection #125
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.
This PR fixes a bug which excepted initial SOCKS5 proxy connection attempts from the punctual enforcement of timeouts.
Before this change, invoking
Socks5Stream::connect
(orSocks5Stream::connect_with_password
) could block for much longer than the configured timeout. In practice, this manifested asClient::from_config
apparently failing to respect the timeout specified in theConfig
passed to it. AFAICT this only applied to SOCKS proxy connections.Example
To demonstrate, here is a simple example program which attempts to connect to an unreachable electrum server with a 10 second timeout.
You'd expect the connection attempt to always fail at around 10 seconds, but in fact most attempts take considerably longer.
Cause and Fix
This was happening because the private method
Socks5Stream::connect_raw
only respected thetimeout
parameter for the initial connection to the proxy address.Once that TCP socket is established, the SOCKS5 client code must exchange a couple of messages with the proxy itself: One request/response cycle to authenticate, and then another request/response cycle to configure the forward proxy to the ultimate destination address. The latter of these two request/response cycles could block for long periods of time, in the case where the proxy was responsive but the ultimate destination was unresponsive.
Since no timeout was set on the socket at this stage, the
Socks5Stream
code would wait for an indefinite amount of time for a reply from the proxy, usually only once the proxy itself times out and finally sends a reply.My suggested fix in this PR is to set the read/write timeouts immediately on the socket connecting to the proxy, so that if the proxy doesn't reply in time, we return an error to the caller promptly.