Skip to content

Report a shut-down socket on IOCP instead of panicking - #260

Open
endel wants to merge 1 commit into
mitchellh:mainfrom
endel:iocp-shutdown-errors
Open

endel wants to merge 1 commit into
mitchellh:mainfrom
endel:iocp-shutdown-errors

Conversation

@endel

@endel endel commented Oct 30, 2026

Copy link
Copy Markdown

On the IOCP backend, recv and send on a socket that has been shut down fail with WSAESHUTDOWN, which neither maps. It falls through to unexpectedWSAError, which casts the code to Win32Error. WSA codes aren't in that enum, so a safe build panics with invalid enum value. Any other unmapped WSA code takes the same path.

We hit this in quic-zig, when a write raced a connection being closed. POSIX reports that race as EPIPE, and a read after shutdown as EOF.

Fix

  • recv reports WSAESHUTDOWN as error.EOF, and send as error.ConnectionResetByPeer, both when the call fails at once and when it completes with that status.
  • unexpectedWSAError logs the code and returns error.Unexpected without the cast.

Test

"iocp: recv and send on a socket that was shut down" shuts a connected socket down, queues a recv and a send, and checks both results. Without the fix it panics.

  • Windows (aarch64, under Wine 10): the test passes, and fails with the fix reverted. Not run on real Windows. The process tests can't run in that container, as it lacks their helper binary.
  • macOS (aarch64, kqueue): zig build test, 59 passed
  • Linux (aarch64, epoll and io_uring): 143 passed, 3 skipped
  • zig build -Demit-example -Demit-bench, and zig build for every target in the CI matrix

CI on main fails until #250 moves the workflow to Zig 0.17, so this PR's checks will fail the same way until then.

🤖 Generated with Claude Code

recv and send on a socket that had been shut down fell through to
unexpectedWSAError, which cast the code to Win32Error. WSA codes aren't in
that enum, so safe builds panicked. POSIX reports the same race as EOF and
EPIPE, and any other unmapped WSA code took the same path.

Assisted-by: Claude Opus 5.5
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