#!/usr/bin/perl use Net::DNS; use IO::Select; use strict; $|=1; my $q; my $domain = $ARGV[0] || "nic"; my $i = 0; my $registered = 0; my $verbosity = 0; my $tldcache = "TLDs"; my $max_sel = 32; my $max_resend = 3; my $glob_expire = 21*86400; my $sock_resend = 4; my @RootServers = qw(198.41.0.4 128.9.0.107 192.33.4.12 128.8.10.90 192.203.230.10 192.5.5.241 192.112.36.4 128.63.2.53 198.41.0.10 193.0.14.129 198.32.64.12); my $cache_updated = 0; print "Content-type: text/html\r\n\r\n"; $domain = $1 if ($ENV{QUERY_STRING} =~ /domain=([\w-]+)/); my (%TLD_NAME, %TLD_NS, %TLD_CACHED, %TLD_RESULT); load_tld_table(); print "Checking '$domain' against ", scalar keys %TLD_NAME, " TLDs...\n"; print "
\r\n";
my $sel = IO::Select->new();
my $res = Net::DNS::Resolver->new();
$res->usevc(0); # be quick
$res->debug(0); # be silent
$res->recurse(1); # be recursive...why not?
$res->retry(1);
$res->retrans(3);
my @tlds = keys %TLD_NAME;
my @ready;
my (%SOCK_TLD, %SOCK_AGE, %SOCK_FILENO);
my $i = 0;
my $stdom = 0;
TLD: while ((@tlds and $sel->count < $max_sel) or $sel->count) {
@ready = $sel->can_read(0.1);
# print scalar @tlds, ", cnt: ", $sel->count, ", ", scalar keys %SOCK_TLD, " keys, ", $#ready+1, " ready\n";
# resend timed out queries
if (!@ready and $sel->count >= $max_sel or !@tlds) {
print "Sanitizing overflowed queue..." if $sel->count >= $max_sel and $verbosity;
sleep(1);
my $sock;
foreach $sock(keys %SOCK_AGE) {
my $ctime = time();
if ($ctime - $SOCK_AGE{$sock} > $sock_resend) {
# return domain to queue
unshift @tlds, $SOCK_TLD{$sock};
print "Request for $SOCK_TLD{$sock} timed out.\n" if $verbosity;
$sel->remove($SOCK_FILENO{$sock});
delete $SOCK_AGE{$sock};
delete $SOCK_TLD{$sock};
delete $SOCK_FILENO{$sock};
undef $sock;
}
}
# print "cleaned: ", scalar @tlds, ", cnt: ", $sel->count, ", ", scalar keys %SOCK_TLD, " keys, ", $#ready+1, " ready\n";
}
if (@tlds and $sel->count < $max_sel) {
my $tld = pop @tlds;
if ($TLD_RESULT{$tld} > 0) {
$TLD_RESULT{$tld}--;
} else {
next TLD if (defined $TLD_RESULT{$tld});
$TLD_RESULT{$tld} = $max_resend;
}
my $ns = get_ns($tld);
print "Could not get NS for $domain$tld, skipped.\n" and next TLD unless $ns;
$res->nameservers($ns);
my $sock = $res->bgsend($domain.$tld, "NS", "IN");
print "Could not queue request: ", $res->errorstring, "\n" and next TLD unless $sock;
$sel->add($sock);
$SOCK_TLD{$sock} = $tld;
$SOCK_AGE{$sock} = time();
$SOCK_FILENO{$sock} = fileno($sock);
print "Sent request for $domain$tld to $ns\n" if $verbosity;
}
SOCK: foreach my $sock(@ready) {
next SOCK unless $sock; #???
my $rep;
my $tld = $SOCK_TLD{$sock};
$rep = handle_response($res->bgread($sock));
$sel->remove($sock);
delete $SOCK_TLD{$sock};
delete $SOCK_AGE{$sock};
undef $sock;
unless ($rep) {
print "Could not read reply for $domain$tld: ", $res->errorstring, "\n";
push @tlds, $tld;
next TLD;
}
# print "Read reply for $domain$tld: ";
if ($rep == 1) {
# print "exists.\n";
$TLD_RESULT{$tld} = 'reg';
print "$tld ";
if ($stdom++ > 15) {
print "\r\n";
$stdom = 0;
}
} elsif ($rep == -1) {
# print "FREE.\n";
print "$tld ";
if ($stdom++ > 15) {
print "\r\n";
$stdom = 0;
}
$TLD_RESULT{$tld} = 'free';
} else {
$rep = $$rep[rand(100) % (scalar @$rep)];
# print "-> $rep\n";
$res->nameservers($rep);
my $sock = $res->bgsend($domain.$tld, "NS", "IN");
unless ($sock) {
print "Could not queue request for $domain$tld: ", $res->errorstring, "\n";
push @tlds, $tld;
next TLD;
}
print "Sent request for $domain$tld to $rep\n" if $verbosity;
$sel->add($sock);
$SOCK_TLD{$sock} = $tld;
$SOCK_AGE{$sock} = time();
$SOCK_FILENO{$sock} = fileno($sock);
$TLD_RESULT{$tld} = $max_resend;
}
}
}
store_tld_table() if $cache_updated;
print "Stored $cache_updated new records in TLD NS cache.\n" if $cache_updated;
print "\r\n\r\n| ", ($tld ? $tld : ' '), " | \r\n"; $cellcount++; } print "