diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index f36d6a29a97..426c423f52d 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -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)"; diff --git a/test/socket/test_tcp.rb b/test/socket/test_tcp.rb index 0c1e3cc4e39..e17f1d06dd2 100644 --- a/test/socket/test_tcp.rb +++ b/test/socket/test_tcp.rb @@ -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/