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