1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "statnode.hh"
StatNode::Stat StatNode::print(unsigned int depth, Stat newstat, bool silent) const
{
if(!silent) {
cout<<string(depth, ' ');
cout<<name<<": "<<endl;
}
Stat childstat;
childstat.queries += s.queries;
childstat.noerrors += s.noerrors;
childstat.nxdomains += s.nxdomains;
childstat.servfails += s.servfails;
childstat.drops += s.drops;
childstat.bytes += s.bytes;
if(children.size()>1024 && !silent) {
cout<<string(depth, ' ')<<name<<": too many to print"<<endl;
}
for(const children_t::value_type& child : children) {
childstat=child.second.print(depth+8, childstat, silent || children.size()>1024);
}
if(!silent || children.size()>1)
cout<<string(depth, ' ')<<childstat.queries<<" queries, " <<
childstat.noerrors<<" noerrors, "<<
childstat.nxdomains<<" nxdomains, "<<
childstat.servfails<<" servfails, "<<
childstat.drops<<" drops, "<<
childstat.bytes<<" bytes"<<endl;
newstat+=childstat;
return newstat;
}
void StatNode::visit(visitor_t visitor, Stat &newstat, unsigned int depth) const
{
Stat childstat(s);
for (const auto& child : children) {
child.second.visit(visitor, childstat, depth+8);
}
visitor(this, s, childstat);
newstat += childstat;
}
void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote)
{
// cerr<<"FIRST submit called on '"<<domain<<"'"<<endl;
std::vector<string> tmp = domain.getRawLabels();
if (tmp.empty()) {
return;
}
auto last = tmp.end() - 1;
children[*last].submit(last, tmp.begin(), "", rcode, bytes, remote, 1);
}
/* www.powerdns.com. ->
. <- fullnames
com.
powerdns.com
www.powerdns.com.
*/
void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote, unsigned int count)
{
// cerr<<"Submit called for domain='"<<domain<<"': ";
// for(const std::string& n : labels)
// cerr<<n<<".";
// cerr<<endl;
if (name.empty()) {
name=*end;
// cerr<<"Set short name to '"<<name<<"'"<<endl;
}
else {
// cerr<<"Short name was already set to '"<<name<<"'"<<endl;
}
if (end == begin) {
if (fullname.empty()) {
size_t needed = name.size() + 1 + domain.size();
if (fullname.capacity() < needed) {
fullname.reserve(needed);
}
fullname = name;
fullname.append(".");
fullname.append(domain);
labelsCount = count;
}
// cerr<<"Hit the end, set our fullname to '"<<fullname<<"'"<<endl<<endl;
s.queries++;
s.bytes += bytes;
if(rcode<0)
s.drops++;
else if(rcode==0)
s.noerrors++;
else if(rcode==2)
s.servfails++;
else if(rcode==3)
s.nxdomains++;
if (remote) {
s.remotes[*remote]++;
}
}
else {
if (fullname.empty()) {
size_t needed = name.size() + 1 + domain.size();
if (fullname.capacity() < needed) {
fullname.reserve(needed);
}
fullname = name;
fullname.append(".");
fullname.append(domain);
labelsCount = count;
}
// cerr<<"Not yet end, set our fullname to '"<<fullname<<"', recursing"<<endl;
--end;
children[*end].submit(end, begin, fullname, rcode, bytes, remote, count+1);
}
}
|