--- 摄于 2017 年 9 月 藏川线前段
日常接触的 TCP 协议,里面有非常多复杂的状态,由消息驱动,让通信协议在这些状态中转换,进行正常的开启,通信,关闭工作。里面最复杂的算是开启时的三次握手和结束时的四次挥手了,最容易出问题的就是关闭过程中的半关状态,实现错误可能导致 fd leak。实话实说,正常通信中,极其稀少状态下会使用半关状态的通信,这部分的案例可能有且仅利用它进行关闭消息通知,而不是进行其他通信。
问题起始于 issue,社区小伙伴发现 yamux 的子流在对方正常关闭的时候,直接返回了 unexpectedeof
错误,而不是 Ok(0),这样的行为是不符合接口 trait 约定的,正常关闭与异常关闭需要区分开。本以为只是一个状态返回问题,哪知道,后续的修复中引出了另一个问题,即半关状态通信行为异常。
首先从 yamux 协议的子流状态说起,大致有如下几个状态:
相较于 TCP 状态,yamux 的状态已经少很多了,但大致还是相同的,都有开关状态,只是在处理上简化了一部分。这次的问题主要出在对半关状态的处理上。
核心点在于,原来的实现里:
BrokenPipe
。BrokenPipe
这样的行为阻止了半关状态的通信,实际上,半关状态的行为应该是:本地发出 Fin 消息后,等待远端返回 Fin 消息,这段时间内,本地不能发送消息,但可以读任何远端到来的消息。
那么这个 bug 行为的影响是什么呢?其实影响相对较小,它造成的影响是,所有关闭流程都不是正常关闭的,相当于自己想关闭的时候,在对方看来是强制关闭的状态,同时,可能会丢失一部分远端 syn 发送之前的正常消息。
上述影响在我所了解的使用场景中,影响可以忽略不计,不过建议还是尽可能升级到最新版本。
请登录后评论
评论区
加载更多