I'm confused about the handshake process of socks5 protocol. According to the page 5 of RFC1928:
In the reply to a CONNECT, BND.PORT contains the port number that the server assigned to connect to the target host, while BND.ADDR contains the associated IP address. The supplied BND.ADDR is often different from the IP address that the client uses to reach the SOCKS server, since such servers are often multi-homed. It is expected that the SOCKS server will use DST.ADDR and DST.PORT, and the client-side source address and port in evaluating the CONNECT request.
It seems BND.ADDR
and BND.PORT
is redundancy and useless. And according to the article How Socks 5 Works:
- IPv4 Address: 00 00 00 00 (I don't know why this is zeroes, but since the proxy will do the DNS resolution and fetch the page, there is no real need for the local host to know the IP address of the destination machine at all, so this is apparently just dummy data.)
- Port number: 00 00 (Apparently also a dummy value)
and the implementation of shadowsocks:
self._write_to_sock((b'\x05\x00\x00\x01' b'\x00\x00\x00\x00\x10\x10'), self._local_sock)
Seems that they all suggest that BND.ADDR
and BND.PORT
in the reply of socks5 server is unimportant.
So, why exists these two redundant fields BND.ADDR
and BND.PORT
?
There are 4 objects involved with as I understand:
SOCKS5 protocol only involved with SOCKS5 client and SOCKS5 server. The real proxy process happens among SOCKS5 client, relay server, and target server.
# SOCKS5 protocol
SOCKS5 client <--> SOCKS5 server
# proxy process
SOCKS5 client <--> relay server <--> target server
BND.ADDR
and BND.PORT
is used to tell the SOCKS5 client where the relay server is. But in most cases, the SOCKS5 server is the relay server (which means taking charge of proxy), so returning BND.ADDR
with all zeros will tell the SOCKS5 client to connect to the SOCKS5 server as the relay server.