File Coverage

blib/lib/Zonemaster/Engine/Test/Delegation.pm
Criterion Covered Total %
statement 216 226 95.5
branch 64 80 80.0
condition 20 38 52.6
subroutine 26 26 100.0
pod 11 11 100.0
total 337 381 88.4


line stmt bran cond sub pod time code
1             package Zonemaster::Engine::Test::Delegation;
2              
3 26     26   10576 use version; our $VERSION = version->declare("v1.0.7");
  26         67  
  26         159  
4              
5 26     26   2141 use strict;
  26         54  
  26         528  
6 26     26   115 use warnings;
  26         51  
  26         605  
7              
8 26     26   509 use 5.014002;
  26         122  
9              
10 26     26   271 use Zonemaster::Engine;
  26         172  
  26         500  
11 26     26   128 use Zonemaster::Engine::Util;
  26         52  
  26         1642  
12 26     26   160 use Zonemaster::Engine::Test::Address;
  26         51  
  26         514  
13 26     26   119 use Zonemaster::Engine::Test::Syntax;
  26         54  
  26         483  
14 26     26   124 use Zonemaster::Engine::TestMethods;
  26         49  
  26         538  
15 26     26   130 use Zonemaster::Engine::Constants ':all';
  26         64  
  26         5600  
16              
17 26     26   176 use Zonemaster::Engine::Net::IP;
  26         56  
  26         1171  
18 26     26   143 use List::MoreUtils qw[uniq];
  26         53  
  26         189  
19 26     26   15875 use Zonemaster::LDNS::Packet;
  26         108818  
  26         544  
20 26     26   132 use Zonemaster::LDNS::RR;
  26         52  
  26         52449  
