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

PowerDNS / pdns / 18837422702

27 Oct 2025 10:15AM UTC coverage: 73.025% (+0.02%) from 73.004%
18837422702

Pull #16375

github

web-flow
Merge 2f23fc90d into 82ea647b4
Pull Request #16375: dnsdist: Include a Date: response header for rejected HTTP1 requests

38279 of 63122 branches covered (60.64%)

Branch coverage included in aggregate %.

0 of 11 new or added lines in 1 file covered. (0.0%)

10680 existing lines in 98 files now uncovered.

127481 of 163870 relevant lines covered (77.79%)

5384548.9 hits per line

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

90.09
/pdns/dns.cc
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
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
#include "dns.hh"
26
#include "misc.hh"
27
#include "views.hh"
28
#include <stdexcept>
29
#include <iostream>
30
#include <boost/algorithm/string.hpp>
31
#include <boost/assign/list_of.hpp>
32
#include "dnsparser.hh"
33

34
const std::array<std::string, 24> RCode::rcodes_s = {
35
  "No Error",
36
  "Form Error",
37
  "Server Failure",
38
  "Non-Existent domain",
39
  "Not Implemented",
40
  "Query Refused",
41
  "Name Exists when it should not",
42
  "RR Set Exists when it should not",
43
  "RR Set that should exist does not",
44
  "Server Not Authoritative for zone / Not Authorized",
45
  "Name not contained in zone",
46
  "Err#11",
47
  "Err#12",
48
  "Err#13",
49
  "Err#14",
50
  "Err#15",  // Last non-extended RCode
51
  "Bad OPT Version / TSIG Signature Failure",
52
  "Key not recognized",
53
  "Signature out of time window",
54
  "Bad TKEY Mode",
55
  "Duplicate key name",
56
  "Algorithm not supported",
57
  "Bad Truncation",
58
  "Bad/missing Server Cookie"
59
};
60

61
static const std::array<std::string, 24> rcodes_short_s =  {
62
  "noerror",
63
  "formerr",
64
  "servfail",
65
  "nxdomain",
66
  "notimp",
67
  "refused",
68
  "yxdomain",
69
  "yxrrset",
70
  "nxrrset",
71
  "notauth",
72
  "notzone",
73
  "rcode11",
74
  "rcode12",
75
  "rcode13",
76
  "rcode14",
77
  "rcode15",
78
  "badvers",
79
  "badkey",
80
  "badtime",
81
  "badmode",
82
  "badname",
83
  "badalg",
84
  "badtrunc",
85
  "badcookie",
86
};
87

88
std::string RCode::to_s(uint8_t rcode) {
12,661✔
89
  if (rcode > 0xF) {
12,661✔
90
    return "ErrOutOfRange";
3✔
91
  }
3✔
92
  return ERCode::to_s(rcode);
12,658✔
93
}
12,661✔
94

95
std::string RCode::to_short_s(uint8_t rcode) {
3,332✔
96
  if (rcode > 0xF) {
3,332✔
97
    return "ErrOutOfRange";
3✔
98
  }
3✔
99
  return ERCode::to_short_s(rcode);
3,329✔
100
}
3,332✔
101

102
std::optional<uint8_t> RCode::from_short(const std::string_view& rcode_string)
103
{
56✔
104
  const auto* position = std::find(rcodes_short_s.begin(), rcodes_short_s.end(), rcode_string);
56✔
105
  if (position == rcodes_short_s.end()) {
56✔
UNCOV
106
    return std::nullopt;
8✔
UNCOV
107
  }
8✔
108
  auto code = std::distance(rcodes_short_s.begin(), position);
48✔
109
  if (code > 0xF) {
48✔
110
    return std::nullopt;
3✔
111
  }
3✔
112
  return code;
45✔
113
}
48✔
114

115
std::string ERCode::to_s(uint16_t rcode) {
19,648✔
116
  if (rcode >= RCode::rcodes_s.size()) {
19,648✔
117
    return std::string("Err#") + std::to_string(rcode);
3✔
118
  }
3✔
119
  return RCode::rcodes_s.at(rcode);
19,645✔
120
}
19,648✔
121

122
std::string ERCode::to_short_s(uint16_t rcode) {
3,353✔
123
  if (rcode >= rcodes_short_s.size()) {
3,353!
124
    return "rcode" + std::to_string(rcode);
×
125
  }
×
126
  return rcodes_short_s.at(rcode);
3,353✔
127
}
3,353✔
128

129
std::optional<uint16_t> ERCode::from_short(const std::string_view& ercode_string)
130
{
24✔
131
  const auto* position = std::find(rcodes_short_s.begin(), rcodes_short_s.end(), ercode_string);
24✔
132
  if (position == rcodes_short_s.end()) {
24!
133
    return std::nullopt;
×
134
  }
×
135
  return std::distance(rcodes_short_s.begin(), position);
24✔
136
}
24✔
137

138
std::string Opcode::to_s(uint8_t opcode) {
31✔
139
  static const std::array<std::string, 6> s_opcodes = { "Query", "IQuery", "Status", "", "Notify", "Update" };
31✔
140

141
  if (opcode >= s_opcodes.size() || s_opcodes.at(opcode).empty()) {
31✔
142
    return std::to_string(opcode);
6✔
143
  }
6✔
144

145
  return s_opcodes.at(opcode);
25✔
146
}
31✔
147

148
std::optional<uint8_t> Opcode::from_lowercase_string(const std::string_view& opcode_string)
149
{
23✔
150
  static const std::array<std::string, 6> s_opcodes = { "query", "iquery", "status", "", "notify", "update" };
23✔
151
  const auto* position = std::find(s_opcodes.begin(), s_opcodes.end(), opcode_string);
23✔
152
  if (position == s_opcodes.end() || position->empty()) {
23!
153
    return std::nullopt;
6✔
154
  }
6✔
155
  return std::distance(s_opcodes.begin(), position);
17✔
156
}
23✔
157

158
// goal is to hash based purely on the question name, and turn error into 'default'
159
uint32_t hashQuestion(const uint8_t* packet, uint16_t packet_len, uint32_t init, bool& wasOK)
160
{
303,633✔
161
  if (packet_len < sizeof(dnsheader)) {
303,633!
162
    wasOK = false;
×
163
    return init;
×
164
  }
×
165
  // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
166
  pdns::views::UnsignedCharView name(packet + sizeof(dnsheader), packet_len - sizeof(dnsheader));
303,633✔
167
  pdns::views::UnsignedCharView::size_type len = 0;
303,633✔
168

169
  while (len < name.length()) {
914,244✔
170
    uint8_t labellen = name[len++];
914,232✔
171
    if (labellen == 0) {
914,232✔
172
      wasOK = true;
303,621✔
173
      // len is name.length() at max as it was < before the increment
174
      return burtleCI(name.data(), len, init);
303,621✔
175
    }
303,621✔
176
    len += labellen;
610,611✔
177
  }
610,611✔
178
  // We've encountered a label that is too long
179
  wasOK = false;
12✔
180
  return init;
12✔
181
}
303,633✔
182

183
static const std::array<std::string, 4> placeNames = {
184
  "QUESTION",
185
  "ANSWER",
186
  "AUTHORITY",
187
  "ADDITIONAL"
188
};
189

190
std::string DNSResourceRecord::placeString(uint8_t place)
191
{
45✔
192
  if (place >= placeNames.size()) {
45✔
193
    return "?";
3✔
194
  }
3✔
195
  return placeNames.at(place);
42✔
196
}
45✔
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