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.47 by root, Thu May 29 17:51:33 2008 UTC vs.
Revision 1.48 by root, Thu May 29 22:02:19 2008 UTC

76Example: 76Example:
77 77
78 AnyEvent::DNS::srv "sip", "udp", "schmorp.de", sub { ... 78 AnyEvent::DNS::srv "sip", "udp", "schmorp.de", sub { ...
79 # @_ = ( [10, 10, 5060, "sip1.schmorp.de" ] ) 79 # @_ = ( [10, 10, 5060, "sip1.schmorp.de" ] )
80 80
81=item AnyEvent::DNS::ptr $ipv4_or_6, $cb->(@hostnames) 81=item AnyEvent::DNS::ptr $domain, $cb->(@hostnames)
82
83Tries to make a PTR lookup on the given domain. See C<reverse_lookup>
84and C<reverse_verify> if you want to resolve an IP address to a hostname
85instead.
86
87=item AnyEvent::DNS::any $domain, $cb->(@rrs)
88
89Tries to resolve the given domain and passes all resource records found to
90the callback.
91
92=item AnyEvent::DNS::reverse_lookup $ipv4_or_6, $cb->(@hostnames)
82 93
83Tries to reverse-resolve the given IPv4 or IPv6 address (in textual form) 94Tries to reverse-resolve the given IPv4 or IPv6 address (in textual form)
84into it's hostname(s). 95into it's hostname(s). Handles V4MAPPED and V4COMPAT IPv6 addresses
96transparently.
97
98=item AnyEvent::DNS::reverse_verify $ipv4_or_6, $cb->(@hostnames)
99
100The same as C<reverse_lookup>, but does forward-lookups to verify that
101the resolved hostnames indeed point to the address, which makes spoofing
102harder.
103
104If you want to resolve an address into a hostname, this is the preferred
105method: The DNS records could still change, but at least this function
106verified that the hostname, at one point in the past, pointed at the IP
107address you originally resolved.
85 108
86Example: 109Example:
87 110
88 AnyEvent::DNS::ptr "2001:500:2f::f", sub { print shift }; 111 AnyEvent::DNS::ptr "2001:500:2f::f", sub { print shift };
89 # => f.root-servers.net 112 # => f.root-servers.net
90
91=item AnyEvent::DNS::any $domain, $cb->(@rrs)
92
93Tries to resolve the given domain and passes all resource records found to
94the callback.
95 113
96=cut 114=cut
97 115
98sub MAX_PKT() { 4096 } # max packet size we advertise and accept 116sub MAX_PKT() { 4096 } # max packet size we advertise and accept
99 117
149 $cb->(map [@$_[3,4,5,6]], sort { $a->[3] <=> $b->[3] || $b->[4] <=> $a->[4] } @_); 167 $cb->(map [@$_[3,4,5,6]], sort { $a->[3] <=> $b->[3] || $b->[4] <=> $a->[4] } @_);
150 }); 168 });
151} 169}
152 170
153sub ptr($$) { 171sub ptr($$) {
172 my ($domain, $cb) = @_;
173
174 resolver->resolve ($domain => "ptr", sub {
175 $cb->(map $_->[3], @_);
176 });
177}
178
179sub any($$) {
180 my ($domain, $cb) = @_;
181
182 resolver->resolve ($domain => "*", $cb);
183}
184
185# convert textual ip address into reverse lookup form
186sub _munge_ptr($) {
187 my $ipn = $_[0]
188 or return;
189
190 my $ptr;
191
192 my $af = AnyEvent::Socket::address_family ($ipn);
193
194 if ($af == AF_INET6) {
195 $ipn = substr $ipn, 0, 16; # anticipate future expansion
196
197 # handle v4mapped and v4compat
198 if ($ipn =~ s/^\x00{10}(?:\xff\xff|\x00\x00)//) {
199 $af = AF_INET;
200 } else {
201 $ptr = join ".", (reverse split //, unpack "H32", $ipn), "ip6.arpa.";
202 }
203 }
204
205 if ($af == AF_INET) {
206 $ptr = join ".", (reverse unpack "C4", $ipn), "in-addr.arpa.";
207 }
208
209 $ptr
210}
211
212sub reverse_lookup($$) {
154 my ($ip, $cb) = @_; 213 my ($ip, $cb) = @_;
155 214
156 $ip = AnyEvent::Socket::parse_address ($ip) 215 $ip = _munge_ptr AnyEvent::Socket::parse_address ($ip)
157 or return $cb->(); 216 or return $cb->();
158
159 my $af = AnyEvent::Socket::address_family ($ip);
160
161 if ($af == AF_INET) {
162 $ip = join ".", (reverse split /\./, $ip), "in-addr.arpa.";
163 } elsif ($af == AF_INET6) {
164 $ip = join ".", (reverse split //, unpack "H*", $ip), "ip6.arpa.";
165 } else {
166 return $cb->();
167 }
168 217
169 resolver->resolve ($ip => "ptr", sub { 218 resolver->resolve ($ip => "ptr", sub {
170 $cb->(map $_->[3], @_); 219 $cb->(map $_->[3], @_);
171 }); 220 });
172} 221}
173 222
174sub any($$) { 223sub reverse_verify($$) {
175 my ($domain, $cb) = @_; 224 my ($ip, $cb) = @_;
225
226 my $ipn = AnyEvent::Socket::parse_address ($ip)
227 or return $cb->();
176 228
177 resolver->resolve ($domain => "*", $cb); 229 my $af = AnyEvent::Socket::address_family ($ipn);
230
231 my @res;
232 my $cnt;
233
234 my $ptr = _munge_ptr $ipn
235 or return $cb->();
236
237 $ip = AnyEvent::Socket::format_address ($ipn); # normalise into the same form
238
239 ptr $ptr, sub {
240 for my $name (@_) {
241 ++$cnt;
242
243 # () around AF_INET to work around bug in 5.8
244 resolver->resolve ($name => ($af == (AF_INET) ? "a" : "aaaa"), sub {
245 for (@_) {
246 push @res, $name
247 if $_->[3] eq $ip;
248 }
249 $cb->(@res) unless --$cnt;
250 });
251 }
252
253 $cb->() unless $cnt;
254 };
178} 255}
179 256
180################################################################################# 257#################################################################################
181 258
182=back 259=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines