Bug #21088
closedTCPSocket.new raises Socket::ResolutionError instead of Errno::ECONNREFUSED for hosts defined in /etc/hosts
Description
TCPSocket.new
raises Socket::ResolutionError
when the connection is refused for hosts defined in /etc/hosts. It should raise Errno::ECONNREFUSED
.
[6] pry(main)> TCPSocket.new("test_system", 22)
=> #<TCPSocket:fd 8, AF_INET, 10.1.1.1, 51690>
[7] pry(main)> TCPSocket.new("test_system", 12345)
Socket::ResolutionError: getaddrinfo(3): No address associated with hostname (Socket::ResolutionError)
[14] pry(main)> ::Socket.getaddrinfo("test_system", nil)
=> [["AF_INET", 0, "10.1.1.204", "10.1.1.204", 2 (0x2), 1 (0x1), 6 (0x6)],
["AF_INET", 0, "10.1.1.204", "10.1.1.204", 2 (0x2), 2 (0x2), 17 (0x11)],
["AF_INET", 0, "10.1.1.204", "10.1.1.204", 2 (0x2), 3 (0x3), 0]]
I've confirmed with tcpdump that the local system is sending the SYN to the remote host, and it is getting RST back.
This was not a problem in 3.3.0.
This does not happen when using localhost
This does not happen for hosts resolvable via DNS.
This is not the same as #20172 as this is a consistent failure and the fix for that was merged almost a year ago.
Updated by alanwu (Alan Wu) 11 days ago
This might be related to HEv2(#20108). Try testing with Socket.tcp_fast_fallback = false
.
Updated by dmlary (David Lary) 8 days ago ยท Edited
Setting Socket.tcp_fast_fallback = false
does fix the issue. I get Errno::ECONNREFUSED
in that case.
[1] pry(main)> require "socket"
=> true
[2] pry(main)> TCPSocket.new("test_system", 12345)
Socket::ResolutionError: getaddrinfo(3): No address associated with hostname (Socket::ResolutionError)
from (pry):2:in 'TCPSocket#initialize'
[3] pry(main)> Socket.tcp_fast_fallback = false
=> false
[4] pry(main)> TCPSocket.new("test_system", 12345)
Errno::ECONNREFUSED: Connection refused - connect(2) for "test_system" port 12345 (Errno::ECONNREFUSED)
from (pry):4:in 'TCPSocket#initialize'
Updated by midnight (Sarun R) 7 days ago
This feature was merged a few months ago (#20782) by @shioimm (Misaki Shioi),
with a non-trivial state machine implementation.
I'm pretty sure this is a missing edge case.
Updated by shioimm (Misaki Shioi) 7 days ago
Thank you for reporting.
I am aware of this issue and am working on resolving it.
Updated by hsbt (Hiroshi SHIBATA) 6 days ago
- Status changed from Open to Assigned
- Assignee set to shioimm (Misaki Shioi)
Updated by Anonymous 1 day ago
- Status changed from Assigned to Closed
Applied in changeset git|1683dadb19876f0a64589bdbbcf6fff8143f78ff.
Do not save ResolutionError if resolution succeeds for any address family (#12678)
- Do not save ResolutionError if resolution succeeds for any address family
Socket with Happy Eyeballs Version 2 performs connection attempts and name resolution in parallel.
In the existing implementation, if a connection attempt failed for one address family while name resolution was still in progress for the other, and that name resolution later failed, the method would terminate with a name resolution error.
This behavior was intended to ensure that the final error reflected the most recent failure, potentially overriding an earlier error.
However, Bug #21088 made me realize that terminating with a name resolution error is unnatural when name resolution succeeded for at least one address family.
This PR modifies the behavior so that if name resolution succeeds for one address family, any name resolution error from the other is not saved.
This PR includes the following changes:
-
Do not display select(2) as the system call that caused the raised error, as it is for internal processing
-
Fix bug: Get errno with Socket::SO_ERROR in Windows environment with a workaround for tests not passing
Updated by shioimm (Misaki Shioi) 1 day ago
- Status changed from Closed to Assigned
Updated by shioimm (Misaki Shioi) 1 day ago
- Status changed from Assigned to Closed
@dmlary
Unfortunately, I was unable to reproduce the issue you reported. However, I believe I have fixed the code that was likely causing the problem in this change.
https://github.com/ruby/ruby/pull/12678
It should be resolved in the next Ruby version.
If the issue still occurs, please let me know. Thank you very much for your report.
Updated by nagachika (Tomoyuki Chikanaga) 1 day ago
- Backport changed from 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: DONTNEED, 3.3: DONTNEED, 3.4: REQUIRED
I think the changeset is worth to backport to ruby_3_4.