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   57 use strict;
  7         16  
  7         268  
4 7     7   41 use warnings;
  7         18  
  7         438  
5             our $VERSION = (qw$Id: SOA.pm 1931 2023-08-23 13:14:15Z willem $)[2];
6              
7 7     7   49 use base qw(Net::DNS::RR);
  7         18  
  7         1352  
8              
9              
10             =head1 NAME
11              
12             Net::DNS::RR::SOA - DNS SOA resource record
13              
14             =cut
15              
16 7     7   111 use integer;
  7         22  
  7         47  
17              
18 7     7   268 use Net::DNS::DomainName;
  7         24  
  7         224  
19 7     7   3839 use Net::DNS::Mailbox;
  7         25  
  7         7553  
20              
21              
22             sub _decode_rdata { ## decode rdata from wire-format octet string
23 27     27   191 my ( $self, @argument ) = @_;
24 27         149 my ( $data, $offset, @opaque ) = @argument;
25              
26 27         107 ( $self->{mname}, $offset ) = Net::DNS::DomainName1035->decode(@argument);
27 27         214 ( $self->{rname}, $offset ) = Net::DNS::Mailbox1035->decode( $data, $offset, @opaque );
28 27         177 @{$self}{qw(serial refresh retry expire minimum)} = unpack "\@$offset N5", $$data;
  27         160  
29 27         109 return;
30             }
31              
32              
33             sub _encode_rdata { ## encode rdata as wire-format octet string
34 12     12   30 my ( $self, @argument ) = @_;
35 12         28 my ( $offset, @opaque ) = @argument;
36              
37 12         25 my $rname = $self->{rname};
38 12         41 my $rdata = $self->{mname}->encode(@argument);
39 12         68 $rdata .= $rname->encode( $offset + length($rdata), @opaque );
40 12         47 $rdata .= pack 'N5', $self->serial, @{$self}{qw(refresh retry expire minimum)};
  12         43  
41 12         131 return $rdata;
42             }
43              
44              
45             sub _format_rdata { ## format rdata portion of RR string.
46 8     8   18 my $self = shift;
47              
48 8         29 my $mname = $self->{mname}->string;
49 8         33 my $rname = $self->{rname}->string;
50 8         19 my $serial = $self->serial;
51 8 100       24 my $spacer = length "$serial" > 7 ? "" : "\t";
52 8         58 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   82 my ( $self, @argument ) = @_;
62              
63 22         47 for (qw(mname rname)) { $self->$_( shift @argument ) }
  44         174  
64 22 100       110 $self->serial( shift @argument ) if scalar @argument; # possibly undefined
65 22         60 for (qw(refresh retry expire minimum)) {
66 70 100       148 last unless scalar @argument;
67 64         208 $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   15 my $self = shift;
75              
76 7         33 $self->_parse_rdata(qw(. . 0 4h 1h 3w 1h));
77 7         13 delete $self->{serial};
78 7         23 return;
79             }
80              
81              
82             sub mname {
83 25     25 1 63 my ( $self, @value ) = @_;
84 25         50 for (@value) { $self->{mname} = Net::DNS::DomainName1035->new($_) }
  23         104  
85 25 100       148 return $self->{mname} ? $self->{mname}->name : undef;
86             }
87              
88              
89             sub rname {
90 25     25 1 880 my ( $self, @value ) = @_;
91 25         60 for (@value) { $self->{rname} = Net::DNS::Mailbox1035->new($_) }
  23         94  
92 25 100       137 return $self->{rname} ? $self->{rname}->address : undef;
93             }
94              
95              
96             sub serial {
97 81     81 1 1888 my ( $self, @value ) = @_;
98              
99 81 100 100     239 return $self->{serial} || 0 unless scalar @value; # current/default value
100              
101 57         105 my $value = shift @value; # replace if in sequence
102 57 100       148 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 22   100     64 my $serial = 0xFFFFFFFF & ( $self->{serial} || 0 );
106 22 100       52 return $self->{serial} = 0x80000000 if $serial == 0x7FFFFFFF; # wrap
107 21 100       53 return $self->{serial} = 0x00000000 if $serial == 0xFFFFFFFF; # wrap
108 20         97 return $self->{serial} = $serial + 1; # increment
109             }
110              
111              
112             sub refresh {
113 19     19 1 908 my ( $self, @value ) = @_;
114 19         48 for (@value) { $self->{refresh} = 0 + $_ }
  17         41  
115 19   100     80 return $self->{refresh} || 0;
116             }
117              
118              
119             sub retry {
120 19     19 1 879 my ( $self, @value ) = @_;
121 19         42 for (@value) { $self->{retry} = 0 + $_ }
  17         41  
122 19   100     83 return $self->{retry} || 0;
123             }
124              
125              
126             sub expire {
127 19     19 1 857 my ( $self, @value ) = @_;
128 19         39 for (@value) { $self->{expire} = 0 + $_ }
  17         44  
129 19   100     69 return $self->{expire} || 0;
130             }
131              
132              
133             sub minimum {
134 24     24 1 853 my ( $self, @value ) = @_;
135 24         45 for (@value) { $self->{minimum} = 0 + $_ }
  17         53  
136 24   100     98 return $self->{minimum} || 0;
137             }
138              
139              
140             ########################################
141              
142             sub _ordered() { ## irreflexive 32-bit partial ordering
143 57     57   132 my ( $n1, $n2 ) = @_;
144              
145 57 100       155 return 0 unless defined $n2; # ( any, undef )
146 53 100       170 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   57 use integer; # fold, leaving $n2 non-negative
  7         15  
  7         31  
150 31         55 $n1 = ( $n1 & 0xFFFFFFFF ) ^ ( $n2 & 0x80000000 ); # -2**31 <= $n1 < 2**32
151 31         44 $n2 = ( $n2 & 0x7FFFFFFF ); # 0 <= $n2 < 2**31
152              
153 31 100       177 return $n1 < $n2 ? ( $n1 > ( $n2 - 0x80000000 ) ) : ( $n2 < ( $n1 - 0x80000000 ) );
154             }
155              
156             ########################################
157              
158              
159             1;
160             __END__