• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PowerDNS / pdns / 15920880335

26 Jun 2025 03:30PM UTC coverage: 61.923% (-3.7%) from 65.652%
15920880335

push

github

web-flow
Merge pull request #15669 from miodvallat/serial_keyer

Increase zone serial number after zone key operations

38311 of 91850 branches covered (41.71%)

Branch coverage included in aggregate %.

27 of 29 new or added lines in 1 file covered. (93.1%)

6308 existing lines in 78 files now uncovered.

120482 of 164587 relevant lines covered (73.2%)

5965233.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.68
/pdns/recursordist/rec-tcounters.hh
1
/*
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22

23
#pragma once
24

25
#include "tcounters.hh"
26

27
#include <string>
28

29
#include "histogram.hh"
30
#include "rec-responsestats.hh"
31
#include "validate.hh"
32
#include "filterpo.hh"
33

34
namespace rec
35
{
36

37
// Simple counters
38
enum class Counter : uint8_t
39
{
40
  outgoingtimeouts,
41
  outgoing4timeouts,
42
  outgoing6timeouts,
43
  throttledqueries,
44
  dontqueries,
45
  qnameminfallbacksuccess,
46
  authzonequeries,
47
  outqueries,
48
  tcpoutqueries,
49
  dotoutqueries,
50
  unreachables,
51
  servFails,
52
  nxDomains,
53
  noErrors,
54
  qcounter,
55
  ipv6qcounter,
56
  tcpqcounter,
57
  unauthorizedUDP, // when this is increased, qcounter isn't
58
  unauthorizedTCP, // when this is increased, qcounter isn't
59
  sourceDisallowedNotify, // when this is increased, qcounter is also
60
  zoneDisallowedNotify, // when this is increased, qcounter is also
61
  policyDrops,
62
  tcpOverflow,
63
  tcpClientOverflow,
64
  clientParseError,
65
  serverParseError,
66
  tooOldDrops,
67
  truncatedDrops,
68
  queryPipeFullDrops,
69
  unexpectedCount,
70
  caseMismatchCount,
71
  spoofCount,
72
  resourceLimits,
73
  overCapacityDrops,
74
  ipv6queries,
75
  chainResends,
76
  nsSetInvalidations,
77
  ednsPingMatches,
78
  ednsPingMismatches,
79
  noPingOutQueries,
80
  noEdnsOutQueries,
81
  noPacketError,
82
  ignoredCount,
83
  emptyQueriesCount,
84
  dnssecQueries,
85
  dnssecAuthenticDataQueries,
86
  dnssecCheckDisabledQueries,
87
  variableResponses,
88
  maxMThreadStackUsage,
89
  dnssecValidations, // should be the sum of all dnssecResult* stats
90
  rebalancedQueries,
91
  proxyProtocolInvalidCount,
92
  nodLookupsDroppedOversize,
93
  dns64prefixanswers,
94
  maintenanceUsec,
95
  maintenanceCalls,
96
  nodCount,
97
  udrCount,
98
  maxChainLength,
99
  maxChainWeight,
100
  chainLimits,
101

102
  numberOfCounters
103
};
104

105
// double averages times, weighted according to how many packets they processed
106
enum class DoubleWAvgCounter : uint8_t
107
{
108
  avgLatencyUsec,
109
  avgLatencyOursUsec,
110
  numberOfCounters
111
};
112

113
// An RCode histogram
114
enum class RCode : uint8_t
115
{
116
  auth,
117
  numberOfCounters
118
};
119

120
// Recursor Response Stats
121
enum class ResponseStats : uint8_t
122
{
123
  responseStats,
124
  numberOfCounters
125
};
126

127
// A few other histograms
128
enum class Histogram : uint8_t
129
{
130
  answers,
131
  auth4Answers,
132
  auth6Answers,
133
  ourtime,
134
  cumulativeAnswers,
135
  cumulativeAuth4Answers,
136
  cumulativeAuth6Answers,
137

138
  numberOfCounters
139
};
140

141
// DNSSEC validation results
142
enum class DNSSECHistogram : uint8_t
143
{
144
  dnssec,
145
  xdnssec,
146

147
  numberOfCounters
148
};
149

150
// Policy hits
151
enum class PolicyHistogram : uint8_t
152
{
153
  policy,
154

155
  numberOfCounters
156
};
157

158
enum class PolicyNameHits : uint8_t
159
{
160
  policyName,
161

162
  numberOfCounters
163
};
164

165
struct Counters
166
{
167
  // An array of simple counters
168
  std::array<uint64_t, static_cast<size_t>(Counter::numberOfCounters)> uint64Count{};
169

170
  struct WeightedAverage
171
  {
172
    double avg{};
173
    uint64_t weight{};
174

175
    void add(double value)
176
    {
29,458,475✔
177
      avg = value;
29,458,475✔
178
      ++weight;
29,458,475✔
179
    }
29,458,475✔
180

181
    void addToRollingAvg(double value, uint64_t rollsize)
182
    {
8,832✔
183
      add((1.0 - 1.0 / static_cast<double>(rollsize)) * avg + value / static_cast<double>(rollsize));
8,832✔
184
    }
8,832✔
185
  };
186
  // And an array of weighted averaged values
187
  std::array<WeightedAverage, static_cast<size_t>(DoubleWAvgCounter::numberOfCounters)> doubleWAvg{};
188

189
  struct RCodeCounters
190
  {
191
    RCodeCounters& operator+=(const RCodeCounters& rhs)
192
    {
333✔
193
      for (size_t i = 0; i < rcodeCounters.size(); i++) {
5,661✔
194
        rcodeCounters.at(i) += rhs.rcodeCounters.at(i);
5,328✔
195
      }
5,328✔
196
      return *this;
333✔
197
    }
333✔
198
    static const size_t numberOfRCodes = 16;
199
    std::array<uint64_t, numberOfRCodes> rcodeCounters;
200
  };
201
  // An RCodes histogram
202
  RCodeCounters auth{};
203

204
  std::array<pdns::Histogram, static_cast<size_t>(Histogram::numberOfCounters)> histograms = {
205
    pdns::Histogram{"answers", {1000, 10000, 100000, 1000000}},
206
    pdns::Histogram{"auth4answers", {1000, 10000, 100000, 1000000}},
207
    pdns::Histogram{"auth6answers", {1000, 10000, 100000, 1000000}},
208
    pdns::Histogram{"ourtime", {1000, 2000, 4000, 8000, 16000, 32000}},
209
    pdns::Histogram{"cumul-clientanswers-", 10, 19},
210
    pdns::Histogram{"cumul-authanswers-", 1000, 13},
211
    pdns::Histogram{"cumul-authanswers-", 1000, 13}};
212

213
  // Response stats
214
  RecResponseStats responseStats{};
215

216
  // DNSSEC stats
217
  struct DNSSECCounters
218
  {
219
    DNSSECCounters& operator+=(const DNSSECCounters& rhs)
220
    {
6,660✔
221
      for (size_t i = 0; i < counts.size(); i++) {
139,860✔
222
        counts.at(i) += rhs.counts.at(i);
133,200✔
223
      }
133,200✔
224
      return *this;
6,660✔
225
    }
6,660✔
226
    uint64_t& at(vState index)
227
    {
3,823✔
228
      return counts.at(static_cast<size_t>(index));
3,823✔
229
    }
3,823✔
230
    std::array<uint64_t, static_cast<size_t>(vState::BogusInvalidDNSKEYProtocol) + 1> counts;
231
  };
232
  std::array<DNSSECCounters, static_cast<size_t>(DNSSECHistogram::numberOfCounters)> dnssecCounters{};
233

234
  // Policy histogram
235
  struct PolicyCounters
236
  {
237
    PolicyCounters& operator+=(const PolicyCounters& rhs)
238
    {
1,998✔
239
      for (size_t i = 0; i < counts.size(); i++) {
13,986✔
240
        counts.at(i) += rhs.counts.at(i);
11,988✔
241
      }
11,988✔
242
      return *this;
1,998✔
243
    }
1,998✔
244
    uint64_t& at(DNSFilterEngine::PolicyKind index)
245
    {
270✔
246
      return counts.at(static_cast<size_t>(index));
270✔
247
    }
270✔
248
    std::array<uint64_t, static_cast<size_t>(DNSFilterEngine::PolicyKind::Custom) + 1> counts;
249
  };
250
  PolicyCounters policyCounters{};
251

252
  // Policy hits by name
253
  struct PolicyNameCounters
254
  {
255
    PolicyNameCounters& operator+=(const PolicyNameCounters& rhs)
256
    {
46,536✔
257
      for (const auto& [name, count] : rhs.counts) {
46,536!
UNCOV
258
        counts[name] += count;
×
UNCOV
259
      }
×
260
      return *this;
46,536✔
261
    }
46,536✔
262
    std::unordered_map<std::string, uint64_t> counts;
263
  };
264
  PolicyNameCounters policyNameHits;
265

266
  Counters()
267
  {
277✔
268
    for (auto& elem : uint64Count) {
16,897✔
269
      elem = 0;
16,897✔
270
    }
16,897✔
271
    // doubleWAvg has a default constructor that initializes
272
    for (auto& elem : auth.rcodeCounters) {
4,432✔
273
      elem = 0;
4,432✔
274
    }
4,432✔
275
    // Histogram has a constructor that initializes
276
    // RecResponseStats has a default constructor that initializes
277
    for (auto& histogram : dnssecCounters) {
554✔
278
      for (auto& elem : histogram.counts) {
11,080✔
279
        elem = 0;
11,080✔
280
      }
11,080✔
281
    }
554✔
282
    for (auto& elem : policyCounters.counts) {
1,662✔
283
      elem = 0;
1,662✔
284
    }
1,662✔
285
    // PolicyNameCounters has a default constuctor that initializes
286
  }
277✔
287

288
  // Merge a set of counters into an existing set of counters. For simple counters, that will be additions
289
  // for averages, we should take the weights into account. Histograms need to sum all individual counts.
290
  Counters& merge(const Counters& data);
291

292
  // The following accessors select the right counter type based on the index type
293
  uint64_t& at(Counter index)
294
  {
58,332,866✔
295
    return uint64Count.at(static_cast<size_t>(index));
58,332,866✔
296
  }
58,332,866✔
297

298
  WeightedAverage& at(DoubleWAvgCounter index)
299
  {
29,529,787✔
300
    return doubleWAvg.at(static_cast<size_t>(index));
29,529,787✔
301
  }
29,529,787✔
302

303
  RCodeCounters& at(RCode /*unused*/)
