2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002-2010 PowerDNS.COM BV
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2
7 as published by the Free Software Foundation
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <sys/types.h>
29 #include "pdnsexception.hh"
32 #include <sys/socket.h>
38 #include "namespaces.hh"
43 DomainInfo() : backend(0) {}
46 vector<string> masters;
47 uint32_t notified_serial;
50 enum DomainKind { Master, Slave, Native } kind;
53 bool operator<(const DomainInfo& rhs) const
55 return zone < rhs.zone;
58 const char *getKindString() const
60 return DomainInfo::getKindString(kind);
63 static const char *getKindString(enum DomainKind kind)
65 const char *kinds[]={"Master", "Slave", "Native"};
69 static DomainKind stringToKind(const string& kind)
71 if(pdns_iequals(kind,"SLAVE"))
72 return DomainInfo::Slave;
73 else if(pdns_iequals(kind,"MASTER"))
74 return DomainInfo::Master;
76 return DomainInfo::Native;
83 std::string algorithm;
90 //! This virtual base class defines the interface for backends for the ahudns.
91 /** To create a backend, inherit from this class and implement functions for all virtual methods.
92 Methods should not throw an exception if they are sure they did not find the requested data. However,
93 if an error occurred which prevented them temporarily from performing a lockup, they should throw a DBException,
94 which will cause the nameserver to send out a ServFail or take other evasive action. Probably only locking
95 issues should lead to DBExceptions.
97 More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should
98 lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler
99 and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one.
104 //! lookup() initiates a lookup. A lookup without results should not throw!
105 virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
106 virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
109 //! Initiates a list of the specified domain
110 /** Once initiated, DNSResourceRecord objects can be retrieved using get(). Should return false
111 if the backend does not consider itself responsible for the id passed.
112 \param domain_id ID of which a list is requested
114 virtual bool list(const string &target, int domain_id)=0;
116 virtual ~DNSBackend(){};
118 //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
119 virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
121 //! Calculates a SOA serial for the zone and stores it in the third argument.
122 virtual bool calculateSOASerial(const string& domain, const SOAData& sd, time_t& serial);
124 virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
129 virtual bool listSubZone(const string &zone, int domain_id)
134 // the DNSSEC related (getDomainMetadata has broader uses too)
135 virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) { return false; }
136 virtual bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta) {return false;}
138 virtual void getAllDomains(vector<DomainInfo> *domains) { }
147 virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) { return false;}
148 virtual bool removeDomainKey(const string& name, unsigned int id) { return false; }
149 virtual int addDomainKey(const string& name, const KeyData& key){ return -1; }
150 virtual bool activateDomainKey(const string& name, unsigned int id) { return false; }
151 virtual bool deactivateDomainKey(const string& name, unsigned int id) { return false; }
153 virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; }
154 virtual bool setTSIGKey(const string& name, const string& algorithm, const string& content) { return false; }
155 virtual bool deleteTSIGKey(const string& name) { return false; }
156 virtual bool getTSIGKeys(std::vector< struct TSIGKey > &keys) { return false; }
158 virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
160 std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl;
165 bool getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after);
167 virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
172 virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth)
177 virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
182 virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
187 virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type)
192 virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
197 virtual bool doesDNSSEC()
204 //! returns true if master ip is master for domain name.
205 virtual bool isMaster(const string &name, const string &ip)
210 //! starts the transaction for updating domain qname (FIXME: what is id?)
211 virtual bool startTransaction(const string &qname, int id=-1)
216 //! commits the transaction started by startTransaction
217 virtual bool commitTransaction()
222 //! aborts the transaction started by strartTransaction, should leave state unaltered
223 virtual bool abortTransaction()
228 virtual void reload()
232 virtual void rediscover(string* status=0)
236 //! feeds a record to a zone, needs a call to startTransaction first
237 virtual bool feedRecord(const DNSResourceRecord &rr, string *ordername=0)
239 return false; // no problem!
241 virtual bool feedEnts(int domain_id, set<string> &nonterm)
245 virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow)
250 //! if this returns true, DomainInfo di contains information about the domain
251 virtual bool getDomainInfo(const string &domain, DomainInfo &di)
255 //! slave capable backends should return a list of slaves that should be rechecked for staleness
256 virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
260 //! get a list of IP addresses that should also be notified for a domain
261 virtual void alsoNotifies(const string &domain, set<string> *ips)
265 //! get list of domains that have been changed since their last notification to slaves
266 virtual void getUpdatedMasters(vector<DomainInfo>* domains)
270 //! Called by PowerDNS to inform a backend that a domain has been checked for freshness
271 virtual void setFresh(uint32_t domain_id)
275 //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves
276 virtual void setNotified(uint32_t id, uint32_t serial)
280 //! Called when the Master of a domain should be changed
281 virtual bool setMaster(const string &domain, const string &ip)
286 //! Called when the Kind of a domain should be changed (master -> native and similar)
287 virtual bool setKind(const string &domain, const DomainInfo::DomainKind kind)
292 //! Can be called to seed the getArg() function with a prefix
293 void setArgPrefix(const string &prefix);
295 //! determine if ip is a supermaster or a domain
296 virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
301 //! called by PowerDNS to create a new domain
302 virtual bool createDomain(const string &domain)
307 //! called by PowerDNS to create a slave record for a superMaster
308 virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
313 //! called to delete a domain, incl. all metadata, zone contents, etc.
314 virtual bool deleteDomain(const string &domain)
320 bool mustDo(const string &key);
321 const string &getArg(const string &key);
322 int getArgAsNum(const string &key);
323 string getRemote(DNSPacket *p);
324 bool getRemote(DNSPacket *p, struct sockaddr *in, Utility::socklen_t *len);
333 BackendFactory(const string &name) : d_name(name) {}
334 virtual ~BackendFactory(){}
335 virtual DNSBackend *make(const string &suffix)=0;
336 virtual DNSBackend *makeMetadataOnly(const string &suffix)
338 return this->make(suffix);
340 virtual void declareArguments(const string &suffix=""){}
341 const string &getName() const;
344 void declare(const string &suffix, const string ¶m, const string &explanation, const string &value);
350 class BackendMakerClass
353 void report(BackendFactory *bf);
354 void launch(const string &instr);
355 vector<DNSBackend *>all(bool skipBIND=false);
356 void load(const string &module);
357 int numLauncheable();
358 vector<string> getModules();
362 typedef map<string,BackendFactory *>d_repository_t;
363 d_repository_t d_repository;
364 vector<pair<string,string> >d_instances;
367 extern BackendMakerClass &BackendMakers();
369 //! Exception that can be thrown by a DNSBackend to indicate a failure
370 class DBException : public PDNSException
373 DBException(const string &reason) : PDNSException(reason){}