Skip to content

[Windows] Stop silently dropping TCP_NODELAY - #3707

Open
jakepetroules wants to merge 1 commit into
apple:mainfrom
jakepetroules:windows-tcp-nodelay
Open

jakepetroules wants to merge 1 commit into
apple:mainfrom
jakepetroules:windows-tcp-nodelay

Conversation

@jakepetroules

@jakepetroules jakepetroules commented Aug 15, 2026

Copy link
Copy Markdown
Member

BaseSocket.setOption did not set TCP_NODELAY on Windows, because it determines the socket family using localAddress().protocol, which fails for unbound Winsock sockets because getsockname requires the socket to be bound.

Since NIO applies options before bind/connect, the option was silently dropped.

This PR changes it to get the socket family directly from SO_PROTOCOL_INFOW / WSAPROTOCOL_INFOW so that TCP_NODELAY is correctly applied on Windows. (Other platforms continue using the local address, so behavior is unchanged)

ChannelTests.testTCP_NODELAYisOnByDefaultForInetSockets and testTCP_NODELAYisOnByDefaultForInet6Sockets are now fixed.

`BaseSocket.setOption` refuses to set `TCP_NODELAY` on sockets whose protocol
family is not IP, because doing so fails on UNIX domain sockets. It determined
the family from `try? self.localAddress().protocol`, treating a failure to
answer as "not an IP socket" and returning without setting anything.

On Windows that discards the option every time. Winsock fails `getsockname` for
a socket that has not been bound yet, where POSIX reports the wildcard address,
and channel options are applied before the socket is bound or connected. Both
`ClientBootstrap` and `ServerBootstrap` enable `TCP_NODELAY` by default, so in
practice Nagle's algorithm stayed on for every NIO TCP channel on Windows.

Ask the socket for its address family instead of deriving it from an address it
may not have yet: Winsock reports it in the `WSAPROTOCOL_INFOW` returned by
`SO_PROTOCOL_INFOW`. Other platforms keep using the local address exactly as
before.

This fixes `ChannelTests.testTCP_NODELAYisOnByDefaultForInetSockets` and
`testTCP_NODELAYisOnByDefaultForInet6Sockets`, which observed the option reading
back as 0 on Windows.
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