21              
22             ###
23             ### Entry points
24             ###
25              
26             sub all {
27 6     6 1 30 my ( $class, $zone ) = @_;
28 6         16 my @results;
29              
30 6 50       29 push @results, $class->delegation01( $zone ) if Zonemaster::Engine->config->should_run( 'delegation01' );
31 6 50       32 push @results, $class->delegation02( $zone ) if Zonemaster::Engine->config->should_run( 'delegation02' );
32 6 50       30 push @results, $class->delegation03( $zone ) if Zonemaster::Engine->config->should_run( 'delegation03' );
33 6 50       27 push @results, $class->delegation04( $zone ) if Zonemaster::Engine->config->should_run( 'delegation04' );
34 6 50       26 push @results, $class->delegation05( $zone ) if Zonemaster::Engine->config->should_run( 'delegation05' );
35 6 50       28 push @results, $class->delegation06( $zone ) if Zonemaster::Engine->config->should_run( 'delegation06' );
36 6 50       31 push @results, $class->delegation07( $zone ) if Zonemaster::Engine->config->should_run( 'delegation07' );
37              
38 6         48 return @results;
39             }
40              
41             ###
42             ### Metadata Exposure
43             ###
44              
45             sub metadata {
46 3     3 1 7 my ( $class ) = @_;
47              
48             return {
49 3         68 delegation01 => [
50             qw(
51             ENOUGH_NS_GLUE
52             NOT_ENOUGH_NS_GLUE
53             ENOUGH_NS
54             NOT_ENOUGH_NS
55             ENOUGH_NS_TOTAL
56             NOT_ENOUGH_NS_TOTAL
57             )
58             ],
59             delegation02 => [
60             qw(
61             SAME_IP_ADDRESS
62             )
63             ],
64             delegation03 => [
65             qw(
66             REFERRAL_SIZE_LARGE
67             REFERRAL_SIZE_OK
68             )
69             ],
70             delegation04 => [
71             qw(
72             IS_NOT_AUTHORITATIVE
73             IPV4_DISABLED
74             IPV6_DISABLED
75             ARE_AUTHORITATIVE
76             )
77             ],
78             delegation05 => [
79             qw(
80             NS_RR_IS_CNAME
81             )
82             ],
83             delegation06 => [
84             qw(
85             SOA_NOT_EXISTS
86             IPV4_DISABLED
87             IPV6_DISABLED
88             )
89             ],
90             delegation07 => [
91             qw(
92             EXTRA_NAME_PARENT
93             EXTRA_NAME_CHILD
94             TOTAL_NAME_MISMATCH
95             NAMES_MATCH
96             )
97             ],
98             };
99             } ## end sub metadata
100              
101             sub translation {
102             return {
103 1     1 1 20 "REFERRAL_SIZE_LARGE" =>
104             "The smallest possible legal referral packet is larger than 512 octets (it is {size}).",
105             "EXTRA_NAME_CHILD" => "Child has nameserver(s) not listed at parent ({extra}).",
106             "REFERRAL_SIZE_OK" => "The smallest possible legal referral packet is smaller than 513 octets (it is {size}).",
107             "IS_NOT_AUTHORITATIVE" => "Nameserver {ns} response is not authoritative on {proto} port 53.",
108             "ENOUGH_NS_GLUE" => "Parent lists enough ({count}) nameservers ({glue}). Lower limit set to {minimum}.",
109             "NS_RR_IS_CNAME" => "Nameserver {ns} {address_type} RR point to CNAME.",
110             "SAME_IP_ADDRESS" => "IP {address} refers to multiple nameservers ({nss}).",
111             "DISTINCT_IP_ADDRESS" => "All the IP addresses used by the nameservers are unique",
112             "ENOUGH_NS" => "Child lists enough ({count}) nameservers ({ns}). Lower limit set to {minimum}.",
113             "NAMES_MATCH" => "All of the nameserver names are listed both at parent and child.",
114             "TOTAL_NAME_MISMATCH" => "None of the nameservers listed at the parent are listed at the child.",
115             "SOA_NOT_EXISTS" => "A SOA query NOERROR response from {ns} was received empty.",
116             "EXTRA_NAME_PARENT" => "Parent has nameserver(s) not listed at the child ({extra}).",
117             "NOT_ENOUGH_NS_GLUE" => "Parent does not list enough ({count}) nameservers ({glue}). Lower limit set to {minimum}.",
118             "NOT_ENOUGH_NS" => "Child does not list enough ({count}) nameservers ({ns}). Lower limit set to {minimum}.",
119             "ARE_AUTHORITATIVE" => "All these nameservers are confirmed to be authoritative : {nsset}.",
120             "NS_RR_NO_CNAME" => "No nameserver point to CNAME alias.",
121             "SOA_EXISTS" => "All the nameservers have SOA record.",
122             "ENOUGH_NS_TOTAL" => "Parent and child list enough ({count}) nameservers ({ns}). Lower limit set to {minimum}.",
123             "NOT_ENOUGH_NS_TOTAL" =>
124             "Parent and child do not list enough ({count}) nameservers ({ns}). Lower limit set to {minimum}.",
125             'IPV4_DISABLED' => 'IPv4 is disabled, not sending "{rrtype}" query to {ns}/{address}.',
126             'IPV6_DISABLED' => 'IPv6 is disabled, not sending "{rrtype}" query to {ns}/{address}.',
127             };
128             } ## end sub translation
129              
130             sub version {
131 6     6 1 83 return "$Zonemaster::Engine::Test::Delegation::VERSION";
132             }
133              
134             ###
135             ### Tests
136             ###
137              
138             sub delegation01 {
139 6     6 1 22 my ( $class, $zone ) = @_;
140 6         12 my @results;
141              
142 6         12 my @parent_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) };
  13         37  
  6         40  
143              
144 6 100       58 if ( scalar( @parent_nsnames ) >= $MINIMUM_NUMBER_OF_NAMESERVERS ) {
145 5         73 push @results,
146             info(
147             ENOUGH_NS_GLUE => {
148             count => scalar( @parent_nsnames ),
149             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
150             glue => join( q{;}, sort @parent_nsnames ),
151             }
152             );
153             }
154             else {
155 1         11 push @results,
156             info(
157             NOT_ENOUGH_NS_GLUE => {
158             count => scalar( @parent_nsnames ),
159             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
160             glue => join( q{;}, sort @parent_nsnames ),
161             }
162             );
163             }
164              
165 6         18 my @child_nsnames = map { $_->string } @{ Zonemaster::Engine::TestMethods->method3( $zone ) };
  13         45  
  6         36  
