Use dual-mode sockets for hostname endpoints to support IPv6-only brokers#361
Merged
Conversation
Copilot
AI
changed the title
[WIP] Fix Pulsar client connection issue in IPv6-only environments
Use dual-mode sockets for hostname endpoints to support IPv6-only brokers
Jul 6, 2026
Lanayx
approved these changes
Jul 7, 2026
There was a problem hiding this comment.
Pull request overview
This PR updates ConnectionPool socket creation for hostname-based DnsEndPoints so that AddressFamily.Unspecified uses an IPv6 dual-mode socket, enabling connections to IPv6-only (AAAA-only) brokers while keeping explicit address-family behavior testable via a dedicated helper.
Changes:
- Added internal
SocketFactory.createSockethelper and refactoredConnectionPool.getSocketto use it. - Changed
AddressFamily.Unspecifiedsocket creation toInterNetworkV6withDualMode <- true. - Added unit tests covering socket family selection for unspecified/IPv4/IPv6 endpoints and wired them into the UnitTests project.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Pulsar.Client/Internal/ConnectionPool.fs | Introduces SocketFactory.createSocket and delegates socket creation from getSocket. |
| tests/UnitTests/Internal/ConnectionPoolTests.fs | Adds unit tests for socket family/protocol behavior of SocketFactory. |
| tests/UnitTests/UnitTests.fsproj | Includes the new ConnectionPoolTests.fs in the test project compilation list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addresses review feedback: on hosts where IPv6 is disabled/unsupported, creating an InterNetworkV6 socket can throw and break previously-working IPv4 hostname connections. Only use a dual-mode IPv6 socket when Socket.OSSupportsIPv6 is true; otherwise fall back to an IPv4 socket.
Addresses review feedback: the production code falls back to an IPv4 socket when Socket.OSSupportsIPv6 is false, so the test should branch its assertions accordingly to stay portable on IPv6-disabled hosts/containers (and avoid reading DualMode on an IPv4 socket).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hostname-based broker connections were always created with an IPv4 socket when
DnsEndPoint.AddressFamilywasUnspecified, which breaks AAAA-only environments. This change moves socket selection into a testable helper and uses a dual-mode IPv6 socket for the hostname/default path while preserving explicit-family and Unix behavior.Connection behavior
SocketFactory.createSocketinConnectionPool.fs(internal, unit-testable).Unspecifiedendpoints now createSocket(AddressFamily.InterNetworkV6, Stream, Tcp)withDualMode <- true.InterNetwork,InterNetworkV6, andUnixhandling remains unchanged from prior semantics.ConnectionPool integration
getSocketnow delegates socket creation toSocketFactory.createSocket.Unit coverage
tests/UnitTests/Internal/ConnectionPoolTests.fs.DnsEndPoint(host, port)=> IPv6 + dual-mode + TCP stream socket.tests/UnitTests/UnitTests.fsproj.