1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
#!/usr/bin/perl -w
# $Id: mresolv,v 1.2 2000/11/10 16:02:41 mfuhr Exp mfuhr $
=head1 NAME
mresolv - Perform multiple DNS lookups in parallel
=head1 SYNOPSIS
B<mresolv> S<[ B<-d> ]> S<[ B<-n> I<number> ]> S<[ B<-t> I<timeout> ]>
S<[ I<filename>... ]>
=head1 DESCRIPTION
B<mresolv> performs multiple DNS lookups in parallel. Names to query
are read from the list of files given on the command line, or from the
standard input.
=head1 OPTIONS
=over 4
=item B<-d>
Turn on debugging output.
=item B<-n> I<number>
Set the number of queries to have outstanding at any time.
=item B<-t> I<timeout>
Set the timeout in seconds. If no replies are received for this
amount of time, all outstanding queries will be flushed and new
names will be read from the input stream.
=back
=head1 COPYRIGHT
Copyright (c) 1997-2000 Michael Fuhr. All rights reserved. This
program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=head1 SEE ALSO
L<perl(1)>, L<axfr>, L<check_soa>, L<check_zone>, L<mx>, L<perldig>,
L<Net::DNS>
=cut
use Net::DNS;
use IO::Select;
use Getopt::Std;
use strict;
use vars qw($opt_d $opt_n $opt_t);
$| = 1;
$opt_n = 32; # number of requests to have outstanding at any time
$opt_t = 15; # timeout (seconds)
getopts("dn:t:");
my $res = Net::DNS::Resolver->new;
my $sel = IO::Select->new;
my $eof = 0;
while (1) {
my $name;
my $sock;
#----------------------------------------------------------------------
# Read names until we've filled our quota of outstanding requests.
#----------------------------------------------------------------------
while (!$eof && $sel->count < $opt_n) {
print "DEBUG: reading..." if defined $opt_d;
$name = <>;
unless ($name) {
print "EOF.\n" if defined $opt_d;
$eof = 1;
last;
}
chomp $name;
$sock = $res->bgsend($name);
$sel->add($sock);
print "name = $name, outstanding = ", $sel->count, "\n"
if defined $opt_d;
}
#----------------------------------------------------------------------
# Wait for any replies. Remove any replies from the outstanding pool.
#----------------------------------------------------------------------
my @ready;
my $timed_out = 1;
print "DEBUG: waiting for replies\n" if defined $opt_d;
for (@ready = $sel->can_read($opt_t);
@ready;
@ready = $sel->can_read(0)) {
$timed_out = 0;
print "DEBUG: replies received: ", scalar @ready, "\n"
if defined $opt_d;
foreach $sock (@ready) {
print "DEBUG: handling a reply\n" if defined $opt_d;
$sel->remove($sock);
my $ans = $res->bgread($sock);
next unless $ans;
my $rr;
foreach $rr ($ans->answer) {
$rr->print;
}
}
}
#----------------------------------------------------------------------
# If we timed out waiting for replies, remove all entries from the
# outstanding pool.
#----------------------------------------------------------------------
if ($timed_out) {
print "DEBUG: timeout: clearing the outstanding pool.\n"
if defined $opt_d;
my $sock;
foreach $sock ($sel->handles) {
$sel->remove($sock);
}
}
print "DEBUG: outstanding = ", $sel->count, ", eof = $eof\n"
if defined $opt_d;
#----------------------------------------------------------------------
# We're done if there are no outstanding queries and we've read EOF.
#----------------------------------------------------------------------
last if ($sel->count == 0) && $eof;
}
|