ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent/lib/AnyEvent/DNS.pm
(Generate patch)

Comparing AnyEvent/lib/AnyEvent/DNS.pm (file contents):
Revision 1.49 by root, Thu May 29 22:34:51 2008 UTC vs.
Revision 1.53 by root, Fri May 30 09:40:41 2008 UTC

390 die "encoding of resource records is not supported"; 390 die "encoding of resource records is not supported";
391} 391}
392 392
393=item $pkt = AnyEvent::DNS::dns_pack $dns 393=item $pkt = AnyEvent::DNS::dns_pack $dns
394 394
395Packs a perl data structure into a DNS packet. Reading RFC1034 is strongly 395Packs a perl data structure into a DNS packet. Reading RFC 1035 is strongly
396recommended, then everything will be totally clear. Or maybe not. 396recommended, then everything will be totally clear. Or maybe not.
397 397
398Resource records are not yet encodable. 398Resource records are not yet encodable.
399 399
400Examples: 400Examples:
881 $self->parse_resolv_conf (<$fh>); 881 $self->parse_resolv_conf (<$fh>);
882 } 882 }
883 } 883 }
884} 884}
885 885
886=item $resolver->timeout ($timeout, ...)
887
888Sets the timeout values. See the C<timeout> constructor argument (and note
889that this method uses the values itselt, not an array-reference).
890
891=cut
892
893sub timeout {
894 my ($self, @timeout) = @_;
895
896 $self->{timeout} = \@timeout;
897 $self->_compile;
898}
899
900=item $resolver->max_outstanding ($nrequests)
901
902Sets the maximum number of outstanding requests to C<$nrequests>. See the
903C<max_outstanding> constructor argument.
904
905=cut
906
907sub max_outstanding {
908 my ($self, $max) = @_;
909
910 $self->{max_outstanding} = $max;
911 $self->_scheduler;
912}
913
886sub _compile { 914sub _compile {
887 my $self = shift; 915 my $self = shift;
888 916
889 my %search; $self->{search} = [grep 0 < length, grep !$search{$_}++, @{ $self->{search} }]; 917 my %search; $self->{search} = [grep 0 < length, grep !$search{$_}++, @{ $self->{search} }];
890 my %server; $self->{server} = [grep 0 < length, grep !$server{$_}++, @{ $self->{server} }]; 918 my %server; $self->{server} = [grep 0 < length, grep !$server{$_}++, @{ $self->{server} }];
974 my ($res) = @_; 1002 my ($res) = @_;
975 1003
976 if ($res->{tc}) { 1004 if ($res->{tc}) {
977 # success, but truncated, so use tcp 1005 # success, but truncated, so use tcp
978 AnyEvent::Socket::tcp_connect (AnyEvent::Socket::format_address ($server), DOMAIN_PORT, sub { 1006 AnyEvent::Socket::tcp_connect (AnyEvent::Socket::format_address ($server), DOMAIN_PORT, sub {
1007 return unless $do_retry; # some other request could have invalidated us already
1008
979 my ($fh) = @_ 1009 my ($fh) = @_
980 or return &$do_retry; 1010 or return &$do_retry;
981 1011
982 my $handle = new AnyEvent::Handle 1012 my $handle; $handle = new AnyEvent::Handle
983 fh => $fh, 1013 fh => $fh,
1014 timeout => $timeout,
984 on_error => sub { 1015 on_error => sub {
1016 undef $handle;
1017 return unless $do_retry; # some other request could have invalidated us already
985 # failure, try next 1018 # failure, try next
986 &$do_retry; 1019 &$do_retry;
987 }; 1020 };
988 1021
989 $handle->push_write (pack "n/a", $req->[0]); 1022 $handle->push_write (pack "n/a", $req->[0]);
990 $handle->push_read (chunk => 2, sub { 1023 $handle->push_read (chunk => 2, sub {
991 $handle->unshift_read (chunk => (unpack "n", $_[1]), sub { 1024 $handle->unshift_read (chunk => (unpack "n", $_[1]), sub {
1025 undef $handle;
992 $self->_feed ($_[1]); 1026 $self->_feed ($_[1]);
993 }); 1027 });
994 }); 1028 });
995 shutdown $fh, 1;
996 1029
997 }, sub { $timeout }); 1030 }, sub { $timeout });
998 1031
999 } else { 1032 } else {
1000 # success 1033 # success
1016} 1049}
1017 1050
1018sub _scheduler { 1051sub _scheduler {
1019 my ($self) = @_; 1052 my ($self) = @_;
1020 1053
1054 no strict 'refs';
1055
1021 $NOW = time; 1056 $NOW = time;
1022 1057
1023 # first clear id reuse queue 1058 # first clear id reuse queue
1024 delete $self->{id}{ (shift @{ $self->{reuse_q} })->[1] } 1059 delete $self->{id}{ (shift @{ $self->{reuse_q} })->[1] }
1025 while @{ $self->{reuse_q} } && $self->{reuse_q}[0][0] <= $NOW; 1060 while @{ $self->{reuse_q} } && $self->{reuse_q}[0][0] <= $NOW;
1033 $self->_scheduler; 1068 $self->_scheduler;
1034 }); 1069 });
1035 last; 1070 last;
1036 } 1071 }
1037 1072
1038 my $req = shift @{ $self->{queue} } 1073 if (my $req = shift @{ $self->{queue} }) {
1039 or last; 1074 # found a request in the queue, execute it
1040
1041 while () { 1075 while () {
1042 $req->[2] = int rand 65536; 1076 $req->[2] = int rand 65536;
1043 last unless exists $self->{id}{$req->[2]}; 1077 last unless exists $self->{id}{$req->[2]};
1078 }
1079
1080 ++$self->{outstanding};
1081 $self->{id}{$req->[2]} = 1;
1082 substr $req->[0], 0, 2, pack "n", $req->[2];
1083
1084 $self->_exec ($req);
1085
1086 } elsif (my $cb = shift @{ $self->{wait} }) {
1087 # found a wait_for_slot callback, call that one first
1088 $cb->($self);
1089
1090 } else {
1091 # nothing to do, just exit
1092 last;
1044 } 1093 }
1045
1046 ++$self->{outstanding};
1047 $self->{id}{$req->[2]} = 1;
1048 substr $req->[0], 0, 2, pack "n", $req->[2];
1049
1050 $self->_exec ($req);
1051 } 1094 }
1052} 1095}
1053 1096
1054=item $resolver->request ($req, $cb->($res)) 1097=item $resolver->request ($req, $cb->($res))
1055 1098
1071 1114
1072Queries the DNS for the given domain name C<$qname> of type C<$qtype>. 1115Queries the DNS for the given domain name C<$qname> of type C<$qtype>.
1073 1116
1074A C<$qtype> is either a numerical query type (e.g. C<1> for A recods) or 1117A C<$qtype> is either a numerical query type (e.g. C<1> for A recods) or
1075a lowercase name (you have to look at the source to see which aliases are 1118a lowercase name (you have to look at the source to see which aliases are
1076supported, but all types from RFC 1034, C<aaaa>, C<srv>, C<spf> and a few 1119supported, but all types from RFC 1035, C<aaaa>, C<srv>, C<spf> and a few
1077more are known to this module). A qtype of "*" is supported and means 1120more are known to this module). A qtype of "*" is supported and means
1078"any" record type. 1121"any" record type.
1079 1122
1080The callback will be invoked with a list of matching result records or 1123The callback will be invoked with a list of matching result records or
1081none on any error or if the name could not be found. 1124none on any error or if the name could not be found.
1089the domain name, C<$type> a type string or number, C<$class> a class name 1132the domain name, C<$type> a type string or number, C<$class> a class name
1090and @data is resource-record-dependent data. For C<a> records, this will 1133and @data is resource-record-dependent data. For C<a> records, this will
1091be the textual IPv4 addresses, for C<ns> or C<cname> records this will be 1134be the textual IPv4 addresses, for C<ns> or C<cname> records this will be
1092a domain name, for C<txt> records these are all the strings and so on. 1135a domain name, for C<txt> records these are all the strings and so on.
1093 1136
1094All types mentioned in RFC 1034, C<aaaa>, C<srv> and C<spf> are 1137All types mentioned in RFC 1035, C<aaaa>, C<srv> and C<spf> are
1095decoded. All resource records not known to this module will just return 1138decoded. All resource records not known to this module will just return
1096the raw C<rdata> field as fourth entry. 1139the raw C<rdata> field as fourth entry.
1097 1140
1098Note that this resolver is just a stub resolver: it requires a name server 1141Note that this resolver is just a stub resolver: it requires a name server
1099supporting recursive queries, will not do any recursive queries itself and 1142supporting recursive queries, will not do any recursive queries itself and
1242 }; 1285 };
1243 1286
1244 $do_search->(); 1287 $do_search->();
1245} 1288}
1246 1289
1290=item $resolver->wait_for_slot ($cb->($resolver))
1291
1292Wait until a free request slot is available and call the callback with the
1293resolver object.
1294
1295A request slot is used each time a request is actually sent to the
1296nameservers: There are never more than C<max_outstanding> of them.
1297
1298Although you can submit more requests (they will simply be queued until
1299a request slot becomes available), sometimes, usually for rate-limiting
1300purposes, it is useful to instead wait for a slot before generating the
1301request (or simply to know when the request load is low enough so one can
1302submit requests again).
1303
1304This is what this method does: The callback will be called when submitting
1305a DNS request will not result in that request being queued. The callback
1306may or may not generate any requests in response.
1307
1308Note that the callback will only be invoked when the request queue is
1309empty, so this does not play well if somebody else keeps the request queue
1310full at all times.
1311
1312=cut
1313
1314sub wait_for_slot {
1315 my ($self, $cb) = @_;
1316
1317 push @{ $self->{wait} }, $cb;
1318 $self->_scheduler;
1319}
1320
1247use AnyEvent::Socket (); # circular dependency, so do not import anything and do it at the end 1321use AnyEvent::Socket (); # circular dependency, so do not import anything and do it at the end
1248 1322
12491; 13231;
1250 1324
1251=back 1325=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines