Socks5 udp代理

socks5在socks4上多了对udp代理的支持,可以说是“全能代理”了。udp代理较对比tcp代理,流程上要复杂一些,下面从最开始流程讲起

握手阶段

客户端建立和代理服的tcp连接A,并发送第一帧数据:

                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+

代理服务器收到后,会鉴别VER,回应

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+

流程和前一篇socks5协议简介完全相同

准备阶段

客户端发送第二帧数据:

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

CMD:命令,tcp代理0x01,udp代理0x03
RSV:保留字段
ATYP:地址类型 0x01:ipv4,0x03:域名,0x04:ipv6
DST.ADDR:本地使用udp的地址
DST.PORT:本地使用udp的端口
比如数据 :0x05|0x03|0x00|0x01|0x00000000|0x0000
代表需要代理的是udp连接,此时DST.ADDR和DST.PORT代表客户端UDP准备发送的地址和端口,用于服务器权限控制(只给DST.ADDR:DST.PORT发出来的udp包代理),当然可以为空即全是0

代理服收到后,回复

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

REP:状态位,0x00代表连接DST.ADDR成功了
RSV:保留字段
ATYP:地址类型 0x01:ipv4,0x03:域名,0x04:ipv6
BND.ADDR:udp代理地址
BND.PORT:udp代理端口
比如,返回0x05|0x00|0x00|0x01|0xc0a8c76a|0xcdf0,通知客户端UDP代理地址是192.168.199.106:52720,有什么udp包直接向这个地址发

代理阶段

客户端知道udp代理地址后,将所在发送的数据DATA需要包裹成下面的帧发送给192.168.199.106:52720

      +----+------+------+----------+----------+----------+
      |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
      +----+------+------+----------+----------+----------+
      | 2  |  1   |  1   | Variable |    2     | Variable |
      +----+------+------+----------+----------+----------+

RSV:保留位
FRAG:分片位
ATYP:地址类型 0x01:ipv4,0x03:域名,0x04:ipv6
DST.PORT:目标地址
DST.PORT:目标端口
DATA:要发送的数据
其中FRAG分片位,用于控制大帧分成多帧用,一般情况下为0x00(不分帧)

UDP代理收到后,将DATA分离出来,发送给DST.ADDR:DST.PORT,同时,收到目标报的UDP的数据,也包裹成上面帧结构发给客户端

总结

可以发现,udp代理的建立是在与代理服先建立tcp连接,tcp连接上先“握手”和“准备代理”,客户端知道udp代理地址后,就不用这个tcp连接了,直接udp代理了,理论上这个tcp连接无用了,但socks5协议指出,这个tcp连接要保持长连接,如果断开,则相应的udp代理也要结束,真正实现上,我看过的许多socks5代理源码没实现的这么细,我的golang实现socks5上,也只是保持这个tcp长连接,有时间再完善这个细节点
想详细了解的可以参照我的golang实现https://github.com/0990/socks5

引用

RFC1928-SOCKS Protocol Version 5

你可能感兴趣的:(Socks5 udp代理)