Issue #16653 has been updated by jeremyevans0 (Jeremy Evans).

Status changed from Open to Rejected

I've looked into this more.  The underlying cause is that Resolv expects nameservers to be specified as IP addresses, not as domain names.  When using multiple nameservers, Resolv tries to match the IP address of the nameserver responding to one of the nameservers given as input, and if you give a domain name as input, there will be no match.

It makes sense for Resolv to only handle IP addresses as nameservers, as if you are providing a domain name to use as a nameserver, where would you look up the IP address of that nameserver to know where to connect?  You can't use the resolver you are setting up to resolve that.  This is the same reason that no operating system allows you to use a domain name as a DNS server.

I was able to come up with a workaround that uses the system resolver:

```diff
diff --git a/lib/resolv.rb b/lib/resolv.rb
index e7b45e785a..d529550bdb 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -1027,12 +1027,33 @@ def lazy_initialize
             if config_hash.include? :nameserver_port
               @nameserver_port = config_hash[:nameserver_port].map {|ns, port| [ns, (port || Port)] }
             end
+
             @search = config_hash[:search] if config_hash.include? :search
             @ndots = config_hash[:ndots] if config_hash.include? :ndots

-            if @nameserver_port.empty?
+            case @nameserver_port.length
+            when 0
               @nameserver_port << ['0.0.0.0', Port]
+            when 1
+              # nothing
+            else
+              @nameserver_port = @nameserver_port.map do |host, port|
+                dns_name = true
+                case host
+                when /\A[0-9.]+\z/
+                  dns_name = false
+                when  /\A[a-fA-F0-9:]+\z/
+                  dns_name = host.index(':')
+                end
+
+                if dns_name
+                  host = Addrinfo.getaddrinfo(host, nil)[0]&.ip_address
+                end
+
+                [host, port]
+              end
             end
+
             if @search
               @search = @search.map {|arg| Label.split(arg) }
             else
```

However, I'm fairly sure this is a misuse of the resolv library, and therefore I'm going to close this.  The fact that things appear to work with a single domain name is just an implementation detail, not by design (single nameserver uses Requester::ConnectedUDP instead of Requester::UnconnectedUDP).

----------------------------------------
Bug #16653: Weird behaviour of Resolv module
https://bugs.ruby-lang.org/issues/16653#change-85844

* Author: evserykh (Evgeniy Serykh)
* Status: Rejected
* Priority: Normal
* ruby -v: ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
I have to deal with DNS request. Here is some examples.

When I ask A records for example.com at some public DNS servers I get the results:
`> Resolv::DNS.new(nameserver: ['8.8.8.8', '1.1.1.1']).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x00005631491d5918 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=11607>]`

When I ask A records at DNS servers responsible for given domain there is no answer:
`> Resolv::DNS.new(nameserver: ['a.iana-servers.net', 'b.iana-servers.net']).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []`



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>