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

PowerDNS / pdns / 13012068652

28 Jan 2025 01:59PM UTC coverage: 64.71% (+0.01%) from 64.699%
13012068652

Pull #14724

github

web-flow
Merge b15562560 into db18c3a17
Pull Request #14724: dnsdist: Add meson support

38328 of 90334 branches covered (42.43%)

Branch coverage included in aggregate %.

361 of 513 new or added lines in 35 files covered. (70.37%)

42 existing lines in 13 files now uncovered.

128150 of 166934 relevant lines covered (76.77%)

4540890.91 hits per line

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

55.0
/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
  {
82✔
31
  }
82✔
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)
40
  {
46✔
41
  }
46✔
42

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

45
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
46
  {
112✔
47
    return getKeys(dq.ids.origRemote);
112✔
48
  }
112✔
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)
65
  {
32✔
66
  }
32✔
67

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

76
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
77
  {
92✔
78
    return getKeys(dq.ids.qname);
92✔
79
  }
92✔
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)
97
  {
38✔
98
  }
38✔
99

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

102
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
103
  {
56✔
104
    return getKeys(dq.ids.qname);
56✔
105
  }
56✔
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
  {
14✔
125
  }
14✔
126

127
  std::vector<std::string> getKeys(const DNSQuestion& dq) override
128
  {
12✔
129
    if (dq.ids.qTag) {
12!
130
      const auto& it = dq.ids.qTag->find(d_tag);
12✔
131
      if (it != dq.ids.qTag->end()) {
12!
132
        return { it->second };
12✔
133
      }
12✔
134
    }
12✔
135
    return {};
×
136
  }
12✔
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
  {
24✔
152
  }
24✔
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
  {
×
NEW
163
    (void)key;
×
NEW
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
  {
6✔
169
    return false;
6✔
170
  }
6✔
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(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)
181
  {
18✔
182
  }
18✔
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
  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