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

PowerDNS / pdns / 18676545156

21 Oct 2025 07:39AM UTC coverage: 67.713% (-5.3%) from 72.976%
18676545156

push

github

web-flow
Merge pull request #16298 from Habbie/rec-el-gnutls

recursor el-* build: depend on gnutls

31900 of 55802 branches covered (57.17%)

Branch coverage included in aggregate %.

104354 of 145422 relevant lines covered (71.76%)

5952721.81 hits per line

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

39.53
/pdns/dnsdistdist/dnsdist-kvs.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 "dnsdist.hh"
25

26
class KeyValueLookupKey
27
{
28
public:
29
  virtual ~KeyValueLookupKey()
30
  {
16✔
31
  }
16✔
32
  virtual std::vector<std::string> getKeys(const DNSQuestion&) = 0;
33
  virtual std::string toString() const = 0;
34
};
35

36
class KeyValueLookupKeySourceIP: public KeyValueLookupKey
37
{
38
public:
39
  KeyValueLookupKeySourceIP(uint8_t v4Mask, uint8_t v6Mask, bool includePort): d_v4Mask(v4Mask), d_v6Mask(v6Mask), d_includePort(includePort)
6✔
40
  {
6✔
41
  }
6✔
42

43
  std::vector<std::string> getKeys(const ComboAddress& addr);
44

45
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
46
  {
4✔
47
    return getKeys(dq.ids.origRemote);
4✔
48
  }
4✔
49

50
  std::string toString() const override
51
  {
×
52
    return "source IP (masked to " + std::to_string(d_v4Mask) + " (v4) / " + std::to_string(d_v6Mask) + " (v6) bits)" + (d_includePort ? " including the port" : "");
×
53
  }
×
54
private:
55
  uint8_t d_v4Mask;
56
  uint8_t d_v6Mask;
57
  bool d_includePort;
58
};
59

60
class KeyValueLookupKeyQName: public KeyValueLookupKey
61
{
62
public:
63

64
  KeyValueLookupKeyQName(bool wireFormat): d_wireFormat(wireFormat)
4✔
65
  {
4✔
66
  }
4✔
67

68
  std::vector<std::string> getKeys(const DNSName& qname)
69
  {
16✔
70
    if (d_wireFormat) {
16✔
71
      return {qname.toDNSStringLC()};
8✔
72
    }
8✔
73
    return {qname.makeLowerCase().toStringRootDot()};
8✔
74
  }
16✔
75

76
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
77
  {
4✔
78
    return getKeys(dq.ids.qname);
4✔
79
  }
4✔
80

81
  std::string toString() const override
82
  {
×
83
    if (d_wireFormat) {
×
84
      return "qname in wire format";
×
85
    }
×
86
    return "qname";
×
87
  }
×
88

89
private:
90
  bool d_wireFormat;
91
};
92

93
class KeyValueLookupKeySuffix: public KeyValueLookupKey
94
{
95
public:
96
  KeyValueLookupKeySuffix(size_t minLabels, bool wireFormat): d_minLabels(minLabels), d_wireFormat(wireFormat)
6✔
97
  {
6✔
98
  }
6✔
99

100
  std::vector<std::string> getKeys(const DNSName& qname);
101

102
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
103
  {
6✔
104
    return getKeys(dq.ids.qname);
6✔
105
  }
6✔
106

107
  std::string toString() const override
108
  {
×
109
    if (d_minLabels > 0) {
×
110
      return "suffix " + std::string(d_wireFormat ? "in wire format " : "") + "with at least " + std::to_string(d_minLabels) + " label(s)";
×
111
    }
×
112
    return "suffix" + std::string(d_wireFormat ? " in wire format" : "");
×
113
  }
×
114

115
private:
116
  size_t d_minLabels;
117
  bool d_wireFormat;
118
};
119

120
class KeyValueLookupKeyTag: public KeyValueLookupKey
121
{
122
public:
123
  KeyValueLookupKeyTag(const std::string& tag): d_tag(tag)
124
  {
×
125
  }
×
126

127
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
128
  {
×
129
    if (dq.ids.qTag) {
×
130
      const auto& it = dq.ids.qTag->find(d_tag);
×
131
      if (it != dq.ids.qTag->end()) {
×
132
        return { it->second };
×
133
      }
×
134
    }
×
135
    return {};
×
136
  }
×
137

138
  std::string toString() const override
139
  {
×
140
    return "value of the tag named '" + d_tag + "'";
×
141
  }
×
142

143
private:
144
  std::string d_tag;
145
};
146

147
class KeyValueStore
148
{
149
public:
150
  virtual ~KeyValueStore()
151
  {
3✔
152
  }
3✔
153

154
  virtual bool keyExists(const std::string& key) = 0;
155
  virtual bool getValue(const std::string& key, std::string& value) = 0;
156
  // do a range-based lookup (mostly useful for IP addresses), assuming that:
157
  // there is a key for the last element of the range (2001:0db8:ffff:ffff:ffff:ffff:ffff:ffff, in network byte order, for 2001:db8::/32)
158
  // which contains the first element of the range (2001:0db8:0000:0000:0000:0000:0000:0000, in network bytes order) followed by any data in the value
159
  // AND there is no overlapping ranges in the database !!
160
  // This requires that the underlying store supports ordered keys, which is true for LMDB but not for CDB, for example.
161
  virtual bool getRangeValue(const std::string& key, std::string& value)
162
  {
×
163
    (void)key;
×
164
    (void)value;
×
165
    throw std::runtime_error("range-based lookups are not implemented for this Key-Value Store");
×
166
  }
×
167
  virtual bool reload()
168
  {
×
169
    return false;
×
170
  }
×
171
};
172

173
#ifdef HAVE_LMDB
174

175
#include "ext/lmdb-safe/lmdb-safe.hh"
176

177
class LMDBKVStore: public KeyValueStore
178
{
179
public:
180
  LMDBKVStore(const std::string& fname, const std::string& dbName, bool noLock=false): d_env(getMDBEnv(fname.c_str(), noLock ? MDB_NOSUBDIR|MDB_RDONLY|MDB_NOLOCK : MDB_NOSUBDIR|MDB_RDONLY, 0600, 0)), d_dbi(d_env->openDB(dbName, 0)), d_fname(fname), d_dbName(dbName)
2!
181
  {
2✔
182
  }
2✔
183

184
  bool keyExists(const std::string& key) override;
185
  bool getValue(const std::string& key, std::string& value) override;
186
  bool getRangeValue(const std::string& key, std::string& value) override;
187

188
private:
189
  std::shared_ptr<MDBEnv> d_env;
190
  MDBDbi d_dbi;
191
  std::string d_fname;
192
  std::string d_dbName;
193
};
194

195
#endif /* HAVE_LMDB */
196

197
#ifdef HAVE_CDB
198

199
#include "cdb.hh"
200

201
class CDBKVStore: public KeyValueStore
202
{
203
public:
204
  CDBKVStore(const std::string& fname, time_t refreshDelay);
205
  ~CDBKVStore();
206

207
  bool keyExists(const std::string& key) override;
208
  bool getValue(const std::string& key, std::string& value) override;
209
  bool reload() override;
210

211
private:
212
  void refreshDBIfNeeded(time_t now);
213
  bool reload(const struct stat& st);
214

215
  SharedLockGuarded<std::unique_ptr<CDB>> d_cdb{nullptr};
216
  std::string d_fname;
217
  time_t d_mtime{0};
218
  time_t d_nextCheck{0};
219
  time_t d_refreshDelay{0};
220
  std::atomic_flag d_refreshing;
221
};
222

223
#endif /* HAVE_LMDB */
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