I'm using Net::DNS::Nameserver to create a forwarding nameserver.
Unfortunately I need to fork in the reply handler, because I don't want
to stall the whole local DNS server while the upstream server times out
on one query.
In order to do this, I added one optional return parameter (telling it
to exit after sending the response), and implemented a way to not reply
at all.
I made the changes a while ago for version 0.63. Today, I forward-ported
it to 0.65 and did a compile test.
The changes are in the attached patch.
Subject: | Nameserver.diff |
--- Nameserver.pm.ori 2008-09-07 21:37:02.000000000 +0200
+++ Nameserver.pm 2008-09-07 21:29:34.000000000 +0200
@@ -155,7 +155,7 @@ sub make_reply {
my $reply = Net::DNS::Packet->new(); # create empty reply packet
$reply->header->qr(1);
- my $headermask;
+ my ($headermask, $flags);
unless ($query) {
print "ERROR: invalid packet\n" if $self->{"Verbose"};
@@ -190,7 +190,7 @@ sub make_reply {
my ($rcode, $ans, $auth, $add);
if ($query->header->opcode eq "QUERY"){
- ($rcode, $ans, $auth, $add, $headermask) =
+ ($rcode, $ans, $auth, $add, $headermask, $flags) =
&{$self->{"ReplyHandler"}}($qname, $qclass, $qtype, $peerhost, $query);
}else{
$reply->header->rcode("SERVFAIL") unless
@@ -198,8 +198,16 @@ sub make_reply {
($rcode, $ans, $auth, $add, $headermask) =
&{$self->{"NotifyHandler"}}($qname, $qclass, $qtype, $peerhost, $query);
}
- print "$rcode\n" if $self->{"Verbose"};
-
+
+ if (!defined $rcode) {
+ print "remaining silent\n" if $self->{"Verbose"};
+ return undef;
+ } elsif ($rcode eq 'FORKED') {
+ print "Forked, Parent remains silent\n" if $self->{"Verbose"};
+ return undef;
+ }
+ print "rcode=$rcode\n" if $self->{"Verbose"};
+
$reply->header->rcode($rcode);
$reply->push("answer", @$ans) if $ans;
@@ -233,6 +241,7 @@ sub make_reply {
$reply->header->id($query->header->id);
$reply->header->print if $self->{"Verbose"} && defined $headermask;
+ $reply->{flags} = $flags;
return $reply;
}
@@ -360,6 +369,10 @@ sub udp_connection {
else {
print "failed to send reply: $!\n" if $self->{"Verbose"};
}
+ if (defined $reply->{flags} && $reply->{flags}->{exit}) {
+ print "Exiting\n" if $self->{"Verbose"};
+ exit 0;
+ }
}