Net::DNSServer
Last updated: Mon, 19 Jun 2006 12:01:00 GMT
And the perils of Perl programming.
Before we begin, let me hit you with a caveat: I Am Not A Perl Programmer.
With that out of the way, let me save you some time. Time I'll never get back.
There are three errors in the example resolver code given in Net::DNSServer. Actually, in Net:::DNSServer::Base.
Firstly, the example script uses the taint flag, but does not sanitise the environment. It will fail, honking:
Insecure $ENV{PATH} while running with -T switch
Here's a patch that'll fix the script:
@@ -1,5 +1,7 @@
#!/usr/bin/perl -w -T
+delete @ENV{qw(PATH IFS CDPATH ENV BASH_ENV)};
+
use strict;
use Net::DNSServer;
use Net::DNSServer::Cache;
Secondly, the example resolver package pushes Net::DNS::RR references into the response packet wrapped in anonymous arrays. I don't know why, but I know that it doesn't work. It fails:
Can't call method "string" on unblessed reference
and the following patch will fix it:
@@ -16,14 +16,14 @@
my $response = bless \%{$dns_packet}, "Net::DNS::Packet"
|| die "Could not initialize response packet";
$response->push("answer",
- [Net::DNS::RR->new
- ("$self->{dom} 1000 A 127.0.0.100")]);
+ Net::DNS::RR->new
+ ("$self->{dom} 1000 A 127.0.0.100"));
$response->push("authority",
- [Net::DNS::RR->new
- ("$self->{dom} 1000 NS ns1.$self->{dom}")]);
+ Net::DNS::RR->new
+ ("$self->{dom} 1000 NS ns1.$self->{dom}"));
$response->push("additional",
- [Net::DNS::RR->new
- ("ns1.$self->{dom} 1000 A 127.0.0.200")]);
+ Net::DNS::RR->new
+ ("ns1.$self->{dom} 1000 A 127.0.0.200"));
my $response_header = $response->header;
$response_header->aa(1); # Make Authoritative
return $response;
The third one's a doozy, as they say. The example resolver doesn't set the qr flag in the response packet. A lot of tools -- the ever-useful, ever-excellent dnstracer, for instance -- don't flag this up as an error.
Ho-ho.
One thing I can tell you for certain, though, is that a BIND9 caching server will take one look at your malformed response and daintily puke into its handkerchief.
Here's a patch:
@@ -26,6 +26,7 @@
("ns1.$self->{dom} 1000 A 127.0.0.200"));
my $response_header = $response->header;
$response_header->aa(1); # Make Authoritative
+ $response_header->qr(1); # Make Response
return $response;
}
return undef;
There you go. I've learned that the O'Reilly DNS and BIND book isn't all it could be, but it's still pretty good. I've learned that dnstracer doesn't weep over some malformed responses, but BIND9 does. I've learned not to trust example Perl.
I own two O'Reilly Perl books: the camel book and the pocket reference. I used to own a third. It was called Mastering Perl/Tk. It was awful. I bought it because I wanted to explore Perl/Tk as a candidate for a small almost GUI front end to a database I'd written.
As I worked through it I got used to the terrible smell emanating from the example code. Even someone like me, Not A Perl Programmer, could see that the code just wouldn't have passed Go if strict were used. Beyond that, a high-school hacker could have found better ways to solve the given problems than the author. I held my nose and plodded on. When I found a listing that just plain didn't work -- ironically, strictness would have saved his ass -- I just tossed it straight in the bin.
Laziness like that, and like this, sums up the whole Perl experience. And in a wider, broader and sweepingly inaccurater sense, it sums up the whole Free experience. You paid nothing for it so count yourself lucky if it works.
Except that book wasn't free: I paid £35 for it and I'd rather bin it than scalp some other poor sod by selling it on.
My time isn't free either, but my advice is: test your documentation as hard as you test your code.