File Coverage

blib/lib/Zonemaster/Engine/Test/Consistency.pm
Criterion Covered Total %
statement 177 202 87.6
branch 58 76 76.3
condition 10 27 37.0
subroutine 18 18 100.0
pod 9 9 100.0
total 272 332 81.9


line stmt bran cond sub pod time code
1             package Zonemaster::Engine::Test::Consistency;
2              
3 26     26   9643 use version; our $VERSION = version->declare("v1.1.2");
  26         55  
  26         132  
4              
5 26     26   2063 use strict;
  26         63  
  26         461  
6 26     26   115 use warnings;
  26         50  
  26         645  
7              
8 26     26   333 use 5.014002;
  26         86  
9              
10 26     26   125 use Zonemaster::Engine;
  26         55  
  26         452  
11 26     26   116 use Zonemaster::Engine::Util;
  26         163  
  26         1283  
12 26     26   152 use Zonemaster::Engine::Test::Address;
  26         55  
  26         652  
13 26     26   131 use Zonemaster::Engine::Constants qw[:ip :soa];
  26         54  
  26         4568  
14              
15 26     26   167 use List::MoreUtils qw[uniq];
  26         53  
  26         244  
16              
17             ###
18             ### Entry points
19             ###
20              
21             sub all {
22 12     12 1 33 my ( $class, $zone ) = @_;
23 12         20 my @results;
24              
25 12 100       37 if ( Zonemaster::Engine->config->should_run( 'consistency01' ) ) {
26 8         34 push @results, $class->consistency01( $zone );
27             }
28 12 100       52 if ( Zonemaster::Engine->config->should_run( 'consistency02' ) ) {
29 8         48 push @results, $class->consistency02( $zone );
30             }
31 12 100       45 if ( Zonemaster::Engine->config->should_run( 'consistency03' ) ) {
32 8         43 push @results, $class->consistency03( $zone );
33             }
34 12 100       45 if ( Zonemaster::Engine->config->should_run( 'consistency04' ) ) {
35 8         43 push @results, $class->consistency04( $zone );
36             }
37 12 100       49 if ( Zonemaster::Engine->config->should_run( 'consistency05' ) ) {
38 8         43 push @results, $class->consistency05( $zone );
39             }
40              
41 12         55 return @results;
42             }
43              
44             ###
45             ### Metadata Exposure
46             ###
47              
48             sub metadata {
49 2     2 1 6 my ( $class ) = @_;
50              
51             return {
52 2         28 consistency01 => [
53             qw(
54             NO_RESPONSE
55             NO_RESPONSE_SOA_QUERY
56             ONE_SOA_SERIAL
57             MULTIPLE_SOA_SERIALS
58             SOA_SERIAL
59             SOA_SERIAL_VARIATION
60             IPV4_DISABLED
61             IPV6_DISABLED
62             )
63             ],
64             consistency02 => [
65             qw(
66             NO_RESPONSE
67             NO_RESPONSE_SOA_QUERY
68             ONE_SOA_RNAME
69             MULTIPLE_SOA_RNAMES
70             SOA_RNAME
71             IPV4_DISABLED
72             IPV6_DISABLED
73             )
74             ],
75             consistency03 => [
76             qw(
77             NO_RESPONSE
78             NO_RESPONSE_SOA_QUERY
79             ONE_SOA_TIME_PARAMETER_SET
80             MULTIPLE_SOA_TIME_PARAMETER_SET
81             SOA_TIME_PARAMETER_SET
82             IPV4_DISABLED
83             IPV6_DISABLED
84             )
85             ],
86             consistency04 => [
87             qw(
88             NO_RESPONSE
89             NO_RESPONSE_NS_QUERY
90             ONE_NS_SET
91             MULTIPLE_NS_SET
92             NS_SET
93             IPV4_DISABLED
94             IPV6_DISABLED
95             )
96             ],
97             consistency05 => [
98             qw(
99             EXTRA_ADDRESS_PARENT
100             EXTRA_ADDRESS_CHILD
101             TOTAL_ADDRESS_MISMATCH
102             ADDRESSES_MATCH
103             )
104             ],
105             };
106             } ## end sub metadata
107              
108             sub translation {
109             return {
110 1     1 1 22 'SOA_TIME_PARAMETER_SET' =>
111             'Saw SOA time parameter set (REFRESH={refresh},RETRY={retry},EXPIRE={expire},MINIMUM={minimum}) on following nameserver set : {servers}.',
112             'ONE_SOA_RNAME' => 'A single SOA rname value was seen ({rname})',
113             'MULTIPLE_SOA_SERIALS' => 'Saw {count} SOA serial numbers.',
114             'SOA_SERIAL' => 'Saw SOA serial number {serial} on following nameserver set : {servers}.',
115             'SOA_RNAME' => 'Saw SOA rname {rname} on following nameserver set : {servers}.',
116             'MULTIPLE_SOA_RNAMES' => 'Saw {count} SOA rname.',
117             'ONE_SOA_SERIAL' => 'A single SOA serial number was seen ({serial}).',
118             'MULTIPLE_SOA_TIME_PARAMETER_SET' => 'Saw {count} SOA time parameter set.',
119             'NO_RESPONSE' => 'Nameserver {ns}/{address} did not respond.',
120             'ONE_SOA_TIME_PARAMETER_SET' =>
121             'A single SOA time parameter set was seen (REFRESH={refresh},RETRY={retry},EXPIRE={expire},MINIMUM={minimum}).',
122             'NO_RESPONSE_SOA_QUERY' => 'No response from nameserver {ns}/{address} on SOA queries.',
123             'SOA_SERIAL_VARIATION' =>
124             'Difference between the smaller serial ({serial_min}) and the bigger one ({serial_max}) is greater than the maximum allowed ({max_variation}).',
125             'NO_RESPONSE_NS_QUERY' => 'No response from nameserver {ns}/{address} on NS queries.',
126             'ONE_NS_SET' => 'A unique NS set was seen ({nsset}).',
127             'MULTIPLE_NS_SET' => 'Saw {count} NS set.',
128             'NS_SET' => 'Saw NS set ({nsset}) on following nameserver set : {servers}.',
129             'IPV4_DISABLED' => 'IPv4 is disabled, not sending "{rrtype}" query to {ns}/{address}.',
130             'IPV6_DISABLED' => 'IPv6 is disabled, not sending "{rrtype}" query to {ns}/{address}.',
131             'EXTRA_ADDRESS_PARENT' => 'Parent has extra nameserver IP address(es) not listed at child ({addresses}).',
132             'EXTRA_ADDRESS_CHILD' => 'Child has extra nameserver IP address(es) not listed at parent ({addresses}).',
133             'TOTAL_ADDRESS_MISMATCH' => 'No common nameserver IP addresses between child ({child}) and parent ({glue}).',
134             'ADDRESSES_MATCH' => 'Glue records are consistent between glue and authoritative data.',
135             };
136             } ## end sub translation
137              
138             sub version {
139 12     12 1 127 return "$Zonemaster::Engine::Test::Consistency::VERSION";
140             }
141              
142             ###
143             ### Tests
144             ###
145              
146             sub consistency01 {
147 8     8 1 24 my ( $class, $zone ) = @_;
148 8         30 my @results;
149             my %nsnames_and_ip;
150 8         0 my %serials;
151 8         17 my $query_type = q{SOA};
152              
153 8         16 foreach
154 8         48 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  8         64  
155             {
156              
157 72 100       4983 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
158              
159 39 50 33     2348 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
160 0         0 push @results,
161             info(
162             IPV6_DISABLED => {
163             ns => $local_ns->name->string,
164             address => $local_ns->address->short,
165             rrtype => $query_type,
166             }
167             );
168 0         0 next;
169             }
170              
171 39 50 33     127 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
172 0         0 push @results,
173             info(
174             IPV4_DISABLED => {
175             ns => $local_ns->name->string,
176             address => $local_ns->address->short,
177             rrtype => $query_type,
178             }
179             );
180 0         0 next;
181             }
182              
183 39         1147 my $p = $local_ns->query( $zone->name, $query_type );
184              
185 39 100       116 if ( not $p ) {
186 2         59 push @results,
187             info(
188             NO_RESPONSE => {
189             ns => $local_ns->name->string,
190             address => $local_ns->address->short,
191             }
192             );
193 2         8 next;
194             }
195              
196 37         911 my ( $soa ) = $p->get_records_for_name( $query_type, $zone->name );
197              
198 37 50       215 if ( not $soa ) {
199 0         0 push @results,
200             info(
201             NO_RESPONSE_SOA_QUERY => {
202             ns => $local_ns->name->string,
203             address => $local_ns->address->short,
204             }
205             );
206 0         0 next;
207             }
208             else {
209 37         682 push @{ $serials{ $soa->serial } }, $local_ns->name->string . q{/} . $local_ns->address->short;
  37         1139  
210 37         3189 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
211             }
212             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
213              
214 8         542 my @serial_numbers = sort keys %serials;
215 8 100       38 if ( scalar( @serial_numbers ) == 1 ) {
    50          
216 7         49 push @results,
217             info(
218             ONE_SOA_SERIAL => {
219             serial => ( keys %serials )[0],
220             }
221             );
222             }
223             elsif ( scalar @serial_numbers ) {
224 1         7 push @results,
225             info(
226             MULTIPLE_SOA_SERIALS => {
227             count => scalar( keys %serials ),
228             }
229             );
230 1         4 foreach my $serial ( keys %serials ) {
231             push @results,
232             info(
233             SOA_SERIAL => {
234             serial => $serial,
235 2         4 servers => join( q{;}, sort @{ $serials{$serial} } ),
  2         11  
236             }
237             );
238             }
239 1 50       10 if ( $serial_numbers[-1] - $serial_numbers[0] > $MAX_SERIAL_VARIATION ) {
240 1         15 push @results,
241             info(
242             SOA_SERIAL_VARIATION => {
243             serial_min => $serial_numbers[0],
244             serial_max => $serial_numbers[-1],
245             max_variation => $MAX_SERIAL_VARIATION,
246             }
247             );
248             }
249             } ## end elsif ( scalar @serial_numbers)
250              
251 8         64 return @results;
252             } ## end sub consistency01
253              
254             sub consistency02 {
255 8     8 1 27 my ( $class, $zone ) = @_;
256 8         25 my @results;
257             my %nsnames_and_ip;
258 8         0 my %rnames;
259 8         16 my $query_type = q{SOA};
260              
261 8         19 foreach
262 8         48 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  8         40  
263             {
264              
265 72 100       5115 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
266              
267 39 50 33     2234 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
268 0         0 push @results,
269             info(
270             IPV6_DISABLED => {
271             ns => $local_ns->name->string,
272             address => $local_ns->address->short,
273             rrtype => $query_type,
274             }
275             );
276 0         0 next;
277             }
278              
279 39 50 33     104 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
280 0         0 push @results,
281             info(
282             IPV4_DISABLED => {
283             ns => $local_ns->name->string,
284             address => $local_ns->address->short,
285             rrtype => $query_type,
286             }
287             );
288 0         0 next;
289             }
290              
291 39         1098 my $p = $local_ns->query( $zone->name, $query_type );
292              
293 39 100       132 if ( not $p ) {
294 2         53 push @results,
295             info(
296             NO_RESPONSE => {
297             ns => $local_ns->name->string,
298             address => $local_ns->address->short,
299             }
300             );
301 2         8 next;
302             }
303              
304 37         939 my ( $soa ) = $p->get_records_for_name( $query_type, $zone->name );
305              
306 37 50       134 if ( not $soa ) {
307 0         0 push @results,
308             info(
309             NO_RESPONSE_SOA_QUERY => {
310             ns => $local_ns->name->string,
311             address => $local_ns->address->short,
312             }
313             );
314 0         0 next;
315             }
316             else {
317 37         668 push @{ $rnames{ lc( $soa->rname ) } }, $local_ns->name->string . q{/} . $local_ns->address->short;
  37         1312  
318 37         2929 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
319             }
320             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
321              
322 8 100       534 if ( scalar( keys %rnames ) == 1 ) {
    50          
323 7         52 push @results,
324             info(
325             ONE_SOA_RNAME => {
326             rname => ( keys %rnames )[0],
327             }
328             );
329             }
330             elsif ( scalar( keys %rnames ) ) {
331 1         6 push @results,
332             info(
333             MULTIPLE_SOA_RNAMES => {
334             count => scalar( keys %rnames ),
335             }
336             );
337 1         4 foreach my $rname ( keys %rnames ) {
338             push @results,
339             info(
340             SOA_RNAME => {
341             rname => $rname,
342 2         6 servers => join( q{;}, @{ $rnames{$rname} } ),
  2         10  
343             }
344             );
345             }
346             }
347              
348 8         55 return @results;
349             } ## end sub consistency02
350              
351             sub consistency03 {
352 8     8 1 24 my ( $class, $zone ) = @_;
353 8         24 my @results;
354             my %nsnames_and_ip;
355 8         0 my %time_parameter_sets;
356 8         20 my $query_type = q{SOA};
357              
358 8         19 foreach
359 8         43 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  8         35  
360             {
361              
362 72 100       4893 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
363              
364 39 50 33     2142 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
365 0         0 push @results,
366             info(
367             IPV6_DISABLED => {
368             ns => $local_ns->name->string,
369             address => $local_ns->address->short,
370             rrtype => $query_type,
371             }
372             );
373 0         0 next;
374             }
375              
376 39 50 33     110 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
377 0         0 push @results,
378             info(
379             IPV4_DISABLED => {
380             ns => $local_ns->name->string,
381             address => $local_ns->address->short,
382             rrtype => $query_type,
383             }
384             );
385 0         0 next;
386             }
387              
388 39         1074 my $p = $local_ns->query( $zone->name, $query_type );
389              
390 39 100       117 if ( not $p ) {
391 2         58 push @results,
392             info(
393             NO_RESPONSE => {
394             ns => $local_ns->name->string,
395             address => $local_ns->address->short,
396             }
397             );
398 2         7 next;
399             }
400              
401 37         935 my ( $soa ) = $p->get_records_for_name( $query_type, $zone->name );
402              
403 37 50       137 if ( not $soa ) {
404 0         0 push @results,
405             info(
406             NO_RESPONSE_SOA_QUERY => {
407             ns => $local_ns->name->string,
408             address => $local_ns->address->short,
409             }
410             );
411 0         0 next;
412             }
413             else {
414             push
415 37         676 @{ $time_parameter_sets{ sprintf q{%d;%d;%d;%d}, $soa->refresh, $soa->retry, $soa->expire, $soa->minimum }
  37         1407  
416             },
417             $local_ns->name->string . q{/} . $local_ns->address->short;
418 37         2959 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
419             }
420             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
421              
422 8 100       518 if ( scalar( keys %time_parameter_sets ) == 1 ) {
    50          
423 7         48 my ( $refresh, $retry, $expire, $minimum ) = split /;/sxm, ( keys %time_parameter_sets )[0];
424 7         58 push @results,
425             info(
426             ONE_SOA_TIME_PARAMETER_SET => {
427             refresh => $refresh,
428             retry => $retry,
429             expire => $expire,
430             minimum => $minimum,
431             }
432             );
433             }
434             elsif ( scalar( keys %time_parameter_sets ) ) {
435 1         8 push @results,
436             info(
437             MULTIPLE_SOA_TIME_PARAMETER_SET => {
438             count => scalar( keys %time_parameter_sets ),
439             }
440             );
441 1         8 foreach my $time_parameter_set ( keys %time_parameter_sets ) {
442 2         12 my ( $refresh, $retry, $expire, $minimum ) = split /;/sxm, $time_parameter_set;
443             push @results,
444             info(
445             SOA_TIME_PARAMETER_SET => {
446             refresh => $refresh,
447             retry => $retry,
448             expire => $expire,
449             minimum => $minimum,
450 2         9 servers => join( q{;}, sort @{ $time_parameter_sets{$time_parameter_set} } ),
  2         20  
451             }
452             );
453             }
454             } ## end elsif ( scalar( keys %time_parameter_sets...))
455              
456 8         60 return @results;
457             } ## end sub consistency03
458              
459             sub consistency04 {
460 8     8 1 23 my ( $class, $zone ) = @_;
461 8         513 my @results;
462             my %nsnames_and_ip;
463 8         0 my %ns_sets;
464 8         20 my $query_type = q{NS};
465              
466 8         16 foreach
467 8         42 my $local_ns ( @{ Zonemaster::Engine::TestMethods->method4( $zone ) }, @{ Zonemaster::Engine::TestMethods->method5( $zone ) } )
  8         36  
468             {
469              
470 72 100       4741 next if $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short };
471              
472 39 50 33     2202 if ( not Zonemaster::Engine->config->ipv6_ok and $local_ns->address->version == $IP_VERSION_6 ) {
473 0         0 push @results,
474             info(
475             IPV6_DISABLED => {
476             ns => $local_ns->name->string,
477             address => $local_ns->address->short,
478             rrtype => $query_type,
479             }
480             );
481 0         0 next;
482             }
483              
484 39 50 33     108 if ( not Zonemaster::Engine->config->ipv4_ok and $local_ns->address->version == $IP_VERSION_4 ) {
485 0         0 push @results,
486             info(
487             IPV4_DISABLED => {
488             ns => $local_ns->name->string,
489             address => $local_ns->address->short,
490             rrtype => $query_type,
491             }
492             );
493 0         0 next;
494             }
495              
496 39         1084 my $p = $local_ns->query( $zone->name, $query_type );
497              
498 39 100       122 if ( not $p ) {
499 2         54 push @results,
500             info(
501             NO_RESPONSE => {
502             ns => $local_ns->name->string,
503             address => $local_ns->address->short,
504             }
505             );
506 2         7 next;
507             }
508              
509 37         954 my ( @ns ) = sort map { lc( $_->nsdname ) } $p->get_records_for_name( $query_type, $zone->name );
  145         901  
510              
511 37 50       238 if ( not scalar( @ns ) ) {
512 0         0 push @results,
513             info(
514             NO_RESPONSE_NS_QUERY => {
515             ns => $local_ns->name->string,
516             address => $local_ns->address->short,
517             }
518             );
519 0         0 next;
520             }
521             else {
522 37         74 push @{ $ns_sets{ join( q{,}, @ns ) } }, $local_ns->name->string . q{/} . $local_ns->address->short;
  37         1148  
523 37         3075 $nsnames_and_ip{ $local_ns->name->string . q{/} . $local_ns->address->short }++;
524             }
525             } ## end foreach my $local_ns ( @{ Zonemaster::Engine::TestMethods...})
526              
527 8 100       544 if ( scalar( keys %ns_sets ) == 1 ) {
    50          
528 7         55 push @results,
529             info(
530             ONE_NS_SET => {
531             nsset => ( keys %ns_sets )[0],
532             }
533             );
534             }
535             elsif ( scalar( keys %ns_sets ) ) {
536 1         6 push @results,
537             info(
538             MULTIPLE_NS_SET => {
539             count => scalar( keys %ns_sets ),
540             }
541             );
542 1         4 foreach my $ns_set ( keys %ns_sets ) {
543             push @results,
544             info(
545             NS_SET => {
546             nsset => $ns_set,
547 2         5 servers => join( q{;}, @{ $ns_sets{$ns_set} } ),
  2         11  
548             }
549             );
550             }
551             }
552              
553 8         60 return @results;
554             } ## end sub consistency04
555              
556             sub consistency05 {
557 8     8 1 25 my ( $class, $zone ) = @_;
558 8         20 my @results;
559              
560             my %addresses;
561 8         17 foreach my $address ( uniq map { lc( $_->address->short ) } @{ Zonemaster::Engine::TestMethods->method4( $zone ) } ) {
  37         2330  
  8         74  
562 37         589 $addresses{$address} += 1;
563             }
564 8         41 foreach my $address ( uniq map { lc( $_->address->short ) } @{ Zonemaster::Engine::TestMethods->method5( $zone ) } ) {
  35         2109  
  8         41  
565 35         515 $addresses{$address} -= 1;
566             }
567              
568 8         51 my @same_address = sort grep { $addresses{$_} == 0 } keys %addresses;
  38         98  
569 8         34 my @extra_address_parent = sort grep { $addresses{$_} > 0 } keys %addresses;
  38         71  
570 8         28 my @extra_address_child = sort grep { $addresses{$_} < 0 } keys %addresses;
  38         71  
571              
572 8 100       32 if ( @extra_address_parent ) {
573 2         12 push @results,
574             info(
575             EXTRA_ADDRESS_PARENT => {
576             addresses => join( q{;}, @extra_address_parent ),
577             }
578             );
579             }
580              
581 8 100       33 if ( @extra_address_child ) {
582 1         8 push @results,
583             info(
584             EXTRA_ADDRESS_CHILD => {
585             addresses => join( q{;}, @extra_address_child ),
586             }
587             );
588             }
589              
590 8 100 66     52 if ( @extra_address_parent == 0 and @extra_address_child == 0 ) {
591 6         46 push @results,
592             info(
593             ADDRESSES_MATCH => {
594             addresses => join( q{;}, @same_address ),
595             }
596             );
597             }
598              
599 8 50       31 if ( scalar( @same_address ) == 0 ) {
600 0         0 push @results,
601             info(
602             TOTAL_ADDRESS_MISMATCH => {
603             glue => join( q{;}, @extra_address_parent ),
604             child => join( q{;}, @extra_address_child ),
605             }
606             );
607             }
608              
609 8         40 return @results;
610             } ## end sub consistency05
611              
612             1;
613              
614             =head1 NAME
615              
616             Zonemaster::Engine::Test::Consistency - Consistency module showing the expected structure of Zonemaster test modules
617              
618             =head1 SYNOPSIS
619              
620             my @results = Zonemaster::Engine::Test::Consistency->all($zone);
621              
622             =head1 METHODS
623              
624             =over
625              
626             =item all($zone)
627              
628             Runs the default set of tests and returns a list of log entries made by the tests.
629              
630             =item metadata()
631              
632             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
633             lists with all the tags that the method can use in log entries.
634              
635             =item translation()
636              
637             Returns a refernce to a hash with translation data. Used by the builtin translation system.
638              
639             =item version()
640              
641             Returns a version string for the module.
642              
643             =back
644              
645             =head1 TESTS
646              
647             =over
648              
649             =item consistency01($zone)
650              
651             Query all nameservers for SOA, and see that they all have the same SOA serial number.
652              
653             =item consistency02($zone)
654              
655             Query all nameservers for SOA, and see that they all have the same SOA rname.
656              
657             =item consistency03($zone)
658              
659             Query all nameservers for SOA, and see that they all have the same time parameters (REFRESH/RETRY/EXPIRE/MINIMUM).
660              
661             =item consistency04($zone)
662              
663             Query all nameservers for NS set, and see that they have all the same content.
664              
665             =item consistency05($zone)
666              
667             Verify that the glue records are consistent between glue and authoritative data.
668              
669             =back
670              
671             =cut