Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion lib/async/scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,26 @@ def address_resolve(hostname)
# On some platforms, hostnames may contain a device-specific suffix (e.g. %en0). We need to strip this before resolving.
# See <https://github.com/socketry/async/issues/180> for more details.
hostname = hostname.split("%", 2).first
::Resolv.getaddresses(hostname)

return [hostname] if ::Resolv::AddressRegex =~ hostname

::Resolv::DefaultResolver.instance_variable_get(:@resolvers).each do |resolver|
addresses = []

if resolver.is_a?(::Resolv::DNS)
[::Resolv::DNS::Resource::IN::AAAA, ::Resolv::DNS::Resource::IN::A].each do |type|
resolver.each_resource(hostname, type) {|resource| addresses << resource.address.to_s}
end
else
resolver.each_address(hostname) {|address| addresses << address.to_s}
ipv6, ipv4 = addresses.partition {|address| address.include?(":")}
addresses = ipv6 + ipv4
end

return addresses unless addresses.empty?
end

return []
end

# Wait for the specified IO to become ready for the specified events.
Expand Down
13 changes: 13 additions & 0 deletions test/async/scheduler/address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,17 @@
expect(address.ipv6?).to be == true
end
end

with "#address_resolve" do
it "orders IPv6 addresses before IPv4 addresses" do
addresses = Fiber.scheduler.address_resolve("localhost")

ipv4_index = addresses.index {|address| !address.include?(":")}
ipv6_index = addresses.index {|address| address.include?(":")}

if ipv4_index && ipv6_index
expect(ipv6_index).to be < ipv4_index
end
end
end
end
Loading