304
  {
22,073✔
305
    // We only have a single RCode indexed Histogram, so no need to select a specific one
306
    return auth;
22,073✔
307
  }
22,073✔
308

309
  RecResponseStats& at(ResponseStats /*unused*/)
310
  {
4,421✔
311
    // We only have a single ResponseStats indexed RecResponseStats, so no need to select a specific one
312
    return responseStats;
4,421✔
313
  }
4,421✔
314

315
  pdns::Histogram& at(Histogram index)
316
  {
37,840✔
317
    return histograms.at(static_cast<size_t>(index));
37,840✔
318
  }
37,840✔
319

320
  DNSSECCounters& at(DNSSECHistogram index)
321
  {
9,853✔
322
    return dnssecCounters.at(static_cast<size_t>(index));
9,853✔
323
  }
9,853✔
324

325
  // We only have a single PolicyHistogram indexed PolicyCounters, so no need to select a specific one
326
  PolicyCounters& at(PolicyHistogram)
327
  {
2,268✔
328
    return policyCounters;
2,268✔
329
  }
2,268✔
330

331
  // We only have a single policyNameHits indexed PolicyNameCounters, so no need to select a specific one
332
  PolicyNameCounters& at(PolicyNameHits /*unused*/)
UNCOV
333
  {
×
UNCOV
334
    return policyNameHits;
×
UNCOV
335
  }
×
336

337
  // Mainly for debugging purposes
338
  [[nodiscard]] std::string toString() const;
339
};
340

341
// The application specific types, one for thread local, one for the aggregator
342
using TCounters = pdns::TLocalCounters<Counters>;
343
using GlobalCounters = pdns::GlobalCounters<Counters>;
344
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc