]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
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 | */ | |
e8c59f2d | 22 | #pragma once |
12c86877 | 23 | |
ed1038f5 | 24 | #include <algorithm> |
fd9af6ec | 25 | #include <cstddef> |
973ad2b5 BH |
26 | class DNSPacket; |
27 | ||
12c86877 BH |
28 | #include "utility.hh" |
29 | #include <string> | |
68ba155d | 30 | #include <utility> |
12c86877 BH |
31 | #include <vector> |
32 | #include <map> | |
33 | #include <sys/types.h> | |
5c409fa2 | 34 | #include "pdnsexception.hh" |
973ad2b5 | 35 | #include <set> |
702b226d | 36 | #include <iostream> |
76473b92 KM |
37 | #include <sys/socket.h> |
38 | #include <dirent.h> | |
76979e74 | 39 | #include "misc.hh" |
12c86877 BH |
40 | #include "qtype.hh" |
41 | #include "dns.hh" | |
10f4eea8 | 42 | #include "namespaces.hh" |
6cc98ddf | 43 | #include "comment.hh" |
675fa24c | 44 | #include "dnsname.hh" |
28e2e78e | 45 | #include "dnsrecords.hh" |
a2dfc9ea | 46 | #include "iputils.hh" |
ddeea7a6 | 47 | #include "sha.hh" |
8a66a927 | 48 | #include "auth-catalogzone.hh" |
76979e74 | 49 | |
ef20739c CH |
50 | class DNSBackend; |
51 | struct SOAData; | |
52 | ||
12c86877 BH |
53 | struct DomainInfo |
54 | { | |
68ba155d | 55 | DomainInfo() = default; |
52ff1db1 | 56 | |
675fa24c | 57 | DNSName zone; |
4bc3a9e0 | 58 | DNSName catalog; |
ed1038f5 | 59 | time_t last_check{}; |
9da0c596 | 60 | string options; |
8ffb7a9b | 61 | string account; |
d525b58b | 62 | vector<ComboAddress> primaries; |
02789fe0 | 63 | DNSBackend* backend{}; |
52ff1db1 | 64 | |
ed1038f5 FM |
65 | uint32_t id{}; |
66 | uint32_t notified_serial{}; | |
52ff1db1 | 67 | |
ed1038f5 | 68 | bool receivedNotify{}; |
472429fb | 69 | |
ed1038f5 | 70 | uint32_t serial{}; |
ddeea7a6 | 71 | |
7f3d870e BH |
72 | bool operator<(const DomainInfo& rhs) const |
73 | { | |
74 | return zone < rhs.zone; | |
75 | } | |
ec10217f | 76 | |
ddeea7a6 KM |
77 | // Do not reorder (lmdbbackend)!!! One exception 'All' is always last. |
78 | enum DomainKind : uint8_t | |
79 | { | |
d525b58b | 80 | Primary, |
c02c999b | 81 | Secondary, |
ddeea7a6 KM |
82 | Native, |
83 | Producer, | |
84 | Consumer, | |
85 | All | |
68ba155d | 86 | } kind{DomainInfo::Native}; |
ddeea7a6 | 87 | |
02789fe0 | 88 | [[nodiscard]] const char* getKindString() const |
76979e74 CH |
89 | { |
90 | return DomainInfo::getKindString(kind); | |
91 | } | |
92 | ||
02789fe0 | 93 | static const char* getKindString(enum DomainKind kind) |
ec10217f | 94 | { |
68ba155d FM |
95 | std::array<const char*, 6> kinds{"Master", "Slave", "Native", "Producer", "Consumer", "All"}; |
96 | return kinds.at(kind); | |
ec10217f | 97 | } |
76979e74 CH |
98 | |
99 | static DomainKind stringToKind(const string& kind) | |
100 | { | |
ed1038f5 | 101 | if (pdns_iequals(kind, "SECONDARY") || pdns_iequals(kind, "SLAVE")) { |
c02c999b | 102 | return DomainInfo::Secondary; |
ed1038f5 FM |
103 | } |
104 | if (pdns_iequals(kind, "PRIMARY") || pdns_iequals(kind, "MASTER")) { | |
d525b58b | 105 | return DomainInfo::Primary; |
ed1038f5 FM |
106 | } |
107 | if (pdns_iequals(kind, "PRODUCER")) { | |
ddeea7a6 | 108 | return DomainInfo::Producer; |
ed1038f5 FM |
109 | } |
110 | if (pdns_iequals(kind, "CONSUMER")) { | |
ddeea7a6 | 111 | return DomainInfo::Consumer; |
ed1038f5 | 112 | } |
ddeea7a6 KM |
113 | // No "ALL" here please. Yes, I really mean it... |
114 | return DomainInfo::Native; | |
76979e74 CH |
115 | } |
116 | ||
d525b58b | 117 | [[nodiscard]] bool isPrimaryType() const { return (kind == DomainInfo::Primary || kind == DomainInfo::Producer); } |
c02c999b | 118 | [[nodiscard]] bool isSecondaryType() const { return (kind == DomainInfo::Secondary || kind == DomainInfo::Consumer); } |
ed1038f5 | 119 | [[nodiscard]] bool isCatalogType() const { return (kind == DomainInfo::Producer || kind == DomainInfo::Consumer); } |
ddeea7a6 | 120 | |
d525b58b | 121 | [[nodiscard]] bool isPrimary(const ComboAddress& ipAddress) const |
a2dfc9ea | 122 | { |
d525b58b | 123 | return std::any_of(primaries.begin(), primaries.end(), [ipAddress](auto primary) { return ComboAddress::addressOnlyEqual()(ipAddress, primary); }); |
a2dfc9ea | 124 | } |
12c86877 BH |
125 | }; |
126 | ||
02789fe0 FM |
127 | struct TSIGKey |
128 | { | |
129 | DNSName name; | |
130 | DNSName algorithm; | |
131 | std::string key; | |
6f872b78 AT |
132 | }; |
133 | ||
02789fe0 FM |
134 | struct AutoPrimary |
135 | { | |
68ba155d FM |
136 | AutoPrimary(string new_ip, string new_nameserver, string new_account) : |
137 | ip(std::move(new_ip)), nameserver(std::move(new_nameserver)), account(std::move(new_account)){}; | |
02789fe0 FM |
138 | std::string ip; |
139 | std::string nameserver; | |
140 | std::string account; | |
782e9b24 AT |
141 | }; |
142 | ||
12c86877 | 143 | class DNSPacket; |
bdc9f8d2 | 144 | |
35520716 | 145 | //! This virtual base class defines the interface for backends for PowerDNS. |
bdc9f8d2 BH |
146 | /** To create a backend, inherit from this class and implement functions for all virtual methods. |
147 | Methods should not throw an exception if they are sure they did not find the requested data. However, | |
148 | if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException, | |
149 | which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking | |
150 | issues should lead to DBExceptions. | |
151 | ||
152 | More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should | |
3f81d239 | 153 | lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler |
bdc9f8d2 BH |
154 | and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one. |
155 | */ | |
12c86877 BH |
156 | class DNSBackend |
157 | { | |
158 | public: | |
bdc9f8d2 | 159 | //! lookup() initiates a lookup. A lookup without results should not throw! |
02789fe0 FM |
160 | virtual void lookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr) = 0; |
161 | virtual bool get(DNSResourceRecord&) = 0; //!< retrieves one DNSResource record, returns false if no more were available | |
68ba155d | 162 | virtual bool get(DNSZoneRecord& zoneRecord); |
702b226d | 163 | |
bdc9f8d2 BH |
164 | //! Initiates a list of the specified domain |
165 | /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false | |
166 | if the backend does not consider itself responsible for the id passed. | |
167 | \param domain_id ID of which a list is requested | |
168 | */ | |
02789fe0 | 169 | virtual bool list(const DNSName& target, int domain_id, bool include_disabled = false) = 0; |
12c86877 | 170 | |
abb11ca4 | 171 | virtual ~DNSBackend() = default; |
12c86877 | 172 | |
bdc9f8d2 | 173 | //! fills the soadata struct with the SOA details. Returns false if there is no SOA. |
68ba155d | 174 | virtual bool getSOA(const DNSName& domain, SOAData& soaData); |
d07fc616 | 175 | |
d73de874 | 176 | virtual bool replaceRRSet(uint32_t /* domain_id */, const DNSName& /* qname */, const QType& /* qt */, const vector<DNSResourceRecord>& /* rrset */) |
8bbb6f36 BH |
177 | { |
178 | return false; | |
179 | } | |
180 | ||
d73de874 | 181 | virtual bool listSubZone(const DNSName& /* zone */, int /* domain_id */) |
6a323f63 RA |
182 | { |
183 | return false; | |
184 | } | |
185 | ||
4aafcb39 | 186 | // the DNSSEC related (getDomainMetadata has broader uses too) |
ed1038f5 FM |
187 | static bool isDnssecDomainMetadata(const string& name) |
188 | { | |
ad34750d KM |
189 | return (name == "PRESIGNED" || name == "NSEC3PARAM" || name == "NSEC3NARROW"); |
190 | } | |
d73de874 FM |
191 | virtual bool getAllDomainMetadata(const DNSName& /* name */, std::map<std::string, std::vector<std::string>>& /* meta */) { return false; }; |
192 | virtual bool getDomainMetadata(const DNSName& /* name */, const std::string& /* kind */, std::vector<std::string>& /* meta */) { return false; } | |
675fa24c | 193 | virtual bool getDomainMetadataOne(const DNSName& name, const std::string& kind, std::string& value) |
d29d5db7 CH |
194 | { |
195 | std::vector<std::string> meta; | |
196 | if (getDomainMetadata(name, kind, meta)) { | |
ed1038f5 | 197 | if (!meta.empty()) { |
d29d5db7 CH |
198 | value = *meta.begin(); |
199 | return true; | |
200 | } | |
201 | } | |
202 | return false; | |
203 | } | |
204 | ||
d73de874 | 205 | virtual bool setDomainMetadata(const DNSName& /* name */, const std::string& /* kind */, const std::vector<std::string>& /* meta */) { return false; } |
675fa24c | 206 | virtual bool setDomainMetadataOne(const DNSName& name, const std::string& kind, const std::string& value) |
d29d5db7 CH |
207 | { |
208 | const std::vector<std::string> meta(1, value); | |
209 | return setDomainMetadata(name, kind, meta); | |
210 | } | |
211 | ||
39dafc3b | 212 | virtual void getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool include_disabled); |
1325e8a2 | 213 | |
c14bc34a | 214 | /** Determines if we are authoritative for a zone, and at what level */ |
d73de874 | 215 | virtual bool getAuth(const DNSName& target, SOAData* /* sd */); |
c14bc34a | 216 | |
02789fe0 FM |
217 | struct KeyData |
218 | { | |
eda140fa | 219 | std::string content; |
ed5dfdee RG |
220 | unsigned int id{0}; |
221 | unsigned int flags{0}; | |
222 | bool active{false}; | |
223 | bool published{false}; | |
4aafcb39 BH |
224 | }; |
225 | ||
d73de874 FM |
226 | virtual bool getDomainKeys(const DNSName& /* name */, std::vector<KeyData>& /* keys */) { return false; } |
227 | virtual bool removeDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } | |
228 | virtual bool addDomainKey(const DNSName& /* name */, const KeyData& /* key */, int64_t& /* id */) { return false; } | |
229 | virtual bool activateDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } | |
230 | virtual bool deactivateDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } | |
231 | virtual bool publishDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } | |
232 | virtual bool unpublishDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } | |
8ab63616 | 233 | |
d73de874 FM |
234 | virtual bool setTSIGKey(const DNSName& /* name */, const DNSName& /* algorithm */, const string& /* content */) { return false; } |
235 | virtual bool getTSIGKey(const DNSName& /* name */, DNSName& /* algorithm */, string& /* content */) { return false; } | |
236 | virtual bool getTSIGKeys(std::vector<struct TSIGKey>& /* keys */) { return false; } | |
237 | virtual bool deleteTSIGKey(const DNSName& /* name */) { return false; } | |
78bcb858 | 238 | |
d73de874 | 239 | virtual bool getBeforeAndAfterNamesAbsolute(uint32_t /* id */, const DNSName& /* qname */, DNSName& /* unhashed */, DNSName& /* before */, DNSName& /* after */) |
4aafcb39 | 240 | { |
d73de874 | 241 | std::cerr << "Default beforeAndAfterAbsolute called!" << std::endl; |
4aafcb39 BH |
242 | abort(); |
243 | return false; | |
244 | } | |
245 | ||
d73de874 | 246 | virtual bool getBeforeAndAfterNames(uint32_t /* id */, const DNSName& zonename, const DNSName& qname, DNSName& before, DNSName& after); |
4aafcb39 | 247 | |
d73de874 | 248 | virtual bool updateDNSSECOrderNameAndAuth(uint32_t /* domain_id */, const DNSName& /* qname */, const DNSName& /* ordername */, bool /* auth */, const uint16_t /* qtype */ = QType::ANY) |
4aafcb39 BH |
249 | { |
250 | return false; | |
251 | } | |
252 | ||
d73de874 | 253 | virtual bool updateEmptyNonTerminals(uint32_t /* domain_id */, set<DNSName>& /* insert */, set<DNSName>& /* erase */, bool /* remove */) |
c2df797e PD |
254 | { |
255 | return false; | |
256 | } | |
257 | ||
ece45ffb PD |
258 | virtual bool doesDNSSEC() |
259 | { | |
260 | return false; | |
261 | } | |
262 | ||
4aafcb39 BH |
263 | // end DNSSEC |
264 | ||
6cc98ddf | 265 | // comments support |
d73de874 | 266 | virtual bool listComments(uint32_t /* domain_id */) |
6cc98ddf CH |
267 | { |
268 | return false; // unsupported by this backend | |
269 | } | |
270 | ||
d73de874 | 271 | virtual bool getComment(Comment& /* comment */) |
6cc98ddf CH |
272 | { |
273 | return false; | |
274 | } | |
275 | ||
f79eef05 | 276 | virtual bool feedComment(const Comment& /* comment */) |
6cc98ddf | 277 | { |
f79eef05 | 278 | return false; |
6cc98ddf CH |
279 | } |
280 | ||
d73de874 | 281 | virtual bool replaceComments(const uint32_t /* domain_id */, const DNSName& /* qname */, const QType& /* qt */, const vector<Comment>& /* comments */) |
6cc98ddf CH |
282 | { |
283 | return false; | |
284 | } | |
285 | ||
d525b58b | 286 | //! returns true if primary ip is primary for domain name. |
bdc9f8d2 | 287 | //! starts the transaction for updating domain qname (FIXME: what is id?) |
d73de874 | 288 | virtual bool startTransaction(const DNSName& /* qname */, int /* id */ = -1) |
12c86877 BH |
289 | { |
290 | return false; | |
291 | } | |
292 | ||
bdc9f8d2 | 293 | //! commits the transaction started by startTransaction |
12c86877 BH |
294 | virtual bool commitTransaction() |
295 | { | |
296 | return false; | |
297 | } | |
298 | ||
d07ed91e | 299 | //! aborts the transaction started by startTransaction, should leave state unaltered |
12c86877 BH |
300 | virtual bool abortTransaction() |
301 | { | |
302 | return false; | |
303 | } | |
304 | ||
9c56d755 KM |
305 | virtual bool inTransaction() |
306 | { | |
307 | return false; | |
308 | } | |
309 | ||
12c86877 BH |
310 | virtual void reload() |
311 | { | |
312 | } | |
313 | ||
d73de874 | 314 | virtual void rediscover(string* /* status */ = nullptr) |
12c86877 BH |
315 | { |
316 | } | |
317 | ||
bdc9f8d2 | 318 | //! feeds a record to a zone, needs a call to startTransaction first |
d73de874 | 319 | virtual bool feedRecord(const DNSResourceRecord& /* rr */, const DNSName& /* ordername */, bool /* ordernameIsNSEC3 */ = false) |
12c86877 BH |
320 | { |
321 | return false; // no problem! | |
322 | } | |
d73de874 | 323 | virtual bool feedEnts(int /* domain_id */, map<DNSName, bool>& /* nonterm */) |
f9cf6d92 KM |
324 | { |
325 | return false; | |
326 | } | |
d73de874 | 327 | virtual bool feedEnts3(int /* domain_id */, const DNSName& /* domain */, map<DNSName, bool>& /* nonterm */, const NSEC3PARAMRecordContent& /* ns3prc */, bool /* narrow */) |
f9cf6d92 KM |
328 | { |
329 | return false; | |
330 | } | |
331 | ||
bdc9f8d2 | 332 | //! if this returns true, DomainInfo di contains information about the domain |
d73de874 | 333 | virtual bool getDomainInfo(const DNSName& /* domain */, DomainInfo& /* di */, bool /* getSerial */ = true) |
12c86877 BH |
334 | { |
335 | return false; | |
336 | } | |
c02c999b KM |
337 | //! secondary capable backends should return a list of secondaries that should be rechecked for staleness |
338 | virtual void getUnfreshSecondaryInfos(vector<DomainInfo>* /* domains */) | |
12c86877 BH |
339 | { |
340 | } | |
341 | ||
bdc9f8d2 | 342 | //! get a list of IP addresses that should also be notified for a domain |
d73de874 | 343 | virtual void alsoNotifies(const DNSName& domain, set<string>* ips) |
12c86877 | 344 | { |
338041a8 PD |
345 | std::vector<std::string> meta; |
346 | getDomainMetadata(domain, "ALSO-NOTIFY", meta); | |
347 | ips->insert(meta.begin(), meta.end()); | |
12c86877 | 348 | } |
bdc9f8d2 | 349 | |
c02c999b | 350 | //! get list of domains that have been changed since their last notification to secondaries |
d525b58b | 351 | virtual void getUpdatedPrimaries(vector<DomainInfo>& /* domains */, std::unordered_set<DNSName>& /* catalogs */, CatalogHashMap& /* catalogHashes */) |
12c86877 BH |
352 | { |
353 | } | |
ce8c5899 | 354 | |
8a66a927 | 355 | //! get list of all members in a catalog |
d73de874 | 356 | virtual bool getCatalogMembers(const DNSName& /* catalog */, vector<CatalogInfo>& /* members */, CatalogInfo::CatalogType /* type */) |
8a66a927 KM |
357 | { |
358 | return false; | |
359 | } | |
360 | ||
ce8c5899 | 361 | //! Called by PowerDNS to inform a backend that a domain need to be checked for freshness |
d73de874 | 362 | virtual void setStale(uint32_t /* domain_id */) |
ce8c5899 KM |
363 | { |
364 | } | |
365 | ||
bdc9f8d2 | 366 | //! Called by PowerDNS to inform a backend that a domain has been checked for freshness |
d73de874 | 367 | virtual void setFresh(uint32_t /* domain_id */) |
12c86877 | 368 | { |
12c86877 | 369 | } |
ce8c5899 | 370 | |
c02c999b | 371 | //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to secondaries |
d73de874 | 372 | virtual void setNotified(uint32_t /* id */, uint32_t /* serial */) |
12c86877 BH |
373 | { |
374 | } | |
375 | ||
d525b58b KM |
376 | //! Called when the Primary list of a domain should be changed |
377 | virtual bool setPrimaries(const DNSName& /* domain */, const vector<ComboAddress>& /* primaries */) | |
6d58359c CH |
378 | { |
379 | return false; | |
380 | } | |
381 | ||
d525b58b | 382 | //! Called when the Kind of a domain should be changed (primary -> native and similar) |
d73de874 | 383 | virtual bool setKind(const DNSName& /* domain */, const DomainInfo::DomainKind /* kind */) |
6d58359c CH |
384 | { |
385 | return false; | |
386 | } | |
387 | ||
9da0c596 | 388 | //! Called when the options of a domain should be changed |
d73de874 | 389 | virtual bool setOptions(const DNSName& /* domain */, const string& /* options */) |
9da0c596 KM |
390 | { |
391 | return false; | |
392 | } | |
393 | ||
4bc3a9e0 | 394 | //! Called when the catalog of a domain should be changed |
d73de874 | 395 | virtual bool setCatalog(const DNSName& /* domain */, const DNSName& /* catalog */) |
4bc3a9e0 KM |
396 | { |
397 | return false; | |
398 | } | |
399 | ||
79532aa7 | 400 | //! Called when the Account of a domain should be changed |
d73de874 | 401 | virtual bool setAccount(const DNSName& /* domain */, const string& /* account */) |
79532aa7 CH |
402 | { |
403 | return false; | |
404 | } | |
405 | ||
bdc9f8d2 | 406 | //! Can be called to seed the getArg() function with a prefix |
02789fe0 | 407 | void setArgPrefix(const string& prefix); |
bdc9f8d2 | 408 | |
d525b58b KM |
409 | //! Add an entry for a super primary |
410 | virtual bool autoPrimaryAdd(const struct AutoPrimary& /* primary */) | |
3d26f6dc | 411 | { |
d73de874 | 412 | return false; |
3d26f6dc E |
413 | } |
414 | ||
d525b58b | 415 | //! Remove an entry for a super primary |
d73de874 | 416 | virtual bool autoPrimaryRemove(const struct AutoPrimary& /* primary */) |
782e9b24 AT |
417 | { |
418 | return false; | |
419 | } | |
420 | ||
d525b58b | 421 | //! List all AutoPrimaries, returns false if feature not supported. |
d73de874 | 422 | virtual bool autoPrimariesList(std::vector<AutoPrimary>& /* primaries */) |
782e9b24 AT |
423 | { |
424 | return false; | |
425 | } | |
426 | ||
d525b58b KM |
427 | //! determine if ip is a autoprimary or a domain |
428 | virtual bool autoPrimaryBackend(const string& /* ip */, const DNSName& /* domain */, const vector<DNSResourceRecord>& /* nsset */, string* /* nameserver */, string* /* account */, DNSBackend** /* db */) | |
12c86877 BH |
429 | { |
430 | return false; | |
431 | } | |
bdc9f8d2 | 432 | |
487cf033 | 433 | //! called by PowerDNS to create a new domain |
d525b58b | 434 | virtual bool createDomain(const DNSName& /* domain */, const DomainInfo::DomainKind /* kind */, const vector<ComboAddress>& /* primaries */, const string& /* account */) |
487cf033 CH |
435 | { |
436 | return false; | |
437 | } | |
438 | ||
c02c999b KM |
439 | //! called by PowerDNS to create a secondary record for a autoPrimary |
440 | virtual bool createSecondaryDomain(const string& /* ip */, const DNSName& /* domain */, const string& /* nameserver */, const string& /* account */) | |
12c86877 BH |
441 | { |
442 | return false; | |
443 | } | |
444 | ||
44e62984 | 445 | //! called to delete a domain, incl. all metadata, zone contents, etc. |
d73de874 | 446 | virtual bool deleteDomain(const DNSName& /* domain */) |
44e62984 CH |
447 | { |
448 | return false; | |
449 | } | |
450 | ||
d73de874 | 451 | virtual string directBackendCmd(const string& /* query */) |
f641c3b7 PD |
452 | { |
453 | return "directBackendCmd not supported for this backend\n"; | |
454 | } | |
455 | ||
9f8e226e | 456 | //! Search for records, returns true if search was done successfully. |
fd9af6ec | 457 | virtual bool searchRecords(const string& /* pattern */, size_t /* maxResults */, vector<DNSResourceRecord>& /* result */) |
9f8e226e AT |
458 | { |
459 | return false; | |
460 | } | |
461 | ||
462 | //! Search for comments, returns true if search was done successfully. | |
fd9af6ec | 463 | virtual bool searchComments(const string& /* pattern */, size_t /* maxResults */, vector<Comment>& /* result */) |
9f8e226e AT |
464 | { |
465 | return false; | |
466 | } | |
467 | ||
ece1aa0b | 468 | const string& getPrefix() { return d_prefix; }; |
02789fe0 | 469 | |
12c86877 | 470 | protected: |
02789fe0 FM |
471 | bool mustDo(const string& key); |
472 | const string& getArg(const string& key); | |
473 | int getArgAsNum(const string& key); | |
12c86877 BH |
474 | |
475 | private: | |
476 | string d_prefix; | |
477 | }; | |
478 | ||
479 | class BackendFactory | |
480 | { | |
481 | public: | |
02789fe0 FM |
482 | BackendFactory(const string& name) : |
483 | d_name(name) {} | |
abb11ca4 | 484 | virtual ~BackendFactory() = default; |
02789fe0 FM |
485 | virtual DNSBackend* make(const string& suffix) = 0; |
486 | virtual DNSBackend* makeMetadataOnly(const string& suffix) | |
2717b8b3 BH |
487 | { |
488 | return this->make(suffix); | |
489 | } | |
d73de874 FM |
490 | virtual void declareArguments(const string& /* suffix */ = "") {} |
491 | [[nodiscard]] const string& getName() const; | |
492 | ||
12c86877 | 493 | protected: |
02789fe0 | 494 | void declare(const string& suffix, const string& param, const string& explanation, const string& value); |
12c86877 BH |
495 | |
496 | private: | |
68ba155d | 497 | string d_name; |
12c86877 BH |
498 | }; |
499 | ||
500 | class BackendMakerClass | |
501 | { | |
502 | public: | |
5144dfa8 | 503 | void report(std::unique_ptr<BackendFactory>&& backendFactory); |
02789fe0 FM |
504 | void launch(const string& instr); |
505 | vector<std::unique_ptr<DNSBackend>> all(bool metadataOnly = false); | |
68ba155d | 506 | static void load(const string& module); |
ed1038f5 | 507 | [[nodiscard]] size_t numLauncheable() const; |
12c86877 | 508 | vector<string> getModules(); |
b51bb9a2 | 509 | void clear(); |
12c86877 BH |
510 | |
511 | private: | |
68ba155d | 512 | static void load_all(); |
5144dfa8 | 513 | using d_repository_t = map<string, std::unique_ptr<BackendFactory>>; |
12c86877 | 514 | d_repository_t d_repository; |
02789fe0 | 515 | vector<pair<string, string>> d_instances; |
12c86877 BH |
516 | }; |
517 | ||
02789fe0 | 518 | extern BackendMakerClass& BackendMakers(); |
12c86877 | 519 | |
bdc9f8d2 | 520 | //! Exception that can be thrown by a DNSBackend to indicate a failure |
3f81d239 | 521 | class DBException : public PDNSException |
cc3afe25 BH |
522 | { |
523 | public: | |
02789fe0 FM |
524 | DBException(const string& reason_) : |
525 | PDNSException(reason_) {} | |
cc3afe25 BH |
526 | }; |
527 | ||
ef20739c CH |
528 | struct SOAData |
529 | { | |
02789fe0 FM |
530 | SOAData() : |
531 | domain_id(-1){}; | |
ef20739c CH |
532 | |
533 | DNSName qname; | |
534 | DNSName nameserver; | |
d525b58b | 535 | DNSName rname; |
ed1038f5 FM |
536 | uint32_t ttl{}; |
537 | uint32_t serial{}; | |
538 | uint32_t refresh{}; | |
539 | uint32_t retry{}; | |
540 | uint32_t expire{}; | |
541 | uint32_t minimum{}; | |
02789fe0 | 542 | DNSBackend* db{}; |
ed1038f5 FM |
543 | int domain_id{}; |
544 | ||
545 | [[nodiscard]] uint32_t getNegativeTTL() const { return min(ttl, minimum); } | |
ef20739c CH |
546 | }; |
547 | ||
ceea1ba6 | 548 | /** helper function for both DNSPacket and addSOARecord() - converts a line into a struct, for easier parsing */ |
68ba155d | 549 | void fillSOAData(const string& content, SOAData& soaData); |
90ba52e0 | 550 | // same but more karmic |
68ba155d | 551 | void fillSOAData(const DNSZoneRecord& inZoneRecord, SOAData& soaData); |
90ba52e0 | 552 | // the reverse |
68ba155d | 553 | std::shared_ptr<DNSRecordContent> makeSOAContent(const SOAData& soaData); |