Skip to content

close failed v2ray upgrade connections#4241

Open
winter-loo wants to merge 1 commit into
SagerNet:testingfrom
winter-loo:codex/close-failed-v2ray-upgrade-connections
Open

close failed v2ray upgrade connections#4241
winter-loo wants to merge 1 commit into
SagerNet:testingfrom
winter-loo:codex/close-failed-v2ray-upgrade-connections

Conversation

@winter-loo

@winter-loo winter-loo commented Jun 25, 2026

Copy link
Copy Markdown

Problem

ERROR gateway.platforms.base: [Discord] Fallback send also failed: Cannot connect to host localhost:6780 ssl:default [由于系统缓冲区空间不足或队列已满,不能执行套接字上的操作。]
Cannot connect to host localhost:6780
[WinError 10055] 系统缓冲区空间不足或队列已满

Summary

  • close the underlying TCP connection when a v2ray WebSocket upgrade fails after dialing
  • close the underlying TCP connection when a v2ray HTTP Upgrade handshake fails after dialing
  • close the HTTP Upgrade response body on unexpected upgrade status

Root cause

Both transport clients open a lower-level TCP connection before validating the upgrade handshake. Some failure paths returned without closing that connection, so repeated failed URL tests could retain socket/AFD handles on Windows even though they no longer appeared as active established TCP connections.

Validation

  • Built a patched Windows binary from v1.13.13 and replaced the running sing-box process.
  • Before the fix, repeated URL tests caused sing-box handles, AFD handles, and TCP Bound endpoints to grow into the thousands, eventually producing Windows 10055 / insufficient buffer space errors.
  • After the fix, the process was monitored for many hours with handles staying around 540-565, AFD handles around 50-80, TCP Bound endpoints in single/double digits, and proxy/API ports remaining reachable.

@nekohasekai nekohasekai force-pushed the testing branch 2 times, most recently from 22fe3b6 to b2d51f6 Compare June 29, 2026 03:43
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@winter-loo winter-loo force-pushed the codex/close-failed-v2ray-upgrade-connections branch from 1c87b6c to 535434f Compare June 29, 2026 18:46
@winter-loo winter-loo marked this pull request as ready for review July 2, 2026 09:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 535434f85f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if response.StatusCode != 101 ||
!strings.EqualFold(response.Header.Get("Connection"), "upgrade") ||
!strings.EqualFold(response.Header.Get("Upgrade"), "websocket") {
response.Body.Close()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't drain failed HTTP-upgrade responses

When a server rejects the upgrade with a non-101 response that includes a Content-Length or chunked body and then sends it slowly or not at all, response.Body.Close() can block while consuming the unread body. Because the deferred conn.Close() only runs after this call returns, DialContext can hang indefinitely instead of failing and closing the socket; for this error path it is safer to close the underlying connection first or skip closing the response body since the connection is being discarded.

Useful? React with 👍 / 👎.

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