Report the IPv4 resolution error after EAI_ADDRFAMILY for IPv6

EAI_ADDRFAMILY left the IPv6 result looking successful, so a later IPv4 resolution error was not recorded and TCPSocket.new raised Socket::ResolutionError with error_code 0. When the IPv6 notification failed, EAI_ADDRFAMILY was recorded instead and hid the IPv4 error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hiroshi SHIBATAandClaude Opus 5 committed 2026-10-01 10:51:19 +09:00
1 parent cfa8947403
commit ffd032a60b
2 files changed
+20 -4
Notes: git 2026-10-01 01:51:53 +00:00

No files matched your search

+5 -4
View File
@@ -1102,9 +1102,9 @@ init_fast_fallback_inetsock_internal(VALUE v)
if (resolved_type[0] == IPV6_HOSTNAME_RESOLVED) {
resolution_store.v6.finished = true;
if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err &&
arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err != EAI_ADDRFAMILY) {
if (!resolution_store.v4.finished || resolution_store.v4.has_error) {
if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err) {
if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err != EAI_ADDRFAMILY &&
(!resolution_store.v4.finished || resolution_store.v4.has_error)) {
last_error.type = RESOLUTION_ERROR;
last_error.ecode = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err;
syscall = "getaddrinfo(3)";
@@ -1176,7 +1176,8 @@ init_fast_fallback_inetsock_internal(VALUE v)
resolution_store.v6.finished = true;
if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err) {
if (!resolution_store.v4.finished || resolution_store.v4.has_error) {
if (arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err != EAI_ADDRFAMILY &&
(!resolution_store.v4.finished || resolution_store.v4.has_error)) {
last_error.type = RESOLUTION_ERROR;
last_error.ecode = arg->getaddrinfo_entries[IPV6_ENTRY_POS]->err;
syscall = "getaddrinfo(3)";
+15
View File
@@ -415,6 +415,21 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
end
end
def test_initialize_v4_hostname_resolution_failure_after_v6_address_family_error
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
omit "EAI_ADDRFAMILY is not defined" unless defined?(Socket::EAI_ADDRFAMILY)
e = assert_raise(Socket::ResolutionError) do
TCPSocket.new(
"localhost",
12345,
fast_fallback: true,
test_mode_settings: { delay: { ipv4: 100 }, error: { ipv6: Socket::EAI_ADDRFAMILY, ipv4: Socket::EAI_FAIL } }
)
end
assert_equal(Socket::EAI_FAIL, e.error_code)
end
def test_initialize_v6_connected_socket_with_v6_address
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/