File Coverage

blib/lib/Net/DNS/Method/Status.pm
Criterion Covered Total %
statement 76 84 90.4
branch 12 22 54.5
condition 7 18 38.8
subroutine 12 14 85.7
pod 0 3 0.0
total 107 141 75.8


line stmt bran cond sub pod time code
1             package Net::DNS::Method::Status;
2              
3             require 5.005_62;
4 2     2   1954 use Carp;
  2         4  
  2         113  
5 2     2   10 use strict;
  2         4  
  2         59  
6 2     2   10 use warnings;
  2         4  
  2         70  
7              
8 2     2   6953 use Net::DNS;
  2         64441  
  2         220  
9 2     2   16 use Net::DNS::Method;
  2         5  
  2         123  
10              
11 2     2   10 use vars qw(@ISA $VERSION $AUTOLOAD);
  2         4  
  2         2117  
12              
13             @ISA = qw(Net::DNS::Method);
14              
15             $VERSION = '2.00';
16              
17             # Default responses
18             our $DEF_ZONE = 'some.com';
19             our $DEF_RSET = 'reset';
20             our $DEF_SIZE = 10;
21              
22             sub new {
23 1     1 0 24 my $type = shift;
24 1   50     11 my $class = ref($type) || $type || "Net::DNS::Method::Status";
25              
26 1         3 my $ref = shift;
27              
28 1 50 33     37 my $self =
    50 33        
    50 33        
29             {
30             start => time,
31             qs => [],
32             zone => (defined($ref) && defined($ref->{BaseDomain}) ?
33             lc $ref->{BaseDomain} : $DEF_ZONE),
34             reset => (defined($ref) && defined($ref->{Reset}) ?
35             lc $ref->{Reset} : $DEF_RSET),
36             count => (defined($ref) && defined($ref->{StoreResults}) ?
37             $ref->{StoreResults} : $DEF_SIZE),
38             };
39            
40 1         3 bless $self, $class;
41              
42 1         5 return $self->_reset;
43             }
44              
45             sub _reset {
46 1     1   2 my $self = shift;
47 1         11 $self->{counter} = {};
48 1         4 $self->{time} = time;
49 1         4 return $self;
50             }
51              
52             sub _any {
53 4     4   6 my $self = shift;
54 4         5 my $q = shift;
55 4         5 my $ans = shift;
56 4         7 my $data = shift;
57              
58 4         5 unshift @{$self->{qs}}, $data->{from}->addr .
  4         41  
59             '->' . $q->qclass . ' ' . $q->qtype . ' ' .
60             $q->qname;
61              
62 4 100       1319 pop @{$self->{qs}} if @{$self->{qs}} > $self->{count};
  3         6  
  4         16  
63              
64 4         17 $self->{counter}->{$q->qtype}++;
65              
66 4         36 return NS_FAIL;
67             }
68              
69             sub _match {
70 4     4   43 my $q = lc shift;
71 4         5 my $d = shift;
72              
73 4         15 $q =~ s/\.+$//;
74              
75 4         12 my $pos = index($q, $d);
76              
77 4 100       13 return 1 if $q eq $d;
78 3 50 33     10 return 1 if $pos == 0 and (length($q) <= length($d));
79 3 50       12 return 1 if substr($q, $pos - 1, 1) eq '.';
80 3         10 return 0;
81             }
82              
83             sub TXT {
84 4     4 0 7 my $self = shift;
85              
86 4         13 $self->_any(@_); # Account this question...
87            
88 4         6 my $q = shift;
89 4         5 my $ans = shift;
90              
91 4 100       12 if (_match($q->qname, $self->{zone})) {
92              
93             # warn "matched ", $q->qname, "\n";
94              
95 1         4 $self->{counter}->{$q->qtype} --;
96              
97 1         10 my $total = 0;
98 1   50     9 my $age = time - $self->{start} || 1;
99 1   50     9 my $time = time - $self->{time} || 1;
100              
101 1         5 $ans->push('answer', new Net::DNS::RR $q->qname . " 0 IN TXT OK");
102              
103 1 50       7525 if (index($q->qname, $self->{reset}) == 0) {
104 0         0 $self->_reset;
105             }
106             else {
107 1         33 $ans->push('additional', new Net::DNS::RR 'pid.' . $self->{zone}
108             . " 0 IN TXT $$");
109 1         232 $ans->push('additional', new Net::DNS::RR 'started.' .
110             $self->{zone} . " 0 IN TXT " . $age);
111 1         207 $ans->push('additional', new Net::DNS::RR 'last.' . $self->{zone}
112             . " 0 IN TXT " . $time);
113              
114 1         197 foreach my $qt (sort keys %{$self->{counter}}) {
  1         7  
115 1         4 $total += $self->{counter}->{$qt};
116 1         8 $ans->push('additional', new Net::DNS::RR $qt . '.q.' .
117             $self->{zone} . " 0 IN TXT " .
118             $self->{counter}->{$qt});
119             }
120              
121 1         239 $ans->push('additional', new Net::DNS::RR 'total.q.' .
122             $self->{zone} . " IN TXT " . $total);
123            
124 1         211 $ans->push('additional', new Net::DNS::RR 'qps.q.' .
125             $self->{zone} . " IN TXT " .
126             sprintf("%.04f", $total / $time) . " q/sec");
127              
128 1         210 my $ord = 0;
129 1         3 for my $qs (@{$self->{qs}}) {
  1         4  
130 1         8 $ans->push('additional', new Net::DNS::RR 'q' . $ord . '.'
131             . $self->{zone} . " IN TXT " .
132             $qs);
133 1         246 ++ $ord;
134             }
135              
136             }
137              
138 1         5 $ans->header->rcode('NOERROR');
139             # warn "NS_OK | NS_STOP\n";
140 1         9329 return NS_OK | NS_STOP;
141             }
142              
143             # warn "NS_FAIL\n";
144 3         11 return NS_FAIL; # No match or error
145             }
146              
147 4     4 0 3277 sub ANY { TXT @_ };
148              
149             sub AUTOLOAD {
150 0     0     my $sub = $AUTOLOAD;
151 0           $sub =~ s/.*:://;
152              
153             # Insure that the called method has an all
154             # uppercase name. This avoids any clash with
155             # future extensions for these handlers, which
156             # will use mixed case or lowercase.
157              
158 0 0         return undef if $sub eq 'DESTROY';
159 0 0         return NS_FAIL unless $sub eq uc $sub;
160              
161 0     0     *$sub = sub { _any @_; };
  0            
162 0           goto &$sub;
163             }
164              
165              
166             1;
167              
168             __END__