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

PowerDNS / pdns / 19741624072

27 Nov 2025 03:45PM UTC coverage: 73.086% (+0.02%) from 73.065%
19741624072

Pull #16570

github

web-flow
Merge 08a2cdb1d into f94a3f63f
Pull Request #16570: rec: rewrite all unwrap calls in web.rs

38523 of 63408 branches covered (60.75%)

Branch coverage included in aggregate %.

128044 of 164496 relevant lines covered (77.84%)

6531485.83 hits per line

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

88.71
/pdns/dnsdistdist/dnsdist-edns.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
#include "dnsdist-ecs.hh"
23
#include "dnsdist-edns.hh"
24
#include "ednsoptions.hh"
25
#include "ednsextendederror.hh"
26

27
namespace dnsdist::edns
28
{
29
std::pair<std::optional<uint16_t>, std::optional<std::string>> getExtendedDNSError(const PacketBuffer& packet)
30
{
25✔
31
  uint16_t optStart = 0;
25✔
32
  size_t optLen = 0;
25✔
33
  bool last = false;
25✔
34

35
  int res = locateEDNSOptRR(packet, &optStart, &optLen, &last);
25✔
36

37
  if (res != 0) {
25✔
38
    return {std::nullopt, std::nullopt};
3✔
39
  }
3✔
40

41
  size_t optContentStart = 0;
22✔
42
  uint16_t optContentLen = 0;
22✔
43
  uint16_t infoCode{0};
22✔
44
  std::optional<std::string> extraText{std::nullopt};
22✔
45
  /* we need at least 2 bytes after the option length (info-code) */
46
  if (!isEDNSOptionInOpt(packet, optStart, optLen, EDNSOptionCode::EXTENDEDERROR, &optContentStart, &optContentLen) || optContentLen < sizeof(infoCode)) {
22!
47
    return {std::nullopt, std::nullopt};
3✔
48
  }
3✔
49
  memcpy(&infoCode, &packet.at(optContentStart), sizeof(infoCode));
19✔
50
  infoCode = ntohs(infoCode);
19✔
51

52
  if (optContentLen > sizeof(infoCode)) {
19✔
53
    extraText = std::string();
13✔
54
    extraText->resize(optContentLen - sizeof(infoCode));
13✔
55
    memcpy(extraText->data(), &packet.at(optContentStart + sizeof(infoCode)), optContentLen - sizeof(infoCode));
13✔
56
  }
13✔
57
  return {infoCode, std::move(extraText)};
19✔
58
}
22✔
59

60
bool addExtendedDNSError(PacketBuffer& packet, size_t maximumPacketSize, uint16_t code, const std::string& extraStatus)
61
{
23✔
62
  uint16_t optStart = 0;
23✔
63
  size_t optLen = 0;
23✔
64
  bool last = false;
23✔
65

66
  int res = locateEDNSOptRR(packet, &optStart, &optLen, &last);
23✔
67

68
  if (res != 0) {
23✔
69
    /* no EDNS OPT record in the response, something is not right */
70
    return false;
5✔
71
  }
5✔
72

73
  EDNSExtendedError ede{.infoCode = code, .extraText = extraStatus};
18✔
74
  auto edeOptionPayload = makeEDNSExtendedErrorOptString(ede);
18✔
75
  std::string edeOption;
18✔
76
  generateEDNSOption(EDNSOptionCode::EXTENDEDERROR, edeOptionPayload, edeOption);
18✔
77

78
  /* we might have one record after the OPT one, we need to rewrite
79
     the whole packet because of compression */
80
  PacketBuffer newContent;
18✔
81
  bool ednsAdded = false;
18✔
82
  bool edeAdded = false;
18✔
83
  if (!slowRewriteEDNSOptionInQueryWithRecords(packet, newContent, ednsAdded, EDNSOptionCode::EXTENDEDERROR, edeAdded, true, edeOption)) {
18!
84
    return false;
×
85
  }
×
86

87
  if (newContent.size() > maximumPacketSize) {
18!
88
    return false;
×
89
  }
×
90

91
  packet = std::move(newContent);
18✔
92
  return true;
18✔
93
}
18✔
94
}
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