• 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

63.33
/pdns/dnsdistdist/dnsdist-cache.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
#pragma once
23

24
#include <atomic>
25
#include <unordered_map>
26

27
#include "iputils.hh"
28
#include "lock.hh"
29
#include "noinitvector.hh"
30
#include "stat_t.hh"
31
#include "ednsoptions.hh"
32

33
struct DNSQuestion;
34

35
class DNSDistPacketCache : boost::noncopyable
36
{
37
public:
38
  struct CacheSettings
39
  {
40
    std::unordered_set<uint16_t> d_optionsToSkip{EDNSOptionCode::COOKIE, EDNSOptionCode::PADDING};
41
    std::vector<uint16_t> d_payloadRanks{};
42
    size_t d_maxEntries{0};
43
    size_t d_maximumEntrySize{4096};
44
    uint32_t d_maxTTL{86400};
45
    uint32_t d_minTTL{0};
46
    uint32_t d_tempFailureTTL{60};
47
    uint32_t d_maxNegativeTTL{3600};
48
    uint32_t d_truncatedTTL{0};
49
    uint32_t d_staleTTL{60};
50
    uint32_t d_shardCount{1};
51
    bool d_dontAge{false};
52
    bool d_deferrableInsertLock{true};
53
    bool d_parseECS{false};
54
    bool d_keepStaleData{false};
55
    bool d_shuffle{false};
56
  };
57

58
  DNSDistPacketCache(CacheSettings settings);
59

60
  void insert(uint32_t key, const boost::optional<Netmask>& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const PacketBuffer& response, bool receivedOverUDP, uint8_t rcode, boost::optional<uint32_t> tempFailureTTL);
61
  bool get(DNSQuestion& dnsQuestion, uint16_t queryId, uint32_t* keyOut, boost::optional<Netmask>& subnet, bool dnssecOK, bool receivedOverUDP, uint32_t allowExpired = 0, bool skipAging = false, bool truncatedOK = true, bool recordMiss = true);
62
  size_t purgeExpired(size_t upTo, time_t now);
63
  size_t expunge(size_t upTo = 0);
64
  size_t expungeByName(const DNSName& name, uint16_t qtype = QType::ANY, bool suffixMatch = false);
65
  [[nodiscard]] bool isFull();
66
  [[nodiscard]] string toString();
67
  [[nodiscard]] uint64_t getSize();
68
  [[nodiscard]] uint64_t getHits() const { return d_hits.load(); }
212✔
69
  [[nodiscard]] uint64_t getMisses() const { return d_misses.load(); }
212✔
70
  [[nodiscard]] uint64_t getDeferredLookups() const { return d_deferredLookups.load(); }
215✔
71
  [[nodiscard]] uint64_t getDeferredInserts() const { return d_deferredInserts.load(); }
218✔
72
  [[nodiscard]] uint64_t getLookupCollisions() const { return d_lookupCollisions.load(); }
215✔
73
  [[nodiscard]] uint64_t getInsertCollisions() const { return d_insertCollisions.load(); }
230✔
74
  [[nodiscard]] uint64_t getMaxEntries() const { return d_settings.d_maxEntries; }
219✔
75
  [[nodiscard]] uint64_t getTTLTooShorts() const { return d_ttlTooShorts.load(); }
212✔
76
  [[nodiscard]] uint64_t getCleanupCount() const { return d_cleanupCount.load(); }
212✔
77
  [[nodiscard]] uint64_t getEntriesCount();
78
  uint64_t dump(int fileDesc, bool rawResponse = false);
79

80
  /* get the list of domains (qnames) that contains the given address in an A or AAAA record */
81
  [[nodiscard]] std::set<DNSName> getDomainsContainingRecords(const ComboAddress& addr);
82
  /* get the list of IP addresses contained in A or AAAA for a given domains (qname) */
83
  [[nodiscard]] std::set<ComboAddress> getRecordsForDomain(const DNSName& domain);
84

85
  [[nodiscard]] bool isECSParsingEnabled() const { return d_settings.d_parseECS; }
40✔
86

87
  [[nodiscard]] bool keepStaleData() const
88
  {
11✔
89
    return d_settings.d_keepStaleData;
11✔
90
  }
11✔
91

92
  [[nodiscard]] size_t getMaximumEntrySize() const { return d_settings.d_maximumEntrySize; }
2,078,853✔
93

94
  uint32_t getKey(const DNSName::string_t& qname, size_t qnameWireLength, const PacketBuffer& packet, bool receivedOverUDP) const;
95

96
  static uint32_t getMinTTL(const char* packet, uint16_t length, bool* seenNoDataSOA);
97
  static bool getClientSubnet(const PacketBuffer& packet, size_t qnameWireLength, boost::optional<Netmask>& subnet);
98

99
private:
100
  struct CacheValue
101
  {
102
    [[nodiscard]] time_t getTTD() const { return validity; }
×
103
    std::string value;
104
    DNSName qname;
105
    boost::optional<Netmask> subnet;
106
    uint16_t qtype{0};
107
    uint16_t qclass{0};
108
    uint16_t queryFlags{0};
109
    time_t added{0};
110
    time_t validity{0};
111
    uint16_t len{0};
112
    bool receivedOverUDP{false};
113
    bool dnssecOK{false};
114
  };
115

116
  class CacheShard
117
  {
118
  public:
119
    CacheShard() = default;
2,205✔
120
    CacheShard(CacheShard&& /* old */) noexcept
121
    {
×
122
    }
×
123
    CacheShard(const CacheShard& /* old */)
124
    {
×
125
    }
×
126
    CacheShard& operator=(CacheShard&& /* old */) noexcept
127
    {
×
128
      return *this;
×
129
    }
×
130
    CacheShard& operator=(const CacheShard& /* old */)
131
    {
×
132
      return *this;
×
133
    }
×
134
    ~CacheShard() = default;
1,152✔
135

136
    void setSize(size_t maxSize)
137
    {
2,205✔
138
      d_map.write_lock()->reserve(maxSize);
2,205✔
139
    }
2,205✔
140

141
    SharedLockGuarded<std::unordered_map<uint32_t, CacheValue>> d_map{};
142
    std::atomic<uint64_t> d_entriesCount{0};
143
  };
144

145
  [[nodiscard]] bool cachedValueMatches(const CacheValue& cachedValue, uint16_t queryFlags, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool receivedOverUDP, bool dnssecOK, const boost::optional<Netmask>& subnet) const;
146
  [[nodiscard]] uint32_t getShardIndex(uint32_t key) const;
147
  bool insertLocked(std::unordered_map<uint32_t, CacheValue>& map, uint32_t key, CacheValue& newValue);
148

149
  std::vector<CacheShard> d_shards{};
150

151
  pdns::stat_t d_deferredLookups{0};
152
  pdns::stat_t d_deferredInserts{0};
153
  pdns::stat_t d_hits{0};
154
  pdns::stat_t d_misses{0};
155
  pdns::stat_t d_insertCollisions{0};
156
  pdns::stat_t d_lookupCollisions{0};
157
  pdns::stat_t d_ttlTooShorts{0};
158
  pdns::stat_t d_cleanupCount{0};
159

160
  CacheSettings d_settings;
161
};
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