[CS基础]SOCKS5协议

SOCKS5是一个常见的代理协议.

/**

* 1. TCP 握手后, 开始认证流程. 第一步客户端向上报告自己支持的认证方式

*  ___________________________

* | VER  | NMETHODS | METHODS |

* | 0x05 | 0x01     | 0x00 |

*

* VER: socks 协议版本, 我们使用 0x05 即 socks5.

* NMETHODS: 表示 METHODS 部分的长度(字节)

* METHODS: 客户端支持的认证方式列表, 每个方法占1字节

*          0x00 不需要认证

*          0x01 GSSAPI

*          0x02 用户名密码认证

*          0x03 – 0x7F 由IANA分配(保留)

*          0x80 – 0xFE 为私人方法保留

*          0xFF 无可接受的方法

*

* 2. 服务器选择一个方式, 响应客户端

*  ________________

* | VER  | METHODS |

* | 0x05 | 0x00    |

*

* VER: socks 协议版本

* METHODS: 服务端选中的方法. 如果返回 0xFF 则表示没有一个认证方法被选中, 客户端需要关闭连接

*

* 客户端收到响应后, 按对应方式提交认证参数

* 2.1-1 用户名密码认证方式; 见 https://en.wikipedia.org/wiki/SOCKS

*  ____________________________________

* | VFA  | NUSER | USER | NPASS | PASS |

* | 0x01 |       | | |     |

*

* VFA:   鉴定过程的版本号, 用户名/密码方式固定为 0x01

* NUSER: 用户名长度(字节)

* USER:  用户名

* NPASS: 密码长度(字节)

* PASS:  密码

*

* 2.1-2 服务器收到请求后返回鉴定结果

*  _____________

* | VFA  | STAT |

* | 0x01 |      |

*

* VFA:  依然返回固定的 0x01

* STAT:

*       0x00 成功

*       0x01 失败

*

* 3. 登录成功后. 连接被保持. 客户端可发送 SOCKS5 请求(以字节为单位)

*  _________________________________________________

* | VER  | CMD | RSV  | ATYP | DST.ADDR | DST.PORT |

* | 0x05 | 0x01 | 0x00 | 0x03 |          | |

*

* VER: socks 协议版本

* CMD: socks 命令码.

*      0x01 CONNECT请求

*      0x02 BIND请求

*      0x03 UDP转发

* RSV: 0x00 保留字

* ATYP: 目的地的地址类型

*      0x01 IPv4地址, DST.ADDR 部分 4 字节长度

*      0x03 域名, DST.ADDR 部分第一个字节为域名长度, DST.ADDR 剩余的内容为域名, 没有 \0 结尾

*      0x04 IPv6地址,16个字节长度

* DST.ADDR: 目的地地址

* DST.PORT: 目的端口(网络字节序)

*

*

* 4. 服务器返回响应

*  _________________________________________________

* | VER  | REP | RSV  | ATYP | DST.ADDR | DST.PORT |

* | 0x05 | 0x00 | 0x00 | 0x03 |          | |

*

* VER: socks 版本, 返回 0x05 即 socks5

* REP: 应答字段

*      0x00 表示成功

*      0x01 普通SOCKS服务器连接失败

*      0x02 现有规则不允许连接

*      0x03 网络不可达

*      0x04 主机不可达

*      0x05 连接被拒

*      0x06 TTL超时

*      0x07 不支持的命令

*      0x08 不支持的地址类型

*      0x09 – 0xFF 未定义

* RSV: 0x00 保留

*

*/