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
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.
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 St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <sys/types.h>
32 #include "pdnsexception.hh"
35 #include <sys/socket.h>
41 #include "namespaces.hh"
46 DomainInfo() : backend(0) {}
49 vector<string> masters;
50 uint32_t notified_serial;
53 enum DomainKind { Master, Slave, Native } kind;
56 bool operator<(const DomainInfo& rhs) const
58 return zone < rhs.zone;
61 const char *getKindString() const
63 return DomainInfo::getKindString(kind);
66 static const char *getKindString(enum DomainKind kind)
68 const char *kinds[]={"Master", "Slave", "Native"};
72 static DomainKind stringToKind(const string& kind)
74 if(pdns_iequals(kind,"SLAVE"))
75 return DomainInfo::Slave;
76 else if(pdns_iequals(kind,"MASTER"))
77 return DomainInfo::Master;
79 return DomainInfo::Native;
86 std::string algorithm;
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.
100 More serious errors, which may indicate that the database connection is hosed, or a configuration error occurred, should
101 lead to the throwing of an PDNSException. This exception will fall straight through the UeberBackend and the PacketHandler
102 and be caught by the Distributor, which will delete your DNSBackend instance and spawn a new one.
107 //! lookup() initiates a lookup. A lookup without results should not throw!
108 virtual void lookup(const QType &qtype, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1)=0;
109 virtual bool get(DNSResourceRecord &)=0; //!< retrieves one DNSResource record, returns false if no more were available
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
117 virtual bool list(const string &target, int domain_id)=0;
119 virtual ~DNSBackend(){};
121 //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
122 virtual bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
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);
127 virtual bool replaceRRSet(uint32_t domain_id, const string& qname, const QType& qt, const vector<DNSResourceRecord>& rrset)
132 virtual bool listSubZone(const string &zone, int domain_id)
137 // the DNSSEC related (getDomainMetadata has broader uses too)
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;}
141 virtual void getAllDomains(vector<DomainInfo> *domains) { }
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; }
156 virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; }
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; }
161 virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
163 std::cerr<<"Default beforeAndAfterAbsolute called!"<<std::endl;
168 bool getBeforeAndAfterNames(uint32_t id, const std::string& zonename, const std::string& qname, std::string& before, std::string& after);
170 virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
175 virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth)
180 virtual bool updateEmptyNonTerminals(uint32_t domain_id, const std::string& zonename, set<string>& insert, set<string>& erase, bool remove)
185 virtual bool nullifyDNSSECOrderNameAndUpdateAuth(uint32_t domain_id, const std::string& qname, bool auth)
190 virtual bool nullifyDNSSECOrderNameAndAuth(uint32_t domain_id, const std::string& qname, const std::string& type)
195 virtual bool setDNSSECAuthOnDsRecord(uint32_t domain_id, const std::string& qname)
200 virtual bool doesDNSSEC()
207 //! returns true if master ip is master for domain name.
208 virtual bool isMaster(const string &name, const string &ip)
213 //! starts the transaction for updating domain qname (FIXME: what is id?)
214 virtual bool startTransaction(const string &qname, int id=-1)
219 //! commits the transaction started by startTransaction
220 virtual bool commitTransaction()
225 //! aborts the transaction started by strartTransaction, should leave state unaltered
226 virtual bool abortTransaction()
231 virtual void reload()
235 virtual void rediscover(string* status=0)
239 //! feeds a record to a zone, needs a call to startTransaction first
240 virtual bool feedRecord(const DNSResourceRecord &rr, string *ordername=0)
242 return false; // no problem!
244 virtual bool feedEnts(int domain_id, set<string> &nonterm)
248 virtual bool feedEnts3(int domain_id, const string &domain, set<string> &nonterm, unsigned int times, const string &salt, bool narrow)
253 //! if this returns true, DomainInfo di contains information about the domain
254 virtual bool getDomainInfo(const string &domain, DomainInfo &di)
258 //! slave capable backends should return a list of slaves that should be rechecked for staleness
259 virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains)
263 //! get a list of IP addresses that should also be notified for a domain
264 virtual void alsoNotifies(const string &domain, set<string> *ips)
268 //! get list of domains that have been changed since their last notification to slaves
269 virtual void getUpdatedMasters(vector<DomainInfo>* domains)
273 //! Called by PowerDNS to inform a backend that a domain has been checked for freshness
274 virtual void setFresh(uint32_t domain_id)
278 //! Called by PowerDNS to inform a backend that the changes in the domain have been reported to slaves
279 virtual void setNotified(uint32_t id, uint32_t serial)
283 //! Called when the Master of a domain should be changed
284 virtual bool setMaster(const string &domain, const string &ip)
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)
295 //! Can be called to seed the getArg() function with a prefix
296 void setArgPrefix(const string &prefix);
298 //! determine if ip is a supermaster or a domain
299 virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
304 //! called by PowerDNS to create a new domain
305 virtual bool createDomain(const string &domain)
310 //! called by PowerDNS to create a slave record for a superMaster
311 virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
316 //! called to delete a domain, incl. all metadata, zone contents, etc.
317 virtual bool deleteDomain(const string &domain)
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);
336 BackendFactory(const string &name) : d_name(name) {}
337 virtual ~BackendFactory(){}
338 virtual DNSBackend *make(const string &suffix)=0;
339 virtual DNSBackend *makeMetadataOnly(const string &suffix)
341 return this->make(suffix);
343 virtual void declareArguments(const string &suffix=""){}
344 const string &getName() const;
347 void declare(const string &suffix, const string ¶m, const string &explanation, const string &value);
353 class BackendMakerClass
356 void report(BackendFactory *bf);
357 void launch(const string &instr);
358 vector<DNSBackend *>all(bool skipBIND=false);
359 void load(const string &module);
360 int numLauncheable();
361 vector<string> getModules();
365 typedef map<string,BackendFactory *>d_repository_t;
366 d_repository_t d_repository;
367 vector<pair<string,string> >d_instances;
370 extern BackendMakerClass &BackendMakers();
372 //! Exception that can be thrown by a DNSBackend to indicate a failure
373 class DBException : public PDNSException
376 DBException(const string &reason) : PDNSException(reason){}