UDP 端口跳跃,不连续的端口阻断

79 天前
 cnbatch

其他人用 hysteria2 的相关帖子:hysteria2 有什么伪装 TCP 的方案么? 现在跑个几十分钟就随机阻断几分钟 UDP

这个现象其实已经存在很长时间了,去年年中开始,我自己的 kcptube 经常见到这种情况,困扰了我好几个月。

我观察到的阻断是这样的
刚开始的几天、十几天都畅通无阻,但慢慢地,端口临时阻断会越来越多,并且端口阻断并不是一段连续的端口范围,而是分散的不连续端口。
更换成新的端口范围,可以暂时“解决”,然后又重复同样的阻断过程。

后来实在受不了,毕竟一旦跳跃到受阻断的端口等于临时断网。于是趁上个月过年期间,我给自己的 kcptube 加了个小改进:跳跃端口前检查下新端口是否已经阻断,如果是阻断端口就找另一个端口号,找到真正畅通的才跳过去。

有了这个小改进,整个连接就重新畅通了。

不过我也很好奇,这种阻断到底阻隔了多少端口,我猜测范围一定不小。

接着我想起来,我的这个工具有现成的--try命令行参数用于测试连接通断,只不过每次只测 1 个随机端口。
于是,又做了个新改进,改成测试整个端口范围。

测试结果实在“壮观”,3000 个端口,有一百多个是阻断的,剩下都是通畅的。
而这一百多个阻断端口并不是连续的一片,都是分散的。尽管也有极个别的连续端口,但不多,也就三四个而已。


按理来说,其实 hysteria2 是可以做到跳跃前先检查下通断的,发起个探测连接即可。
需要有人给 hysteria2 提个 issue 或者 patch

至少我的 kcptube 就是这样做的。依靠 KCP ,确定性有保障。而 hysteria2 有 QUIC ,理论上来讲其实也是有确定性的。

至于我的另一个工具,UDPHop ,完全就是 raw udp ,我实在想不到有什么好办法能够可靠地做到这种检测。

还好的是,流量很小的情况下不会出现这种阻断。无论多久都还是很顺畅。比如单纯只用来做游戏线路,只用来听电台、Podcast 。


备注:以上情况都特指公网跨大墙,并非指省间、省内、市内的情况。省市内部的连接没那么夸张。

2683 次点击
所在节点    宽带症候群
25 条回复
basncy
77 天前
难道 OP 就认为跨国 udp 不会丢包?hysteria2 就一定发送了冗余包?
hy2 共享一条底层 udp 链路, 一丢包, quic session 也许只有等超时.
kcp 是每条 tcp session 独享一条 udp 连接, 所以即使某条 udp 连接超时或发生重传, 整体感知也不大.
cnbatch
77 天前
@basncy
请先搞清楚这两件事:丢包、阻断
这两个的程度区别很大的

UDP 出现丢包很正常,所以才会有那么多协议和算法给 UDP 做可靠传输,也因此你认为我”认为跨国 udp 不会丢包“完全不成立。如果我认为跨国 UDP 不会丢包,直接用 raw UDP 就行了,根本不可能使用、制作兜底工具。

阻断(某段时间内 100%丢包)就严重得多,连都连不上。

这不是发不发冗余包的问题,而是重传机制也无能为力的问题。划重点,重传机制,发生丢包了就必须重传,阻断的情况下无论怎么重传都没用。能够做的要么继续等,要么跳跃前事先探测,免得选中受阻端口。


然后是谁跟你说的“kcp 是每条 tcp session 独享一条 udp 连接”?
须知道,是否每条 TCP session 独享一条 UDP 连接,那是 kcp 代码使用者说了算。KCP 代码本身并没有限死必须一条 TCP 对应一条 UDP 。
在本例当中,我是多条 TCP session 共享个位数的 UDP 连接,并不是一对一独享。
KCPTube 既可以每条 TCP session 独享一条 UDP 连接,也可以多条 TCP session 共享同一条 UDP 连接,我并未限定必须一对一。
basncy
77 天前
@cnbatch 虽然, 也许,大概, 但只看结果,它用 iptables 给 udp 双倍发包后, 确实管用, 很多 udp app 就不容易抽筋了.
kcp 和 udp 连接, 是用 iftop 肉眼看出来的, 每开一个视频, 就新建了一条 udp 连接(不排除多对一),speedtest 多线程也一样.
cnbatch
76 天前
@basncy
双倍发包有效,那就可以庆幸当地运营商做的并不是很长时间的阻断,而是几秒钟的阻断,或者几秒内的超高丢包。双倍发包在这种情况下才能够起效,使得重传机制能够回到可接受的等待时间。

至于 KCPTube ,像这种立马就新建连接的情况,应该就是没配置 mux_tunnel 参数的缘故。使用了 mux_tunnel 后就会自动建立多条 UDP 连接,共享使用,这样就不会再观察到每接受一个连接就自动建立一个新连接。好处是,可以降低延迟;坏处就是一条路受阻,同路承载的各个 session 就会感知到受阻(这就是去年困扰我情况)


顺便多说一个有关 KCP 的“冗余”发包。
所有的可靠 UDP 拥有重传机制,KCP 也不例外。KCP 特别之处在于,它会在规定时间内收不到确认号的情况下就直接发送重传包,而这个规定时间非常短,短到只有“去程+回程”的总时间,若收不到,那就在(去程+回程)×1.5 的时间后重新来一次。而网络抖动总会造成去程、回程的时间有所浮动,于是就造成第一个重传包经常“过早”就发了出去,第二个重传包也很容易就发了出去。但 KCP 并不会主动地在去程+回程总时间未到的情况下就事先发包

这就是大家说的“冗余包耗费额外流量”的来由,奇怪的是各个 KCP 代码使用者其实是可以观察到这一点的,但没人讲出来,依然还在笼统地用着“浪费 10%-20%”这种模糊的说法,以及“狂发冗余包”这样的印象。其实极端起来 KCP 是可以浪费 25%-40%的(大多数转发工具制作者不至于用到这么极端的配置参数),也可以把浪费降低到 10%以内(抗丢包能力相对没那么好)
basncy
76 天前
quic decouple 了҄应用层 session 与传输层 session, ip:port 就可҄以҄随意套娃找替҃补҃了҄, 铁打的包裹流水的快递员.

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1024299

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX