File Coverage

blib/lib/Net/DNS/RR/SOA.pm
Criterion Covered Total %
statement 92 92 100.0
branch 24 24 100.0
condition 12 12 100.0
subroutine 20 20 100.0
pod 7 7 100.0
total 155 155 100.0


line stmt bran cond sub pod time code
1             package Net::DNS::RR::SOA;
2              
3 7     7   72 use strict;
  7         18  
  7         315  
4 7     7   46 use warnings;
  7         21  
  7         427  
5             our $VERSION = (qw$Id: SOA.pm 1931 2023-08-23 13:14:15Z willem $)[2];
6              
7 7     7   46 use base qw(Net::DNS::RR);
  7         14  
  7         694  
8              
9              
10             =head1 NAME
11              
12             Net::DNS::RR::SOA - DNS SOA resource record
13              
14             =cut
15              
16 7     7   88 use integer;
  7         20  
  7         42  
17              
18 7     7   286 use Net::DNS::DomainName;
  7         31  
  7         202  
19 7     7   4011 use Net::DNS::Mailbox;
  7         19  
  7         7645  
20              
21              
22             sub _decode_rdata { ## decode rdata from wire-format octet string
23 27     27   110 my ( $self, @argument ) = @_;
24 27         88 my ( $data, $offset, @opaque ) = @argument;
25              
26 27         100 ( $self->{mname}, $offset ) = Net::DNS::DomainName1035->decode(@argument);
27 27         230 ( $self->{rname}, $offset ) = Net::DNS::Mailbox1035->decode( $data, $offset, @opaque );
28 27         142 @{$self}{qw(serial refresh retry expire minimum)} = unpack "\@$offset N5", $$data;
  27         151  
29 27         85 return;
30             }
31              
32              
33             sub _encode_rdata { ## encode rdata as wire-format octet string
34 12     12   34 my ( $self, @argument ) = @_;
35 12         27 my ( $offset, @opaque ) = @argument;
36              
37 12         22 my $rname = $self->{rname};
38 12         41 my $rdata = $self->{mname}->encode(@argument);
39 12         86 $rdata .= $rname->encode( $offset + length($rdata), @opaque );
40 12         52 $rdata .= pack 'N5', $self->serial, @{$self}{qw(refresh retry expire minimum)};
  12         127  
41 12         122 return $rdata;
42             }
43              
44              
45             sub _format_rdata { ## format rdata portion of RR string.
46 8     8   10 my $self = shift;
47              
48 8         23 my $mname = $self->{mname}->string;
49 8         41 my $rname = $self->{rname}->string;
50 8         18 my $serial = $self->serial;
51 8 100       25 my $spacer = length "$serial" > 7 ? "" : "\t";
52 8         48 return ($mname, $rname,
53             join( "\n\t\t\t\t",
54             "\t\t\t$serial$spacer\t;serial", "$self->{refresh}\t\t;refresh",
55             "$self->{retry}\t\t;retry", "$self->{expire}\t\t;expire",
56             "$self->{minimum}\t\t;minimum\n" ) );
57             }
58              
59              
60             sub _parse_rdata { ## populate RR from rdata in argument list
61 22     22   80 my ( $self, @argument ) = @_;
62              
63 22         52 for (qw(mname rname)) { $self->$_( shift @argument ) }
  44         131  
64 22 100       99 $self->serial( shift @argument ) if scalar @argument; # possibly undefined
65 22         58 for (qw(refresh retry expire minimum)) {
66 70 100       152 last unless scalar @argument;
67 64         162 $self->$_( Net::DNS::RR::ttl( {}, shift @argument ) );
68             }
69 22         48 return;
70             }
71              
72              
73             sub _defaults { ## specify RR attribute default values
74 7     7   17 my $self = shift;
75              
76 7         26 $self->_parse_rdata(qw(. . 0 4h 1h 3w 1h));
77 7         14 delete $self->{serial};
78 7         30 return;
79             }
80              
81              
82             sub mname {
83 25     25 1 60 my ( $self, @value ) = @_;
84 25         46 for (@value) { $self->{mname} = Net::DNS::DomainName1035->new($_) }
  23         103  
85 25 100       133 return $self->{mname} ? $self->{mname}->name : undef;
86             }
87              
88              
89             sub rname {
90 25     25 1 898 my ( $self, @value ) = @_;
91 25         53 for (@value) { $self->{rname} = Net::DNS::Mailbox1035->new($_) }
  23         91  
92 25 100       143 return $self->{rname} ? $self->{rname}->address : undef;
93             }
94              
95              
96             sub serial {
97 74     74 1 1689 my ( $self, @value ) = @_;
98              
99 74 100 100     273 return $self->{serial} || 0 unless scalar @value; # current/default value
100              
101 50         93 my $value = shift @value; # replace if in sequence
102 50 100       127 return $self->{serial} = ( $value & 0xFFFFFFFF ) if _ordered( $self->{serial}, $value );
103              
104             # unwise to assume 64-bit arithmetic, or that 32-bit integer overflow goes unpunished
105 14   100     37 my $serial = 0xFFFFFFFF & ( $self->{serial} || 0 );
106 14 100       40 return $self->{serial} = 0x80000000 if $serial == 0x7FFFFFFF; # wrap
107 13 100       45 return $self->{serial} = 0x00000000 if $serial == 0xFFFFFFFF; # wrap
108 12         42 return $self->{serial} = $serial + 1; # increment
109             }
110              
111              
112             sub refresh {
113 19     19 1 797 my ( $self, @value ) = @_;
114 19         41 for (@value) { $self->{refresh} = 0 + $_ }
  17         39  
115 19   100     78 return $self->{refresh} || 0;
116             }
117              
118              
119             sub retry {
120 19     19 1 840 my ( $self, @value ) = @_;
121 19         41 for (@value) { $self->{retry} = 0 + $_ }
  17         36  
122 19   100     116 return $self->{retry} || 0;
123             }
124              
125              
126             sub expire {
127 19     19 1 837 my ( $self, @value ) = @_;
128 19         35 for (@value) { $self->{expire} = 0 + $_ }
  17         36  
129 19   100     67 return $self->{expire} || 0;
130             }
131              
132              
133             sub minimum {
134 24     24 1 813 my ( $self, @value ) = @_;
135 24         48 for (@value) { $self->{minimum} = 0 + $_ }
  17         39  
136 24   100     100 return $self->{minimum} || 0;
137             }
138              
139              
140             ########################################
141              
142             sub _ordered() { ## irreflexive 32-bit partial ordering
143 50     50   116 my ( $n1, $n2 ) = @_;
144              
145 50 100       121 return 0 unless defined $n2; # ( any, undef )
146 46 100       165 return 1 unless defined $n1; # ( undef, any )
147              
148             # unwise to assume 64-bit arithmetic, or that 32-bit integer overflow goes unpunished
149 7     7   60 use integer; # fold, leaving $n2 non-negative
  7         17  
  7         29  
150 24         43 $n1 = ( $n1 & 0xFFFFFFFF ) ^ ( $n2 & 0x80000000 ); # -2**31 <= $n1 < 2**32
151 24         46 $n2 = ( $n2 & 0x7FFFFFFF ); # 0 <= $n2 < 2**31
152              
153 24 100       155 return $n1 < $n2 ? ( $n1 > ( $n2 - 0x80000000 ) ) : ( $n2 < ( $n1 - 0x80000000 ) );
154             }
155              
156             ########################################
157              
158              
159             1;
160             __END__