为什么socks5协议的服务器回复可以使用虚拟值?

log*_*ead 5 networking protocols network-protocols socks

我对socks5协议的握手过程感到困惑。根据RFC1928的第 5 页:

在对 CONNECT 的回复中,BND.PORT 包含服务器分配用于连接目标主机的端口号,而 BND.ADDR 包含关联的 IP 地址。提供的 BND.ADDR 通常与客户端用于访问 SOCKS 服务器的 IP 地址不同,因为此类服务器通常是多宿主的。预计 SOCKS 服务器将使用 DST.ADDR 和 DST.PORT,以及客户端源地址和端口来评估 CONNECT 请求。

它似乎BND.ADDR并且BND.PORT是冗余和无用的。根据文章How Socks 5 Works

  • IPv4 地址:00 00 00 00(我不知道为什么这是零,但是由于代理会进行 DNS 解析并获取页面,因此本地主机实际上不需要知道目标机器的 IP 地址根本没有,所以这显然只是虚拟数据。)
  • 端口号:00 00(显然也是一个虚拟值)

shadowsocks 的实现

        self._write_to_sock((b'\x05\x00\x00\x01'
                             b'\x00\x00\x00\x00\x10\x10'),
                            self._local_sock)
Run Code Online (Sandbox Code Playgroud)

似乎他们都建议BND.ADDRBND.PORT在socks5服务器的回复中无关紧要。

那么,为什么存在这两个冗余字段BND.ADDRBND.PORT

log*_*ead 0

据我了解,涉及4个对象:

  • SOCKS5客户端
  • SOCKS5服务器
  • 中继服务器
  • 目标服务器

SOCKS5协议只涉及SOCKS5客户端和SOCKS5服务器。真正的代理过程发生在SOCKS5客户端、中继服务器和目标服务器之间。

# SOCKS5 protocol 
SOCKS5 client <--> SOCKS5 server
# proxy process
SOCKS5 client <--> relay server <--> target server
Run Code Online (Sandbox Code Playgroud)

BND.ADDR用于BND.PORT告诉 SOCKS5 客户端中继服务器在哪里。但大多数情况下,SOCKS5 服务器是中继服务器(意味着负责代理),因此返回BND.ADDR全零将告诉 SOCKS5 客户端连接到作为中继服务器的 SOCKS5 服务器。