Skip to content

Bind the random UDP source port exclusively on Windows - #158

Merged
mame merged 1 commit into
masterfrom
windows-exclusive-random-port
Oct 14, 2026
Merged

mame merged 1 commit into
masterfrom
windows-exclusive-random-port

Conversation

@mame

@mame mame commented Oct 14, 2026

Copy link
Copy Markdown
Member

TestResolvDNS#test_query_ipv4_address occasionally fails on Windows CI:

  1) Failure:
  TestResolvDNS#test_query_ipv4_address [C:/a/ruby/ruby/src/test/resolv/test_dns.rb:236]:
  <1> expected but was
  <0>.

On Windows, Resolv picks a random source port by itself and binds 0.0.0.0 to it. Windows allows this even when another socket has already bound 127.0.0.1 to the same port, and then delivers datagrams sent to 127.0.0.1 to that other socket. When the chosen port collides like this, the reply from the nameserver on 127.0.0.1 never reaches the resolver, which waits out every timeout and returns no resources.

This commit sets SO_EXCLUSIVEADDRUSE before binding so that bind fails on a port another socket already uses, and retries with another port. Ruby does not define Socket::SO_EXCLUSIVEADDRUSE, so its value, ~SO_REUSEADDR, is used directly.

TestResolvDNS#test_query_ipv4_address occasionally fails on Windows CI:

  1) Failure:
  TestResolvDNS#test_query_ipv4_address [C:/a/ruby/ruby/src/test/resolv/test_dns.rb:236]:
  <1> expected but was
  <0>.

On Windows, Resolv picks a random source port by itself and binds
0.0.0.0 to it.  Windows allows this even when another socket has
already bound 127.0.0.1 to the same port, and then delivers datagrams
sent to 127.0.0.1 to that other socket.  When the chosen port collides
like this, the reply from the nameserver on 127.0.0.1 never reaches the
resolver, which waits out every timeout and returns no resources.

This commit sets SO_EXCLUSIVEADDRUSE before binding so that bind fails
on a port another socket already uses, and retries with another port.
Ruby does not define Socket::SO_EXCLUSIVEADDRUSE, so its value,
~SO_REUSEADDR, is used directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mame
mame merged commit 7c850d9 into master Oct 14, 2026
74 checks passed
@mame
mame deleted the windows-exclusive-random-port branch October 14, 2026 05:45
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