118 lines
2.6 KiB
Perl
Executable File
118 lines
2.6 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
|
|
use strict;
|
|
use warnings "all";
|
|
|
|
use Net::DNS;
|
|
use threads;
|
|
use threads::shared;
|
|
|
|
my $max_sleep = 2000; # max sleep between sequental lookups 2 seconds long
|
|
my $max_burst_lookups = 15; # max amount of lookup without delay
|
|
my $threads_max = 310; # on my vm threads gonna die if amount more than 313, seems like some pthread limit?
|
|
my @nameservers = ('192.168.88.2');
|
|
|
|
my $domfile = 'domfile.txt'; # file format: domainname record_type number_of_values
|
|
# num_of_values can be -1 if no A record exist
|
|
sub worker; # main sub of worker
|
|
sub lookup; # hotpath :)
|
|
sub nodomlist;
|
|
sub usleep; # millisecond sleep, 1000 milliseconds = 1 second
|
|
|
|
nodomlist() unless ( -f $domfile );
|
|
|
|
my $res;
|
|
|
|
my @list;
|
|
open (LIST, $domfile) or die ("Unable to read $domfile");
|
|
|
|
while (<LIST>){
|
|
next if (($_ eq '') or ($_ =~ /^\s*#/));
|
|
chomp($_); chomp($_);
|
|
push @list, $_;
|
|
}
|
|
|
|
close LIST;
|
|
|
|
# TODO: looks like this stuff should be created on per thread basis, not shared
|
|
|
|
my @threads;
|
|
for (my $m = 1; $m <= $threads_max; $m++){
|
|
push @threads, threads->create('worker');
|
|
syswrite STDOUT, "thread $m/$threads_max spawned\r";
|
|
usleep('10');
|
|
}
|
|
|
|
syswrite STDOUT, "\n";
|
|
|
|
# we'll wait forever 'till threads' exit :)
|
|
foreach my $thread (@threads){ $thread->join(); }
|
|
|
|
exit 0;
|
|
|
|
|
|
sub worker {
|
|
threads->yield();
|
|
|
|
$res = Net::DNS::Resolver->new(
|
|
nameservers => [ @nameservers ],
|
|
recurse => 1,
|
|
debug => 0
|
|
);
|
|
|
|
my $lookup_cnt = int(rand($max_burst_lookups));
|
|
while ( 1 ) {
|
|
my $ok = 0; my $error = 0;
|
|
|
|
for (my $i = 0; $i < 10000; $i++) {
|
|
|
|
if ($lookup_cnt <= 0){
|
|
usleep(int(rand($max_sleep)));
|
|
$lookup_cnt = int(rand($max_burst_lookups));
|
|
} else {
|
|
$lookup_cnt--;
|
|
}
|
|
|
|
my ($domain, $record_type, $amount) = split(/\s+/, $list[int(rand(@list))]);
|
|
my $result = lookup($domain, $record_type);
|
|
|
|
if (defined($result) and ($result == $amount)){ $ok++; }
|
|
elsif (($amount == -1) and ($result == undef)){ $ok++; }
|
|
else { $error++; }
|
|
}
|
|
|
|
syswrite STDOUT, "Success/Error: $ok/$error\n";
|
|
}
|
|
return 0; # we'll never return :(
|
|
}
|
|
|
|
sub lookup {
|
|
my $host = shift;
|
|
my $type = shift;
|
|
my $rec_count = 0;
|
|
my $reply = $res->query($host, $type);
|
|
|
|
if (defined($reply)) {
|
|
|
|
foreach my $rr ($reply->answer) {
|
|
$rec_count++ if ($rr->type eq $type);
|
|
}
|
|
|
|
return $rec_count;
|
|
} else {
|
|
# warn "query failed: ", $res->errorstring, "\n";
|
|
return undef;
|
|
}
|
|
}
|
|
|
|
sub nodomlist {
|
|
print "Unable to find $domfile\n";
|
|
exit 1;
|
|
}
|
|
|
|
sub usleep {
|
|
my $delay = shift;
|
|
select(undef, undef, undef, $delay/1000);
|
|
return;
|
|
}
|