AberSheeran
Aber Sheeran
I know nothing except the fact of my ignorance.

使用WebSocket进行网络穿透(续)

起笔自
所属文集: Hack
共计 960 个字符
落笔于

继上一篇使用WebSocket进行网络穿透,实际使用中,UDP转发并不常用,并且使用Websocket转发UDP包也会导致较高的延迟(我当时之所以有这个需求是因为学校网络限制)。

所以为了更简单的实现,更短的延迟,在此重新设计一种新的基于Websocket的协议。

代码实现在websocks

自定义协议

由于只考虑支持TCP的数据转发,所以参考HTTP Connect

协商

当客户端试图连接example.com:443端口时,在第一次HTTP请求中,附带Headers信息——TARGET: example.com\r\nPORT: 443

按照Proxy-Authorization,发送身份验证信息。

当服务器已经成功连接,客户端可开始发送数据包时,服务器再响应101状态,否则应返回其他状态。

转发

所有Websocket数据均走二进制帧,仅转发,不做修改。

复用版协议

当服务器与客户端之间网络通畅时,使用上述实现会很简单,并且速度很快。但如果服务器与客户端之间网络较差时,则需要复用websocket连接。

协商

客户端首先需要在HTTP握手阶段进行身份验证,按照Proxy-Authorization,发送身份验证信息。

服务端响应应按照HTTP标准,如身份验证失败则返回401,身份验证成功但被限制访问则返回403,成功则返回201。

转发

为了单条websocket连接的复用,转发过程会稍显繁琐。

一次完整的请求周期如下:

请求连接

websocket使用文本帧传递JSON格式的字符串,请求连接的服务器HOST与PORT。

{
    "HOST": "example.com",
    "PORT": 443
}

服务器成功或失败之后,返回一个状态

{
    "ALLOW": true/false
}

转发

此过程较为简单,使用二进制帧转发数据即可。

结束连接

客户端或服务端主动断开连接,需使用文本帧发送或者响应

{
    "STATUS": "CLOSED"
}

当结束连接之后,客户端可重新使用此条websocket连接进行其他请求。

如果你觉得本文值得,不妨赏杯茶
使用WebSocket进行网络穿透
没有下一篇