Incorrect IP address resolving when using socks5 proxy
Description
When using a proxy, you can select the socks5:// or socks5h:// protocol.
For example, we want to make a request via proxy to the domain example.org. Let's say this domain has a public IP address 10.20.30.40. But we can change the IP of this domain by editing the hosts file or in the local DNS resolver, for example, we set the IP address for this domain to 192.168.1.100 (It would be great if this custom IP address could be specified as an option when creating a CycleTLS request).
What is the expected behavior when using the socks5 or socks5h protocol?
socks5: The domain IP address must be resolved locally on the client, and the proxy must create a connection to this previously resolved IP address. socks5h: The IP address of the domain is not resolved locally, and the proxy itself must resolve the IP address of the domain.
That is, in our example it turns out that if we use the socks5:// protocol, the connection should be created to the IP address 192.168.1.100 (since we specified it in the local hosts file), and for the socks5h:// protocol, the proxy itself will resolve the IP address to the public 10.20.30.40.
How the socks5 protocol works technically (you can see it in Wireshark):
| VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
|---|---|---|---|---|---|
| 1 | 1 | 0x00 | 1 | Variable | 2 |
VER — 0x05
CMD — command:
-
0x01— CONNECT (TCP) -
0x02— BIND (rare) -
0x03— UDP ASSOCIATE
RSV — reserved, always 0x00
ATYP — address type:
-
0x01— IPv4 (4 bytes) -
0x03— Domain name (1-byte length + name) -
0x04— IPv6 (16 bytes)
DST.ADDR — destination address DST.PORT — destination port (big-endian)
Example (CONNECT to 10.20.30.40:443):
05 01 00 01 0A 14 1E 28 01 BB
05 — version
01 — CONNECT
00 — RSV
01 — IPv4
0A 14 1E 28 — IP 10.20.30.40
01 BB — port 433 (0x01BB)
How it works now in CycleTLS:
Regardless of which protocol we specified - socks5 or socks5h - when creating a connection to a socks proxy, it specifies the destination domain as the destination address, not its IP address. That is, even when choosing the socks5:// protocol, we make the following connection:
Example (CONNECT to example.org:443):
05 01 00 03 0B 65 78 61 6D 70 6C 65 2E 6F 72 67 01 BB
05 — version
01 — CONNECT
00 — RSV
03 — domain name
0B — length of example.org (11)
65 78 61 6D 70 6C 65 2E 6F 72 67 — domain example.org
01 BB — port 433 (0x01BB)
What's the problem?
If we want to use some custom IP address for the domain (for example 192.168.1.100), then for now this is not possible even when specifying the socks5:// protocol, since the destination domain is still specified to the proxy instead of its locally resolved IP address.
Issue Type
Bug
Operating System
Windows 10
Node Version
Node 22.x
Golang Version
None
Relevant Log Output