File Coverage

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


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