]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/ueberbackend.hh
Merge pull request #6588 from rgacogne/rec-safe-load-rpz
[thirdparty/pdns.git] / pdns / ueberbackend.hh
1 /*
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 */
22 #ifndef UEBERBACKEND_HH
23 #define UEBERBACKEND_HH
24
25 #include <vector>
26 #include <map>
27 #include <string>
28 #include <algorithm>
29 #include <pthread.h>
30 #include <semaphore.h>
31
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <boost/utility.hpp>
37 #include "dnspacket.hh"
38 #include "dnsbackend.hh"
39
40 #include "namespaces.hh"
41
42 /** This is a very magic backend that allows us to load modules dynamically,
43 and query them in order. This is persistent over all UeberBackend instantiations
44 across multiple threads.
45
46 The UeberBackend is transparent for exceptions, which should fall straight through.
47 */
48
49 class UeberBackend : public boost::noncopyable
50 {
51 public:
52 UeberBackend(const string &pname="default");
53 ~UeberBackend();
54
55 bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
56
57 /** Tracks all created UeberBackend instances for us. We use this vector to notify
58 existing threads of new modules
59 */
60 static vector<UeberBackend *>instances;
61 static pthread_mutex_t instances_lock;
62
63 static bool loadmodule(const string &name);
64 static bool loadModules(const vector<string>& modules, const string& path);
65
66 static void go(void);
67
68 /** This contains all registered backends. The DynListener modifies this list for us when
69 new modules are loaded */
70 vector<DNSBackend*> backends;
71
72 void cleanup();
73
74 //! the very magic handle for UeberBackend questions
75 class handle
76 {
77 public:
78 bool get(DNSZoneRecord &dr);
79 handle();
80 ~handle();
81
82 //! The UeberBackend class where this handle belongs to
83 UeberBackend *parent;
84 //! The current real backend, which is answering questions
85 DNSBackend *d_hinterBackend;
86
87 //! DNSPacket who asked this question
88 DNSPacket *pkt_p;
89 DNSName qname;
90
91 //! Index of the current backend within the backends vector
92 unsigned int i;
93 QType qtype;
94
95 private:
96
97 static AtomicCounter instances;
98 };
99
100 void lookup(const QType &, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
101
102 /** Determines if we are authoritative for a zone, and at what level */
103 bool getAuth(const DNSName &target, const QType &qtype, SOAData* sd, bool cachedOk=true);
104 bool getSOA(const DNSName &domain, SOAData &sd);
105 /** Load SOA info from backends, ignoring the cache. Callers that will write to the backend should use this
106 * function, possibly setting unmodifiedSerial=true when editing the SOA Serial. */
107 bool getSOAUncached(const DNSName &domain, SOAData &sd, bool unmodifiedSerial=false);
108 bool get(DNSZoneRecord &r);
109 void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
110
111 void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
112 void getUpdatedMasters(vector<DomainInfo>* domains);
113 bool getDomainInfo(const DNSName &domain, DomainInfo &di, bool getSerial=true);
114 bool createDomain(const DNSName &domain);
115
116 bool doesDNSSEC();
117 bool addDomainKey(const DNSName& name, const DNSBackend::KeyData& key, int64_t& id);
118 bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys);
119 bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta);
120 bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta);
121 bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta);
122
123 bool removeDomainKey(const DNSName& name, unsigned int id);
124 bool activateDomainKey(const DNSName& name, unsigned int id);
125 bool deactivateDomainKey(const DNSName& name, unsigned int id);
126
127 bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content);
128 bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content);
129 bool deleteTSIGKey(const DNSName& name);
130 bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
131
132 void alsoNotifies(const DNSName &domain, set<string> *ips);
133 void rediscover(string* status=0);
134 void reload();
135 bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result);
136 bool searchComments(const string &pattern, int maxResults, vector<Comment>& result);
137 private:
138 pthread_t d_tid;
139 handle d_handle;
140 vector<DNSZoneRecord> d_answers;
141 vector<DNSZoneRecord>::const_iterator d_cachehandleiter;
142
143 static pthread_mutex_t d_mut;
144 static pthread_cond_t d_cond;
145
146 struct Question
147 {
148 DNSName qname;
149 int zoneId;
150 QType qtype;
151 }d_question;
152
153 unsigned int d_cache_ttl, d_negcache_ttl;
154 int d_domain_id;
155 int d_ancount;
156
157 bool d_negcached;
158 bool d_cached;
159 static bool d_go;
160 bool d_stale;
161
162 int cacheHas(const Question &q, vector<DNSZoneRecord> &rrs);
163 void addNegCache(const Question &q);
164 void addCache(const Question &q, const vector<DNSZoneRecord> &rrs);
165
166 };
167
168 #endif