166              
167 6 100       160 if ( scalar( @child_nsnames ) >= $MINIMUM_NUMBER_OF_NAMESERVERS ) {
168 5         80 push @results,
169             info(
170             ENOUGH_NS => {
171             count => scalar( @child_nsnames ),
172             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
173             ns => join( q{;}, sort @child_nsnames ),
174             }
175             );
176             }
177             else {
178 1         12 push @results,
179             info(
180             NOT_ENOUGH_NS => {
181             count => scalar( @child_nsnames ),
182             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
183             ns => join( q{;}, sort @child_nsnames ),
184             }
185             );
186             }
187              
188 26         80 my @all_nsnames = uniq map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) },
  6         35  
189 6         19 @{ Zonemaster::Engine::TestMethods->method3( $zone ) };
  6         25  
190              
191 6 100       197 if ( scalar( @all_nsnames ) >= $MINIMUM_NUMBER_OF_NAMESERVERS ) {
192 5         100 push @results,
193             info(
194             ENOUGH_NS_TOTAL => {
195             count => scalar( @all_nsnames ),
196             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
197             ns => join( q{;}, sort @all_nsnames ),
198             }
199             );
200             }
201             else {
202 1         11 push @results,
203             info(
204             NOT_ENOUGH_NS_TOTAL => {
205             count => scalar( @all_nsnames ),
206             minimum => $MINIMUM_NUMBER_OF_NAMESERVERS,
207             ns => join( q{;}, sort @all_nsnames ),
208             }
209             );
210             }
211              
212 6         43 return @results;
213             } ## end sub delegation01
214              
215             sub delegation02 {
216 6     6 1 22 my ( $class, $zone ) = @_;
217 6         22 my @results;
218             my %nsnames_and_ip;
219 6         0 my %ips;
220              
221 6         14 foreach
222 6         33 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  6         38  
223             {
224              
225 38 100       2410 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
226              
227 21         1047 push @{ $ips{ $local_ns->address->short } }, $local_ns->name->string;
  21         555  
228              
229 21         538 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
230              
231             }
232              
233 6         333 foreach my $local_ip ( sort keys %ips ) {
234 19 100       31 if ( scalar @{ $ips{$local_ip} } > 1 ) {
  19         56  
235             push @results,
236             info(
237             SAME_IP_ADDRESS => {
238 2         8 nss => join( q{;}, @{ $ips{$local_ip} } ),
  2         24  
239             address => $local_ip,
240             }
241             );
242             }
243             }
244              
245 6 100 66     50 if ( scalar keys %ips and not scalar @results ) {
246 5         25 push @results, info( DISTINCT_IP_ADDRESS => {} );
247             }
248              
249 6         43 return @results;
250             } ## end sub delegation02
251              
252             sub delegation03 {
253 7     7 1 29 my ( $class, $zone ) = @_;
254 7         20 my @results;
255             my %nsnames_and_ip;
256              
257 52         124 my @nsnames = uniq map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) },
  7         39  
258 7         17 @{ Zonemaster::Engine::TestMethods->method3( $zone ) };
  7         37  
259 7         204 my @needs_glue;
260              
261 7         20 foreach
262 7         36 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  7         32  
263             {
264 86 100       6416 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
265 50 100       4210 if ( $zone->is_in_zone( $local_ns->name->string ) ) {
266 6         17 push @needs_glue, $local_ns;
267             }
268 50         1234 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
269             }
270 7         406 @needs_glue = sort { length( $a->name->string ) <=> length( $b->name->string ) } @needs_glue;
  5         128  
271 7         23 my @needs_v4_glue = grep { $_->address->version == $IP_VERSION_4 } @needs_glue;
  6         211  
