Skip Menu |

This queue is for tickets about the Net-DNS CPAN distribution.

Report information
The Basics
Id: 127012
Status: resolved
Priority: 0/
Queue: Net-DNS

People
Owner: Nobody in particular
Requestors: spam [...] nowaker.net
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.11
  • 1.13
  • 1.17
Fixed in: 1.18



Subject: DNS resolution broken when options ndots used in /etc/resolv.conf (regression as of 1.11+)
Hello! Net::DNS 1.11+ incorrectly handles /etc/resolv.conf's `options ndots:` option. Net::DNS 1.10 is the last version without a bug. Net::DNS 1.11+ has the same bug as Ruby used to have but was fixed in Ruby 2.1 and backported to 2.0: https://bugs.ruby-lang.org/issues/10412. If search within domains listed in /etc/resolv.conf fails, the check should fallback to a bare domain. This is how the operating system works (getent hosts / getaddrinfo), how other programming languages work, and a list goes on. # Reproduction ``` echo "search example.com\noptions ndots:5" >> /etc/hosts cpanm -n Net::DNS~'== 1.10' perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(nameservers => qw('a.root-servers.net'), recurse => 0, retrans => 2, retry => 1)->send('google.com', 'A'));' # => ... gets you the records as intended cpanm -n Net::DNS~'== 1.11' perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(nameservers => qw('a.root-servers.net'), recurse => 0, retrans => 2, retry => 1)->send('google.com', 'A'));' # => unresolvable name: a.root-servers.net at -e line 1. ``` Passing extra options like `ndots => 1, dnsrch => 0, defnames => 0` to `Net::DNS::Resolver->new` has no effect. # Analysis Use this command to see dump the resolver: ``` perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(nameservers => qw('a.root-servers.net'), recurse => 0, retrans => 2, retry => 1));' ``` This will show an empty value for nameserver4 # Workarounds 1. Change the nameserver from 'a.root-servers.net' to 'a.root-servers.net.' 2. Use `nameserver4 => ...` instead of `nameservers => ...`. ``` perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(nameserver4 => qw('a.root-servers.net'), recurse => 0, retrans => 2, retry => 1)->send('google.com', 'A'));' ``` 3. Downgrade to 1.10.
On Fri Aug 31 16:22:46 2018, spam@nowaker.net wrote: Show quoted text
> ... If search within domains listed in > /etc/resolv.conf fails, the check should fallback to a bare domain. > This is how the operating system works (getent hosts / getaddrinfo), > how other programming languages work, and a list goes on.
Man page for resolv.conf says: nameserver Name server IP address Internet address of a name server that the resolver should query, either an IPv4 address (in dot notation), or an IPv6 address in colon (and possibly dot) notation as per RFC 2373. Anything beyond that is implementation dependent. Show quoted text
> # Reproduction > > ``` > echo "search example.com\noptions ndots:5" >> /etc/hosts
Two things wrong with this: 1) echo command does not interpret \n as a line terminator. 2) Net::DNS does not look at /etc/hosts; I assume /etc/resolv.conf intended. Show quoted text
> cpanm -n Net::DNS~'== 1.10' > > perl -MData::Dumper -MNet::DNS::Resolver -e 'print > Dumper(Net::DNS::Resolver->new(nameservers => qw('a.root- > servers.net'), recurse => 0, retrans => 2, retry => 1)-
> >send('google.com', 'A'));'
The shell destroys this one-liner by mis-matching the nested single quotes. Rewrite: perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(nameservers => qw(a.root-servers.net), recurse => 0, retrans => 2, retry => 1)->send(qw(google.com A)));' produces: $VAR1 = bless( { 'count' => [ 1, 0, 13, 12 ], 'answerfrom' => '198.41.0.4', 'answer' => [], 'question' => [ bless( { 'qclass' => 1, 'qname' => bless( { 'label' => [ 'google', 'com' ] }, 'Net::DNS::DomainName1035' ), 'qtype' => 1 }, 'Net::DNS::Question' ) ], 'id' => 26242, 'authority' => [ bless( { 'type' => 2, 'owner' => bless( { 'label' => [], 'origin' => bless( { 'label' => [ 'com' ] }, 'Net::DNS::DomainName' ) }, 'Net::DNS::DomainName1035' ), 'ttl' => 172800, 'nsdname' => bless( { 'label' => [ 'e', 'gtld-servers', 'net' ] }, 'Net::DNS::DomainName1035' ), 'rdlength' => 20, 'class' => 1 }, 'Net::DNS::RR::NS' ), ... Show quoted text
> # => ... gets you the records as intended
? This is a negative response. There are no A records returned because ( recurse => 0 ) specified. Show quoted text
> cpanm -n Net::DNS~'== 1.11'
perl -MData::Dumper -MNet::DNS::Resolver -e 'print Dumper(Net::DNS::Resolver->new(debug => 1, nameservers => qw(a.root-servers.net), recurse => 0, retrans => 2, retry => 1)->send(qw(google.com A)));' ;; search( a.root-servers.net.example.com A ) ;; udp send [192.168.65.1]:53 ;; answer from [192.168.65.1] 64 bytes ;; HEADER SECTION ;; id = 49440 ;; qr = 1 aa = 0 tc = 0 rd = 1 opcode = QUERY ;; ra = 1 z = 0 ad = 0 cd = 0 rcode = NOERROR ;; qdcount = 1 ancount = 0 nscount = 0 arcount = 0 ;; do = 0 ;; QUESTION SECTION (1 record) ;; a.root-servers.net.example.com. IN A ;; ANSWER SECTION (0 records) ;; AUTHORITY SECTION (0 records) ;; ADDITIONAL SECTION (0 records) Show quoted text
> # Workarounds > > 1. Change the nameserver from 'a.root-servers.net' to 'a.root- > servers.net.'
Which is what it should have been from the outset. Show quoted text
> 2. Use `nameserver4 => ...` instead of `nameservers => ...`.
Which does not work. Show quoted text
> 3. Downgrade to 1.10.
Which avoidsthe problem by ignoring ndots completely. 4. Upgrade to 1.18, when I have figured out what to do about this.