#!/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 (){ 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; }