Ik ben bezig een script te maken dat voor een gegeven domeinnaam en een gegeven lijst met tld's controleert of er NS-, A-, of MX-records van bestaan. Dit wil ik doen op zo'n manier dat een time-out van een dns-server niet het hele script laat wachten. Via CPAN vond ik Net::DNS die me netjes vertelde dat ik hiervoor IO::Select kan gebruiken. Dit werkt inderdaad prima, maar ik loop tegen het volgende probleem aan. Als ik met mijn script bijvoorbeeld de naam 'dude' controleer met tld's 'nl,com,org,net,nu,co.uk,de,be', dan krijg ik daar de eerste keer de volgende output:
De 1 of 0 geeft aan of het domein vrij (0) is of bezet (1).
Draai ik het script echter direct nog eens, krijg ik als output:
De code:
Ik vermoed dat het script te snel ziet dat er een positief antwoord terugkomt van een nameserver (meestal de .nl), en daarna alles teruggeeft terwijl nog niet alle antwoorden binnen zijn. De 2e keer dat het script draait hebben de nameservers de aanvraag ge-cached en krijg ik wel op alle aanvragen een correct antwoord.
Ik denk dat ik op regel 42 wat extra logica in moet bouwen, maar ik weet zo niet hoe of wat. Weet iemand misschien duidelijk uit te leggen wat hier fout gaat en wat ik er aan zou kunnen doen?
code:
1
2
3
4
5
6
7
8
| dude.org:0 dude.be:0 dude.nl:1 dude.nu:1 dude.com:0 dude.co.uk:0 dude.de:0 dude.net:0 |
De 1 of 0 geeft aan of het domein vrij (0) is of bezet (1).
Draai ik het script echter direct nog eens, krijg ik als output:
code:
1
2
3
4
5
6
7
8
| dude.org:0 dude.be:1 dude.nl:1 dude.nu:0 dude.com:1 dude.co.uk:0 dude.de:1 dude.net:1 |
De code:
PHP:
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
| #!/usr/bin/perl use strict; use warnings; use Net::DNS; use IO::Select; use CGI::Carp qw(fatalsToBrowser); use CGI qw/param/; use Data::Dumper; print "Content-Type: text/plain\n\n"; my $domain = param('d'); my @tlds = split(',', param('tlds')); our $dns_ = Net::DNS::Resolver->new; our $sel_ = IO::Select->new; our $DEBUG = 1; my $timeout = 5; my $counter = 0; my @ready = (); my @bgsocks = (); my @selects = (); my %domains = (); foreach my $t (@tlds) { $domains{"$domain.$t"} = 0; # print "$domain.$t: query sent\n"; push( @bgsocks, $dns_->bgsend( "$domain.$t", 'NS' ) ); push( @bgsocks, $dns_->bgsend( "$domain.$t", 'A' ) ); push( @bgsocks, $dns_->bgsend( "$domain.$t", 'MX' ) ); push( @bgsocks, $dns_->bgsend( "www.$domain.$t", 'A' ) ); $sel_->add( $bgsocks[ ($counter * 4) + 0 ] ); $sel_->add( $bgsocks[ ($counter * 4) + 1 ] ); $sel_->add( $bgsocks[ ($counter * 4) + 2 ] ); $sel_->add( $bgsocks[ ($counter * 4) + 3 ] ); push( @ready, $sel_->can_read( $timeout ) ); $counter++; } #print Dumper(@ready); if( @ready ) { foreach my $sock ( @ready ) { foreach my $bgsock ( @bgsocks ) { if( $sock == $bgsock ) { my $packet = $dns_->bgread($bgsock); my @answer = $packet->answer; my @question = $packet->question; foreach my $q (@question) { if( @answer ) { # er is een antwoord, dus domein is bezet my $temp_domain = $q->qname; # evt 'www.' van de naam kappen $temp_domain =~ s/^www\.//; $domains{$temp_domain} = 1; } } $bgsock = undef; } } $sel_->remove( $sock ); $sock = undef; } } # print naar stdout while( (my $c, my $free) = each( %domains ) ) { print "$c:$free\n"; } |
Ik vermoed dat het script te snel ziet dat er een positief antwoord terugkomt van een nameserver (meestal de .nl), en daarna alles teruggeeft terwijl nog niet alle antwoorden binnen zijn. De 2e keer dat het script draait hebben de nameservers de aanvraag ge-cached en krijg ik wel op alle aanvragen een correct antwoord.
Ik denk dat ik op regel 42 wat extra logica in moet bouwen, maar ik weet zo niet hoe of wat. Weet iemand misschien duidelijk uit te leggen wat hier fout gaat en wat ik er aan zou kunnen doen?
[ Voor 6% gewijzigd door Gertjan op 26-02-2005 02:26 ]