272 7         33 my @needs_v6_glue = grep { $_->address->version == $IP_VERSION_6 } @needs_glue;
  6         167  
273 7         189 my $long_name = _max_length_name_for( $zone->name );
274              
275 7         118 my $p = Zonemaster::LDNS::Packet->new( $long_name, q{NS}, q{IN} );
276              
277 7         24 foreach my $ns ( @nsnames ) {
278 28         775 my $rr = Zonemaster::LDNS::RR->new( sprintf( q{%s IN NS %s}, $zone->name, $ns ) );
279 28         1147 $p->unique_push( q{authority}, $rr );
280             }
281              
282 7 100       29 if ( @needs_v4_glue ) {
283 2         7 my $ns = $needs_v4_glue[0];
284 2         61 my $rr = Zonemaster::LDNS::RR->new( sprintf( q{%s IN A %s}, $ns->name, $ns->address->short ) );
285 2         85 $p->unique_push( q{additional}, $rr );
286             }
287              
288 7 100       27 if ( @needs_v6_glue ) {
289 1         3 my $ns = $needs_v6_glue[0];
290 1         30 my $rr = Zonemaster::LDNS::RR->new( sprintf( q{%s IN AAAA %s}, $ns->name, $ns->address->short ) );
291 1         34 $p->unique_push( q{additional}, $rr );
292             }
293              
294 7         42 my $size = length( $p->data );
295 7 50       244 if ( $size > $UDP_PAYLOAD_LIMIT ) {
296 0         0 push @results,
297             info(
298             REFERRAL_SIZE_LARGE => {
299             size => $size,
300             }
301             );
302             }
303             else {
304 7         86 push @results,
305             info(
306             REFERRAL_SIZE_OK => {
307             size => $size,
308             }
309             );
310             }
311              
312 7         284 return @results;
313             } ## end sub delegation03
314              
315             sub delegation04 {
316 6     6 1 22 my ( $class, $zone ) = @_;
317 6         20 my @results;
318             my %nsnames;
319 6         0 my @authoritatives;
320 6         14 my $query_type = q{SOA};
321              
322 6         11 foreach
323 6         26 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  6         24  
324             {
325              
326 38 50 33     107 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
327 0         0 push @results,
328             info(
329             IPV6_DISABLED => {
330             ns => $local_ns->name->string,
331             address => $local_ns->address->short,
332             rrtype => $query_type,
333             }
334             );
335 0         0 next;
336             }
337              
338 38 50 33     82 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
339 0         0 push @results,
340             info(
341             IPV4_DISABLED => {
342             ns => $local_ns->name->string,
343             address => $local_ns->address->short,
344             rrtype => $query_type,
345             }
346             );
347 0         0 next;
348             }
349              
350 38 100       1012 next if $nsnames{ $local_ns->name->string };
351              
352 15         40 foreach my $usevc ( 0, 1 ) {
353 30         798 my $p = $local_ns->query( $zone->name, $query_type, { usevc => $usevc } );
354 30 100       89 if ( $p ) {
355 27 100       111 if ( not $p->aa ) {
356 2 100       75 push @results,
357             info(
358             IS_NOT_AUTHORITATIVE => {
359             ns => $local_ns->name->string,
360             proto => $usevc ? q{TCP} : q{UDP},
361             }
362             );
363             }
364             else {
365 25         1009 push @authoritatives, $local_ns->name->string;
366             }
367             }
368             }
369              
370 15         391 $nsnames{ $local_ns->name }++;
371             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
372              
373 6 50 50     31 if (
      66        
      100        
374             (
375             scalar @{ Zonemaster::Engine::TestMethods->method4( $zone ) }
376             or scalar @{ Zonemaster::Engine::TestMethods->method5( $zone ) }
377             )
378             and not scalar @results
379             and scalar @authoritatives
380             )
381             {
382 5         87 push @results,
383             info(
384             ARE_AUTHORITATIVE => {
385             nsset => join( q{,}, uniq sort @authoritatives ),
386             }
387             );
388             }
389              
390 6         31 return @results;
391             } ## end sub delegation04
392              
393             sub delegation05 {
394 6     6 1 19 my ( $class, $zone ) = @_;
395 6         15 my @results;
396              
397 26         68 my @nsnames = uniq map { $_->string } @{ Zonemaster::Engine::TestMethods->method2( $zone ) },
  6         23  
398 6         11 @{ Zonemaster::Engine::TestMethods->method3( $zone ) };
  6         25  
399              
400 6         171 foreach my $local_nsname ( @nsnames ) {
401              
402 15         43 foreach my $address_type ( q{A}, q{AAAA} ) {
403 30         124 my $p = $zone->query_one( $local_nsname, $address_type );
404 30 50       110 if ( $p ) {
405 30 50       861 if ( $p->has_rrs_of_type_for_name( q{CNAME}, $zone->name ) ) {
406 0         0 push @results,
407             info(
408             NS_RR_IS_CNAME => {
409             ns => $local_nsname,
410             address_type => $address_type,
411             }
412             );
413             }
414             }
415             }
416              
417             }
418              
419 6 50 50     13 if (
      33        
420             (
421             scalar @{ Zonemaster::Engine::TestMethods->method2( $zone ) }
422             or scalar @{ Zonemaster::Engine::TestMethods->method3( $zone ) }
423             )
424             and not scalar @results
425             )
426             {
427 6         32 push @results, info( NS_RR_NO_CNAME => {} );
428             }
429              
430 6         30 return @results;
431             } ## end sub delegation05
432              
433             sub delegation06 {
434 6     6 1 22 my ( $class, $zone ) = @_;
435 6         17 my @results;
436             my %nsnames;
437 6         18 my $query_type = q{SOA};
438              
439 6         13 foreach
440 6         29 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  6         221  
441             {
442              
443 38 50 33     122 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
444 0         0 push @results,
445             info(
446             IPV6_DISABLED => {
447             ns => $local_ns->name->string,
448             address => $local_ns->address->short,
449             rrtype => $query_type,
450             }
451             );
452 0         0 next;
453             }
454              
455 38 50 33     96 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
456 0         0 push @results,
457             info(
458             IPV4_DISABLED => {
459             ns => $local_ns->name->string,
460             address => $local_ns->address->short,
461             rrtype => $query_type,
462             }
463             );
464 0         0 next;
465             }
466              
467 38 100       1140 next if $nsnames{ $local_ns->name->string };
468              
469 15         441 my $p = $local_ns->query( $zone->name, $query_type );
470 15 100 66     129 if ( $p and $p->rcode eq q{NOERROR} ) {
471 14 100       331 if ( not $p->get_records( $query_type, q{answer} ) ) {
472 1         29 push @results,
473             info(
474             SOA_NOT_EXISTS => {
475             ns => $local_ns->name->string,
476             }
477             );
478             }
479             }
480              
481 15         538 $nsnames{ $local_ns->name->string }++;
482             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
483              
484 6 100 50     29 if (
      66        
485             (
486             scalar @{ Zonemaster::Engine::TestMethods->method4( $zone ) }
487             or scalar @{ Zonemaster::Engine::TestMethods->method5( $zone ) }
488             )
489             and not scalar @results
490             )
491             {
492 5         34 push @results, info( SOA_EXISTS => {} );
493             }
494              
495 6         25 return @results;
496             } ## end sub delegation06
497              
498             sub delegation07 {
499 6     6 1 35 my ( $class, $zone ) = @_;
500 6         15 my @results;
501              
502             my %names;
503 6         14 foreach my $name ( @{ Zonemaster::Engine::TestMethods->method2( $zone ) } ) {
  6         29  
504 13         44 $names{$name} += 1;
505             }
506 6         16 foreach my $name ( @{ Zonemaster::Engine::TestMethods->method3( $zone ) } ) {
  6         26  
507 13         35 $names{$name} -= 1;
508             }
509              
510 6         281 my @same_name = sort grep { $names{$_} == 0 } keys %names;
  15         67  
511 6         21 my @extra_name_parent = sort grep { $names{$_} > 0 } keys %names;
  15         47  
512 6         20 my @extra_name_child = sort grep { $names{$_} < 0 } keys %names;
  15         39  
513              
514 6 100       28 if ( @extra_name_parent ) {
515 1         14 push @results,
516             info(
517             EXTRA_NAME_PARENT => {
518             extra => join( q{;}, sort @extra_name_parent ),
519             }
520             );
521             }
522              
523 6 100       25 if ( @extra_name_child ) {
524 1         14 push @results,
525             info(
526             EXTRA_NAME_CHILD => {
527             extra => join( q{;}, sort @extra_name_child ),
528             }
529             );
530             }
531              
532 6 100 66     39 if ( @extra_name_parent == 0 and @extra_name_child == 0 ) {
533 5         42 push @results,
534             info(
535             NAMES_MATCH => {
536             names => join( q{;}, sort @same_name ),
537             }
538             );
539             }
540              
541 6 100       27 if ( scalar( @same_name ) == 0 ) {
542 1         19 push @results,
543             info(
544             TOTAL_NAME_MISMATCH => {
545             glue => join( q{;}, sort @extra_name_parent ),
546             child => join( q{;}, sort @extra_name_child ),
547             }
548             );
549             }
550              
551 6         38 return @results;
552             } ## end sub delegation07
553              
554             ###
555             ### Helper functions
556             ###
557              
558             # Make up a name of maximum length in the given domain
559             sub _max_length_name_for {
560 7     7   20 my ( $top ) = @_;
561 7         47 my @chars = q{A} .. q{Z};
562              
563 7         34 my $name = name( $top )->fqdn;
564 7 100       178 $name = q{} if $name eq q{.}; # Special case for root zone
565              
566 7         49 while ( length( $name ) < $FQDN_MAX_LENGTH - 1 ) {
567 28         167 my $len = $FQDN_MAX_LENGTH - length( $name ) - 1;
568 28 100       145 $len = $LABEL_MAX_LENGTH if $len > $LABEL_MAX_LENGTH;
569 28         225 $name = join( q{}, map { $chars[ rand @chars ] } 1 .. $len ) . q{.} . $name;
  1674         2909  
570             }
571              
572 7         52 return $name;
573             }
574              
575             1;
576              
577             =head1 NAME
578              
579             Zonemaster::Engine::Test::Delegation - Tests regarding delegation details
580              
581             =head1 SYNOPSIS
582              
583             my @results = Zonemaster::Engine::Test::Delegation->all($zone);
584              
585             =head1 METHODS
586              
587             =over
588              
589             =item all($zone)
590              
591             Runs the default set of tests and returns a list of log entries made by the tests.
592              
593             =item translation()
594              
595             Returns a refernce to a hash with translation data. Used by the builtin translation system.
596              
597             =item metadata()
598              
599             Returns a reference to a hash, the keys of which are the names of all test methods in the module, and the corresponding values are references to
600             lists with all the tags that the method can use in log entries.
601              
602             =item version()
603              
604             Returns a version string for the module.
605              
606             =back
607              
608             =head1 TESTS
609              
610             =over
611              
612             =item delegation01($zone)
613              
614             Verify that there is more than two nameserver.
615              
616             =item delegation02($zone)
617              
618             Verify that name servers have distinct IP addresses.
619              
620             =item delegation03($zone)
621              
622             Verify that there is no truncation on referrals.
623              
624             =item delegation04($zone)
625              
626             Verify that nameservers are authoritative.
627              
628             =item delegation05($zone)
629              
630             Verify that NS RRs do not point to CNAME alias.
631              
632             =item delegation06($zone)
633              
634             Verify existence of SOA.
635              
636             =item delegation07($zone)
637              
638             Verify that parent glue name records are present in child.
639              
640             =back
641              
642             =cut