… | |
… | |
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 | |
395 | Packs a perl data structure into a DNS packet. Reading RFC1034 is strongly |
395 | Packs a perl data structure into a DNS packet. Reading RFC 1035 is strongly |
396 | recommended, then everything will be totally clear. Or maybe not. |
396 | recommended, then everything will be totally clear. Or maybe not. |
397 | |
397 | |
398 | Resource records are not yet encodable. |
398 | Resource records are not yet encodable. |
399 | |
399 | |
400 | Examples: |
400 | Examples: |
… | |
… | |
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 | |
|
|
888 | Sets the timeout values. See the C<timeout> constructor argument (and note |
|
|
889 | that this method uses the values itselt, not an array-reference). |
|
|
890 | |
|
|
891 | =cut |
|
|
892 | |
|
|
893 | sub timeout { |
|
|
894 | my ($self, @timeout) = @_; |
|
|
895 | |
|
|
896 | $self->{timeout} = \@timeout; |
|
|
897 | $self->_compile; |
|
|
898 | } |
|
|
899 | |
|
|
900 | =item $resolver->max_outstanding ($nrequests) |
|
|
901 | |
|
|
902 | Sets the maximum number of outstanding requests to C<$nrequests>. See the |
|
|
903 | C<max_outstanding> constructor argument. |
|
|
904 | |
|
|
905 | =cut |
|
|
906 | |
|
|
907 | sub max_outstanding { |
|
|
908 | my ($self, $max) = @_; |
|
|
909 | |
|
|
910 | $self->{max_outstanding} = $max; |
|
|
911 | $self->_scheduler; |
|
|
912 | } |
|
|
913 | |
886 | sub _compile { |
914 | sub _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 | |
1018 | sub _scheduler { |
1051 | sub _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 | |
1072 | Queries the DNS for the given domain name C<$qname> of type C<$qtype>. |
1115 | Queries the DNS for the given domain name C<$qname> of type C<$qtype>. |
1073 | |
1116 | |
1074 | A C<$qtype> is either a numerical query type (e.g. C<1> for A recods) or |
1117 | A C<$qtype> is either a numerical query type (e.g. C<1> for A recods) or |
1075 | a lowercase name (you have to look at the source to see which aliases are |
1118 | a lowercase name (you have to look at the source to see which aliases are |
1076 | supported, but all types from RFC 1034, C<aaaa>, C<srv>, C<spf> and a few |
1119 | supported, but all types from RFC 1035, C<aaaa>, C<srv>, C<spf> and a few |
1077 | more are known to this module). A qtype of "*" is supported and means |
1120 | more are known to this module). A qtype of "*" is supported and means |
1078 | "any" record type. |
1121 | "any" record type. |
1079 | |
1122 | |
1080 | The callback will be invoked with a list of matching result records or |
1123 | The callback will be invoked with a list of matching result records or |
1081 | none on any error or if the name could not be found. |
1124 | none on any error or if the name could not be found. |
… | |
… | |
1089 | the domain name, C<$type> a type string or number, C<$class> a class name |
1132 | the domain name, C<$type> a type string or number, C<$class> a class name |
1090 | and @data is resource-record-dependent data. For C<a> records, this will |
1133 | and @data is resource-record-dependent data. For C<a> records, this will |
1091 | be the textual IPv4 addresses, for C<ns> or C<cname> records this will be |
1134 | be the textual IPv4 addresses, for C<ns> or C<cname> records this will be |
1092 | a domain name, for C<txt> records these are all the strings and so on. |
1135 | a domain name, for C<txt> records these are all the strings and so on. |
1093 | |
1136 | |
1094 | All types mentioned in RFC 1034, C<aaaa>, C<srv> and C<spf> are |
1137 | All types mentioned in RFC 1035, C<aaaa>, C<srv> and C<spf> are |
1095 | decoded. All resource records not known to this module will just return |
1138 | decoded. All resource records not known to this module will just return |
1096 | the raw C<rdata> field as fourth entry. |
1139 | the raw C<rdata> field as fourth entry. |
1097 | |
1140 | |
1098 | Note that this resolver is just a stub resolver: it requires a name server |
1141 | Note that this resolver is just a stub resolver: it requires a name server |
1099 | supporting recursive queries, will not do any recursive queries itself and |
1142 | supporting 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 | |
|
|
1292 | Wait until a free request slot is available and call the callback with the |
|
|
1293 | resolver object. |
|
|
1294 | |
|
|
1295 | A request slot is used each time a request is actually sent to the |
|
|
1296 | nameservers: There are never more than C<max_outstanding> of them. |
|
|
1297 | |
|
|
1298 | Although you can submit more requests (they will simply be queued until |
|
|
1299 | a request slot becomes available), sometimes, usually for rate-limiting |
|
|
1300 | purposes, it is useful to instead wait for a slot before generating the |
|
|
1301 | request (or simply to know when the request load is low enough so one can |
|
|
1302 | submit requests again). |
|
|
1303 | |
|
|
1304 | This is what this method does: The callback will be called when submitting |
|
|
1305 | a DNS request will not result in that request being queued. The callback |
|
|
1306 | may or may not generate any requests in response. |
|
|
1307 | |
|
|
1308 | Note that the callback will only be invoked when the request queue is |
|
|
1309 | empty, so this does not play well if somebody else keeps the request queue |
|
|
1310 | full at all times. |
|
|
1311 | |
|
|
1312 | =cut |
|
|
1313 | |
|
|
1314 | sub wait_for_slot { |
|
|
1315 | my ($self, $cb) = @_; |
|
|
1316 | |
|
|
1317 | push @{ $self->{wait} }, $cb; |
|
|
1318 | $self->_scheduler; |
|
|
1319 | } |
|
|
1320 | |
1247 | use AnyEvent::Socket (); # circular dependency, so do not import anything and do it at the end |
1321 | use AnyEvent::Socket (); # circular dependency, so do not import anything and do it at the end |
1248 | |
1322 | |
1249 | 1; |
1323 | 1; |
1250 | |
1324 | |
1251 | =back |
1325 | =back |