Skip Menu |

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

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

People
Owner: Nobody in particular
Requestors: 7eggert [...] gmx.de
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



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; + } }
That can't be the right way to do what you need. Forking on each DNS request isn't going to work for anything but development and Very Small environments.
Hi Bodo, I can see that what you want is convenient. I have silently committed a patch that prevents the Net::DNS::Nameserver from answering when a ReplyHandler returns undef, but I am reluctant to put that forward as a feature. Regards, -- Willem
CC: 7eggert [...] gmx.de
Subject: Re: [rt.cpan.org #43142] Enheance Net::DNS::Nameserver to support forking nameservers
Date: Fri, 21 Oct 2011 15:14:42 +0200 (CEST)
To: Willem Toorop via RT <bug-Net-DNS [...] rt.cpan.org>
From: Bodo Eggert <7eggert [...] gmx.de>
On Wed, 19 Oct 2011, Willem Toorop via RT wrote: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=43142 > > > Hi Bodo, > > I can see that what you want is convenient. I have silently committed a > patch that prevents the Net::DNS::Nameserver from answering when a > ReplyHandler returns undef, but I am reluctant to put that forward as a > feature. > Regards,
Thanks. I had some other issues (don´t remember), which forced me to abandon my own DNS server and return to bind, though. I think I tried returning undef, but being able to find a feature in the documentation tends to help.-) I don´t see why you would not advertize it.
Subject: Re: [rt.cpan.org #43142] Enheance Net::DNS::Nameserver to support forking nameservers
Date: Fri, 21 Oct 2011 10:04:59 -0600
To: bug-Net-DNS [...] rt.cpan.org
From: Rob Brown <bbb [...] cpan.org>
I really like this feature of ReplyHandler returning undef as a way to just not respond to the client because "not responding" can be a valid intentional response under certain conditions, such as abusive clients or delinquent service payment for zones or even for testing purposes. And as an added bonus, this feature could still crudely be used for your fork() design. However, it would require a double fork to avoid zombies, and the ReplyHandler would have to be responsible for sending the response packet directly itself. Unfortunately, I don't think this fork() hack work with TCP very easily. So I say leave the "undef means no response" and document it as an intended feature. On Fri, Oct 21, 2011 at 7:14 AM, Bodo Eggert via RT <bug-Net-DNS@rt.cpan.org> wrote: Show quoted text
>       Queue: Net-DNS >  Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=43142 > > > On Wed, 19 Oct 2011, Willem Toorop via RT wrote: >
>> <URL: https://rt.cpan.org/Ticket/Display.html?id=43142 > >> >> Hi Bodo, >> >> I can see that what you want is convenient. I have silently committed a >> patch that prevents the Net::DNS::Nameserver from answering when a >> ReplyHandler returns undef, but I am reluctant to put that forward as a >> feature. >> Regards,
> > Thanks. I had some other issues (don´t remember), which forced me to > abandon my own DNS server and return to bind, though. > > I think I tried returning undef, but being able to find a feature in the > documentation tends to help.-) I don´t see why you would not advertize it. >
RT-Send-CC: net-dns-dev [...] nlnetlabs.nl
On Fri Oct 21 12:05:08 2011, BBB wrote: Show quoted text
> Unfortunately, I don't think this > fork() hack work with TCP very easily.
Yes, and also to determine if a query came in from TCP and which socket was used would be quiet difficult. Show quoted text
> So I say leave the "undef means no response" and document it as an > intended feature.
Agreed. I propose to change the sentence about ReplyHanlder's return value(s) from: It must return the response code and references to the answer, authority, and additional sections of the response. in It must either return the response code and references to the answer, authority, and additional sections of the response, or C<undef> to leave the query unanswered. Better formulations are welcome.
Closing ticket...