File Coverage

blib/lib/Net/DNS/Resolver/Base.pm
Criterion Covered Total %
statement 613 616 99.5
branch 263 266 99.6
condition 68 70 97.1
subroutine 89 89 100.0
pod 24 29 100.0
total 1057 1070 99.4


line stmt bran cond sub pod time code
1             package Net::DNS::Resolver::Base;
2              
3 92     92   822 use strict;
  92         186  
  92         3933  
4 92     92   547 use warnings;
  92         234  
  92         10352  
5             our $VERSION = (qw$Id: Base.pm 2031 2025-07-28 13:52:18Z willem $)[2];
6              
7              
8             #
9             # Implementation notes wrt IPv6 support when using perl before 5.20.0.
10             #
11             # In general we try to be gracious to those stacks that do not have IPv6 support.
12             # The socket code is conditionally compiled depending upon the availability of
13             # the IO::Socket::IP package.
14             #
15             # We have chosen not to use mapped IPv4 addresses, there seem to be issues
16             # with this; as a result we use separate sockets for each family type.
17             #
18             # inet_pton is not available on WIN32, so we only use the getaddrinfo
19             # call to translate IP addresses to socketaddress.
20             #
21             # The configuration options force_v4, force_v6, prefer_v4 and prefer_v6
22             # are provided to control IPv6 behaviour for test purposes.
23             #
24             # Olaf Kolkman, RIPE NCC, December 2003.
25             # [Revised March 2016, June 2018]
26              
27              
28 92     92   618 use constant OS_SPEC => "Net::DNS::Resolver::$^O";
  92         230  
  92         11529  
29 92     92   643 use constant OS_UNIX => "Net::DNS::Resolver::UNIX";
  92         203  
  92         9262  
30 92     92   680 use constant OS_CONF => grep( eval "require $_", OS_SPEC ), OS_UNIX; ## no critic
  92         568  
  92         7746  
31 92     92   545 use base (OS_CONF)[0];
  92         218  
  92         51756  
32              
33              
34 92     92   1678 use constant USE_SOCKET_IP => defined eval 'use IO::Socket::IP 0.38; 1;'; ## no critic
  92     92   407  
  92         23843  
  92         91500  
  92         5092798  
  92         637  
35             require IO::Socket::INET unless USE_SOCKET_IP;
36              
37 92     92   1037 use constant IPv6 => USE_SOCKET_IP;
  92         202  
  92         8217  
38              
39              
40             # If SOCKSified Perl, use TCP instead of UDP and keep the socket open.
41 92     92   593 use constant SOCKS => scalar eval { require Config; $Config::Config{usesocks}; };
  92         202  
  92         248  
  92         389  
  92         19343  
42              
43              
44             # Allow taint tests to be optimised away when appropriate.
45 92     92   1512 use constant TAINT => eval { ${^TAINT} };
  92         436  
  92         289  
  92         8219  
46 92     92   1333 use constant TESTS => TAINT && defined eval { require Scalar::Util; };
  92         205  
  92         5278  
47              
48              
49 92     92   3989 use integer;
  92         263  
  92         1482  
50 92     92   3208 use Carp;
  92         185  
  92         7267  
51 92     92   54365 use IO::File;
  92         195784  
  92         13174  
52 92     92   51238 use IO::Select;
  92         186654  
  92         5607  
53 92     92   773 use IO::Socket;
  92         208  
  92         667  
54              
55 92     92   88756 use Socket;
  92         246  
  92         66478  
56             {
57 92     92   779 no strict 'subs'; ## no critic ProhibitNoStrict
  92         187  
  92         5086  
58 92     92   587 use constant AI_NUMERICHOST => Socket::AI_NUMERICHOST;
  92         2087  
  92         7914  
59 92     92   606 use constant IPPROTO_UDP => Socket::IPPROTO_UDP;
  92         199  
  92         6741  
60             }
61              
62 92     92   58367 use Net::DNS::RR;
  92         474  
  92         4334  
63 92     92   65656 use Net::DNS::Packet;
  92         461  
  92         4312  
64              
65 92     92   743 use constant PACKETSZ => 512;
  92         201  
  92         389908  
66              
67              
68             #
69             # Set up a closure to be our class data.
70             #
71             {
72             my $defaults = bless {
73             nameservers => [qw(::1 127.0.0.1)],
74             nameserver4 => ['127.0.0.1'],
75             nameserver6 => ['::1'],
76             port => 53,
77             srcaddr4 => '0.0.0.0',
78             srcaddr6 => '::',
79             srcport => 0,
80             searchlist => [],
81             retrans => 5,
82             retry => 4,
83             usevc => ( SOCKS ? 1 : 0 ),
84             igntc => 0,
85             recurse => 1,
86             defnames => 1,
87             dnsrch => 1,
88             ndots => 1,
89             debug => 0,
90             tcp_timeout => 120,
91             udp_timeout => 30,
92             persistent_tcp => ( SOCKS ? 1 : 0 ),
93             persistent_udp => 0,
94             dnssec => 0,
95             adflag => 0, # see RFC6840, 5.7
96             cdflag => 0, # see RFC6840, 5.9
97             udppacketsize => 0, # value bounded below by PACKETSZ
98             force_v4 => 0,
99             force_v6 => 0,
100             prefer_v4 => 0,
101             prefer_v6 => 0,
102             },
103             __PACKAGE__;
104              
105              
106 254     254   2095 sub _defaults { return $defaults; }
107             }
108              
109              
110             my %warned;
111              
112             sub _deprecate {
113 7     7   25 my ( undef, @note ) = @_;
114 7 100       1084 carp join ' ', 'deprecated method;', "@note" unless $warned{"@note"}++;
115 7         89 return;
116             }
117              
118              
119             sub _untaint { ## no critic # recurses into user list arguments
120 10     10   262 return TAINT ? map { ref($_) ? [_untaint(@$_)] : do { /^(.*)$/; $1 } } @_ : @_;
121             }
122              
123              
124             # These are the attributes that the user may specify in the new() constructor.
125             my %public_attr = (
126             map { $_ => $_ } keys %{&_defaults},
127             qw(domain nameserver srcaddr),
128             map { $_ => 0 } qw(nameserver4 nameserver6 srcaddr4 srcaddr6),
129             );
130              
131              
132             my $initial;
133              
134             sub new {
135 94     94 1 1896858 my ( $class, %args ) = @_;
136              
137 94         257 my $self;
138 94         517 my $base = $class->_defaults;
139 94         236 my $init = $initial;
140 94   100     695 $initial ||= [%$base];
141 94 100       542 if ( my $file = $args{config_file} ) {
    100          
142 4         57 my $conf = bless {@$initial}, $class;
143 4         29 $conf->_read_config_file($file); # user specified config
144 2         20 $self = bless {_untaint(%$conf)}, $class;
145 2 100       62 %$base = %$self unless $init; # define default configuration
146              
147             } elsif ($init) {
148 82         2183 $self = bless {%$base}, $class;
149              
150             } else {
151 8         142 $class->_init(); # define default configuration
152 8         203 $self = bless {%$base}, $class;
153             }
154              
155 92         702 while ( my ( $attr, $value ) = each %args ) {
156 77 100       321 next unless $public_attr{$attr};
157 75         209 my $ref = ref($value);
158 75 100 100     1396 croak "usage: $class->new( $attr => [...] )"
159             if $ref && ( $ref ne 'ARRAY' );
160 71 100       749 $self->$attr( $ref ? @$value : $value );
161             }
162              
163 88         450 return $self;
164             }
165              
166              
167             my %resolv_conf = ( ## map traditional resolv.conf option names
168             attempts => 'retry',
169             inet6 => 'prefer_v6',
170             timeout => 'retrans',
171             );
172              
173             my %res_option = ( ## any resolver attribute plus those listed above
174             %public_attr,
175             %resolv_conf,
176             );
177              
178             sub _option {
179 10     10   21 my ( $self, $name, @value ) = @_;
180 10   100     60 my $attribute = $res_option{lc $name} || return;
181 7 100       28 push @value, 1 unless scalar @value;
182 7         44 return $self->$attribute(@value);
183             }
184              
185              
186             sub _read_env { ## read resolver config environment variables
187 8     8   21 my $self = shift;
188              
189 8 100       39 $self->searchlist( map {split} $ENV{LOCALDOMAIN} ) if defined $ENV{LOCALDOMAIN};
  1         5  
190              
191 8 100       45 $self->nameservers( map {split} $ENV{RES_NAMESERVERS} ) if defined $ENV{RES_NAMESERVERS};
  1         4  
192              
193 8 100       47 $self->searchlist( map {split} $ENV{RES_SEARCHLIST} ) if defined $ENV{RES_SEARCHLIST};
  1         5  
194              
195 8   100     58 foreach ( map {split} $ENV{RES_OPTIONS} || '' ) {
  8         39  
196 4         10 $self->_option( split m/:/ );
197             }
198 8         22 return;
199             }
200              
201              
202             sub _read_config_file { ## read resolver config file
203 19     19   64 my ( $self, $file ) = @_;
204              
205 19 100       223 my $filehandle = IO::File->new( $file, '<' ) or croak "$file: $!";
206              
207 17         2561 my @nameserver;
208             my @searchlist;
209              
210 17         43 local $_;
211 17         558 while (<$filehandle>) {
212 90         333 s/[;#].*$//; # strip comments
213              
214 90 100       217 /^nameserver/ && do {
215 18         85 my ( $keyword, @ip ) = grep {defined} split;
  38         128  
216 18         51 push @nameserver, @ip;
217 18         70 next;
218             };
219              
220 72 100       160 /^domain/ && do {
221 2         9 my ( $keyword, $domain ) = grep {defined} split;
  4         15  
222 2         16 $self->domain($domain);
223 2         12 next;
224             };
225              
226 70 100       155 /^search/ && do {
227 10         42 my ( $keyword, @domain ) = grep {defined} split;
  22         66  
228 10         48 push @searchlist, @domain;
229 10         37 next;
230             };
231              
232 60 100       280 /^option/ && do {
233 2         7 my ( $keyword, @option ) = grep {defined} split;
  8         19  
234 2         7 foreach (@option) {
235 6         25 $self->_option( split m/:/ );
236             }
237             };
238             }
239              
240 17         261 close($filehandle);
241              
242 17 100       183 $self->nameservers(@nameserver) if @nameserver;
243 17 100       89 $self->searchlist(@searchlist) if @searchlist;
244 17         127 return;
245             }
246              
247              
248             sub string {
249 2     2 1 4 my $self = shift;
250 2 100       8 $self = $self->_defaults unless ref($self);
251              
252 2         6 my @nslist = $self->nameservers();
253 2         5 my ($force) = ( grep( { $self->{$_} } qw(force_v6 force_v4) ), 'force_v4' );
  4         9  
254 2         4 my ($prefer) = ( grep( { $self->{$_} } qw(prefer_v6 prefer_v4) ), 'prefer_v4' );
  4         6  
255 2         6 return <
256             ;; RESOLVER state:
257             ;; nameservers = @nslist
258 2         35 ;; searchlist = @{$self->{searchlist}}
259             ;; defnames = $self->{defnames} dnsrch = $self->{dnsrch}
260             ;; igntc = $self->{igntc} usevc = $self->{usevc}
261             ;; recurse = $self->{recurse} port = $self->{port}
262             ;; retrans = $self->{retrans} retry = $self->{retry}
263             ;; tcp_timeout = $self->{tcp_timeout} persistent_tcp = $self->{persistent_tcp}
264             ;; udp_timeout = $self->{udp_timeout} persistent_udp = $self->{persistent_udp}
265             ;; ${prefer} = $self->{$prefer} ${force} = $self->{$force}
266             ;; debug = $self->{debug} ndots = $self->{ndots}
267             END
268             }
269              
270              
271             sub print {
272 1     1 1 320 return print shift->string;
273             }
274              
275              
276             sub searchlist {
277 99     99 1 3022 my ( $self, @domain ) = @_;
278 99 100       437 $self = $self->_defaults unless ref($self);
279              
280 99         251 foreach (@domain) { $_ = Net::DNS::Domain->new($_)->name }
  32         280  
281 99 100       351 $self->{searchlist} = \@domain if scalar(@domain);
282 99         176 return @{$self->{searchlist}};
  99         398  
283             }
284              
285             sub domain {
286 31     31 1 290595 return (&searchlist)[0];
287             }
288              
289              
290             sub nameservers {
291 234     234 1 3066 my ( $self, @ns ) = @_;
292 234 100       845 $self = $self->_defaults unless ref($self);
293              
294 234         508 my @ip;
295 234         672 foreach my $ns ( grep {defined} @ns ) {
  297         695  
296 297 100 100     686 if ( _ipv4($ns) || _ipv6($ns) ) {
297 289         855 push @ip, $ns;
298              
299             } else {
300 8         82 my $defres = ref($self)->new( debug => $self->{debug} );
301 8         24 $defres->{persistent} = $self->{persistent};
302              
303 8         17 my $names = {};
304 8         132 my $packet = $defres->send( $ns, 'A' );
305 8         87 my @iplist = _cname_addr( $packet, $names );
306              
307 8         16 if (IPv6) {
308 8         47 $packet = $defres->send( $ns, 'AAAA' );
309 8         83 push @iplist, _cname_addr( $packet, $names );
310             }
311              
312 8         29 my %unique = map { $_ => $_ } @iplist;
  13         50  
313              
314 8         34 my @address = values(%unique); # tainted
315 8 100       236 carp "unresolvable name: $ns" unless scalar @address;
316              
317 8         237 push @ip, @address;
318             }
319             }
320              
321 234 100 100     1183 if ( scalar(@ns) || !defined(wantarray) ) {
322 97         226 my @ipv4 = grep { _ipv4($_) } @ip;
  302         576  
323 97         225 my @ipv6 = grep { _ipv6($_) } @ip;
  302         688  
324 97         408 $self->{nameservers} = \@ip;
325 97         282 $self->{nameserver4} = \@ipv4;
326 97         290 $self->{nameserver6} = \@ipv6;
327             }
328              
329 234         463 my @IPv4 = @{$self->{nameserver4}};
  234         863  
330 234         471 my @IPv6 = IPv6 ? @{$self->{nameserver6}} : ();
  234         750  
331              
332 234 100       732 my @IPlist = @IPv6 ? @{$self->{nameservers}} : @IPv4;
  125         426  
333 234 100       714 @IPlist = ( @IPv6, @IPv4 ) if $self->{prefer_v6};
334 234 100       2220 @IPlist = ( @IPv4, @IPv6 ) if $self->{prefer_v4};
335 234 100       651 @IPlist = @IPv6 if $self->{force_v6};
336 234 100       701 @IPlist = @IPv4 if $self->{force_v4};
337              
338 234 100       620 $self->errorstring('no nameservers') unless @IPlist;
339 234         1091 return @IPlist;
340             }
341              
342 10     10 1 1364 sub nameserver { return &nameservers; }
343              
344             sub _cname_addr {
345              
346             # TODO 20081217
347             # This code does not follow CNAME chains, it only looks inside the packet.
348             # Out of bailiwick will fail.
349 17     17   60 my @null;
350 17   100     75 my $packet = shift || return @null;
351 14         50 my $names = shift;
352              
353 14         81 $names->{lc( $_->qname )}++ foreach $packet->question;
354 14         68 $names->{lc( $_->cname )}++ foreach grep { $_->can('cname') } $packet->answer;
  15         1782  
355              
356 14         187 my @addr = grep { $_->can('address') } $packet->answer;
  15         87  
357 14         37 return map { $_->address } grep { $names->{lc( $_->name )} } @addr;
  13         68  
  13         65  
358             }
359              
360              
361             sub replyfrom {
362 2     2 1 19 return shift->{replyfrom};
363             }
364              
365 1     1 0 16 sub answerfrom { return &replyfrom; } # uncoverable pod
366              
367              
368             sub _reset_errorstring {
369 107     107   432 shift->{errorstring} = '';
370 107         282 return;
371             }
372              
373             sub errorstring {
374 415     415 1 1512 my ( $self, $text ) = @_;
375 415 100       1916 $self->_diag( 'errorstring:', $self->{errorstring} = $text ) if $text;
376 415         5880 return $self->{errorstring};
377             }
378              
379              
380             sub query {
381 13     13 1 81 my ( $self, @argument ) = @_;
382              
383 13   100     73 my $name = shift(@argument) || '.';
384 13 100 100     216 my @sfix = $self->{defnames} && ( $name !~ m/[.:]/ ) ? $self->domain : ();
385              
386 13         64 my $fqdn = join '.', $name, @sfix;
387 13         91 $self->_diag( 'query(', $fqdn, @argument, ')' );
388 13   100     64 my $packet = $self->send( $fqdn, @argument ) || return;
389 10 100       85 return $packet->header->ancount ? $packet : undef;
390             }
391              
392              
393             sub search {
394 7     7 1 39 my ( $self, @argument ) = @_;
395              
396 7 100       64 return $self->query(@argument) unless $self->{dnsrch};
397              
398 6   100     24 my $name = shift(@argument) || '.';
399 6         20 my $dots = $name =~ tr/././;
400              
401 6 100       23 my @sfix = ( $dots < $self->{ndots} ) ? @{$self->{searchlist}} : ();
  1         4  
402 6 100       60 my ( $one, @more ) = ( $name =~ m/:|\.\d*$/ ) ? () : ( $dots ? ( undef, @sfix ) : @sfix );
    100          
403              
404 6         16 foreach my $suffix ( $one, @more ) {
405 7 100       23 my $fqname = $suffix ? join( '.', $name, $suffix ) : $name;
406 7         55 $self->_diag( 'search(', $fqname, @argument, ')' );
407 7   100     25 my $packet = $self->send( $fqname, @argument ) || next;
408 2 100       9 return $packet if $packet->header->ancount;
409             }
410              
411 5         39 return;
412             }
413              
414              
415             sub send {
416 91     91 1 469 my ( $self, @argument ) = @_;
417 91         428 my $packet = $self->_make_query_packet(@argument);
418 91         385 my $packet_data = $packet->encode;
419              
420 91         486 $self->_reset_errorstring;
421              
422             return $self->_send_tcp( $packet, $packet_data )
423 91 100 100     707 if $self->{usevc} || length $packet_data > $self->_packetsz;
424              
425 84   100     398 my $reply = $self->_send_udp( $packet, $packet_data ) || return;
426              
427 67 100       1153 return $reply if $self->{igntc};
428 63 100       301 return $reply unless $reply->header->tc;
429              
430 1         5 $self->_diag('packet truncated: retrying using TCP');
431 1         15 return $self->_send_tcp( $packet, $packet_data );
432             }
433              
434              
435             sub _send_tcp {
436 9     9   31 my ( $self, $query, $query_data ) = @_;
437              
438 9         38 my $tcp_packet = pack 'n a*', length($query_data), $query_data;
439 9         38 my @ns = $self->nameservers();
440 9         21 my $fallback;
441 9         22 my $timeout = $self->{tcp_timeout};
442              
443 9         28 foreach my $ip (@ns) {
444 12         145 $self->_diag( 'tcp send', "[$ip]" );
445              
446 12         70 my $connection = $self->_create_tcp_socket($ip);
447 12         80 $self->errorstring($!);
448 12   100     193 my $select = IO::Select->new( $connection || next );
449              
450 10         997 $connection->send($tcp_packet);
451 10         1550 $self->errorstring($!);
452              
453 10         68 my @ready = $select->can_read($timeout);
454 10 50       153945 next unless @ready; # uncoverable branch true
455 10         67 my $socket = shift @ready;
456 10         67 my $buffer = _read_tcp($socket);
457              
458 10         78 $self->{replyfrom} = $ip;
459 10         86 $self->_diag( 'packet from', "[$ip]", length($buffer), 'octets' );
460              
461 10         219 my $reply = Net::DNS::Packet->decode( \$buffer, $self->{debug} );
462 10         303 $self->errorstring($@);
463 10 100       92 next unless $self->_accept_reply( $reply, $query );
464 8         63 $reply->from( $socket->peerhost );
465              
466 8 100 100     74 if ( $self->{tsig_rr} && !$reply->verify($query) ) {
467 2         31 $self->errorstring( $reply->verifyerr );
468 2         239 next;
469             }
470              
471 6         35 my $rcode = $reply->header->rcode;
472 6 100       526 return $reply if $rcode eq 'NOERROR';
473 3 100       158 return $reply if $rcode eq 'NXDOMAIN';
474 2         343 $fallback = $reply;
475             }
476              
477 5 100       87 $self->errorstring( $fallback->header->rcode ) if $fallback;
478 5 100       21 $self->errorstring('query timed out') unless $self->errorstring;
479 5         84 return $fallback;
480             }
481              
482              
483             sub _send_udp {
484 85     85   271 my ( $self, $query, $query_data ) = @_;
485              
486 85         331 my @ns = $self->nameservers;
487 85         222 my $port = $self->{port};
488 85   100     294 my $retrans = $self->{retrans} || 1;
489 85   100     297 my $retry = $self->{retry} || 1;
490 85         181 my $servers = scalar(@ns);
491 92 100   92   961 my $timeout = $servers ? do { no integer; $retrans / $servers } : 0;
  92         221  
  92         1008  
  85         247  
  84         300  
492 85         181 my $fallback;
493              
494             # Perform each round of retries.
495 85         423 RETRY: for ( 1 .. $retry ) { # assumed to be a small number
496              
497             # Try each nameserver.
498 100         1074 my $select = IO::Select->new();
499              
500 100         1486 NAMESERVER: foreach my $ns (@ns) {
501              
502             # state vector replaces corresponding element of @ns array
503 180 100       654 unless ( ref $ns ) {
504 129         616 my $sockaddr = $self->_create_dst_sockaddr( $ns, $port );
505 129   100     662 my $socket = $self->_create_udp_socket($ns) || next;
506 90         432 $ns = [$socket, $ns, $sockaddr];
507             }
508              
509 141         457 my ( $socket, $ip, $sockaddr, $failed ) = @$ns;
510 141 100       479 next if $failed;
511              
512 90         904 $self->_diag( 'udp send', "[$ip]:$port" );
513              
514 90         660 $select->add($socket);
515 90         8254 $socket->send( $query_data, 0, $sockaddr );
516 90         20984 $self->errorstring( $$ns[3] = $! );
517              
518             # handle failure to detect taint inside socket->send()
519 90         191 die 'Insecure dependency while running with -T switch'
520             if TESTS && Scalar::Util::tainted($sockaddr);
521              
522 90         6221 my $reply;
523 90         519 while ( my @ready = $select->can_read($timeout) ) {
524 72         3041523 my $socket = shift @ready;
525 72         492 my $buffer = _read_udp($socket);
526              
527 72         407 $self->{replyfrom} = $ip;
528 72         679 $self->_diag( 'packet from', "[$ip]", length($buffer), 'octets' );
529              
530 72         1622 my $packet = Net::DNS::Packet->decode( \$buffer, $self->{debug} );
531 72         567 $self->errorstring($@);
532 72 100       470 next unless $self->_accept_reply( $packet, $query );
533              
534 70         599 $packet->from( $socket->peerhost );
535 70         180 $reply = $packet;
536 70         254 last;
537             } #SELECT LOOP
538              
539 90 100       17915076 next unless $reply;
540              
541 70 100 100     421 if ( $self->{tsig_rr} && !$reply->verify($query) ) {
542 2         10 $self->errorstring( $$ns[3] = $reply->verifyerr );
543 2         24 next;
544             }
545              
546 68         276 my $rcode = $reply->header->rcode;
547 68 100       9385 return $reply if $rcode eq 'NOERROR';
548 5 100       152 return $reply if $rcode eq 'NXDOMAIN';
549 2         16 $fallback = $reply;
550 2         10 $$ns[3] = $rcode;
551             } #NAMESERVER LOOP
552              
553 92     92   43662 no integer;
  92         215  
  92         869  
554 34         202 $timeout += $timeout;
555             } #RETRY LOOP
556              
557 19 100       61 $self->errorstring( $fallback->header->rcode ) if $fallback;
558 19 100       75 $self->errorstring('query timed out') unless $self->errorstring;
559 19         658 return $fallback;
560             }
561              
562              
563             sub bgsend {
564 16     16 1 40200 my ( $self, @argument ) = @_;
565 16         79 my $packet = $self->_make_query_packet(@argument);
566 16         71 my $packet_data = $packet->encode;
567              
568 16         78 $self->_reset_errorstring;
569              
570             return $self->_bgsend_tcp( $packet, $packet_data )
571 16 100 100     118 if $self->{usevc} || length $packet_data > $self->_packetsz;
572              
573 9         52 return $self->_bgsend_udp( $packet, $packet_data );
574             }
575              
576              
577             sub _bgsend_tcp {
578 9     9   31 my ( $self, $packet, $packet_data ) = @_;
579              
580 9         39 my $tcp_packet = pack 'n a*', length($packet_data), $packet_data;
581              
582 9         41 foreach my $ip ( $self->nameservers ) {
583 10         55 $self->_diag( 'bgsend', "[$ip]" );
584              
585 10         44 my $socket = $self->_create_tcp_socket($ip);
586 10         95 $self->errorstring($!);
587 10 100       41 next unless $socket;
588              
589 8         35 $socket->blocking(0);
590 8         144 $socket->send($tcp_packet);
591 8         1059 $self->errorstring($!);
592 8         34 $socket->blocking(1);
593              
594 8         122 my $expire = time() + $self->{tcp_timeout};
595 8         40 ${*$socket}{net_dns_bg} = [$expire, $packet];
  8         77  
596 8         95 return $socket;
597             }
598              
599 1         13 return;
600             }
601              
602              
603             sub _bgsend_udp {
604 10     10   34 my ( $self, $packet, $packet_data ) = @_;
605              
606 10         27 my $port = $self->{port};
607              
608 10         41 foreach my $ip ( $self->nameservers ) {
609 11         59 my $sockaddr = $self->_create_dst_sockaddr( $ip, $port );
610 11   100     48 my $socket = $self->_create_udp_socket($ip) || next;
611              
612 9         90 $self->_diag( 'bgsend', "[$ip]:$port" );
613              
614 9         51 $socket->send( $packet_data, 0, $sockaddr );
615 9         1783 $self->errorstring($!);
616              
617             # handle failure to detect taint inside $socket->send()
618 9         3060 die 'Insecure dependency while running with -T switch'
619             if TESTS && Scalar::Util::tainted($sockaddr);
620              
621 9         42 my $expire = time() + $self->{udp_timeout};
622 9         34 ${*$socket}{net_dns_bg} = [$expire, $packet];
  9         58  
623 9         85 return $socket;
624             }
625              
626 1         15 return;
627             }
628              
629              
630             sub bgbusy { ## no critic # overwrites user UDP handle
631 11501     11501 1 523733 my ( $self, $handle ) = @_;
632 11501 100       25620 return unless $handle;
633              
634 11499   100     18310 my $appendix = ${*$handle}{net_dns_bg} ||= [time() + $self->{udp_timeout}];
  11499         35640  
635 11499         22673 my ( $expire, $query, $read ) = @$appendix;
636 11499 100       20969 return if ref($read);
637              
638 11498 100       26343 return time() < $expire unless IO::Select->new($handle)->can_read(0.02); # limit CPU burn
639              
640 13 100       115652 return unless $query; # SpamAssassin 3.4.1 workaround
641 12 100       96 return unless $handle->socktype() == SOCK_DGRAM;
642              
643 6         167 my $ans = $self->_bgread($handle);
644 6         21 $$appendix[0] = time();
645 6         24 $$appendix[2] = [$ans];
646 6 100       32 return unless $ans;
647 5 100       22 return if $self->{igntc};
648 4 50       34 return unless $ans->header->tc;
649              
650 0         0 $self->_diag('packet truncated: retrying using TCP');
651 0   0     0 my $tcp = $self->_bgsend_tcp( $query, $query->encode ) || return;
652 0         0 return defined( $_[1] = $tcp ); # caller's UDP handle now TCP
653             }
654              
655              
656             sub bgisready { ## historical
657 1     1 0 35 __PACKAGE__->_deprecate('prefer ! bgbusy(...)'); # uncoverable pod
658 1         5 return !&bgbusy;
659             }
660              
661              
662             sub bgread {
663 11     11 1 2225 1 while &bgbusy; ## side effect: TCP retry if TC flag set
664 11         207 return &_bgread;
665             }
666              
667              
668             sub _bgread {
669 18     18   90 my ( $self, $handle ) = @_;
670 18 100       64 return unless $handle;
671              
672 17         32 my $appendix = ${*$handle}{net_dns_bg};
  17         66  
673 17         56 my ( $expire, $query, $read ) = @$appendix;
674 17 100       99 return shift(@$read) if ref($read);
675              
676 11 100       70 return unless IO::Select->new($handle)->can_read(0.2);
677              
678 10         1329 my $dgram = $handle->socktype() == SOCK_DGRAM;
679 10 100       231 my $buffer = $dgram ? _read_udp($handle) : _read_tcp($handle);
680              
681 10         62 my $peerhost = $self->{replyfrom} = $handle->peerhost;
682 10         794 $self->_diag( "packet from [$peerhost]", length($buffer), 'octets' );
683              
684 10         152 my $reply = Net::DNS::Packet->decode( \$buffer, $self->{debug} );
685 10         61 $self->errorstring($@);
686              
687 10 100       56 return unless $self->_accept_reply( $reply, $query );
688 9         55 $reply->from($peerhost);
689              
690 9 100 100     113 return $reply unless $self->{tsig_rr} && !$reply->verify($query);
691 1         7 $self->errorstring( $reply->verifyerr );
692 1         21 return;
693             }
694              
695              
696             sub _accept_reply {
697 97     97   355 my ( $self, $reply, $query ) = @_;
698              
699 97 100       369 return unless $reply;
700              
701 96         619 my $header = $reply->header;
702 96 100       598 return unless $header->qr;
703              
704 95 100 100     798 return if $query && ( $header->id != $query->header->id );
705              
706 89         510 return $self->errorstring( $header->rcode ); # historical quirk
707             }
708              
709              
710             sub axfr { ## zone transfer
711 9     9 1 1944 my ( $self, @argument ) = @_;
712 9 100       39 my $zone = scalar(@argument) ? shift @argument : $self->domain;
713 9         23 my @class = @argument;
714              
715 9         46 my $request = $self->_make_query_packet( $zone, 'AXFR', @class );
716              
717 8         22 return eval {
718 8         75 $self->_diag("axfr( $zone @class )");
719 8         43 my ( $select, $verify, @rr, $soa ) = $self->_axfr_start($request);
720              
721             my $iterator = sub { ## iterate over RRs
722 2688     2688   13320 my $rr = shift(@rr);
723              
724 2688 100       4445 if ( ref($rr) eq 'Net::DNS::RR::SOA' ) {
725 6 100       25 if ($soa) {
726 3         461 $select = undef;
727 3 100       73 return if $rr->canonical eq $soa->canonical;
728 1         7 croak $self->errorstring('mismatched final SOA');
729             }
730 3         7 $soa = $rr;
731             }
732              
733 2685 100       4186 unless ( scalar @rr ) {
734 28         77 my $reply; # refill @rr
735 28         189 ( $reply, $verify ) = $self->_axfr_next( $select, $verify );
736 28 100       232 @rr = $reply->answer if $reply;
737             }
738              
739 2685         3690 return $rr;
740 3         36 };
741              
742 3 100       26 return $iterator unless wantarray;
743              
744 2         4 my @zone; ## subvert iterator to assemble entire zone
745 2         8 while ( my $rr = $iterator->() ) {
746 20         519 push @zone, $rr, @rr; # copy RRs en bloc
747 20         292 @rr = pop(@zone); # leave last one in @rr
748             }
749 2         1688 return @zone;
750             };
751             }
752              
753              
754             sub axfr_start { ## historical
755 1     1 0 33 my ( $self, @argument ) = @_; # uncoverable pod
756 1         9 $self->_deprecate('prefer $iterator = $self->axfr(...)');
757 1         4 my $iterator = $self->axfr(@argument);
758 1     1   9 ( $self->{axfr_iter} ) = grep {defined} ( $iterator, sub { } );
  2         8  
759 1         5 return defined($iterator);
760             }
761              
762              
763             sub axfr_next { ## historical
764 1     1 0 31 my $self = shift; # uncoverable pod
765 1         6 $self->_deprecate('prefer $iterator->()');
766 1         4 return $self->{axfr_iter}->();
767             }
768              
769              
770             sub _axfr_start {
771 8     8   22 my ( $self, $request ) = @_;
772 8         32 my $content = $request->encode;
773 8         30 my $TCP_msg = pack 'n a*', length($content), $content;
774              
775 8         17 my ( $select, $reply, $rcode );
776 8         35 foreach my $ns ( $self->nameservers ) {
777 11         60 $self->_diag("axfr send [$ns]");
778              
779 11         31 local $self->{persistent_tcp};
780 11         57 my $socket = $self->_create_tcp_socket($ns);
781 11         75 $self->errorstring($!);
782 11   100     169 $select = IO::Select->new( $socket || next );
783              
784 9         1422 $socket->send($TCP_msg);
785 9         1277 $self->errorstring($!);
786              
787 9         83 ($reply) = $self->_axfr_next($select);
788 9 100       58 last if ( $rcode = $reply->header->rcode ) eq 'NOERROR';
789             }
790              
791 8 100       41 croak $self->errorstring unless $reply;
792              
793 6         60 $self->errorstring($rcode); # historical quirk
794              
795 6 100       33 my $verify = $request->sigrr ? $request : undef;
796 6 100       47 unless ($verify) {
797 3 100       12 croak $self->errorstring unless $rcode eq 'NOERROR';
798 2         8 return ( $select, $verify, $reply->answer );
799             }
800              
801 3         20 my $verifyok = $reply->verify($verify);
802 3 100       19 croak $self->errorstring( $reply->verifyerr ) unless $verifyok;
803 2 100       14 croak $self->errorstring if $rcode ne 'NOERROR';
804 1         9 return ( $select, $verifyok, $reply->answer );
805             }
806              
807              
808             sub _axfr_next {
809 40     40   510 my $self = shift;
810 40   100     176 my $select = shift || return;
811 39         106 my $verify = shift;
812              
813 39         355 my ($socket) = $select->can_read( $self->{tcp_timeout} );
814 39 100       118832 croak $self->errorstring('timed out') unless $socket;
815              
816 38         205 my $buffer = _read_tcp($socket);
817 38         556 my $packet = Net::DNS::Packet->decode( \$buffer );
818 38 100       205 croak $@, $self->errorstring('corrupt packet') if $@;
819              
820 37 100       364 return ( $packet, $verify ) unless $verify;
821              
822 10         105 my $verifyok = $packet->verify($verify);
823 10 100       68 croak $self->errorstring( $packet->verifyerr ) unless $verifyok;
824 9         211 return ( $packet, $verifyok );
825             }
826              
827              
828             #
829             # Usage: $data = _read_tcp($socket);
830             #
831             sub _read_socket {
832 296     296   914 my ( $socket, $size ) = @_;
833 296         582 my $buffer = '';
834 296 100       2218 $socket->recv( $buffer, $size ) if $size;
835 296         47416 return $buffer;
836             }
837              
838             sub _read_tcp {
839 52     52   135 my $socket = shift;
840              
841 52         118 my $buffer = '';
842 52         201 my $header = _read_socket( $socket, 2 );
843 52         267 $header .= _read_socket( $socket, 2 - length $header );
844 52 50       237 return $buffer if length($header) < 2; # uncoverable branch true
845 52         253 my $size = unpack 'n', $header;
846              
847 52         204 while ( my $fragment = _read_socket( $socket, $size - length $buffer ) ) {
848 62         436 $buffer .= $fragment;
849             }
850 52         392 return $buffer;
851             }
852              
853              
854             #
855             # Usage: $data = _read_udp($socket);
856             #
857             sub _read_udp {
858 78     78   386 return _read_socket( shift(), 9000 ); ## payload limit for Ethernet "Jumbo" packet
859             }
860              
861              
862             sub _create_tcp_socket {
863 29     29   110 my ( $self, $ip, @sockopt ) = @_;
864              
865 29         59 my $socket;
866 29         58 my $sock_key = "TCP[$ip]";
867 29 100       144 if ( $socket = $self->{persistent}{$sock_key} ) {
868 2         9 $self->_diag( 'using persistent socket', $sock_key );
869 2 100       15 return $socket if $socket->connected;
870 1         23 $self->_diag('socket disconnected (trying to connect)');
871             }
872              
873 28         110 my $ip6_addr = IPv6 && _ipv6($ip);
874             $socket = IO::Socket::IP->new(
875             LocalAddr => $ip6_addr ? $self->{srcaddr6} : $self->{srcaddr4},
876             LocalPort => $self->{srcport},
877             PeerAddr => $ip,
878             PeerPort => $self->{port},
879             Proto => 'tcp',
880             Timeout => $self->{tcp_timeout},
881 28 100       570 GetAddrInfoFlags => AI_NUMERICHOST,
882             @sockopt
883             )
884             if USE_SOCKET_IP;
885              
886 28         326692 unless ( USE_SOCKET_IP or $ip6_addr ) {
887             $socket = IO::Socket::INET->new(
888             LocalAddr => $self->{srcaddr4},
889             LocalPort => $self->{srcport} || undef,
890             PeerAddr => $ip,
891             PeerPort => $self->{port},
892             Proto => 'tcp',
893             Timeout => $self->{tcp_timeout},
894             @sockopt
895             );
896             }
897              
898 28 100       244 $self->{persistent}{$sock_key} = $socket if $self->{persistent_tcp};
899 28         124 return $socket;
900             }
901              
902              
903             sub _create_udp_socket {
904 101     101   366 my ( $self, $ip, @sockopt ) = @_;
905              
906 101         248 my $socket;
907 101         275 my $sock_key = "UDP[$ip]";
908 101 100       562 return $socket if $socket = $self->{persistent}{$sock_key};
909              
910 100         344 my $ip6_addr = IPv6 && _ipv6($ip);
911             $socket = IO::Socket::IP->new(
912             LocalAddr => $ip6_addr ? $self->{srcaddr6} : $self->{srcaddr4},
913             LocalPort => $self->{srcport},
914 100 100       1743 Proto => 'udp',
915             Type => SOCK_DGRAM,
916             GetAddrInfoFlags => AI_NUMERICHOST,
917             @sockopt
918             )
919             if USE_SOCKET_IP;
920              
921 100         88653 unless ( USE_SOCKET_IP or $ip6_addr ) {
922             $socket = IO::Socket::INET->new(
923             LocalAddr => $self->{srcaddr4},
924             LocalPort => $self->{srcport} || undef,
925             Proto => 'udp',
926             Type => SOCK_DGRAM,
927             @sockopt
928             );
929             }
930              
931 100 100       660 $self->{persistent}{$sock_key} = $socket if $self->{persistent_udp};
932 100         573 return $socket;
933             }
934              
935              
936             my $ip4 = {
937             family => AF_INET,
938             flags => AI_NUMERICHOST,
939             protocol => IPPROTO_UDP,
940             socktype => SOCK_DGRAM
941             };
942             my $ip6 = {
943             family => AF_INET6,
944             flags => AI_NUMERICHOST,
945             protocol => IPPROTO_UDP,
946             socktype => SOCK_DGRAM
947             };
948              
949             sub _create_dst_sockaddr { ## create UDP destination sockaddr structure
950 140     140   429 my ( $self, $ip, $port ) = @_;
951              
952 140         313 unless (USE_SOCKET_IP) { # NB: errors raised in socket->send
953             return _ipv6($ip) ? undef : sockaddr_in( $port, inet_aton($ip) );
954             }
955              
956 140 100       1257 my @addrinfo = Socket::getaddrinfo( $ip, $port, _ipv6($ip) ? $ip6 : $ip4 );
957 140         547 return ( grep {ref} @addrinfo, {} )[0]->{addr};
  420         1572  
958             }
959              
960              
961             # Lightweight versions of subroutines from Net::IP module, recoded to fix RT#96812
962              
963             sub _ipv4 {
964 599     599   1051 for (shift) {
965 599 100       7723 last if m/[^.0-9]/; # dots and digits only
966 357         2036 return m/\.\d+\./; # dots separated by digits
967             }
968 242         849 return;
969             }
970              
971             sub _ipv6 {
972 694     694   1443 for (shift) {
973 694 100       2667 last unless m/:.*:/; # must contain two colons
974 286 100       1994 return 1 unless m/[^:0-9A-Fa-f]/; # colons and hexdigits only
975 4 100       11 return 1 if m/^[:.0-9A-Fa-f]+\%.+$/; # RFC4007 scoped address
976 2         8 return m/^[:0-9A-Fa-f]+:[.0-9]+$/; # prefix : dotted digits
977             }
978 408         2947 return;
979             }
980              
981              
982             sub _make_query_packet {
983 135     135   397 my ( $self, @argument ) = @_;
984              
985 135         326 my ($packet) = @argument;
986 135 100       546 unless ( ref($packet) ) {
987 88         578 $packet = Net::DNS::Packet->new(@argument);
988 87         391 $packet->edns->udpsize( $self->{udppacketsize} );
989              
990 87         305 my $header = $packet->header;
991 87         466 $header->ad( $self->{adflag} ); # RFC6840, 5.7
992 87         372 $header->cd( $self->{cdflag} ); # RFC6840, 5.9
993 87 100       257 $header->do(1) if $self->{dnssec};
994 87         388 $header->rd( $self->{recurse} );
995             }
996              
997 134 100       751 if ( $self->{tsig_rr} ) {
998 12 100       58 $packet->sign_tsig( $self->{tsig_rr} ) unless $packet->sigrr;
999             }
1000              
1001 134         515 return $packet;
1002             }
1003              
1004              
1005             sub dnssec {
1006 11     11 1 2596 my ( $self, @argument ) = @_;
1007 11         31 for (@argument) {
1008 7         87 $self->udppacketsize(1232);
1009 7         43 $self->{dnssec} = $_;
1010             }
1011 11         124 return $self->{dnssec};
1012             }
1013              
1014              
1015             sub force_v6 {
1016 7     7 1 1578 my ( $self, @value ) = @_;
1017 7 100       18 for (@value) { $self->{force_v4} = 0 if $self->{force_v6} = $_ }
  4         26  
1018 7 100       36 return $self->{force_v6} ? 1 : 0;
1019             }
1020              
1021             sub force_v4 {
1022 8     8 1 1552 my ( $self, @value ) = @_;
1023 8 100       25 for (@value) { $self->{force_v6} = 0 if $self->{force_v4} = $_ }
  5         86  
1024 8 100       111 return $self->{force_v4} ? 1 : 0;
1025             }
1026              
1027             sub prefer_v6 {
1028 8     8 1 1554 my ( $self, @value ) = @_;
1029 8 100       20 for (@value) { $self->{prefer_v4} = 0 if $self->{prefer_v6} = $_ }
  5         27  
1030 8 100       40 return $self->{prefer_v6} ? 1 : 0;
1031             }
1032              
1033             sub prefer_v4 {
1034 6     6 1 1467 my ( $self, @value ) = @_;
1035 6 100       12 for (@value) { $self->{prefer_v6} = 0 if $self->{prefer_v4} = $_ }
  3         18  
1036 6 100       32 return $self->{prefer_v4} ? 1 : 0;
1037             }
1038              
1039             sub srcaddr {
1040 2     2 1 1148 my ( $self, @value ) = @_;
1041 2         5 for (@value) {
1042 2 100       4 my $hashkey = _ipv6($_) ? 'srcaddr6' : 'srcaddr4';
1043 2         5 $self->{$hashkey} = $_;
1044             }
1045 2         6 return shift @value;
1046             }
1047              
1048              
1049             sub tsig {
1050 9     9 1 734 my ( $self, $arg, @etc ) = @_;
1051 9 100       64 return $arg unless $arg;
1052 8 100       34 return $arg if ref($arg) eq 'Net::DNS::RR::TSIG';
1053 7         17 $self->{tsig_rr} = eval {
1054 7         39 local $SIG{__DIE__};
1055 7         2155 require Net::DNS::RR::TSIG;
1056 7         93 Net::DNS::RR::TSIG->create( $arg, @etc );
1057             };
1058 7 100       2302 croak "${@}unable to create TSIG record" if $@;
1059 6         23 return;
1060             }
1061              
1062              
1063             # if ($self->{udppacketsize} > PACKETSZ
1064             # then we use EDNS and $self->{udppacketsize}
1065             # should be taken as the maximum packet_data length
1066             sub _packetsz {
1067 108   100 108   579 my $udpsize = shift->{udppacketsize} || 0;
1068 108 100       586 return $udpsize > PACKETSZ ? $udpsize : PACKETSZ;
1069             }
1070              
1071             sub udppacketsize {
1072 13     13 1 51 my ( $self, @value ) = @_;
1073 13         31 for (@value) { $self->{udppacketsize} = $_ }
  11         26  
1074 13         50 return $self->_packetsz;
1075             }
1076              
1077              
1078             #
1079             # Keep this method around. Folk depend on it although it is neither documented nor exported.
1080             #
1081             sub make_query_packet { ## historical
1082 2     2 0 69 __PACKAGE__->_deprecate('see RT#37104'); # uncoverable pod
1083 2         6 return &_make_query_packet;
1084             }
1085              
1086              
1087             sub _diag { ## debug output
1088 479 100   479   2208 return unless shift->{debug};
1089 1         16 return print "\n;; @_\n";
1090             }
1091              
1092              
1093             {
1094             my $parse_dig = sub {
1095             require Net::DNS::ZoneFile;
1096              
1097             my $dug = Net::DNS::ZoneFile->new( \*DATA );
1098             my @rr = $dug->read;
1099              
1100             my @auth = grep { $_->type eq 'NS' } @rr;
1101             my %auth = map { lc $_->nsdname => 1 } @auth;
1102             my %glue;
1103             my @glue = grep { $auth{lc $_->name} } @rr;
1104             foreach ( grep { $_->can('address') } @glue ) {
1105             push @{$glue{lc $_->name}}, $_->address;
1106             }
1107             return map {@$_} values %glue;
1108             };
1109              
1110             my @ip;
1111              
1112             sub _hints { ## default hints
1113 6 100   6   557 @ip = &$parse_dig unless scalar @ip; # once only, on demand
1114 6         235 splice @ip, 0, 0, splice( @ip, int( rand scalar @ip ) ); # cut deck
1115 6         95 return @ip;
1116             }
1117             }
1118              
1119              
1120       1     sub DESTROY { } ## Avoid tickling AUTOLOAD (in cleanup)
1121              
1122             sub AUTOLOAD { ## Default method
1123 44     44   1371 my ($self) = @_;
1124              
1125 92     92   475582 no strict 'refs'; ## no critic ProhibitNoStrict
  92         251  
  92         29571  
1126 44         76 our $AUTOLOAD;
1127 44         94 my $name = $AUTOLOAD;
1128 44         300 $name =~ s/.*://;
1129 44 100       352 croak qq[unknown method "$name"] unless $public_attr{$name};
1130              
1131 43         329 *{$AUTOLOAD} = sub {
1132 101     101   5256 my $self = shift;
1133 101 100       294 $self = $self->_defaults unless ref($self);
1134 101 100 100     793 $self->{$name} = shift || 0 if scalar @_;
1135 101         501 return $self->{$name};
1136 43         287 };
1137              
1138 43         148 return &$AUTOLOAD;
1139             }
1140              
1141              
1142             1;
1143              
1144              
1145             =head1 NAME
1146              
1147             Net::DNS::Resolver::Base - DNS resolver base class
1148              
1149             =head1 SYNOPSIS
1150              
1151             use base qw(Net::DNS::Resolver::Base);
1152              
1153             =head1 DESCRIPTION
1154              
1155             This class is the common base class for the different platform
1156             sub-classes of L.
1157              
1158             No user serviceable parts inside, see L
1159             for all your resolving needs.
1160              
1161              
1162             =head1 METHODS
1163              
1164             =head2 new, domain, searchlist, nameserver, nameservers,
1165              
1166             =head2 search, query, send, bgsend, bgbusy, bgread, axfr,
1167              
1168             =head2 force_v4, force_v6, prefer_v4, prefer_v6,
1169              
1170             =head2 dnssec, srcaddr, tsig, udppacketsize,
1171              
1172             =head2 print, string, errorstring, replyfrom
1173              
1174             See L.
1175              
1176              
1177             =head1 COPYRIGHT
1178              
1179             Copyright (c)2003,2004 Chris Reinhardt.
1180              
1181             Portions Copyright (c)2005 Olaf Kolkman.
1182              
1183             Portions Copyright (c)2014-2017 Dick Franks.
1184              
1185             All rights reserved.
1186              
1187              
1188             =head1 LICENSE
1189              
1190             Permission to use, copy, modify, and distribute this software and its
1191             documentation for any purpose and without fee is hereby granted, provided
1192             that the original copyright notices appear in all copies and that both
1193             copyright notice and this permission notice appear in supporting
1194             documentation, and that the name of the author not be used in advertising
1195             or publicity pertaining to distribution of the software without specific
1196             prior written permission.
1197              
1198             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1199             IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1200             FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1201             THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1202             LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1203             FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1204             DEALINGS IN THE SOFTWARE.
1205              
1206              
1207             =head1 SEE ALSO
1208              
1209             L L L
1210              
1211             =cut
1212              
1213              
1214             ########################################
1215              
1216             __DATA__ ## DEFAULT HINTS