File Coverage

blib/lib/Net/DNS/Resolver/Base.pm
Criterion Covered Total %
statement 612 612 100.0
branch 264 264 100.0
condition 80 80 100.0
subroutine 84 84 100.0
pod 24 29 100.0
total 1064 1069 100.0


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