|
Packit |
e6c8bb |
#!/usr/local/bin/perl -w
|
|
Packit |
e6c8bb |
# $Id: mresolv 264 2005-04-06 09:16:15Z olaf $
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 NAME
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
mresolv - Perform multiple DNS lookups in parallel
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 SYNOPSIS
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
B<mresolv> S<[ B<-d> ]> S<[ B<-n> I<number> ]> S<[ B<-t> I<timeout> ]>
|
|
Packit |
e6c8bb |
S<[ I<filename>... ]>
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 DESCRIPTION
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
B<mresolv> performs multiple DNS lookups in parallel. Names to query
|
|
Packit |
e6c8bb |
are read from the list of files given on the command line, or from the
|
|
Packit |
e6c8bb |
standard input.
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 OPTIONS
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=over 4
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=item B<-d>
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
Turn on debugging output.
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=item B<-n> I<number>
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
Set the number of queries to have outstanding at any time.
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=item B<-t> I<timeout>
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
Set the timeout in seconds. If no replies are received for this
|
|
Packit |
e6c8bb |
amount of time, all outstanding queries will be flushed and new
|
|
Packit |
e6c8bb |
names will be read from the input stream.
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=back
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 COPYRIGHT
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
Copyright (c) 1997-2000 Michael Fuhr. All rights reserved. This
|
|
Packit |
e6c8bb |
program is free software; you can redistribute it and/or modify it
|
|
Packit |
e6c8bb |
under the same terms as Perl itself.
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=head1 SEE ALSO
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
L<perl(1)>, L<axfr>, L<check_soa>, L<check_zone>, L<mx>, L<perldig>,
|
|
Packit |
e6c8bb |
L<Net::DNS>
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
=cut
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
use Net::DNS;
|
|
Packit |
e6c8bb |
use IO::Select;
|
|
Packit |
e6c8bb |
use Getopt::Std;
|
|
Packit |
e6c8bb |
use strict;
|
|
Packit |
e6c8bb |
use vars qw($opt_d $opt_n $opt_t);
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
$| = 1;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
$opt_n = 32; # number of requests to have outstanding at any time
|
|
Packit |
e6c8bb |
$opt_t = 15; # timeout (seconds)
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
getopts("dn:t:");
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
my $res = Net::DNS::Resolver->new;
|
|
Packit |
e6c8bb |
my $sel = IO::Select->new;
|
|
Packit |
e6c8bb |
my $eof = 0;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
while (1) {
|
|
Packit |
e6c8bb |
my $name;
|
|
Packit |
e6c8bb |
my $sock;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
# Read names until we've filled our quota of outstanding requests.
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
while (!$eof && $sel->count < $opt_n) {
|
|
Packit |
e6c8bb |
print "DEBUG: reading..." if defined $opt_d;
|
|
Packit |
e6c8bb |
$name = <>;
|
|
Packit |
e6c8bb |
unless ($name) {
|
|
Packit |
e6c8bb |
print "EOF.\n" if defined $opt_d;
|
|
Packit |
e6c8bb |
$eof = 1;
|
|
Packit |
e6c8bb |
last;
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
chomp $name;
|
|
Packit |
e6c8bb |
$sock = $res->bgsend($name);
|
|
Packit |
e6c8bb |
$sel->add($sock);
|
|
Packit |
e6c8bb |
print "name = $name, outstanding = ", $sel->count, "\n"
|
|
Packit |
e6c8bb |
if defined $opt_d;
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
# Wait for any replies. Remove any replies from the outstanding pool.
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
my @ready;
|
|
Packit |
e6c8bb |
my $timed_out = 1;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
print "DEBUG: waiting for replies\n" if defined $opt_d;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
for (@ready = $sel->can_read($opt_t);
|
|
Packit |
e6c8bb |
@ready;
|
|
Packit |
e6c8bb |
@ready = $sel->can_read(0)) {
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
$timed_out = 0;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
print "DEBUG: replies received: ", scalar @ready, "\n"
|
|
Packit |
e6c8bb |
if defined $opt_d;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
foreach $sock (@ready) {
|
|
Packit |
e6c8bb |
print "DEBUG: handling a reply\n" if defined $opt_d;
|
|
Packit |
e6c8bb |
$sel->remove($sock);
|
|
Packit |
e6c8bb |
my $ans = $res->bgread($sock);
|
|
Packit |
e6c8bb |
next unless $ans;
|
|
Packit |
e6c8bb |
my $rr;
|
|
Packit |
e6c8bb |
foreach $rr ($ans->answer) {
|
|
Packit |
e6c8bb |
$rr->print;
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
# If we timed out waiting for replies, remove all entries from the
|
|
Packit |
e6c8bb |
# outstanding pool.
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
if ($timed_out) {
|
|
Packit |
e6c8bb |
print "DEBUG: timeout: clearing the outstanding pool.\n"
|
|
Packit |
e6c8bb |
if defined $opt_d;
|
|
Packit |
e6c8bb |
my $sock;
|
|
Packit |
e6c8bb |
foreach $sock ($sel->handles) {
|
|
Packit |
e6c8bb |
$sel->remove($sock);
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
}
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
print "DEBUG: outstanding = ", $sel->count, ", eof = $eof\n"
|
|
Packit |
e6c8bb |
if defined $opt_d;
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
# We're done if there are no outstanding queries and we've read EOF.
|
|
Packit |
e6c8bb |
#----------------------------------------------------------------------
|
|
Packit |
e6c8bb |
|
|
Packit |
e6c8bb |
last if ($sel->count == 0) && $eof;
|
|
Packit |
e6c8bb |
}
|