Skip to content

fix: guard snell pooled connection reuse state#2878

Draft
xream wants to merge 1 commit into
MetaCubeX:Alphafrom
xream:codex/fix-snell-server-eof
Draft

fix: guard snell pooled connection reuse state#2878
xream wants to merge 1 commit into
MetaCubeX:Alphafrom
xream:codex/fix-snell-server-eof

Conversation

@xream

@xream xream commented Jun 5, 2026

Copy link
Copy Markdown

已重新结合 snell-server 修复

Summary

当前 mihomo 使用 Snell reuse 连接官方 snell-server 时,在某些提前关闭路径下可能触发服务端报错:

Recevie client EOF before command, abort
Error: signal 11

根本原因是 pooled Snell 连接在 request command header 尚未完整建立、或者 header 已写出但连接还没有成功交给上层使用时,就可能在 Close / CloseWrite 中发送 zero chunk。对 snell-server 来说,这等价于在 command 前收到 client EOF,属于非法的协议时序;同时,如果这种 in-flight 连接被放回 pool,下一次复用还可能读到上一条请求残留的 reply。

本次改动收紧了 Snell pooled connection 的复用状态机:连接只有在 request bytes 完整写成功,并且 DialContext 成功完成 header setup、准备交给上层后,才会标记为 reusable。未进入 reusable 状态的连接在关闭时会直接关闭底层 socket,不发送 zero chunk,也不会放回 pool;正常 reusable 的连接仍保持原来的 half-close 和回池行为。

Testing

  • go test -count=1 ./transport/snell
  • go test -race -count=1 ./transport/snell
  • go test -count=1 ./transport/snell ./adapter/outbound ./listener/snell
  • go test -count=1 ./listener/inbound -run Snell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant