Skip to content
Hoping White edited this page Aug 24, 2020 · 11 revisions

关于gracefully shutdown问题

trojan-rs在写完之后,使用中经常感觉会有一些比较奇怪的问题出现,当时没仔细想,今天在用iperf3测试的时候终于想明白问题出在哪里了。我在服务器端直接运行iperf3的时候会提示iperf3: error - the server is busy running a test. try again later,但是在路由器上运行时,却会提示control socket has closed unexpectedly。用strace追踪了一下发现,前一个提示会返回\377之后再close,而后一个直接读了个空字符串,也就是说直接断开连接了。那这个时候结论已经很明确了:当目标地址断开连接的时候,如果还有数据没从代理链路回来,那代理链路应该等到结果回到客户端之后再断开连接;同理,对于代理端也是一样。简而言之,如果数据已经收到了,那么就要发出去之后再跟对端断开连接,这样才表现的像个真正的透明代理。 那么写完之后怎么测试呢?其实也很简单,随便找一个比较大的文件,如果能一次下载完成,说明连接完美断开了,如果不能,那说明有问题。新版本修改之前,测试下载文件总会在最后几十k的时候断开连接;新版本修改之后,这个问题就再也没出现了。

TODO

  1. BytesMut使用上有个问题,现在是split了之后又调用了extend,但是这个时候新的BytesMut还没销毁,所以旧的内存没有被复用,这会导致buffer比实际要的大(问题不大)
  2. 用iperf3进行udp reserve test发现丢包比直接在服务器上测试要严重的多,这个需要确认一下原因(关于这一点,目前的猜测是iperf3在reverse状态下的机制有问题,它同时开了一个tcp和udp,tcp用来传控制信令,udp用于传数据,然后它在信令数据到达之后,计算有多少udp包到达,这一点在经过proxy之后就不准了,因为他们实际上都是通过tcp中转的,由于信令数据小,所以肯定会先到达,于是之后到达的udp数据就被iperf3认为是loss的数据)
  3. 如何控制缓存大小,如果缓存太大的话,不应该再读取服务器push过来的数据,否则proxy可能被压爆。对于https部分,rustl的Session提供了set_buffer_limit方法来限制缓存大小,但是目前来看,如果要支持缓存需要对整体结构有一个比较大的调整才行,后面有时间了再搞吧(搞定)
  4. QUIC协议目前来看还是有问题,但是目前没发现跟proxy有啥直接的关联,udp的数据包都已经到从服务器到了代理,但是再到具体设备可能出了问题,需要在设备上用iperf3再做测试对比一下结果。使用quinn去测试了一下,QUIC协议本身应该是没问题的,但是udp的传输速度比tcp要慢很多,主要是因为服务器端udp丢包率就比tcp要高一些,所以保险起见还是把QUIC禁掉比较好
Clone this wiki locally