Filename | /usr/local/lib/perl5/site_perl/Net/DNS/DomainName.pm |
Statements | Executed 89594 statements in 554ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1968 | 1 | 1 | 450ms | 521ms | encode | Net::DNS::DomainName1035::
3006 | 2 | 2 | 58.3ms | 58.3ms | _wire | Net::DNS::DomainName::
8348 | 1 | 1 | 25.8ms | 25.8ms | CORE:pack (opcode) | Net::DNS::DomainName1035::
1 | 1 | 1 | 47µs | 58µs | BEGIN@41 | Net::DNS::DomainName::
1 | 1 | 1 | 38µs | 292µs | BEGIN@158 | Net::DNS::DomainName1035::
1 | 1 | 1 | 28µs | 60µs | BEGIN@42 | Net::DNS::DomainName::
1 | 1 | 1 | 24µs | 270µs | BEGIN@43 | Net::DNS::DomainName::
1 | 1 | 1 | 23µs | 280µs | BEGIN@220 | Net::DNS::DomainName2535::
1 | 1 | 1 | 21µs | 29µs | BEGIN@45 | Net::DNS::DomainName::
1 | 1 | 1 | 20µs | 221µs | BEGIN@46 | Net::DNS::DomainName::
0 | 0 | 0 | 0s | 0s | encode | Net::DNS::DomainName2535::
0 | 0 | 0 | 0s | 0s | canonical | Net::DNS::DomainName::
0 | 0 | 0 | 0s | 0s | decode | Net::DNS::DomainName::
0 | 0 | 0 | 0s | 0s | encode | Net::DNS::DomainName::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Net::DNS::DomainName; | ||||
2 | |||||
3 | # | ||||
4 | # $Id: DomainName.pm 1558 2017-04-03 11:38:22Z willem $ | ||||
5 | # | ||||
6 | 1 | 2µs | our $VERSION = (qw$LastChangedRevision: 1558 $)[1]; | ||
7 | |||||
8 | |||||
9 | =head1 NAME | ||||
10 | |||||
11 | Net::DNS::DomainName - DNS name representation | ||||
12 | |||||
13 | =head1 SYNOPSIS | ||||
14 | |||||
15 | use Net::DNS::DomainName; | ||||
16 | |||||
17 | $object = new Net::DNS::DomainName('example.com'); | ||||
18 | $name = $object->name; | ||||
19 | $data = $object->encode; | ||||
20 | |||||
21 | ( $object, $next ) = decode Net::DNS::DomainName( \$data, $offset ); | ||||
22 | |||||
23 | =head1 DESCRIPTION | ||||
24 | |||||
25 | The Net::DNS::DomainName module implements the concrete representation | ||||
26 | of DNS domain names used within DNS packets. | ||||
27 | |||||
28 | Net::DNS::DomainName defines methods for encoding and decoding wire | ||||
29 | format octet strings as defined in RFC1035. All other behaviour, | ||||
30 | including the new() constructor, is inherited from Net::DNS::Domain. | ||||
31 | |||||
32 | The Net::DNS::DomainName1035 and Net::DNS::DomainName2535 packages | ||||
33 | implement disjoint domain name subtypes which provide the name | ||||
34 | compression and canonicalisation specified by RFC1035 and RFC2535. | ||||
35 | These are necessary to meet the backward compatibility requirements | ||||
36 | introduced by RFC3597. | ||||
37 | |||||
38 | =cut | ||||
39 | |||||
40 | |||||
41 | 2 | 85µs | 2 | 69µs | # spent 58µs (47+11) within Net::DNS::DomainName::BEGIN@41 which was called:
# once (47µs+11µs) by Net::DNS::RR::BEGIN@43 at line 41 # spent 58µs making 1 call to Net::DNS::DomainName::BEGIN@41
# spent 11µs making 1 call to strict::import |
42 | 2 | 76µs | 2 | 92µs | # spent 60µs (28+32) within Net::DNS::DomainName::BEGIN@42 which was called:
# once (28µs+32µs) by Net::DNS::RR::BEGIN@43 at line 42 # spent 60µs making 1 call to Net::DNS::DomainName::BEGIN@42
# spent 32µs making 1 call to warnings::import |
43 | 2 | 78µs | 2 | 270µs | # spent 270µs (24+246) within Net::DNS::DomainName::BEGIN@43 which was called:
# once (24µs+246µs) by Net::DNS::RR::BEGIN@43 at line 43 # spent 270µs making 1 call to Net::DNS::DomainName::BEGIN@43
# spent 246µs making 1 call to base::import, recursion: max depth 2, sum of overlapping time 246µs |
44 | |||||
45 | 2 | 56µs | 2 | 36µs | # spent 29µs (21+7) within Net::DNS::DomainName::BEGIN@45 which was called:
# once (21µs+7µs) by Net::DNS::RR::BEGIN@43 at line 45 # spent 29µs making 1 call to Net::DNS::DomainName::BEGIN@45
# spent 7µs making 1 call to integer::import |
46 | 2 | 828µs | 2 | 421µs | # spent 221µs (20+201) within Net::DNS::DomainName::BEGIN@46 which was called:
# once (20µs+201µs) by Net::DNS::RR::BEGIN@43 at line 46 # spent 221µs making 1 call to Net::DNS::DomainName::BEGIN@46
# spent 201µs making 1 call to Exporter::import |
47 | |||||
48 | |||||
49 | =head1 METHODS | ||||
50 | |||||
51 | =head2 new | ||||
52 | |||||
53 | $object = new Net::DNS::DomainName('example.com'); | ||||
54 | |||||
55 | Creates a domain name object which identifies the domain specified | ||||
56 | by the character string argument. | ||||
57 | |||||
58 | |||||
59 | =head2 canonical | ||||
60 | |||||
61 | $data = $object->canonical; | ||||
62 | |||||
63 | Returns the canonical wire-format representation of the domain name | ||||
64 | as defined in RFC2535(8.1). | ||||
65 | |||||
66 | =cut | ||||
67 | |||||
68 | sub canonical { | ||||
69 | join '', map( { tr /\101-\132/\141-\172/; | ||||
70 | pack 'C a*', length($_), $_; | ||||
71 | } shift->_wire ), | ||||
72 | 1 | 4µs | pack 'x'; # spent 4µs making 1 call to main::CORE:pack | ||
73 | } | ||||
74 | |||||
75 | |||||
76 | =head2 decode | ||||
77 | |||||
78 | $object = decode Net::DNS::DomainName( \$buffer, $offset, $hash ); | ||||
79 | |||||
80 | ( $object, $next ) = decode Net::DNS::DomainName( \$buffer, $offset, $hash ); | ||||
81 | |||||
82 | Creates a domain name object which represents the DNS domain name | ||||
83 | identified by the wire-format data at the indicated offset within | ||||
84 | the data buffer. | ||||
85 | |||||
86 | The argument list consists of a reference to a scalar containing the | ||||
87 | wire-format data and specified offset. The optional reference to a | ||||
88 | hash table provides improved efficiency of decoding compressed names | ||||
89 | by exploiting already cached compression pointers. | ||||
90 | |||||
91 | The returned offset value indicates the start of the next item in the | ||||
92 | data buffer. | ||||
93 | |||||
94 | =cut | ||||
95 | |||||
96 | sub decode { | ||||
97 | my $label = []; | ||||
98 | my $self = bless {label => $label}, shift; | ||||
99 | my $buffer = shift; # reference to data buffer | ||||
100 | my $offset = shift || 0; # offset within buffer | ||||
101 | my $cache = shift || {}; # hashed objectref by offset | ||||
102 | |||||
103 | my $buflen = length $$buffer; | ||||
104 | my $index = $offset; | ||||
105 | |||||
106 | while ( $index < $buflen ) { | ||||
107 | my $header = unpack( "\@$index C", $$buffer ) | ||||
108 | || return wantarray ? ( $self, ++$index ) : $self; | ||||
109 | |||||
110 | if ( $header < 0x40 ) { # non-terminal label | ||||
111 | push @$label, substr( $$buffer, ++$index, $header ); | ||||
112 | $index += $header; | ||||
113 | |||||
114 | } elsif ( $header < 0xC0 ) { # deprecated extended label types | ||||
115 | croak 'unimplemented label type'; | ||||
116 | |||||
117 | } else { # compression pointer | ||||
118 | my $link = 0x3FFF & unpack( "\@$index n", $$buffer ); | ||||
119 | croak 'corrupt compression pointer' unless $link < $offset; | ||||
120 | |||||
121 | # uncoverable condition false | ||||
122 | $self->{origin} = $cache->{$link} ||= decode Net::DNS::DomainName( $buffer, $link, $cache ); | ||||
123 | return wantarray ? ( $self, $index + 2 ) : $self; | ||||
124 | } | ||||
125 | } | ||||
126 | croak 'corrupt wire-format data'; | ||||
127 | } | ||||
128 | |||||
129 | |||||
130 | =head2 encode | ||||
131 | |||||
132 | $data = $object->encode; | ||||
133 | |||||
134 | Returns the wire-format representation of the domain name suitable | ||||
135 | for inclusion in a DNS packet buffer. | ||||
136 | |||||
137 | =cut | ||||
138 | |||||
139 | sub encode { | ||||
140 | join '', map pack( 'C a*', length($_), $_ ), shift->_wire, ''; | ||||
141 | } | ||||
142 | |||||
143 | |||||
144 | ######################################## | ||||
145 | |||||
146 | # spent 58.3ms within Net::DNS::DomainName::_wire which was called 3006 times, avg 19µs/call:
# 1968 times (45.0ms+0s) by Net::DNS::DomainName1035::encode at line 198, avg 23µs/call
# 1038 times (13.3ms+0s) by Net::DNS::Domain::name at line 167 of Net/DNS/Domain.pm, avg 13µs/call | ||||
147 | 3006 | 5.27ms | my $self = shift; | ||
148 | |||||
149 | 3006 | 11.6ms | my $label = $self->{label}; | ||
150 | 3006 | 45.1ms | my $origin = $self->{origin} || return (@$label); | ||
151 | return ( @$label, $origin->_wire ); | ||||
152 | } | ||||
153 | |||||
154 | |||||
155 | ######################################## | ||||
156 | |||||
157 | package Net::DNS::DomainName1035; | ||||
158 | 2 | 415µs | 2 | 292µs | # spent 292µs (38+255) within Net::DNS::DomainName1035::BEGIN@158 which was called:
# once (38µs+255µs) by Net::DNS::RR::BEGIN@43 at line 158 # spent 292µs making 1 call to Net::DNS::DomainName1035::BEGIN@158
# spent 255µs making 1 call to base::import, recursion: max depth 2, sum of overlapping time 255µs |
159 | |||||
160 | =head1 Net::DNS::DomainName1035 | ||||
161 | |||||
162 | Net::DNS::DomainName1035 implements a subclass of domain name | ||||
163 | objects which are to be encoded using the compressed wire format | ||||
164 | defined in RFC1035. | ||||
165 | |||||
166 | use Net::DNS::DomainName; | ||||
167 | |||||
168 | $object = new Net::DNS::DomainName1035('compressible.example.com'); | ||||
169 | $data = $object->encode( $offset, $hash ); | ||||
170 | |||||
171 | ( $object, $next ) = decode Net::DNS::DomainName1035( \$data, $offset ); | ||||
172 | |||||
173 | Note that RFC3597 implies that the RR types defined in RFC1035 | ||||
174 | section 3.3 are the only types eligible for compression. | ||||
175 | |||||
176 | |||||
177 | =head2 encode | ||||
178 | |||||
179 | $data = $object->encode( $offset, $hash ); | ||||
180 | |||||
181 | Returns the wire-format representation of the domain name suitable | ||||
182 | for inclusion in a DNS packet buffer. | ||||
183 | |||||
184 | The optional arguments are the offset within the packet data where | ||||
185 | the domain name is to be stored and a reference to a hash table used | ||||
186 | to index compressed names within the packet. | ||||
187 | |||||
188 | If the hash reference is undefined, encode() returns the lowercase | ||||
189 | uncompressed canonical representation defined in RFC2535(8.1). | ||||
190 | |||||
191 | =cut | ||||
192 | |||||
193 | # spent 521ms (450+70.8) within Net::DNS::DomainName1035::encode which was called 1968 times, avg 265µs/call:
# 1968 times (450ms+70.8ms) by Net::DNS::Question::encode at line 139 of Net/DNS/Question.pm, avg 265µs/call | ||||
194 | 1968 | 3.49ms | my $self = shift; | ||
195 | 1968 | 4.37ms | my $offset = shift || 0; # offset in data buffer | ||
196 | 1968 | 4.21ms | my $hash = shift || return $self->canonical; # hashed offset by name | ||
197 | |||||
198 | 1968 | 36.0ms | 1968 | 45.0ms | my @labels = $self->_wire; # spent 45.0ms making 1968 calls to Net::DNS::DomainName::_wire, avg 23µs/call |
199 | 1968 | 4.03ms | my $data = ''; | ||
200 | 1968 | 7.26ms | while (@labels) { | ||
201 | 8348 | 32.1ms | my $name = join( '.', @labels ); | ||
202 | |||||
203 | 8348 | 16.6ms | return $data . pack( 'n', 0xC000 | $hash->{$name} ) if defined $hash->{$name}; | ||
204 | |||||
205 | 8348 | 23.3ms | my $label = shift @labels; | ||
206 | 8348 | 20.6ms | my $length = length $label; | ||
207 | 8348 | 172ms | 8348 | 25.8ms | $data .= pack( 'C a*', $length, $label ); # spent 25.8ms making 8348 calls to Net::DNS::DomainName1035::CORE:pack, avg 3µs/call |
208 | |||||
209 | 8348 | 14.8ms | next unless $offset < 0x4000; | ||
210 | 8348 | 71.0ms | $hash->{$name} = $offset; | ||
211 | 8348 | 47.9ms | $offset += 1 + $length; | ||
212 | } | ||||
213 | 1968 | 31.9ms | 1 | 3µs | $data .= pack 'x'; # spent 3µs making 1 call to main::CORE:pack |
214 | } | ||||
215 | |||||
216 | |||||
217 | ######################################## | ||||
218 | |||||
219 | package Net::DNS::DomainName2535; | ||||
220 | 2 | 209µs | 2 | 280µs | # spent 280µs (23+257) within Net::DNS::DomainName2535::BEGIN@220 which was called:
# once (23µs+257µs) by Net::DNS::RR::BEGIN@43 at line 220 # spent 280µs making 1 call to Net::DNS::DomainName2535::BEGIN@220
# spent 257µs making 1 call to base::import, recursion: max depth 2, sum of overlapping time 257µs |
221 | |||||
222 | =head1 Net::DNS::DomainName2535 | ||||
223 | |||||
224 | Net::DNS::DomainName2535 implements a subclass of domain name | ||||
225 | objects which are to be encoded using uncompressed wire format. | ||||
226 | |||||
227 | Note that RFC3597, and latterly RFC4034, specifies that the lower | ||||
228 | case canonical encoding defined in RFC2535 is to be used for RR | ||||
229 | types defined prior to RFC3597. | ||||
230 | |||||
231 | use Net::DNS::DomainName; | ||||
232 | |||||
233 | $object = new Net::DNS::DomainName2535('incompressible.example.com'); | ||||
234 | $data = $object->encode( $offset, $hash ); | ||||
235 | |||||
236 | ( $object, $next ) = decode Net::DNS::DomainName2535( \$data, $offset ); | ||||
237 | |||||
238 | |||||
239 | =head2 encode | ||||
240 | |||||
241 | $data = $object->encode( $offset, $hash ); | ||||
242 | |||||
243 | Returns the uncompressed wire-format representation of the domain | ||||
244 | name suitable for inclusion in a DNS packet buffer. | ||||
245 | |||||
246 | If the hash reference is undefined, encode() returns the lowercase | ||||
247 | canonical form defined in RFC2535(8.1). | ||||
248 | |||||
249 | =cut | ||||
250 | |||||
251 | sub encode { | ||||
252 | return shift->canonical unless defined $_[2]; | ||||
253 | join '', map pack( 'C a*', length($_), $_ ), shift->_wire, ''; | ||||
254 | } | ||||
255 | |||||
256 | 1 | 15µs | 1; | ||
257 | __END__ | ||||
# spent 25.8ms within Net::DNS::DomainName1035::CORE:pack which was called 8348 times, avg 3µs/call:
# 8348 times (25.8ms+0s) by Net::DNS::DomainName1035::encode at line 207, avg 3µs/call |