Skip to content

Commit 8f9bf1c

Browse files
committed
Resolve AAAA before A in address_resolve.
1 parent 886d62c commit 8f9bf1c

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

lib/async/scheduler.rb

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,22 @@ def address_resolve(hostname)
295295
# On some platforms, hostnames may contain a device-specific suffix (e.g. %en0). We need to strip this before resolving.
296296
# See <https://github.com/socketry/async/issues/180> for more details.
297297
hostname = hostname.split("%", 2).first
298-
::Resolv.getaddresses(hostname)
298+
299+
return [hostname] if ::Resolv::AddressRegex =~ hostname
300+
301+
addresses = ::Resolv::Hosts.new.getaddresses(hostname)
302+
303+
if addresses.empty?
304+
dns = ::Resolv::DNS.new
305+
[::Resolv::DNS::Resource::IN::AAAA, ::Resolv::DNS::Resource::IN::A].each do |type|
306+
dns.each_resource(hostname, type) {|resource| addresses << resource.address.to_s}
307+
end
308+
else
309+
ipv6, ipv4 = addresses.partition {|address| address.include?(":")}
310+
addresses = ipv6 + ipv4
311+
end
312+
313+
addresses
299314
end
300315

301316
# Wait for the specified IO to become ready for the specified events.

test/async/scheduler/address.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,18 @@
3434
expect(address.ipv6?).to be == true
3535
end
3636
end
37+
38+
with "#address_resolve" do
39+
it "preserves the platform's address selection ordering" do
40+
hostname = "localhost"
41+
42+
expected = Socket.getaddrinfo(hostname, nil, Socket::AF_UNSPEC, Socket::SOCK_STREAM)
43+
.map {|info| info[3]}
44+
.uniq
45+
46+
actual = Fiber.scheduler.address_resolve(hostname)
47+
48+
expect(actual).to be == expected
49+
end
50+
end
3751
end

0 commit comments

Comments
 (0)