File Coverage

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


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