On Thu, 10 Nov 2005 10:52:29 -0500
Matt Sergeant <[EMAIL PROTECTED]> wrote:

> >> Why? You should just get the callback called twice.
>
> > But that makes notes('pending_dns_queries') (in trunk/plugins/dnsbl) go
> > negative, revealing a race between receiving the rest of the answers
> > and going on to the next plugin.
> >
> > Got any suggestions on a more resilient way to lock here?
>
> Hmm. I don't know too much about DNS, but can we assume that all the
> responses will come back in one packet? If so I guess we can accumulate
> the results and do the callback once. Or if we don't want to change the
> API I guess we could have a "finished()" callback. Thoughts?

I think so.  Net::DNS::Resolver::send() returns either a Packet object
or undef, so it seems reasonable to assume there will be only one packet
even when using the asyncronous interface (bgsend).  Also, the bgread()
docs say that you should close the socket after reading it; I take that as
confirmation that there will only be one packet.

A plugin can emit several unrelated queries before calling for a
CONTINUATION (mine does), so I think changing the Danga::DNS callback API
will be necessary.

I'll be happy to write up a patch if you like, but I'd first like your
thoughts on what to pass to the callback.

I'm thinking something like:
        my @data;
        for my $rr ($packet->answer) {
                my $type = $rr->type;
                my $type_specific_data;
                if( $type eq 'TXT' ) {
                        $type_specific_data = $rr->txtdata;
                        }
                elsif ...
                push(@data, [ $type, $type_specific_data ]);
                }
        query = lc $query;
        $self->{cache}{$query} = [EMAIL PROTECTED];
        $self->{cache_timeout}{$query} = $now+60;
        $asker->run_callback($query, [EMAIL PROTECTED]);

But that would require checking the cache for the record type before
sending the request.  The cached @data should be small enough that's
not of much concern.

Brian



BTW, here's the most extreme example of Net::DNS returning multiple data
I could find:

#!/usr/bin/perl -w
use Net::DNS;
my $res = Net::DNS::Resolver->new;
my $socket = $res->bgsend('67.117.97.61.dnsbl.sorbs.net', 'ANY');
until($res->bgisready($socket)) {}
my $packet = $res->bgread($socket);
for my $rr ($packet->answer) {
  print $rr->type."\t".$rr->name." ".$rr->rdatastr."\n";
  }

Reply via email to