ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/DNS.pm
Revision: 1.102
Committed: Mon Jul 6 23:32:49 2009 UTC (14 years, 11 months ago) by root
Branch: MAIN
Changes since 1.101: +35 -9 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     AnyEvent::DNS - fully asynchronous DNS resolution
4    
5     =head1 SYNOPSIS
6    
7 root 1.57 use AnyEvent::DNS;
8    
9     my $cv = AnyEvent->condvar;
10     AnyEvent::DNS::a "www.google.de", $cv;
11     # ... later
12     my @addrs = $cv->recv;
13 root 1.26
14 root 1.1 =head1 DESCRIPTION
15    
16     This module offers both a number of DNS convenience functions as well
17     as a fully asynchronous and high-performance pure-perl stub resolver.
18    
19 root 1.46 The stub resolver supports DNS over IPv4 and IPv6, UDP and TCP, optional
20     EDNS0 support for up to 4kiB datagrams and automatically falls back to
21     virtual circuit mode for large responses.
22 root 1.12
23 root 1.1 =head2 CONVENIENCE FUNCTIONS
24    
25     =over 4
26    
27     =cut
28    
29     package AnyEvent::DNS;
30    
31 root 1.3 no warnings;
32 root 1.1 use strict;
33    
34 root 1.102 use Carp ();
35 root 1.29 use Socket qw(AF_INET SOCK_DGRAM SOCK_STREAM);
36    
37 root 1.35 use AnyEvent ();
38 root 1.37 use AnyEvent::Util qw(AF_INET6);
39 root 1.1
40 root 1.101 our $VERSION = 4.8;
41 root 1.39
42 root 1.32 our @DNS_FALLBACK = (v208.67.220.220, v208.67.222.222);
43    
44 root 1.4 =item AnyEvent::DNS::a $domain, $cb->(@addrs)
45    
46     Tries to resolve the given domain to IPv4 address(es).
47    
48 root 1.17 =item AnyEvent::DNS::aaaa $domain, $cb->(@addrs)
49    
50     Tries to resolve the given domain to IPv6 address(es).
51    
52 root 1.4 =item AnyEvent::DNS::mx $domain, $cb->(@hostnames)
53    
54     Tries to resolve the given domain into a sorted (lower preference value
55     first) list of domain names.
56    
57     =item AnyEvent::DNS::ns $domain, $cb->(@hostnames)
58    
59     Tries to resolve the given domain name into a list of name servers.
60    
61     =item AnyEvent::DNS::txt $domain, $cb->(@hostnames)
62    
63     Tries to resolve the given domain name into a list of text records.
64    
65     =item AnyEvent::DNS::srv $service, $proto, $domain, $cb->(@srv_rr)
66    
67     Tries to resolve the given service, protocol and domain name into a list
68     of service records.
69    
70 root 1.59 Each C<$srv_rr> is an array reference with the following contents:
71 root 1.4 C<[$priority, $weight, $transport, $target]>.
72    
73 root 1.49 They will be sorted with lowest priority first, then randomly
74     distributed by weight as per RFC 2782.
75 root 1.4
76     Example:
77    
78     AnyEvent::DNS::srv "sip", "udp", "schmorp.de", sub { ...
79     # @_ = ( [10, 10, 5060, "sip1.schmorp.de" ] )
80    
81 root 1.48 =item AnyEvent::DNS::ptr $domain, $cb->(@hostnames)
82    
83     Tries to make a PTR lookup on the given domain. See C<reverse_lookup>
84     and C<reverse_verify> if you want to resolve an IP address to a hostname
85     instead.
86    
87     =item AnyEvent::DNS::any $domain, $cb->(@rrs)
88    
89     Tries to resolve the given domain and passes all resource records found to
90     the callback.
91    
92     =item AnyEvent::DNS::reverse_lookup $ipv4_or_6, $cb->(@hostnames)
93 root 1.4
94     Tries to reverse-resolve the given IPv4 or IPv6 address (in textual form)
95 root 1.48 into it's hostname(s). Handles V4MAPPED and V4COMPAT IPv6 addresses
96     transparently.
97    
98     =item AnyEvent::DNS::reverse_verify $ipv4_or_6, $cb->(@hostnames)
99    
100     The same as C<reverse_lookup>, but does forward-lookups to verify that
101     the resolved hostnames indeed point to the address, which makes spoofing
102     harder.
103    
104     If you want to resolve an address into a hostname, this is the preferred
105     method: The DNS records could still change, but at least this function
106     verified that the hostname, at one point in the past, pointed at the IP
107     address you originally resolved.
108 root 1.4
109     Example:
110    
111     AnyEvent::DNS::ptr "2001:500:2f::f", sub { print shift };
112     # => f.root-servers.net
113    
114     =cut
115    
116 root 1.38 sub MAX_PKT() { 4096 } # max packet size we advertise and accept
117    
118     sub DOMAIN_PORT() { 53 } # if this changes drop me a note
119    
120 root 1.4 sub resolver;
121    
122     sub a($$) {
123     my ($domain, $cb) = @_;
124    
125     resolver->resolve ($domain => "a", sub {
126     $cb->(map $_->[3], @_);
127     });
128     }
129    
130 root 1.17 sub aaaa($$) {
131     my ($domain, $cb) = @_;
132    
133     resolver->resolve ($domain => "aaaa", sub {
134     $cb->(map $_->[3], @_);
135     });
136     }
137    
138 root 1.4 sub mx($$) {
139     my ($domain, $cb) = @_;
140    
141     resolver->resolve ($domain => "mx", sub {
142     $cb->(map $_->[4], sort { $a->[3] <=> $b->[3] } @_);
143     });
144     }
145    
146     sub ns($$) {
147     my ($domain, $cb) = @_;
148    
149     resolver->resolve ($domain => "ns", sub {
150     $cb->(map $_->[3], @_);
151     });
152     }
153    
154     sub txt($$) {
155     my ($domain, $cb) = @_;
156    
157     resolver->resolve ($domain => "txt", sub {
158     $cb->(map $_->[3], @_);
159     });
160     }
161    
162     sub srv($$$$) {
163     my ($service, $proto, $domain, $cb) = @_;
164    
165     # todo, ask for any and check glue records
166     resolver->resolve ("_$service._$proto.$domain" => "srv", sub {
167 root 1.49 my @res;
168    
169     # classify by priority
170     my %pri;
171     push @{ $pri{$_->[3]} }, [ @$_[3,4,5,6] ]
172     for @_;
173    
174     # order by priority
175 elmex 1.64 for my $pri (sort { $a <=> $b } keys %pri) {
176 root 1.49 # order by weight
177     my @rr = sort { $a->[1] <=> $b->[1] } @{ delete $pri{$pri} };
178    
179     my $sum; $sum += $_->[1] for @rr;
180    
181     while (@rr) {
182     my $w = int rand $sum + 1;
183     for (0 .. $#rr) {
184     if (($w -= $rr[$_][1]) <= 0) {
185     $sum -= $rr[$_][1];
186     push @res, splice @rr, $_, 1, ();
187     last;
188     }
189     }
190     }
191     }
192    
193     $cb->(@res);
194 root 1.4 });
195     }
196    
197     sub ptr($$) {
198 root 1.48 my ($domain, $cb) = @_;
199    
200     resolver->resolve ($domain => "ptr", sub {
201     $cb->(map $_->[3], @_);
202     });
203     }
204    
205     sub any($$) {
206     my ($domain, $cb) = @_;
207    
208     resolver->resolve ($domain => "*", $cb);
209     }
210    
211     # convert textual ip address into reverse lookup form
212     sub _munge_ptr($) {
213     my $ipn = $_[0]
214     or return;
215    
216     my $ptr;
217    
218     my $af = AnyEvent::Socket::address_family ($ipn);
219 root 1.4
220 root 1.48 if ($af == AF_INET6) {
221     $ipn = substr $ipn, 0, 16; # anticipate future expansion
222 root 1.4
223 root 1.48 # handle v4mapped and v4compat
224     if ($ipn =~ s/^\x00{10}(?:\xff\xff|\x00\x00)//) {
225     $af = AF_INET;
226     } else {
227     $ptr = join ".", (reverse split //, unpack "H32", $ipn), "ip6.arpa.";
228     }
229     }
230 root 1.37
231     if ($af == AF_INET) {
232 root 1.48 $ptr = join ".", (reverse unpack "C4", $ipn), "in-addr.arpa.";
233 root 1.4 }
234    
235 root 1.48 $ptr
236     }
237    
238     sub reverse_lookup($$) {
239     my ($ip, $cb) = @_;
240    
241     $ip = _munge_ptr AnyEvent::Socket::parse_address ($ip)
242     or return $cb->();
243    
244 root 1.17 resolver->resolve ($ip => "ptr", sub {
245 root 1.4 $cb->(map $_->[3], @_);
246     });
247     }
248 root 1.1
249 root 1.48 sub reverse_verify($$) {
250     my ($ip, $cb) = @_;
251    
252     my $ipn = AnyEvent::Socket::parse_address ($ip)
253     or return $cb->();
254    
255     my $af = AnyEvent::Socket::address_family ($ipn);
256    
257     my @res;
258     my $cnt;
259    
260     my $ptr = _munge_ptr $ipn
261     or return $cb->();
262    
263     $ip = AnyEvent::Socket::format_address ($ipn); # normalise into the same form
264    
265     ptr $ptr, sub {
266     for my $name (@_) {
267     ++$cnt;
268    
269     # () around AF_INET to work around bug in 5.8
270 root 1.55 resolver->resolve ("$name." => ($af == (AF_INET) ? "a" : "aaaa"), sub {
271 root 1.48 for (@_) {
272     push @res, $name
273     if $_->[3] eq $ip;
274     }
275     $cb->(@res) unless --$cnt;
276     });
277     }
278 root 1.5
279 root 1.48 $cb->() unless $cnt;
280     };
281 root 1.5 }
282    
283 root 1.36 #################################################################################
284 root 1.18
285 root 1.15 =back
286    
287 root 1.13 =head2 LOW-LEVEL DNS EN-/DECODING FUNCTIONS
288 root 1.1
289     =over 4
290    
291 root 1.11 =item $AnyEvent::DNS::EDNS0
292    
293 root 1.13 This variable decides whether dns_pack automatically enables EDNS0
294 root 1.24 support. By default, this is disabled (C<0>), unless overridden by
295 root 1.40 C<$ENV{PERL_ANYEVENT_EDNS0}>, but when set to C<1>, AnyEvent::DNS will use
296 root 1.21 EDNS0 in all requests.
297 root 1.11
298 root 1.1 =cut
299    
300 root 1.93 our $EDNS0 = $ENV{PERL_ANYEVENT_EDNS0}*1; # set to 1 to enable (partial) edns0
301 root 1.10
302 root 1.1 our %opcode_id = (
303     query => 0,
304     iquery => 1,
305     status => 2,
306 root 1.5 notify => 4,
307     update => 5,
308     map +($_ => $_), 3, 6..15
309 root 1.1 );
310    
311     our %opcode_str = reverse %opcode_id;
312    
313     our %rcode_id = (
314 root 1.5 noerror => 0,
315     formerr => 1,
316     servfail => 2,
317     nxdomain => 3,
318     notimp => 4,
319     refused => 5,
320     yxdomain => 6, # Name Exists when it should not [RFC 2136]
321     yxrrset => 7, # RR Set Exists when it should not [RFC 2136]
322     nxrrset => 8, # RR Set that should exist does not [RFC 2136]
323     notauth => 9, # Server Not Authoritative for zone [RFC 2136]
324     notzone => 10, # Name not contained in zone [RFC 2136]
325     # EDNS0 16 BADVERS Bad OPT Version [RFC 2671]
326     # EDNS0 16 BADSIG TSIG Signature Failure [RFC 2845]
327     # EDNS0 17 BADKEY Key not recognized [RFC 2845]
328     # EDNS0 18 BADTIME Signature out of time window [RFC 2845]
329     # EDNS0 19 BADMODE Bad TKEY Mode [RFC 2930]
330     # EDNS0 20 BADNAME Duplicate key name [RFC 2930]
331     # EDNS0 21 BADALG Algorithm not supported [RFC 2930]
332     map +($_ => $_), 11..15
333 root 1.1 );
334    
335     our %rcode_str = reverse %rcode_id;
336    
337     our %type_id = (
338     a => 1,
339     ns => 2,
340     md => 3,
341     mf => 4,
342     cname => 5,
343     soa => 6,
344     mb => 7,
345     mg => 8,
346     mr => 9,
347     null => 10,
348     wks => 11,
349     ptr => 12,
350     hinfo => 13,
351     minfo => 14,
352     mx => 15,
353     txt => 16,
354     aaaa => 28,
355     srv => 33,
356 root 1.47 naptr => 35, # rfc2915
357 root 1.90 dname => 39, # rfc2672
358 root 1.5 opt => 41,
359     spf => 99,
360     tkey => 249,
361     tsig => 250,
362     ixfr => 251,
363 root 1.1 axfr => 252,
364     mailb => 253,
365     "*" => 255,
366     );
367    
368     our %type_str = reverse %type_id;
369    
370     our %class_id = (
371 root 1.5 in => 1,
372     ch => 3,
373     hs => 4,
374     none => 254,
375     "*" => 255,
376 root 1.1 );
377    
378     our %class_str = reverse %class_id;
379    
380 root 1.34 sub _enc_name($) {
381 root 1.29 pack "(C/a*)*", (split /\./, shift), ""
382 root 1.1 }
383    
384     sub _enc_qd() {
385 root 1.34 (_enc_name $_->[0]) . pack "nn",
386 root 1.1 ($_->[1] > 0 ? $_->[1] : $type_id {$_->[1]}),
387     ($_->[2] > 0 ? $_->[2] : $class_id{$_->[2] || "in"})
388     }
389    
390     sub _enc_rr() {
391     die "encoding of resource records is not supported";
392     }
393    
394     =item $pkt = AnyEvent::DNS::dns_pack $dns
395    
396 root 1.50 Packs a perl data structure into a DNS packet. Reading RFC 1035 is strongly
397 root 1.1 recommended, then everything will be totally clear. Or maybe not.
398    
399     Resource records are not yet encodable.
400    
401     Examples:
402    
403 root 1.57 # very simple request, using lots of default values:
404     { rd => 1, qd => [ [ "host.domain", "a"] ] }
405    
406     # more complex example, showing how flags etc. are named:
407    
408     {
409     id => 10000,
410     op => "query",
411     rc => "nxdomain",
412    
413     # flags
414     qr => 1,
415     aa => 0,
416     tc => 0,
417     rd => 0,
418     ra => 0,
419     ad => 0,
420     cd => 0,
421    
422     qd => [@rr], # query section
423     an => [@rr], # answer section
424     ns => [@rr], # authority section
425     ar => [@rr], # additional records section
426     }
427 root 1.1
428     =cut
429    
430     sub dns_pack($) {
431     my ($req) = @_;
432    
433 root 1.7 pack "nn nnnn a* a* a* a* a*",
434 root 1.1 $req->{id},
435    
436     ! !$req->{qr} * 0x8000
437     + $opcode_id{$req->{op}} * 0x0800
438     + ! !$req->{aa} * 0x0400
439     + ! !$req->{tc} * 0x0200
440     + ! !$req->{rd} * 0x0100
441     + ! !$req->{ra} * 0x0080
442 root 1.5 + ! !$req->{ad} * 0x0020
443     + ! !$req->{cd} * 0x0010
444 root 1.1 + $rcode_id{$req->{rc}} * 0x0001,
445    
446     scalar @{ $req->{qd} || [] },
447     scalar @{ $req->{an} || [] },
448     scalar @{ $req->{ns} || [] },
449 root 1.44 $EDNS0 + scalar @{ $req->{ar} || [] }, # EDNS0 option included here
450 root 1.1
451     (join "", map _enc_qd, @{ $req->{qd} || [] }),
452     (join "", map _enc_rr, @{ $req->{an} || [] }),
453     (join "", map _enc_rr, @{ $req->{ns} || [] }),
454 root 1.7 (join "", map _enc_rr, @{ $req->{ar} || [] }),
455    
456 root 1.44 ($EDNS0 ? pack "C nnNn", 0, 41, MAX_PKT, 0, 0 : "") # EDNS0 option
457 root 1.1 }
458    
459     our $ofs;
460     our $pkt;
461    
462     # bitches
463 root 1.34 sub _dec_name {
464 root 1.1 my @res;
465     my $redir;
466     my $ptr = $ofs;
467     my $cnt;
468    
469     while () {
470     return undef if ++$cnt >= 256; # to avoid DoS attacks
471    
472     my $len = ord substr $pkt, $ptr++, 1;
473    
474 root 1.34 if ($len >= 0xc0) {
475 root 1.1 $ptr++;
476     $ofs = $ptr if $ptr > $ofs;
477     $ptr = (unpack "n", substr $pkt, $ptr - 2, 2) & 0x3fff;
478     } elsif ($len) {
479     push @res, substr $pkt, $ptr, $len;
480     $ptr += $len;
481     } else {
482     $ofs = $ptr if $ptr > $ofs;
483     return join ".", @res;
484     }
485     }
486     }
487    
488     sub _dec_qd {
489 root 1.34 my $qname = _dec_name;
490 root 1.1 my ($qt, $qc) = unpack "nn", substr $pkt, $ofs; $ofs += 4;
491     [$qname, $type_str{$qt} || $qt, $class_str{$qc} || $qc]
492     }
493    
494     our %dec_rr = (
495 root 1.29 1 => sub { join ".", unpack "C4", $_ }, # a
496 root 1.34 2 => sub { local $ofs = $ofs - length; _dec_name }, # ns
497     5 => sub { local $ofs = $ofs - length; _dec_name }, # cname
498 root 1.1 6 => sub {
499     local $ofs = $ofs - length;
500 root 1.34 my $mname = _dec_name;
501     my $rname = _dec_name;
502 root 1.1 ($mname, $rname, unpack "NNNNN", substr $pkt, $ofs)
503     }, # soa
504 root 1.29 11 => sub { ((join ".", unpack "C4", $_), unpack "C a*", substr $_, 4) }, # wks
505 root 1.34 12 => sub { local $ofs = $ofs - length; _dec_name }, # ptr
506 root 1.29 13 => sub { unpack "C/a* C/a*", $_ }, # hinfo
507 root 1.34 15 => sub { local $ofs = $ofs + 2 - length; ((unpack "n", $_), _dec_name) }, # mx
508 root 1.29 16 => sub { unpack "(C/a*)*", $_ }, # txt
509 root 1.100 28 => sub { AnyEvent::Socket::format_ipv6 ($_) }, # aaaa
510 root 1.34 33 => sub { local $ofs = $ofs + 6 - length; ((unpack "nnn", $_), _dec_name) }, # srv
511 root 1.47 35 => sub { # naptr
512 root 1.66 # requires perl 5.10, sorry
513 root 1.47 my ($order, $preference, $flags, $service, $regexp, $offset) = unpack "nn C/a* C/a* C/a* .", $_;
514     local $ofs = $ofs + $offset - length;
515     ($order, $preference, $flags, $service, $regexp, _dec_name)
516     },
517 root 1.90 39 => sub { local $ofs = $ofs - length; _dec_name }, # dname
518 root 1.29 99 => sub { unpack "(C/a*)*", $_ }, # spf
519 root 1.1 );
520    
521     sub _dec_rr {
522 root 1.34 my $name = _dec_name;
523 root 1.1
524     my ($rt, $rc, $ttl, $rdlen) = unpack "nn N n", substr $pkt, $ofs; $ofs += 10;
525     local $_ = substr $pkt, $ofs, $rdlen; $ofs += $rdlen;
526    
527     [
528 root 1.34 $name,
529 root 1.1 $type_str{$rt} || $rt,
530     $class_str{$rc} || $rc,
531     ($dec_rr{$rt} || sub { $_ })->(),
532     ]
533     }
534    
535     =item $dns = AnyEvent::DNS::dns_unpack $pkt
536    
537     Unpacks a DNS packet into a perl data structure.
538    
539     Examples:
540    
541 root 1.57 # an unsuccessful reply
542     {
543     'qd' => [
544     [ 'ruth.plan9.de.mach.uni-karlsruhe.de', '*', 'in' ]
545     ],
546     'rc' => 'nxdomain',
547     'ar' => [],
548     'ns' => [
549     [
550     'uni-karlsruhe.de',
551     'soa',
552     'in',
553     'netserv.rz.uni-karlsruhe.de',
554     'hostmaster.rz.uni-karlsruhe.de',
555     2008052201, 10800, 1800, 2592000, 86400
556     ]
557     ],
558     'tc' => '',
559     'ra' => 1,
560     'qr' => 1,
561     'id' => 45915,
562     'aa' => '',
563     'an' => [],
564     'rd' => 1,
565     'op' => 'query'
566     }
567    
568     # a successful reply
569    
570     {
571     'qd' => [ [ 'www.google.de', 'a', 'in' ] ],
572     'rc' => 0,
573     'ar' => [
574     [ 'a.l.google.com', 'a', 'in', '209.85.139.9' ],
575     [ 'b.l.google.com', 'a', 'in', '64.233.179.9' ],
576     [ 'c.l.google.com', 'a', 'in', '64.233.161.9' ],
577     ],
578     'ns' => [
579     [ 'l.google.com', 'ns', 'in', 'a.l.google.com' ],
580     [ 'l.google.com', 'ns', 'in', 'b.l.google.com' ],
581     ],
582     'tc' => '',
583     'ra' => 1,
584     'qr' => 1,
585     'id' => 64265,
586     'aa' => '',
587     'an' => [
588     [ 'www.google.de', 'cname', 'in', 'www.google.com' ],
589     [ 'www.google.com', 'cname', 'in', 'www.l.google.com' ],
590     [ 'www.l.google.com', 'a', 'in', '66.249.93.104' ],
591     [ 'www.l.google.com', 'a', 'in', '66.249.93.147' ],
592     ],
593     'rd' => 1,
594     'op' => 0
595     }
596 root 1.1
597     =cut
598    
599     sub dns_unpack($) {
600     local $pkt = shift;
601     my ($id, $flags, $qd, $an, $ns, $ar)
602     = unpack "nn nnnn A*", $pkt;
603    
604     local $ofs = 6 * 2;
605    
606     {
607     id => $id,
608     qr => ! ! ($flags & 0x8000),
609     aa => ! ! ($flags & 0x0400),
610     tc => ! ! ($flags & 0x0200),
611     rd => ! ! ($flags & 0x0100),
612     ra => ! ! ($flags & 0x0080),
613 root 1.5 ad => ! ! ($flags & 0x0020),
614     cd => ! ! ($flags & 0x0010),
615 root 1.1 op => $opcode_str{($flags & 0x001e) >> 11},
616     rc => $rcode_str{($flags & 0x000f)},
617    
618     qd => [map _dec_qd, 1 .. $qd],
619     an => [map _dec_rr, 1 .. $an],
620     ns => [map _dec_rr, 1 .. $ns],
621     ar => [map _dec_rr, 1 .. $ar],
622     }
623     }
624    
625     #############################################################################
626    
627     =back
628    
629     =head2 THE AnyEvent::DNS RESOLVER CLASS
630    
631 root 1.13 This is the class which does the actual protocol work.
632 root 1.1
633     =over 4
634    
635     =cut
636    
637     use Carp ();
638     use Scalar::Util ();
639     use Socket ();
640    
641     our $NOW;
642    
643 root 1.2 =item AnyEvent::DNS::resolver
644    
645     This function creates and returns a resolver that is ready to use and
646     should mimic the default resolver for your system as good as possible.
647    
648     It only ever creates one resolver and returns this one on subsequent
649     calls.
650    
651     Unless you have special needs, prefer this function over creating your own
652     resolver object.
653    
654 root 1.102 The resolver is created with the following parameters:
655    
656     untaint enabled
657     max_outstanding $ENV{PERL_ANYEVENT_MAX_OUTSTANDING_DNS}
658    
659     C<os_config> will be used for OS-specific configuration, unless
660     C<$ENV{PERL_ANYEVENT_RESOLV_CONF}> is specified, in which case that file
661     gets parsed.
662    
663 root 1.2 =cut
664    
665     our $RESOLVER;
666    
667     sub resolver() {
668     $RESOLVER || do {
669 root 1.102 $RESOLVER = new AnyEvent::DNS
670     untaint => 1,
671     exists $ENV{PERL_ANYEVENT_MAX_OUTSTANDING_DNS}
672     ? (max_outstanding => $ENV{PERL_ANYEVENT_MAX_OUTSTANDING_DNS}*1 || 1) : (),
673     ;
674    
675     exists $ENV{PERL_ANYEVENT_RESOLV_CONF}
676     ? length $ENV{PERL_ANYEVENT_RESOLV_CONF} && $RESOLVER->_parse_resolv_conf_file ($ENV{PERL_ANYEVENT_RESOLV_CONF})
677     : $RESOLVER->os_config;
678    
679 root 1.2 $RESOLVER
680     }
681     }
682    
683 root 1.1 =item $resolver = new AnyEvent::DNS key => value...
684    
685 root 1.6 Creates and returns a new resolver.
686 root 1.2
687     The following options are supported:
688 root 1.1
689     =over 4
690    
691     =item server => [...]
692    
693 root 1.41 A list of server addresses (default: C<v127.0.0.1>) in network format
694 root 1.42 (i.e. as returned by C<AnyEvent::Socket::parse_address> - both IPv4 and
695 root 1.41 IPv6 are supported).
696 root 1.1
697     =item timeout => [...]
698    
699     A list of timeouts to use (also determines the number of retries). To make
700     three retries with individual time-outs of 2, 5 and 5 seconds, use C<[2,
701     5, 5]>, which is also the default.
702    
703     =item search => [...]
704    
705     The default search list of suffixes to append to a domain name (default: none).
706    
707 root 1.2 =item ndots => $integer
708 root 1.1
709     The number of dots (default: C<1>) that a name must have so that the resolver
710     tries to resolve the name without any suffixes first.
711    
712 root 1.2 =item max_outstanding => $integer
713 root 1.1
714 root 1.43 Most name servers do not handle many parallel requests very well. This
715     option limits the number of outstanding requests to C<$integer>
716     (default: C<10>), that means if you request more than this many requests,
717     then the additional requests will be queued until some other requests have
718     been resolved.
719 root 1.1
720 root 1.13 =item reuse => $seconds
721    
722 root 1.22 The number of seconds (default: C<300>) that a query id cannot be re-used
723 root 1.54 after a timeout. If there was no time-out then query ids can be reused
724 root 1.22 immediately.
725 root 1.13
726 root 1.93 =item untaint => $boolean
727    
728     When true, then the resolver will automatically untaint results, and might
729     also ignore certain environment variables.
730    
731 root 1.1 =back
732    
733     =cut
734    
735     sub new {
736     my ($class, %arg) = @_;
737    
738     my $self = bless {
739 root 1.32 server => [],
740 root 1.1 timeout => [2, 5, 5],
741     search => [],
742     ndots => 1,
743     max_outstanding => 10,
744 root 1.54 reuse => 300,
745 root 1.1 %arg,
746     reuse_q => [],
747     }, $class;
748    
749     # search should default to gethostname's domain
750     # but perl lacks a good posix module
751    
752 root 1.63 # try to create an ipv4 and an ipv6 socket
753     # only fail when we cannot create either
754     my $got_socket;
755    
756 root 1.1 Scalar::Util::weaken (my $wself = $self);
757 root 1.38
758 root 1.63 if (socket my $fh4, AF_INET , &Socket::SOCK_DGRAM, 0) {
759     ++$got_socket;
760    
761 root 1.38 AnyEvent::Util::fh_nonblocking $fh4, 1;
762     $self->{fh4} = $fh4;
763     $self->{rw4} = AnyEvent->io (fh => $fh4, poll => "r", cb => sub {
764     if (my $peer = recv $fh4, my $pkt, MAX_PKT, 0) {
765     $wself->_recv ($pkt, $peer);
766     }
767     });
768     }
769    
770 root 1.63 if (AF_INET6 && socket my $fh6, AF_INET6, &Socket::SOCK_DGRAM, 0) {
771     ++$got_socket;
772    
773 root 1.38 $self->{fh6} = $fh6;
774     AnyEvent::Util::fh_nonblocking $fh6, 1;
775     $self->{rw6} = AnyEvent->io (fh => $fh6, poll => "r", cb => sub {
776     if (my $peer = recv $fh6, my $pkt, MAX_PKT, 0) {
777     $wself->_recv ($pkt, $peer);
778     }
779     });
780     }
781 root 1.1
782 root 1.63 $got_socket
783     or Carp::croak "unable to create either an IPv4 or an IPv6 socket";
784    
785 root 1.1 $self->_compile;
786    
787     $self
788     }
789    
790 root 1.102 =item $resolver->parse_resolv_conf ($string)
791 root 1.1
792 root 1.24 Parses the given string as if it were a F<resolv.conf> file. The following
793     directives are supported (but not necessarily implemented).
794 root 1.1
795     C<#>-style comments, C<nameserver>, C<domain>, C<search>, C<sortlist>,
796     C<options> (C<timeout>, C<attempts>, C<ndots>).
797    
798     Everything else is silently ignored.
799    
800     =cut
801    
802     sub parse_resolv_conf {
803     my ($self, $resolvconf) = @_;
804    
805     $self->{server} = [];
806     $self->{search} = [];
807    
808     my $attempts;
809    
810     for (split /\n/, $resolvconf) {
811     if (/^\s*#/) {
812     # comment
813     } elsif (/^\s*nameserver\s+(\S+)\s*$/i) {
814     my $ip = $1;
815 root 1.36 if (my $ipn = AnyEvent::Socket::parse_address ($ip)) {
816 root 1.25 push @{ $self->{server} }, $ipn;
817 root 1.1 } else {
818     warn "nameserver $ip invalid and ignored\n";
819     }
820     } elsif (/^\s*domain\s+(\S*)\s+$/i) {
821     $self->{search} = [$1];
822     } elsif (/^\s*search\s+(.*?)\s*$/i) {
823     $self->{search} = [split /\s+/, $1];
824     } elsif (/^\s*sortlist\s+(.*?)\s*$/i) {
825     # ignored, NYI
826     } elsif (/^\s*options\s+(.*?)\s*$/i) {
827     for (split /\s+/, $1) {
828     if (/^timeout:(\d+)$/) {
829     $self->{timeout} = [$1];
830     } elsif (/^attempts:(\d+)$/) {
831     $attempts = $1;
832     } elsif (/^ndots:(\d+)$/) {
833     $self->{ndots} = $1;
834     } else {
835     # debug, rotate, no-check-names, inet6
836     }
837     }
838     }
839     }
840    
841     $self->{timeout} = [($self->{timeout}[0]) x $attempts]
842     if $attempts;
843    
844     $self->_compile;
845     }
846    
847 root 1.102 sub _parse_resolv_conf_file {
848     my ($self, $resolv_conf) = @_;
849    
850     open my $fh, "<:perlio", $resolv_conf
851     or Carp::croak "$resolv_conf: $!";
852    
853     local $/;
854     $self->parse_resolv_conf (<$fh>);
855     }
856    
857 root 1.14 =item $resolver->os_config
858 root 1.1
859 root 1.93 Tries so load and parse F</etc/resolv.conf> on portable operating
860     systems. Tries various egregious hacks on windows to force the DNS servers
861     and searchlist out of the system.
862 root 1.1
863     =cut
864    
865 root 1.14 sub os_config {
866 root 1.1 my ($self) = @_;
867    
868 root 1.32 $self->{server} = [];
869     $self->{search} = [];
870    
871 root 1.102 if ((AnyEvent::WIN32 || $^O =~ /cygwin/i)) {
872 root 1.32 no strict 'refs';
873    
874     # there are many options to find the current nameservers etc. on windows
875     # all of them don't work consistently:
876     # - the registry thing needs separate code on win32 native vs. cygwin
877     # - the registry layout differs between windows versions
878     # - calling windows api functions doesn't work on cygwin
879     # - ipconfig uses locale-specific messages
880    
881 root 1.54 # we use ipconfig parsing because, despite all its brokenness,
882 root 1.32 # it seems most stable in practise.
883     # for good measure, we append a fallback nameserver to our list.
884 root 1.14
885     if (open my $fh, "ipconfig /all |") {
886 root 1.32 # parsing strategy: we go through the output and look for
887     # :-lines with DNS in them. everything in those is regarded as
888     # either a nameserver (if it parses as an ip address), or a suffix
889     # (all else).
890 root 1.14
891 root 1.32 my $dns;
892 root 1.14 while (<$fh>) {
893 root 1.32 if (s/^\s.*\bdns\b.*://i) {
894     $dns = 1;
895     } elsif (/^\S/ || /^\s[^:]{16,}: /) {
896     $dns = 0;
897     }
898     if ($dns && /^\s*(\S+)\s*$/) {
899     my $s = $1;
900 root 1.54 $s =~ s/%\d+(?!\S)//; # get rid of ipv6 scope id
901 root 1.36 if (my $ipn = AnyEvent::Socket::parse_address ($s)) {
902 root 1.32 push @{ $self->{server} }, $ipn;
903     } else {
904     push @{ $self->{search} }, $s;
905 root 1.14 }
906     }
907     }
908    
909 root 1.32 # always add one fallback server
910     push @{ $self->{server} }, $DNS_FALLBACK[rand @DNS_FALLBACK];
911 root 1.14
912     $self->_compile;
913     }
914     } else {
915 root 1.102 # try resolv.conf everywhere else
916 root 1.1
917 root 1.102 $self->_parse_resolv_conf_file ("/etc/resolv.conf")
918     if -e "/etc/resolv.conf";
919 root 1.14 }
920 root 1.1 }
921    
922 root 1.53 =item $resolver->timeout ($timeout, ...)
923    
924     Sets the timeout values. See the C<timeout> constructor argument (and note
925 root 1.54 that this method uses the values itself, not an array-reference).
926 root 1.53
927     =cut
928    
929     sub timeout {
930     my ($self, @timeout) = @_;
931    
932     $self->{timeout} = \@timeout;
933     $self->_compile;
934     }
935    
936     =item $resolver->max_outstanding ($nrequests)
937    
938     Sets the maximum number of outstanding requests to C<$nrequests>. See the
939     C<max_outstanding> constructor argument.
940    
941     =cut
942    
943     sub max_outstanding {
944     my ($self, $max) = @_;
945    
946     $self->{max_outstanding} = $max;
947     $self->_scheduler;
948     }
949    
950 root 1.1 sub _compile {
951     my $self = shift;
952    
953 root 1.38 my %search; $self->{search} = [grep 0 < length, grep !$search{$_}++, @{ $self->{search} }];
954     my %server; $self->{server} = [grep 0 < length, grep !$server{$_}++, @{ $self->{server} }];
955 root 1.32
956     unless (@{ $self->{server} }) {
957     # use 127.0.0.1 by default, and one opendns nameserver as fallback
958     $self->{server} = [v127.0.0.1, $DNS_FALLBACK[rand @DNS_FALLBACK]];
959     }
960    
961 root 1.1 my @retry;
962    
963     for my $timeout (@{ $self->{timeout} }) {
964     for my $server (@{ $self->{server} }) {
965     push @retry, [$server, $timeout];
966     }
967     }
968    
969     $self->{retry} = \@retry;
970     }
971    
972 root 1.6 sub _feed {
973     my ($self, $res) = @_;
974    
975 root 1.93 ($res) = $res =~ /^(.*)$/s
976     if AnyEvent::TAINT && $self->{untaint};
977    
978 root 1.6 $res = dns_unpack $res
979     or return;
980    
981     my $id = $self->{id}{$res->{id}};
982    
983     return unless ref $id;
984    
985     $NOW = time;
986     $id->[1]->($res);
987     }
988    
989 root 1.1 sub _recv {
990 root 1.38 my ($self, $pkt, $peer) = @_;
991 root 1.1
992 root 1.32 # we ignore errors (often one gets port unreachable, but there is
993     # no good way to take advantage of that.
994 root 1.1
995 root 1.38 my ($port, $host) = AnyEvent::Socket::unpack_sockaddr ($peer);
996    
997     return unless $port == 53 && grep $_ eq $host, @{ $self->{server} };
998 root 1.1
999 root 1.38 $self->_feed ($pkt);
1000 root 1.1 }
1001    
1002 root 1.22 sub _free_id {
1003     my ($self, $id, $timeout) = @_;
1004    
1005     if ($timeout) {
1006     # we need to block the id for a while
1007     $self->{id}{$id} = 1;
1008     push @{ $self->{reuse_q} }, [$NOW + $self->{reuse}, $id];
1009     } else {
1010     # we can quickly recycle the id
1011     delete $self->{id}{$id};
1012     }
1013    
1014     --$self->{outstanding};
1015     $self->_scheduler;
1016     }
1017    
1018     # execute a single request, involves sending it with timeouts to multiple servers
1019 root 1.1 sub _exec {
1020 root 1.22 my ($self, $req) = @_;
1021    
1022     my $retry; # of retries
1023     my $do_retry;
1024    
1025     $do_retry = sub {
1026     my $retry_cfg = $self->{retry}[$retry++]
1027     or do {
1028     # failure
1029     $self->_free_id ($req->[2], $retry > 1);
1030     undef $do_retry; return $req->[1]->();
1031     };
1032 root 1.1
1033     my ($server, $timeout) = @$retry_cfg;
1034    
1035     $self->{id}{$req->[2]} = [AnyEvent->timer (after => $timeout, cb => sub {
1036     $NOW = time;
1037    
1038     # timeout, try next
1039 root 1.70 &$do_retry if $do_retry;
1040 root 1.1 }), sub {
1041     my ($res) = @_;
1042    
1043 root 1.6 if ($res->{tc}) {
1044     # success, but truncated, so use tcp
1045 root 1.38 AnyEvent::Socket::tcp_connect (AnyEvent::Socket::format_address ($server), DOMAIN_PORT, sub {
1046 root 1.52 return unless $do_retry; # some other request could have invalidated us already
1047    
1048 root 1.6 my ($fh) = @_
1049 root 1.22 or return &$do_retry;
1050 root 1.6
1051 root 1.97 require AnyEvent::Handle;
1052    
1053 root 1.52 my $handle; $handle = new AnyEvent::Handle
1054 root 1.6 fh => $fh,
1055 root 1.52 timeout => $timeout,
1056 root 1.6 on_error => sub {
1057 root 1.52 undef $handle;
1058     return unless $do_retry; # some other request could have invalidated us already
1059 root 1.6 # failure, try next
1060 root 1.22 &$do_retry;
1061 root 1.6 };
1062    
1063     $handle->push_write (pack "n/a", $req->[0]);
1064 root 1.27 $handle->push_read (chunk => 2, sub {
1065     $handle->unshift_read (chunk => (unpack "n", $_[1]), sub {
1066 root 1.52 undef $handle;
1067 root 1.6 $self->_feed ($_[1]);
1068     });
1069     });
1070    
1071 root 1.17 }, sub { $timeout });
1072 root 1.1
1073 root 1.6 } else {
1074     # success
1075 root 1.22 $self->_free_id ($req->[2], $retry > 1);
1076     undef $do_retry; return $req->[1]->($res);
1077 root 1.6 }
1078 root 1.1 }];
1079 root 1.38
1080     my $sa = AnyEvent::Socket::pack_sockaddr (DOMAIN_PORT, $server);
1081    
1082 root 1.39 my $fh = AF_INET == Socket::sockaddr_family ($sa)
1083 root 1.38 ? $self->{fh4} : $self->{fh6}
1084     or return &$do_retry;
1085 root 1.1
1086 root 1.38 send $fh, $req->[0], 0, $sa;
1087 root 1.22 };
1088 root 1.1
1089 root 1.22 &$do_retry;
1090 root 1.1 }
1091    
1092     sub _scheduler {
1093     my ($self) = @_;
1094    
1095 root 1.51 no strict 'refs';
1096    
1097 root 1.1 $NOW = time;
1098    
1099     # first clear id reuse queue
1100     delete $self->{id}{ (shift @{ $self->{reuse_q} })->[1] }
1101 root 1.13 while @{ $self->{reuse_q} } && $self->{reuse_q}[0][0] <= $NOW;
1102 root 1.1
1103     while ($self->{outstanding} < $self->{max_outstanding}) {
1104 root 1.13
1105     if (@{ $self->{reuse_q} } >= 30000) {
1106     # we ran out of ID's, wait a bit
1107     $self->{reuse_to} ||= AnyEvent->timer (after => $self->{reuse_q}[0][0] - $NOW, cb => sub {
1108     delete $self->{reuse_to};
1109     $self->_scheduler;
1110     });
1111     last;
1112     }
1113    
1114 root 1.51 if (my $req = shift @{ $self->{queue} }) {
1115     # found a request in the queue, execute it
1116     while () {
1117     $req->[2] = int rand 65536;
1118     last unless exists $self->{id}{$req->[2]};
1119     }
1120    
1121     ++$self->{outstanding};
1122     $self->{id}{$req->[2]} = 1;
1123     substr $req->[0], 0, 2, pack "n", $req->[2];
1124    
1125     $self->_exec ($req);
1126    
1127     } elsif (my $cb = shift @{ $self->{wait} }) {
1128     # found a wait_for_slot callback, call that one first
1129     $cb->($self);
1130 root 1.1
1131 root 1.51 } else {
1132     # nothing to do, just exit
1133     last;
1134 root 1.1 }
1135     }
1136     }
1137    
1138     =item $resolver->request ($req, $cb->($res))
1139    
1140 root 1.54 This is the main low-level workhorse for sending DNS requests.
1141    
1142     This function sends a single request (a hash-ref formated as specified
1143     for C<dns_pack>) to the configured nameservers in turn until it gets a
1144     response. It handles timeouts, retries and automatically falls back to
1145     virtual circuit mode (TCP) when it receives a truncated reply.
1146    
1147     Calls the callback with the decoded response packet if a reply was
1148     received, or no arguments in case none of the servers answered.
1149 root 1.1
1150     =cut
1151    
1152     sub request($$) {
1153     my ($self, $req, $cb) = @_;
1154    
1155 root 1.3 push @{ $self->{queue} }, [dns_pack $req, $cb];
1156 root 1.1 $self->_scheduler;
1157     }
1158    
1159 root 1.80 =item $resolver->resolve ($qname, $qtype, %options, $cb->(@rr))
1160 root 1.1
1161 root 1.44 Queries the DNS for the given domain name C<$qname> of type C<$qtype>.
1162    
1163 root 1.54 A C<$qtype> is either a numerical query type (e.g. C<1> for A records) or
1164 root 1.44 a lowercase name (you have to look at the source to see which aliases are
1165 root 1.50 supported, but all types from RFC 1035, C<aaaa>, C<srv>, C<spf> and a few
1166 root 1.54 more are known to this module). A C<$qtype> of "*" is supported and means
1167 root 1.44 "any" record type.
1168 root 1.1
1169     The callback will be invoked with a list of matching result records or
1170     none on any error or if the name could not be found.
1171    
1172 root 1.61 CNAME chains (although illegal) are followed up to a length of 10.
1173 root 1.1
1174 root 1.83 The callback will be invoked with arraryefs of the form C<[$name, $type,
1175     $class, @data>], where C<$name> is the domain name, C<$type> a type string
1176     or number, C<$class> a class name and @data is resource-record-dependent
1177     data. For C<a> records, this will be the textual IPv4 addresses, for C<ns>
1178     or C<cname> records this will be a domain name, for C<txt> records these
1179     are all the strings and so on.
1180 root 1.44
1181 root 1.55 All types mentioned in RFC 1035, C<aaaa>, C<srv>, C<naptr> and C<spf> are
1182     decoded. All resource records not known to this module will have
1183 root 1.44 the raw C<rdata> field as fourth entry.
1184    
1185 root 1.24 Note that this resolver is just a stub resolver: it requires a name server
1186 root 1.3 supporting recursive queries, will not do any recursive queries itself and
1187     is not secure when used against an untrusted name server.
1188    
1189 root 1.1 The following options are supported:
1190    
1191     =over 4
1192    
1193     =item search => [$suffix...]
1194    
1195     Use the given search list (which might be empty), by appending each one
1196     in turn to the C<$qname>. If this option is missing then the configured
1197 root 1.55 C<ndots> and C<search> values define its value (depending on C<ndots>, the
1198     empty suffix will be prepended or appended to that C<search> value). If
1199     the C<$qname> ends in a dot, then the searchlist will be ignored.
1200 root 1.1
1201     =item accept => [$type...]
1202    
1203     Lists the acceptable result types: only result types in this set will be
1204     accepted and returned. The default includes the C<$qtype> and nothing
1205 root 1.44 else. If this list includes C<cname>, then CNAME-chains will not be
1206     followed (because you asked for the CNAME record).
1207 root 1.1
1208     =item class => "class"
1209    
1210     Specify the query class ("in" for internet, "ch" for chaosnet and "hs" for
1211 root 1.2 hesiod are the only ones making sense). The default is "in", of course.
1212 root 1.1
1213     =back
1214    
1215     Examples:
1216    
1217 root 1.46 # full example, you can paste this into perl:
1218 root 1.45 use Data::Dumper;
1219     use AnyEvent::DNS;
1220     AnyEvent::DNS::resolver->resolve (
1221     "google.com", "*", my $cv = AnyEvent->condvar);
1222     warn Dumper [$cv->recv];
1223    
1224     # shortened result:
1225     # [
1226     # [ 'google.com', 'soa', 'in', 'ns1.google.com', 'dns-admin.google.com',
1227     # 2008052701, 7200, 1800, 1209600, 300 ],
1228     # [
1229     # 'google.com', 'txt', 'in',
1230     # 'v=spf1 include:_netblocks.google.com ~all'
1231     # ],
1232     # [ 'google.com', 'a', 'in', '64.233.187.99' ],
1233     # [ 'google.com', 'mx', 'in', 10, 'smtp2.google.com' ],
1234     # [ 'google.com', 'ns', 'in', 'ns2.google.com' ],
1235     # ]
1236    
1237     # resolve a records:
1238     $res->resolve ("ruth.plan9.de", "a", sub { warn Dumper [@_] });
1239    
1240     # result:
1241     # [
1242     # [ 'ruth.schmorp.de', 'a', 'in', '129.13.162.95' ]
1243     # ]
1244 root 1.1
1245 root 1.45 # resolve any records, but return only a and aaaa records:
1246 root 1.1 $res->resolve ("test1.laendle", "*",
1247     accept => ["a", "aaaa"],
1248     sub {
1249     warn Dumper [@_];
1250     }
1251     );
1252    
1253 root 1.45 # result:
1254     # [
1255     # [ 'test1.laendle', 'a', 'in', '10.0.0.255' ],
1256     # [ 'test1.laendle', 'aaaa', 'in', '3ffe:1900:4545:0002:0240:0000:0000:f7e1' ]
1257     # ]
1258 root 1.1
1259     =cut
1260    
1261     sub resolve($%) {
1262     my $cb = pop;
1263     my ($self, $qname, $qtype, %opt) = @_;
1264    
1265     my @search = $qname =~ s/\.$//
1266     ? ""
1267     : $opt{search}
1268     ? @{ $opt{search} }
1269     : ($qname =~ y/.//) >= $self->{ndots}
1270     ? ("", @{ $self->{search} })
1271     : (@{ $self->{search} }, "");
1272    
1273     my $class = $opt{class} || "in";
1274    
1275     my %atype = $opt{accept}
1276     ? map +($_ => 1), @{ $opt{accept} }
1277     : ($qtype => 1);
1278    
1279     # advance in searchlist
1280 root 1.22 my ($do_search, $do_req);
1281    
1282     $do_search = sub {
1283 root 1.1 @search
1284 root 1.22 or (undef $do_search), (undef $do_req), return $cb->();
1285 root 1.1
1286 root 1.4 (my $name = lc "$qname." . shift @search) =~ s/\.$//;
1287 root 1.61 my $depth = 10;
1288 root 1.1
1289     # advance in cname-chain
1290 root 1.22 $do_req = sub {
1291 root 1.1 $self->request ({
1292     rd => 1,
1293     qd => [[$name, $qtype, $class]],
1294     }, sub {
1295     my ($res) = @_
1296     or return $do_search->();
1297    
1298     my $cname;
1299    
1300     while () {
1301 root 1.2 # results found?
1302 root 1.4 my @rr = grep $name eq lc $_->[0] && ($atype{"*"} || $atype{$_->[1]}), @{ $res->{an} };
1303 root 1.1
1304 root 1.22 (undef $do_search), (undef $do_req), return $cb->(@rr)
1305 root 1.1 if @rr;
1306    
1307     # see if there is a cname we can follow
1308 root 1.4 my @rr = grep $name eq lc $_->[0] && $_->[1] eq "cname", @{ $res->{an} };
1309 root 1.1
1310     if (@rr) {
1311     $depth--
1312     or return $do_search->(); # cname chain too long
1313    
1314     $cname = 1;
1315 root 1.99 $name = lc $rr[0][3];
1316 root 1.1
1317     } elsif ($cname) {
1318     # follow the cname
1319     return $do_req->();
1320    
1321     } else {
1322 root 1.2 # no, not found anything
1323 root 1.1 return $do_search->();
1324     }
1325     }
1326     });
1327     };
1328    
1329     $do_req->();
1330     };
1331    
1332     $do_search->();
1333     }
1334    
1335 root 1.51 =item $resolver->wait_for_slot ($cb->($resolver))
1336    
1337     Wait until a free request slot is available and call the callback with the
1338     resolver object.
1339    
1340     A request slot is used each time a request is actually sent to the
1341     nameservers: There are never more than C<max_outstanding> of them.
1342    
1343     Although you can submit more requests (they will simply be queued until
1344     a request slot becomes available), sometimes, usually for rate-limiting
1345     purposes, it is useful to instead wait for a slot before generating the
1346     request (or simply to know when the request load is low enough so one can
1347     submit requests again).
1348    
1349     This is what this method does: The callback will be called when submitting
1350     a DNS request will not result in that request being queued. The callback
1351     may or may not generate any requests in response.
1352    
1353     Note that the callback will only be invoked when the request queue is
1354     empty, so this does not play well if somebody else keeps the request queue
1355     full at all times.
1356    
1357     =cut
1358    
1359     sub wait_for_slot {
1360     my ($self, $cb) = @_;
1361    
1362     push @{ $self->{wait} }, $cb;
1363     $self->_scheduler;
1364     }
1365    
1366 root 1.17 use AnyEvent::Socket (); # circular dependency, so do not import anything and do it at the end
1367    
1368 root 1.1 1;
1369    
1370     =back
1371    
1372     =head1 AUTHOR
1373    
1374 root 1.58 Marc Lehmann <schmorp@schmorp.de>
1375     http://home.schmorp.de/
1376 root 1.1
1377     =cut
1378