stable connection
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.

README.md

gosconn

断线重连服务器端代理

用法

client <--> goscon <---> server

client和goscon之间使用断线重连协议,goscon把客户端的请求内容,转发到server。

编译时开启sproto扩展,可以新建连接后自动给后端发送一条sproto消息,宣布客户端的IP地址信息。

协议

新建连接

Client->Server: 传输一个 2 byte size(big-endian) + content 的包, size == len(content)

包的内容如下:

0\n
base64(DHPublicKey)\n
targetServer

DHPublicKey 是一个 8 bytes 值, 经过 DH 算法计算出来的 key。

targetServer用于提示优先连接的后端服务器名字。targetServer应该仅包括[a-zA-Z_0-9]。

DHPrivateKey = dh64.PrivateKey()
DHPublicKey = dh64.PublicKey(DHPrivateKey)

Server->Client: 回应给 Client 一个握手信息:

id\n
base64(DHPublicKey)

这里, id 是一个 10 进制的非 0 数字串. 建议在 [1,2^32) 之间. 因为实现可能利用 uint32_t 保存这个 id .

DHPublicKey 的算法同 client 的算法.

握手完毕后, 双方获得一个公有的 64bit secret, 计算方法为:

secret = dh64.Secret(myDHPrivateKey, otherDHPublicKey)

恢复连接

Client->Server: 传输一个 2 byte size(big-endian) + content 的包, size == len(content)

包的内容如下:

id\n
index\n
recvnumber\n
base64(HMAC_CODE)

这里 id 为新建连接时, 服务器交给 Client 的 id .

index 是一个从 1 开始(第一次恢复为 1), 递增的十进制数字. 服务器会拒绝重复使用过的数字.

recvnumber 是一个 10 进制数字, 表示 (曾经从服务器收到多少字节 mod 2^32).

把以上三行放在一起(保留 \n) content, 以及在新建连接时交换得到的 serect, 计算一个 HMAC_CODE, 算法是:

HMAC_CODE = crypt.hmac64(crypt.hashkey(content), secret)

Server->Client: 回应握手消息:

recvnumber\n
CODE msg

这里, recvnumber 是一个 10 进制数字, 表示 (曾经在这个会话上, 服务器收到过客户端发出的多少字节 mod 2^32). CODE 是一个10进制三位数, 表示连接是否恢复:

  • 200 OK : 表示连接成功
  • 401 Unauthorized : 表示 HMAC 计算错误
  • 403 Index Expired : 表示 Index 已经使用过
  • 404 User Not Found : 表示连接 id 已经无效
  • 406 Not Acceptable : 表示 cache 的数据流不够

当连接恢复后, 服务器应当根据之前记录的发送出去的字节数(不计算每次握手包的字节), 减去客户端通知它收到的字节数, 开始补发未收到的字节。 客户端也做相同的事情。