DanielLavrushin:b4 自己注入的伪造包和分片会占用连接队列窗口

DanielLavrushin 说明,b4 的连接队列限制默认只处理前 19 个包,但 conntrack 也会计入 b4 自己注入的伪造包和分片,因此客户端后续数据包可能比预期更早停止进入 b4。他在 nftables 测试虚拟机中观察到,3 个握手后记录有时只有 2 个被处理;主线和测试中的 #426 均存在该现象。作者将影响描述为较低:这些测试中 ClientHello 出现较早,绕过本身未受影响,但后续仍需策略处理的包可能跳过 b4。把注入包计入限额或排除其 conntrack 计数仍是待评估方案,还需检查 NAT 和 TUN 引擎的限制。

作者原文

The queue rules send only the first packets of each connection to b4: connbytes 0:19 in iptables and ct original packets < 20 in nftables, from queue.tcp_conn_bytes_limit (default 19: config.go#L209, iptables.go#L550, nftables.go#L364). conntrack also counts the fakes and fragments b4 injects into the connection. So the client's own packets stop reaching b4 sooner than the limit suggests, and a strategy that injects many packets uses up more of the window.

Found while testing #426. It happens on main too.

Evidence

A/B runs on a test VM (nftables) with a fragmenting set: in some runs b4 processed 2 of the client's 3 post-handshake records instead of 3. Packet timing showed the third record left about 2 ms after the first two, when b4's own packets had already used up the window. Seen with and without #426.

Impact

Low. The ClientHello comes early, so the bypass itself was not affected in these runs. Later packets that a set would still act on can skip b4: data that a desync strategy decorates, or the later packets that #426 keeps on a domain-only set.

Fix notes

Options to evaluate: account for b4's injected packets in the limit, or keep them out of conntrack's count. Both need checking against NAT and the TUN engine's own packet limit.