feat(client): add proxy::SocksV4 and proxy::SocksV5 connectors - #187
Merged
Conversation
JPDye
marked this pull request as draft
April 25, 2025 14:18
Member
|
I think this looks pretty great! What's holding it back as a draft? |
Contributor
Author
|
Needed to test optimistic sending to see if it was worth including. 5/8 of the server implementations I tested worked so I feel like it's a worthwhile addition even if it's not in the RFC. Will fix the failing check and some of the dirty code in a little, but I'm mostly happy with everything now |
JPDye
marked this pull request as ready for review
May 8, 2025 12:41
seanmonstar
approved these changes
May 19, 2025
seanmonstar
left a comment
Member
There was a problem hiding this comment.
This looks phenomenal, thank you!
Contributor
Author
|
Thanks for merging this. Is the goal still to refactor Reqwest to use these connectors? I'm happy to take that on to pad my stats so to speak ;) |
Member
|
Yes it is, just filed a new issue: seanmonstar/reqwest#2683 I've got the HTTP tunnel one nearly done, but I haven't started on the SOCKS, if you want to try that :) |
seanmonstar
pushed a commit
that referenced
this pull request
Aug 2, 2026
`Request::write_to_buf` emitted two NULL bytes after DSTIP, labelled
`USERID` and `NULL`. Per SOCKS4 ("SOCKS: A protocol for TCP proxy across
firewalls", Ying-Da Lee, https://www.openssh.com/txt/socks4.protocol),
a CONNECT request is
VN(1) CD(1) DSTPORT(2) DSTIP(4) USERID(variable) NULL(1)
where USERID is a variable-length field terminated by a single NULL.
This connector never sends a user ID, so USERID is zero bytes long and
only its terminator belongs on the wire: 9 bytes, not 10.
The extra byte breaks SOCKS4a ("SOCKS 4A: A Simple Extension to SOCKS 4
Protocol", https://www.openssh.com/txt/socks4a.protocol), which appends
a NULL-terminated hostname after the USERID terminator. A server reads
USERID up to the first NULL (correctly empty), then reads the hostname
up to the next NULL -- the stray byte -- so the destination arrives as
an empty string. The request fails, and the real hostname plus its
terminator remain in the server's receive buffer, to be relayed into the
tunnel as the first bytes of application data.
Plain SOCKS4 requests still parse, since the destination is carried in
DSTIP, but the trailing byte is likewise left over and reaches the
target as a stray leading NULL of the tunneled stream.
The bug dates back to the connectors' introduction in #187, and the
domain path had no test coverage, so a SOCKS4a test is added alongside.
Two stale comments on the touched lines are corrected as well:
`put_u16(*port)` was labelled `IP`, and the layout diagram read
"only do IP is 0.0.0.X".
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.
cc hyperium/hyper#3851, hyperium/hyper#3877 #173
Adds
SocksV4andSocksV5connectors with simple configuration for local and remote DNS. Supports SOCKSv5 user/pass authentication and allows optimistic message sending (not in RFC but supported by most servers) to reduce number of round-trips in SOCKSv5 handshake.TODO: