2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
26 class KeyValueLookupKey
29 virtual ~KeyValueLookupKey()
32 virtual std::vector<std::string> getKeys(const DNSQuestion&) = 0;
33 virtual std::string toString() const = 0;
36 class KeyValueLookupKeySourceIP: public KeyValueLookupKey
39 std::vector<std::string> getKeys(const ComboAddress& addr);
41 std::vector<std::string> getKeys(const DNSQuestion& dq) override
43 return getKeys(*dq.remote);
46 std::string toString() const override
52 class KeyValueLookupKeyQName: public KeyValueLookupKey
56 KeyValueLookupKeyQName(bool wireFormat): d_wireFormat(wireFormat)
60 std::vector<std::string> getKeys(const DNSName& qname)
63 return {qname.toDNSStringLC()};
65 return {qname.makeLowerCase().toStringRootDot()};
68 std::vector<std::string> getKeys(const DNSQuestion& dq) override
70 return getKeys(*dq.qname);
73 std::string toString() const override
76 return "qname in wire format";
85 class KeyValueLookupKeySuffix: public KeyValueLookupKey
88 KeyValueLookupKeySuffix(size_t minLabels, bool wireFormat): d_minLabels(minLabels), d_wireFormat(wireFormat)
92 std::vector<std::string> getKeys(const DNSName& qname);
94 std::vector<std::string> getKeys(const DNSQuestion& dq) override
96 return getKeys(*dq.qname);
99 std::string toString() const override
101 if (d_minLabels > 0) {
102 return "suffix " + std::string(d_wireFormat ? "in wire format " : "") + "with at least " + std::to_string(d_minLabels) + " label(s)";
104 return "suffix" + std::string(d_wireFormat ? " in wire format" : "");
112 class KeyValueLookupKeyTag: public KeyValueLookupKey
115 KeyValueLookupKeyTag(const std::string& tag): d_tag(tag)
119 std::vector<std::string> getKeys(const DNSQuestion& dq) override
122 const auto& it = dq.qTag->find(d_tag);
123 if (it != dq.qTag->end()) {
124 return { it->second };
130 std::string toString() const override
132 return "value of the tag named '" + d_tag + "'";
142 virtual ~KeyValueStore()
146 virtual bool keyExists(const std::string& key) = 0;
147 virtual bool getValue(const std::string& key, std::string& value) = 0;
148 virtual bool reload()
156 #include "ext/lmdb-safe/lmdb-safe.hh"
158 class LMDBKVStore: public KeyValueStore
161 LMDBKVStore(const std::string& fname, const std::string& dbName): d_env(fname.c_str(), MDB_NOSUBDIR, 0600), d_fname(fname), d_dbName(dbName)
165 bool keyExists(const std::string& key) override;
166 bool getValue(const std::string& key, std::string& value) override;
171 std::string d_dbName;
174 #endif /* HAVE_LMDB */
180 class CDBKVStore: public KeyValueStore
183 CDBKVStore(const std::string& fname, time_t refreshDelay);
186 bool keyExists(const std::string& key) override;
187 bool getValue(const std::string& key, std::string& value) override;
188 bool reload() override;
191 void refreshDBIfNeeded(time_t now);
192 bool reload(const struct stat& st);
194 std::unique_ptr<CDB> d_cdb{nullptr};
196 ReadWriteLock d_lock;
198 time_t d_nextCheck{0};
199 time_t d_refreshDelay{0};
200 std::atomic_flag d_refreshing;
203 #endif /* HAVE_LMDB */