Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: cpan [...] aaroncrane.co.uk
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.62
Fixed in: 0.63



Subject: Default LocalAddr broken in Net::DNS::Nameserver 0.62
Net::DNS::Nameserver is documented to listen on all local addresses if no LocalAddr is set as a constructor option. This no longer works in 0.62; if no LocalAddr is passed, the ->main_loop method on Net::DNS::Nameserver enters a tight loop, repeatedly trying to read from an IO::Select object with no sockets. The attached patch seems to be the simplest change to restore the documented behaviour, and includes tests to verify that the created select object has at least one socket. The new tests fail with 0.62 as released, and pass with my patch to Net::DNS::Nameserver. But there are two caveats for that patch. First, I haven't thought at all about what's needed for IPv6. Second, I confess that the constructor's behaviour as introduced in r688 is somewhat obscure to me. What's the purpose of the Net::DNS::Resolver object here? And why is ->nameservers called twice on the resolver, once with @DEFAULT_ADDR, and once with the @LocalAddr passed to the constructor? (Also, I'm afraid Googling has failed me on this, but if there's a mailing list or anything for Net::DNS, I'd be very interested in subscribing.)
Subject: net_dns_default_localaddr.diff
Index: lib/Net/DNS/Nameserver.pm =================================================================== --- lib/Net/DNS/Nameserver.pm (revision 701) +++ lib/Net/DNS/Nameserver.pm (working copy) @@ -63,7 +63,8 @@ } # local server addresses must also be accepted by a resolver - my @LocalAddr = ref $self{LocalAddr} ? @{$self{LocalAddr}} : ($self{LocalAddr}); + my @LocalAddr = ref $self{LocalAddr} ? @{$self{LocalAddr}} + : ($self{LocalAddr} || '0.0.0.0'); my $resolver = Net::DNS::Resolver->new; $resolver->nameservers(@DEFAULT_ADDR); my @localaddresses = $resolver->nameservers(@LocalAddr); Index: t/13-nameserver.t =================================================================== --- t/13-nameserver.t (revision 0) +++ t/13-nameserver.t (revision 0) @@ -0,0 +1,22 @@ +# $Id$ -*- perl + +use Test::More tests => 10; +use strict; + +use_ok('Net::DNS::Nameserver'); + +for ([LocalAddr => '0.0.0.0'], [LocalAddr => '127.0.0.1'], []) { + my $nameserver = Net::DNS::Nameserver->new( + LocalPort => 8053, + ReplyHandler => sub { 'NXDOMAIN' }, + @$_, + ); + # This is a white-box test; it knows (too much?) about the implementation + ok($nameserver, "created server @$_"); + my $select = $nameserver->{select}; + ok($select, "got IO::Select for server @$_"); + SKIP: { + skip 'skip check for handles if no IO::Select', 1 if !$select; + ok($select->count, "got sockets for server @$_"); + } +}
Output of perl -V on my development machine, as requested: Summary of my perl5 (revision 5 version 8 subversion 8) configuration: Platform: osname=linux, osvers=2.6.15.7, archname=i486-linux-gnu-thread-multi uname='linux terranova 2.6.15.7 #1 smp thu jul 12 14:27:56 utc 2007 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des' hint=recommended, useposix=true, d_sigaction=define usethreads=define use5005threads=undef useithreads=define usemultiplicity=define useperlio=define d_sfio=undef uselargefiles=define usesocks=undef use64bitint=undef use64bitall=undef uselongdouble=undef usemymalloc=n, bincompat5005=undef Compiler: cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64', optimize='-O2', cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include' ccversion='', gccversion='4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)', gccosandvers='' intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234 d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12 ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8 alignbytes=4, prototype=define Linker and Libraries: ld='cc', ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8 gnulibc_version='2.6.1' Dynamic Linking: dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E' cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib' Characteristics of this binary (from libperl): Compile-time options: MULTIPLICITY PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP THREADS_HAVE_PIDS USE_ITHREADS USE_LARGE_FILES USE_PERLIO USE_REENTRANT_API Built under linux Compiled at Dec 4 2007 08:56:39 @INC: /etc/perl /usr/local/lib/perl/5.8.8 /usr/local/share/perl/5.8.8 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.8 /usr/share/perl/5.8 /usr/local/lib/site_perl . Additionally, the 0.62 release has the same failure for me on all of: Perl 5.8.4, amd64, Linux 2.6.8 (Debian Sarge) Perl 5.8.4, i386, Linux 2.4.20 (Debian Sarge) Perl 5.8.8, amd64, Linux 2.6.18 (Debian Etch) Perl 5.8.6, i386, Mac OS X 10.4 Applying my patch makes my test pass on all of those systems. Further, on the Mac, creating a Net::DNS::Nameserver takes a long time (a minute or more); it seems to be waiting for a timeout while trying to do the very odd-looking resolver lookups.