Blame demo/mresolv

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
}