]>
Commit | Line | Data |
---|---|---|
12c86877 BH |
1 | /* |
2 | PowerDNS Versatile Database Driven Nameserver | |
66dba9d7 | 3 | Copyright (C) 2002-2010 PowerDNS.COM BV |
12c86877 BH |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
22dc646a BH |
6 | it under the terms of the GNU General Public License version 2 |
7 | as published by the Free Software Foundation | |
f782fe38 MH |
8 | |
9 | Additionally, the license of this program contains a special | |
10 | exception which allows to distribute the program in binary form when | |
11 | it is linked against OpenSSL. | |
12c86877 BH |
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 | |
06bd9ccf | 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12c86877 | 21 | */ |
12c86877 BH |
22 | #ifndef DNSBACKEND_HH |
23 | #define DNSBACKEND_HH | |
24 | ||
973ad2b5 BH |
25 | class DNSPacket; |
26 | ||
12c86877 BH |
27 | #include "utility.hh" |
28 | #include <string> | |
29 | #include <vector> | |
30 | #include <map> | |
31 | #include <sys/types.h> | |
5c409fa2 | 32 | #include "pdnsexception.hh" |
973ad2b5 | 33 | #include <set> |
702b226d | 34 | #include <iostream> |
76473b92 KM |
35 | #include <sys/socket.h> |
36 | #include <dirent.h> | |
76979e74 | 37 | #include "misc.hh" |
12c86877 BH |
38 | #include "qtype.hh" |
39 | #include "dns.hh" | |
e5b11b2f | 40 | #include <vector> |
10f4eea8 | 41 | #include "namespaces.hh" |
76979e74 | 42 | |
12c86877 BH |
43 | class DNSBackend; |
44 | struct DomainInfo | |
45 | { | |
90c9a70e | 46 | DomainInfo() : backend(0) {} |
092f210a | 47 | uint32_t id; |
12c86877 | 48 | string zone; |
e5b11b2f | 49 | vector<string> masters; |
092f210a BH |
50 | uint32_t notified_serial; |
51 | uint32_t serial; | |
12c86877 | 52 | time_t last_check; |
76979e74 | 53 | enum DomainKind { Master, Slave, Native } kind; |
12c86877 | 54 | DNSBackend *backend; |
7f3d870e BH |
55 | |
56 | bool operator<(const DomainInfo& rhs) const | |
57 | { | |
58 | return zone < rhs.zone; | |
59 | } | |
ec10217f CH |
60 | |
61 | const char *getKindString() const | |
76979e74 CH |
62 | { |
63 | return DomainInfo::getKindString(kind); | |
64 | } | |
65 | ||
66 | static const char *getKindString(enum DomainKind kind) | |
ec10217f CH |
67 | { |
68 | const char *kinds[]={"Master", "Slave", "Native"}; | |
69 | return kinds[kind]; | |
70 | } | |
76979e74 CH |
71 | |
72 | static DomainKind stringToKind(const string& kind) | |
73 | { | |
74 | if(pdns_iequals(kind,"SLAVE")) | |
75 | return DomainInfo::Slave; | |
76 | else if(pdns_iequals(kind,"MASTER")) | |
77 | return DomainInfo::Master; | |
78 | else | |
79 | return DomainInfo::Native; | |
80 | } | |
81 | ||
12c86877 BH |
82 | }; |
83 | ||
6f872b78 AT |
84 | struct TSIGKey { |
85 | std::string name; | |
86 | std::string algorithm; | |
87 | std::string key; | |
88 | }; | |
89 | ||
12c86877 | 90 | class DNSPacket; |
bdc9f8d2 BH |
91 | |
92 | ||
93 | //! This virtual base class defines the interface for backends for the ahudns. | |
94 | /** To create a backend, inherit from this class and implement functions for all virtual methods. | |
95 | Methods should not throw an exception if they are sure they did not find the requested data. However, | |
96 | if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException, | |
97 | which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking | |
98 | issues should lead to DBExceptions. | |
99 | ||
100 | More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should | |
3f81d239 | 101 | lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler |
bdc9f8d2 BH |
102 | and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one. |
103 | */ | |
12c86877 BH |
104 | class DNSBackend |
105 | { | |
106 | public: | |
bdc9f8d2 | 107 | //! lookup() initiates a lookup. A lookup without results should not throw! |
12c86877 | 108 | virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0; |
bdc9f8d2 | 109 | virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available |
702b226d | 110 | |
5c3bf2db | 111 | |
bdc9f8d2 BH |
112 | //! Initiates a list of the specified domain |
113 | /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false | |
114 | if the backend does not consider itself responsible for the id passed. | |
115 | \param domain_id ID of which a list is requested | |
116 | */ | |
88def049 | 117 | virtual bool list(const string &target, int domain_id)=0; |
12c86877 BH |
118 | |
119 | virtual ~DNSBackend(){}; | |
120 | ||
bdc9f8d2 | 121 | //! fills the soadata struct with the SOA details. Returns false if there is no SOA. |
35933370 | 122 | virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0); |
12c86877 | 123 | |
d07fc616 PD |
124 | //! Calculates a SOA serial for the zone and stores it in the third argument. |
125 | virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial); | |
126 | ||
8bbb6f36 BH |
127 | virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) |
128 | { | |
129 | return false; | |
130 | } | |
131 | ||
6a323f63 RA |
132 | virtual bool listSubZone(const string &zone, int domain_id) |
133 | { | |
134 | return false; | |
135 | } | |
136 | ||
4aafcb39 | 137 | // the DNSSEC related (getDomainMetadata has broader uses too) |
8ab63616 BH |
138 | virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; } |
139 | virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;} | |
4aafcb39 | 140 | |
1325e8a2 PD |
141 | virtual void getAllDomains(vector<DomainInfo> *domains) { } |
142 | ||
4aafcb39 BH |
143 | struct KeyData { |
144 | unsigned int id; | |
145 | unsigned int flags; | |
146 | bool active; | |
147 | std::string content; | |
148 | }; | |
149 | ||
8ab63616 BH |
150 | virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) { return false;} |
151 | virtual bool removeDomainKey(const string& name, unsigned int id) { return false; } | |
152 | virtual int addDomainKey(const string& name, const KeyData& key){ return -1; } | |
153 | virtual bool activateDomainKey(const string& name, unsigned int id) { return false; } | |
154 | virtual bool deactivateDomainKey(const string& name, unsigned int id) { return false; } | |
155 | ||
78bcb858 | 156 | virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; } |
6f872b78 AT |
157 | virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content) { return false; } |
158 | virtual bool deleteTSIGKey(const string& name) { return false; } | |
159 | virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; } | |
78bcb858 | 160 | |
4aafcb39 BH |
161 | virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after) |
162 | { | |
163 | std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl; | |
164 | abort(); | |
165 | return false; | |
166 | } | |
167 | ||
168 | bool getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after); | |
169 | ||
170 | virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth) | |
171 | { | |
172 | return false; | |
173 | } | |
174 | ||
175 | virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth) | |
176 | { | |
177 | return false; | |
178 | } | |
179 | ||
b5baefaf PD |
180 | virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove) |
181 | { | |
182 | return false; | |
183 | } | |
184 | ||
c2df797e | 185 | virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth) |
b5baefaf PD |
186 | { |
187 | return false; | |
188 | } | |
189 | ||
27045410 PD |
190 | virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type) |
191 | { | |
192 | return false; | |
193 | } | |
194 | ||
c2df797e PD |
195 | virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname) |
196 | { | |
197 | return false; | |
198 | } | |
199 | ||
ece45ffb PD |
200 | virtual bool doesDNSSEC() |
201 | { | |
202 | return false; | |
203 | } | |
204 | ||
4aafcb39 BH |
205 | // end DNSSEC |
206 | ||
bdc9f8d2 | 207 | //! returns true if master ip is master for domain name. |
12c86877 BH |
208 | virtual bool isMaster(const string &name, const string &ip) |
209 | { | |
210 | return false; | |
211 | } | |
212 | ||
bdc9f8d2 | 213 | //! starts the transaction for updating domain qname (FIXME: what is id?) |
12c86877 BH |
214 | virtual bool startTransaction(const string &qname, int id=-1) |
215 | { | |
216 | return false; | |
217 | } | |
218 | ||
bdc9f8d2 | 219 | //! commits the transaction started by startTransaction |
12c86877 BH |
220 | virtual bool commitTransaction() |
221 | { | |
222 | return false; | |
223 | } | |
224 | ||
bdc9f8d2 | 225 | //! aborts the transaction started by strartTransaction, should leave state unaltered |
12c86877 BH |
226 | virtual bool abortTransaction() |
227 | { | |
228 | return false; | |
229 | } | |
230 | ||
231 | virtual void reload() | |
232 | { | |
233 | } | |
234 | ||
973ad2b5 | 235 | virtual void rediscover(string* status=0) |
12c86877 BH |
236 | { |
237 | } | |
238 | ||
bdc9f8d2 | 239 | //! feeds a record to a zone, needs a call to startTransaction first |
f9cf6d92 | 240 | virtual bool feedRecord(const DNSResourceRecord &rr, string *ordername=0) |
12c86877 BH |
241 | { |
242 | return false; // no problem! | |
243 | } | |
f9cf6d92 KM |
244 | virtual bool feedEnts(int domain_id, set<string> &nonterm) |
245 | { | |
246 | return false; | |
247 | } | |
248 | virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow) | |
249 | { | |
250 | return false; | |
251 | } | |
252 | ||
bdc9f8d2 | 253 | //! if this returns true, DomainInfo di contains information about the domain |
12c86877 BH |
254 | virtual bool getDomainInfo(const string &domain, DomainInfo &di) |
255 | { | |
256 | return false; | |
257 | } | |
bdc9f8d2 | 258 | //! slave capable backends should return a list of slaves that should be rechecked for staleness |
12c86877 BH |
259 | virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains) |
260 | { | |
261 | } | |
262 | ||
bdc9f8d2 | 263 | //! get a list of IP addresses that should also be notified for a domain |
12c86877 BH |
264 | virtual void alsoNotifies(const string &domain, set<string> *ips) |
265 | { | |
266 | } | |
bdc9f8d2 BH |
267 | |
268 | //! get list of domains that have been changed since their last notification to slaves | |
12c86877 BH |
269 | virtual void getUpdatedMasters(vector<DomainInfo>* domains) |
270 | { | |
271 | } | |
bdc9f8d2 BH |
272 | |
273 | //! Called by PowerDNS to inform a backend that a domain has been checked for freshness | |
092f210a | 274 | virtual void setFresh(uint32_t domain_id) |
12c86877 BH |
275 | { |
276 | ||
277 | } | |
bdc9f8d2 | 278 | //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves |
092f210a | 279 | virtual void setNotified(uint32_t id, uint32_t serial) |
12c86877 BH |
280 | { |
281 | } | |
282 | ||
6d58359c CH |
283 | //! Called when the Master of a domain should be changed |
284 | virtual bool setMaster(const string &domain, const string &ip) | |
285 | { | |
286 | return false; | |
287 | } | |
288 | ||
289 | //! Called when the Kind of a domain should be changed (master -> native and similar) | |
290 | virtual bool setKind(const string &domain, const DomainInfo::DomainKind kind) | |
291 | { | |
292 | return false; | |
293 | } | |
294 | ||
bdc9f8d2 | 295 | //! Can be called to seed the getArg() function with a prefix |
12c86877 | 296 | void setArgPrefix(const string &prefix); |
bdc9f8d2 BH |
297 | |
298 | //! determine if ip is a supermaster or a domain | |
12c86877 BH |
299 | virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db) |
300 | { | |
301 | return false; | |
302 | } | |
bdc9f8d2 | 303 | |
487cf033 CH |
304 | //! called by PowerDNS to create a new domain |
305 | virtual bool createDomain(const string &domain) | |
306 | { | |
307 | return false; | |
308 | } | |
309 | ||
bdc9f8d2 | 310 | //! called by PowerDNS to create a slave record for a superMaster |
12c86877 BH |
311 | virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account) |
312 | { | |
313 | return false; | |
314 | } | |
315 | ||
44e62984 CH |
316 | //! called to delete a domain, incl. all metadata, zone contents, etc. |
317 | virtual bool deleteDomain(const string &domain) | |
318 | { | |
319 | return false; | |
320 | } | |
321 | ||
12c86877 BH |
322 | protected: |
323 | bool mustDo(const string &key); | |
324 | const string &getArg(const string &key); | |
325 | int getArgAsNum(const string &key); | |
326 | string getRemote(DNSPacket *p); | |
327 | bool getRemote(DNSPacket *p, struct sockaddr *in, Utility::socklen_t *len); | |
328 | ||
329 | private: | |
330 | string d_prefix; | |
331 | }; | |
332 | ||
333 | class BackendFactory | |
334 | { | |
335 | public: | |
336 | BackendFactory(const string &name) : d_name(name) {} | |
337 | virtual ~BackendFactory(){} | |
338 | virtual DNSBackend *make(const string &suffix)=0; | |
2717b8b3 BH |
339 | virtual DNSBackend *makeMetadataOnly(const string &suffix) |
340 | { | |
341 | return this->make(suffix); | |
342 | } | |
12c86877 BH |
343 | virtual void declareArguments(const string &suffix=""){} |
344 | const string &getName() const; | |
345 | ||
346 | protected: | |
347 | void declare(const string &suffix, const string ¶m, const string &explanation, const string &value); | |
348 | ||
349 | private: | |
350 | const string d_name; | |
351 | }; | |
352 | ||
353 | class BackendMakerClass | |
354 | { | |
355 | public: | |
356 | void report(BackendFactory *bf); | |
357 | void launch(const string &instr); | |
e0d84497 | 358 | vector<DNSBackend *>all(bool skipBIND=false); |
12c86877 BH |
359 | void load(const string &module); |
360 | int numLauncheable(); | |
361 | vector<string> getModules(); | |
362 | ||
363 | private: | |
364 | void load_all(); | |
365 | typedef map<string,BackendFactory *>d_repository_t; | |
366 | d_repository_t d_repository; | |
367 | vector<pair<string,string> >d_instances; | |
368 | }; | |
369 | ||
370 | extern BackendMakerClass &BackendMakers(); | |
371 | ||
bdc9f8d2 | 372 | //! Exception that can be thrown by a DNSBackend to indicate a failure |
3f81d239 | 373 | class DBException : public PDNSException |
cc3afe25 BH |
374 | { |
375 | public: | |
3f81d239 | 376 | DBException(const string &reason) : PDNSException(reason){} |
cc3afe25 BH |
377 | }; |
378 | ||
12c86877 BH |
379 | |
380 | #endif |