Filename | /usr/local/lib/perl5/site_perl/Net/DNS/Question.pm |
Statements | Executed 49218 statements in 406ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1968 | 1 | 1 | 170ms | 617ms | new | Net::DNS::Question::
1968 | 1 | 1 | 73.3ms | 600ms | encode | Net::DNS::Question::
1968 | 1 | 1 | 33.8ms | 50.9ms | class | Net::DNS::Question::
1968 | 1 | 1 | 33.6ms | 236ms | qname | Net::DNS::Question::
1968 | 1 | 1 | 31.1ms | 51.3ms | type | Net::DNS::Question::
1968 | 1 | 1 | 23.2ms | 74.4ms | qtype | Net::DNS::Question::
1968 | 1 | 1 | 22.8ms | 73.7ms | qclass | Net::DNS::Question::
1968 | 1 | 1 | 22.7ms | 22.7ms | CORE:match (opcode) | Net::DNS::Question::
1969 | 2 | 1 | 5.85ms | 5.85ms | CORE:pack (opcode) | Net::DNS::Question::
1 | 1 | 1 | 48µs | 64µs | BEGIN@27 | Net::DNS::Question::
1 | 1 | 1 | 40µs | 268µs | BEGIN@107 | Net::DNS::Question::
1 | 1 | 1 | 33µs | 33µs | BEGIN@33 | Net::DNS::Question::
1 | 1 | 1 | 29µs | 701µs | BEGIN@32 | Net::DNS::Question::
1 | 1 | 1 | 28µs | 51µs | BEGIN@28 | Net::DNS::Question::
1 | 1 | 1 | 23µs | 28µs | BEGIN@29 | Net::DNS::Question::
1 | 1 | 1 | 19µs | 204µs | BEGIN@30 | Net::DNS::Question::
1 | 1 | 1 | 18µs | 18µs | BEGIN@34 | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | _dns_addr | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | decode | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | name | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | |
0 | 0 | 0 | 0s | 0s | string | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | zclass | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | zname | Net::DNS::Question::
0 | 0 | 0 | 0s | 0s | ztype | Net::DNS::Question::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Net::DNS::Question; | ||||
2 | |||||
3 | # | ||||
4 | # $Id: Question.pm 1530 2017-01-27 10:40:37Z willem $ | ||||
5 | # | ||||
6 | 1 | 2µs | our $VERSION = (qw$LastChangedRevision: 1530 $)[1]; | ||
7 | |||||
8 | |||||
9 | =head1 NAME | ||||
10 | |||||
11 | Net::DNS::Question - DNS question record | ||||
12 | |||||
13 | =head1 SYNOPSIS | ||||
14 | |||||
15 | use Net::DNS::Question; | ||||
16 | |||||
17 | $question = new Net::DNS::Question('example.com', 'A', 'IN'); | ||||
18 | |||||
19 | =head1 DESCRIPTION | ||||
20 | |||||
21 | A Net::DNS::Question object represents a record in the question | ||||
22 | section of a DNS packet. | ||||
23 | |||||
24 | =cut | ||||
25 | |||||
26 | |||||
27 | 2 | 65µs | 2 | 80µs | # spent 64µs (48+16) within Net::DNS::Question::BEGIN@27 which was called:
# once (48µs+16µs) by Net::DNS::Packet::BEGIN@36 at line 27 # spent 64µs making 1 call to Net::DNS::Question::BEGIN@27
# spent 16µs making 1 call to strict::import |
28 | 2 | 66µs | 2 | 75µs | # spent 51µs (28+23) within Net::DNS::Question::BEGIN@28 which was called:
# once (28µs+23µs) by Net::DNS::Packet::BEGIN@36 at line 28 # spent 51µs making 1 call to Net::DNS::Question::BEGIN@28
# spent 23µs making 1 call to warnings::import |
29 | 2 | 75µs | 2 | 33µs | # spent 28µs (23+5) within Net::DNS::Question::BEGIN@29 which was called:
# once (23µs+5µs) by Net::DNS::Packet::BEGIN@36 at line 29 # spent 28µs making 1 call to Net::DNS::Question::BEGIN@29
# spent 5µs making 1 call to integer::import |
30 | 2 | 65µs | 2 | 388µs | # spent 204µs (19+184) within Net::DNS::Question::BEGIN@30 which was called:
# once (19µs+184µs) by Net::DNS::Packet::BEGIN@36 at line 30 # spent 204µs making 1 call to Net::DNS::Question::BEGIN@30
# spent 184µs making 1 call to Exporter::import |
31 | |||||
32 | 2 | 78µs | 2 | 1.37ms | # spent 701µs (29+673) within Net::DNS::Question::BEGIN@32 which was called:
# once (29µs+673µs) by Net::DNS::Packet::BEGIN@36 at line 32 # spent 701µs making 1 call to Net::DNS::Question::BEGIN@32
# spent 673µs making 1 call to Exporter::import |
33 | 2 | 68µs | 1 | 33µs | # spent 33µs within Net::DNS::Question::BEGIN@33 which was called:
# once (33µs+0s) by Net::DNS::Packet::BEGIN@36 at line 33 # spent 33µs making 1 call to Net::DNS::Question::BEGIN@33 |
34 | 2 | 580µs | 1 | 18µs | # spent 18µs within Net::DNS::Question::BEGIN@34 which was called:
# once (18µs+0s) by Net::DNS::Packet::BEGIN@36 at line 34 # spent 18µs making 1 call to Net::DNS::Question::BEGIN@34 |
35 | |||||
36 | |||||
37 | =head1 METHODS | ||||
38 | |||||
39 | =head2 new | ||||
40 | |||||
41 | $question = new Net::DNS::Question('example.com', 'A', 'IN'); | ||||
42 | $question = new Net::DNS::Question('example.com'); | ||||
43 | |||||
44 | $question = new Net::DNS::Question('192.0.32.10', 'PTR', 'IN'); | ||||
45 | $question = new Net::DNS::Question('192.0.32.10'); | ||||
46 | |||||
47 | Creates a question object from the domain, type, and class passed as | ||||
48 | arguments. One or both type and class arguments may be omitted and | ||||
49 | will assume the default values shown above. | ||||
50 | |||||
51 | RFC4291 and RFC4632 IP address/prefix notation is supported for | ||||
52 | queries in both in-addr.arpa and ip6.arpa namespaces. | ||||
53 | |||||
54 | =cut | ||||
55 | |||||
56 | # spent 617ms (170+447) within Net::DNS::Question::new which was called 1968 times, avg 314µs/call:
# 1968 times (170ms+447ms) by Net::DNS::Packet::new at line 73 of Net/DNS/Packet.pm, avg 314µs/call | ||||
57 | 1968 | 6.62ms | my $self = bless {}, shift; | ||
58 | 1968 | 7.55ms | my $qname = shift; | ||
59 | 1968 | 7.08ms | my $qtype = shift || ''; | ||
60 | 1968 | 4.21ms | my $qclass = shift || ''; | ||
61 | |||||
62 | # tolerate (possibly unknown) type and class in zone file order | ||||
63 | 1968 | 5.05ms | unless ( exists $classbyname{$qclass} ) { | ||
64 | ( $qtype, $qclass ) = ( $qclass, $qtype ) if exists $classbyname{$qtype}; | ||||
65 | ( $qtype, $qclass ) = ( $qclass, $qtype ) if $qtype =~ /CLASS/; | ||||
66 | } | ||||
67 | 1968 | 6.57ms | unless ( exists $typebyname{$qtype} ) { | ||
68 | ( $qtype, $qclass ) = ( $qclass, $qtype ) if exists $typebyname{$qclass}; | ||||
69 | ( $qtype, $qclass ) = ( $qclass, $qtype ) if $qclass =~ /TYPE/; | ||||
70 | } | ||||
71 | |||||
72 | # if argument is an IP address, do appropriate reverse lookup | ||||
73 | 1968 | 38.7ms | 1968 | 22.7ms | if ( defined $qname and $qname =~ m/:|\d$/ ) { # spent 22.7ms making 1968 calls to Net::DNS::Question::CORE:match, avg 12µs/call |
74 | if ( my $reverse = _dns_addr($qname) ) { | ||||
75 | $qname = $reverse; | ||||
76 | $qtype ||= 'PTR'; | ||||
77 | } | ||||
78 | } | ||||
79 | |||||
80 | 1968 | 24.7ms | 1968 | 384ms | $self->{qname} = new Net::DNS::DomainName1035($qname); # spent 384ms making 1968 calls to Net::DNS::Domain::new, avg 195µs/call |
81 | 1968 | 18.9ms | 1968 | 22.7ms | $self->{qtype} = typebyname( $qtype || 'A' ); # spent 22.7ms making 1968 calls to Net::DNS::Parameters::typebyname, avg 12µs/call |
82 | 1968 | 16.4ms | 1968 | 17.5ms | $self->{qclass} = classbyname( $qclass || 'IN' ); # spent 17.5ms making 1968 calls to Net::DNS::Parameters::classbyname, avg 9µs/call |
83 | |||||
84 | 1968 | 27.4ms | return $self; | ||
85 | } | ||||
86 | |||||
87 | |||||
88 | =head2 decode | ||||
89 | |||||
90 | $question = decode Net::DNS::Question(\$data, $offset); | ||||
91 | |||||
92 | ($question, $offset) = decode Net::DNS::Question(\$data, $offset); | ||||
93 | |||||
94 | Decodes the question record at the specified location within a DNS | ||||
95 | wire-format packet. The first argument is a reference to the buffer | ||||
96 | containing the packet data. The second argument is the offset of | ||||
97 | the start of the question record. | ||||
98 | |||||
99 | Returns a Net::DNS::Question object and the offset of the next | ||||
100 | location in the packet. | ||||
101 | |||||
102 | An exception is raised if the object cannot be created | ||||
103 | (e.g., corrupt or insufficient data). | ||||
104 | |||||
105 | =cut | ||||
106 | |||||
107 | 2 | 2.00ms | 3 | 497µs | # spent 268µs (40+229) within Net::DNS::Question::BEGIN@107 which was called:
# once (40µs+229µs) by Net::DNS::Packet::BEGIN@36 at line 107 # spent 268µs making 1 call to Net::DNS::Question::BEGIN@107
# spent 222µs making 1 call to constant::import
# spent 6µs making 1 call to Net::DNS::Question::CORE:pack |
108 | |||||
109 | sub decode { | ||||
110 | my $self = bless {}, shift; | ||||
111 | my ( $data, $offset ) = @_; | ||||
112 | |||||
113 | ( $self->{qname}, $offset ) = decode Net::DNS::DomainName1035(@_); | ||||
114 | |||||
115 | my $next = $offset + QFIXEDSZ; | ||||
116 | die 'corrupt wire-format data' if length $$data < $next; | ||||
117 | @{$self}{qw(qtype qclass)} = unpack "\@$offset n2", $$data; | ||||
118 | |||||
119 | wantarray ? ( $self, $next ) : $self; | ||||
120 | } | ||||
121 | |||||
122 | |||||
123 | =head2 encode | ||||
124 | |||||
125 | $data = $question->encode( $offset, $hash ); | ||||
126 | |||||
127 | Returns the Net::DNS::Question in binary format suitable for | ||||
128 | inclusion in a DNS packet buffer. | ||||
129 | |||||
130 | The optional arguments are the offset within the packet data where | ||||
131 | the Net::DNS::Question is to be stored and a reference to a hash | ||||
132 | table used to index compressed names within the packet. | ||||
133 | |||||
134 | =cut | ||||
135 | |||||
136 | # spent 600ms (73.3+527) within Net::DNS::Question::encode which was called 1968 times, avg 305µs/call:
# 1968 times (73.3ms+527ms) by Net::DNS::Packet::encode at line 205 of Net/DNS/Packet.pm, avg 305µs/call | ||||
137 | 1968 | 3.59ms | my $self = shift; | ||
138 | |||||
139 | 3936 | 73.4ms | 3936 | 527ms | pack 'a* n2', $self->{qname}->encode(@_), @{$self}{qw(qtype qclass)}; # spent 521ms making 1968 calls to Net::DNS::DomainName1035::encode, avg 265µs/call
# spent 5.84ms making 1968 calls to Net::DNS::Question::CORE:pack, avg 3µs/call |
140 | } | ||||
141 | |||||
142 | |||||
143 | =head2 print | ||||
144 | |||||
145 | $object->print; | ||||
146 | |||||
147 | Prints the record to the standard output. Calls the string() method | ||||
148 | to get the string representation. | ||||
149 | |||||
150 | =cut | ||||
151 | |||||
152 | sub print { | ||||
153 | print shift->string, "\n"; | ||||
154 | } | ||||
155 | |||||
156 | |||||
157 | =head2 string | ||||
158 | |||||
159 | print "string = ", $question->string, "\n"; | ||||
160 | |||||
161 | Returns a string representation of the question record. | ||||
162 | |||||
163 | =cut | ||||
164 | |||||
165 | sub string { | ||||
166 | my $self = shift; | ||||
167 | |||||
168 | join "\t", $self->{qname}->string, $self->qclass, $self->qtype; | ||||
169 | } | ||||
170 | |||||
171 | |||||
172 | =head2 name | ||||
173 | |||||
174 | $name = $question->name; | ||||
175 | |||||
176 | Internationalised domain name corresponding to the qname attribute. | ||||
177 | |||||
178 | Decoding non-ASCII domain names is computationally expensive and | ||||
179 | undesirable for names which are likely to be used to construct | ||||
180 | further queries. | ||||
181 | |||||
182 | When required to communicate with humans, the 'proper' domain name | ||||
183 | should be extracted from a query or reply packet. | ||||
184 | |||||
185 | $query = new Net::DNS::Packet( $example, 'ANY' ); | ||||
186 | $reply = $resolver->send($query) or die; | ||||
187 | ($question) = $reply->question; | ||||
188 | $name = $question->name; | ||||
189 | |||||
190 | =cut | ||||
191 | |||||
192 | sub name { | ||||
193 | my $self = shift; | ||||
194 | |||||
195 | croak 'immutable object: argument invalid' if scalar @_; | ||||
196 | $self->{qname}->xname; | ||||
197 | } | ||||
198 | |||||
199 | |||||
200 | =head2 qname, zname | ||||
201 | |||||
202 | $qname = $question->qname; | ||||
203 | $zname = $question->zname; | ||||
204 | |||||
205 | Canonical ASCII domain name as required for the query subject | ||||
206 | transmitted to a nameserver. In dynamic update packets, this | ||||
207 | attribute is known as zname() and refers to the zone name. | ||||
208 | |||||
209 | =cut | ||||
210 | |||||
211 | # spent 236ms (33.6+202) within Net::DNS::Question::qname which was called 1968 times, avg 120µs/call:
# 1968 times (33.6ms+202ms) by Mail::SpamAssassin::Util::decode_dns_question_entry at line 936 of Mail/SpamAssassin/Util.pm, avg 120µs/call | ||||
212 | 1968 | 3.62ms | my $self = shift; | ||
213 | |||||
214 | 1968 | 3.77ms | croak 'immutable object: argument invalid' if scalar @_; | ||
215 | 1968 | 27.6ms | 1968 | 202ms | $self->{qname}->name; # spent 202ms making 1968 calls to Net::DNS::Domain::name, avg 103µs/call |
216 | } | ||||
217 | |||||
218 | sub zname { &qname; } | ||||
219 | |||||
220 | |||||
221 | =head2 qtype, ztype, type | ||||
222 | |||||
223 | $qtype = $question->type; | ||||
224 | $qtype = $question->qtype; | ||||
225 | $ztype = $question->ztype; | ||||
226 | |||||
227 | Returns the question type attribute. In dynamic update packets, | ||||
228 | this attribute is known as ztype() and refers to the zone type. | ||||
229 | |||||
230 | =cut | ||||
231 | |||||
232 | # spent 51.3ms (31.1+20.2) within Net::DNS::Question::type which was called 1968 times, avg 26µs/call:
# 1968 times (31.1ms+20.2ms) by Net::DNS::Question::qtype at line 239, avg 26µs/call | ||||
233 | 1968 | 3.61ms | my $self = shift; | ||
234 | |||||
235 | 1968 | 3.76ms | croak 'immutable object: argument invalid' if scalar @_; | ||
236 | 1968 | 24.3ms | 1968 | 20.2ms | typebyval( $self->{qtype} ); # spent 20.2ms making 1968 calls to Net::DNS::Parameters::typebyval, avg 10µs/call |
237 | } | ||||
238 | |||||
239 | 1968 | 41.5ms | 1968 | 51.3ms | # spent 74.4ms (23.2+51.3) within Net::DNS::Question::qtype which was called 1968 times, avg 38µs/call:
# 1968 times (23.2ms+51.3ms) by Mail::SpamAssassin::Util::decode_dns_question_entry at line 946 of Mail/SpamAssassin/Util.pm, avg 38µs/call # spent 51.3ms making 1968 calls to Net::DNS::Question::type, avg 26µs/call |
240 | sub ztype { &type; } | ||||
241 | |||||
242 | |||||
243 | =head2 qclass, zclass, class | ||||
244 | |||||
245 | $qclass = $question->class; | ||||
246 | $qclass = $question->qclass; | ||||
247 | $zclass = $question->zclass; | ||||
248 | |||||
249 | Returns the question class attribute. In dynamic update packets, | ||||
250 | this attribute is known as zclass() and refers to the zone class. | ||||
251 | |||||
252 | =cut | ||||
253 | |||||
254 | # spent 50.9ms (33.8+17.1) within Net::DNS::Question::class which was called 1968 times, avg 26µs/call:
# 1968 times (33.8ms+17.1ms) by Net::DNS::Question::qclass at line 261, avg 26µs/call | ||||
255 | 1968 | 3.69ms | my $self = shift; | ||
256 | |||||
257 | 1968 | 3.79ms | croak 'immutable object: argument invalid' if scalar @_; | ||
258 | 1968 | 25.0ms | 1968 | 17.1ms | classbyval( $self->{qclass} ); # spent 17.1ms making 1968 calls to Net::DNS::Parameters::classbyval, avg 9µs/call |
259 | } | ||||
260 | |||||
261 | 1968 | 22.2ms | 1968 | 50.9ms | # spent 73.7ms (22.8+50.9) within Net::DNS::Question::qclass which was called 1968 times, avg 37µs/call:
# 1968 times (22.8ms+50.9ms) by Mail::SpamAssassin::Util::decode_dns_question_entry at line 946 of Mail/SpamAssassin/Util.pm, avg 37µs/call # spent 50.9ms making 1968 calls to Net::DNS::Question::class, avg 26µs/call |
262 | sub zclass { &class; } | ||||
263 | |||||
264 | |||||
265 | ######################################## | ||||
266 | |||||
267 | sub _dns_addr { ## Map IP address into reverse lookup namespace | ||||
268 | local $_ = shift; | ||||
269 | |||||
270 | # IP address must contain address characters only | ||||
271 | s/[%].+$//; # discard RFC4007 scopeid | ||||
272 | return undef unless m#^[a-fA-F0-9:./]+$#; | ||||
273 | |||||
274 | my ( $address, $pfxlen ) = split m#/#; | ||||
275 | |||||
276 | # map IPv4 address to in-addr.arpa space | ||||
277 | if (m#^\d*[.\d]*\d(/\d+)?$#) { | ||||
278 | my @parse = split /\./, $address; | ||||
279 | $pfxlen = scalar(@parse) << 3 unless $pfxlen; | ||||
280 | my $last = $pfxlen > 24 ? 3 : ( $pfxlen - 1 ) >> 3; | ||||
281 | return join '.', reverse( ( @parse, (0) x 3 )[0 .. $last] ), 'in-addr.arpa.'; | ||||
282 | } | ||||
283 | |||||
284 | # map IPv6 address to ip6.arpa space | ||||
285 | return unless m#^[:\w]+:([.\w]*)(/\d+)?$#; | ||||
286 | my $rhs = $1 || '0'; | ||||
287 | return _dns_addr($rhs) if m#^[:0]*:0*:[fF]{4}:[^:]+$#; # IPv4 | ||||
288 | $rhs = sprintf '%x%0.2x:%x%0.2x', map $_ || 0, split( /\./, $rhs, 4 ) if /\./; | ||||
289 | $address =~ s/:[^:]*$/:0$rhs/; | ||||
290 | my @parse = split /:/, ( reverse "0$address" ), 9; | ||||
291 | my @xpand = map { /./ ? $_ : ('0') x ( 9 - @parse ) } @parse; # expand :: | ||||
292 | $pfxlen = ( scalar(@xpand) << 4 ) unless $pfxlen; # implicit length if unspecified | ||||
293 | my $len = $pfxlen > 124 ? 32 : ( $pfxlen + 3 ) >> 2; | ||||
294 | my $hex = pack 'A4' x 8, map { $_ . '000' } ('0') x ( 8 - @xpand ), @xpand; | ||||
295 | return join '.', split( //, substr( $hex, -$len ) ), 'ip6.arpa.'; | ||||
296 | } | ||||
297 | |||||
298 | |||||
299 | 1 | 15µs | 1; | ||
300 | __END__ | ||||
# spent 22.7ms within Net::DNS::Question::CORE:match which was called 1968 times, avg 12µs/call:
# 1968 times (22.7ms+0s) by Net::DNS::Question::new at line 73, avg 12µs/call | |||||
sub Net::DNS::Question::CORE:pack; # opcode |