]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/ueberbackend.hh
add OpenSSL exception to PowerDNS, Netherlabs, van Dijk and Hubert copyrights
[thirdparty/pdns.git] / pdns / ueberbackend.hh
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 - 2011 PowerDNS.COM BV
4
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
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.
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 St, 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 <sys/un.h>
33 #include <dlfcn.h>
34 #include <unistd.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <unistd.h>
40 #include <boost/utility.hpp>
41 #include "dnspacket.hh"
42 #include "dnsbackend.hh"
43
44 #include "namespaces.hh"
45
46 class BackendReporter;
47
48 /** This is a very magic backend that allows us to load modules dynamically,
49 and query them in order. This is persistent over all UeberBackend instantiations
50 across multiple threads.
51
52 The UeberBackend is transparent for exceptions, which should fall straight through.
53 */
54
55 class UeberBackend : public DNSBackend, public boost::noncopyable
56 {
57 public:
58 UeberBackend(const string &pname="default");
59 ~UeberBackend();
60 typedef DNSBackend *BackendMaker(); //!< typedef for functions returning pointers to new backends
61
62 bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db);
63
64 /** contains BackendReporter objects, which contain maker functions and information about
65 weather a module has already been reported to existing instances of the UeberBackend
66 */
67 // static vector<BackendReporter>backendmakers;
68
69 /** Tracks all created UeberBackend instances for us. We use this vector to notify
70 existing threads of new modules
71 */
72 static vector<UeberBackend *>instances;
73 static pthread_mutex_t instances_lock;
74
75 static bool loadmodule(const string &name);
76
77 /** Thread function that listens on our unix domain socket for commands, for example
78 instructions to load new modules */
79 static void *DynListener(void *);
80 static void go(void);
81
82 /** This contains all registered backends. The DynListener modifies this list for us when
83 new modules are loaded */
84 vector<DNSBackend*> backends;
85
86 void die();
87 void cleanup();
88
89 //! the very magic handle for UeberBackend questions
90 class handle
91 {
92 public:
93 bool get(DNSResourceRecord &r);
94 handle();
95 ~handle();
96
97 //! The UeberBackend class where this handle belongs to
98 UeberBackend *parent;
99 //! The current real backend, which is answering questions
100 DNSBackend *d_hinterBackend;
101
102 //! Index of the current backend within the backends vector
103 unsigned int i;
104
105 //! DNSPacket who asked this question
106 DNSPacket *pkt_p;
107 string qname;
108 QType qtype;
109 private:
110
111 static AtomicCounter instances;
112 };
113
114 void lookup(const QType &, const string &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
115
116 bool getSOA(const string &domain, SOAData &sd, DNSPacket *p=0);
117 bool list(const string &target, int domain_id);
118 bool get(DNSResourceRecord &r);
119 void getAllDomains(vector<DomainInfo> *domains);
120
121 static DNSBackend *maker(const map<string,string> &);
122 static void closeDynListener();
123 static void setStatus(const string &st);
124 void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
125 void getUpdatedMasters(vector<DomainInfo>* domains);
126 bool getDomainInfo(const string &domain, DomainInfo &di);
127 bool createDomain(const string &domain);
128
129 int addDomainKey(const string& name, const KeyData& key);
130 bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
131 bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
132 bool setDomainMetadata(const string& name, const std::string& kind, const std::vector<std::string>& meta);
133
134 bool removeDomainKey(const string& name, unsigned int id);
135 bool activateDomainKey(const string& name, unsigned int id);
136 bool deactivateDomainKey(const string& name, unsigned int id);
137
138 bool getTSIGKey(const string& name, string* algorithm, string* content);
139 bool setTSIGKey(const string& name, const string& algorithm, const string& content);
140 bool deleteTSIGKey(const string& name);
141 bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
142
143 void alsoNotifies(const string &domain, set<string> *ips);
144 void rediscover(string* status=0);
145 void reload();
146 private:
147 DNSResourceRecord lastrr;
148 pthread_t tid;
149 handle d_handle;
150 bool d_negcached;
151 bool d_cached;
152 struct Question
153 {
154 QType qtype;
155 string qname;
156 int zoneId;
157 }d_question;
158 vector<DNSResourceRecord> d_answers;
159 vector<DNSResourceRecord>::const_iterator d_cachehandleiter;
160
161 int cacheHas(const Question &q, vector<DNSResourceRecord> &rrs);
162 void addNegCache(const Question &q);
163 void addCache(const Question &q, const vector<DNSResourceRecord> &rrs);
164
165 static pthread_mutex_t d_mut;
166 static pthread_cond_t d_cond;
167 static sem_t d_dynserialize;
168 static bool d_go;
169 static int s_s;
170 static string s_status;
171 int d_ancount;
172
173 bool stale;
174 int domain_id;
175 };
176
177
178 /** Class used to report new backends. It stores a maker function, and a flag that indicates that
179 this module has been reported */
180 class BackendReporter
181 {
182 public:
183 BackendReporter(UeberBackend::BackendMaker *p)
184 {
185 maker=p;
186 reported=false;
187 };
188 map<string,string>d_parameters;
189 UeberBackend::BackendMaker *maker; //!< function to make this backend
190 bool reported; //!< if this backend has been reported to running UeberBackend threads
191 private:
192 };
193
194 #endif