]> git.ipfire.org Git - thirdparty/pdns.git/blob - modules/remotebackend/remotebackend.hh
Merge pull request #9106 from omoerbeek/release-cycles
[thirdparty/pdns.git] / modules / remotebackend / remotebackend.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 #pragma once
23 #include <sys/types.h>
24 #include <sys/wait.h>
25
26 #include <string>
27 #include "pdns/arguments.hh"
28 #include "pdns/dns.hh"
29 #include "pdns/dnsbackend.hh"
30 #include "pdns/dnspacket.hh"
31 #include "pdns/logger.hh"
32 #include "pdns/namespaces.hh"
33 #include "pdns/pdnsexception.hh"
34 #include "pdns/sstuff.hh"
35 #include "pdns/json.hh"
36 #include "pdns/lock.hh"
37 #include "yahttp/yahttp.hpp"
38
39 #ifdef REMOTEBACKEND_ZEROMQ
40 #include <zmq.h>
41
42 // If the available ZeroMQ library version is < 2.x, create macros for the zmq_msg_send/recv functions
43 #ifndef HAVE_ZMQ_MSG_SEND
44 #define zmq_msg_send(msg, socket, flags) zmq_send(socket, msg, flags)
45 #define zmq_msg_recv(msg, socket, flags) zmq_recv(socket, msg, flags)
46 #endif
47 #endif
48
49 using json11::Json;
50
51 class Connector {
52 public:
53 virtual ~Connector() {};
54 bool send(Json &value);
55 bool recv(Json &value);
56 virtual int send_message(const Json &input) = 0;
57 virtual int recv_message(Json &output) = 0;
58 protected:
59 string asString(const Json& value) {
60 if (value.is_number()) return std::to_string(value.int_value());
61 if (value.is_bool()) return (value.bool_value()?"1":"0");
62 if (value.is_string()) return value.string_value();
63 throw JsonException("Json value not convertible to String");
64 };
65 };
66
67 // fwd declarations
68 class UnixsocketConnector: public Connector {
69 public:
70 UnixsocketConnector(std::map<std::string,std::string> options);
71 virtual ~UnixsocketConnector();
72 virtual int send_message(const Json &input);
73 virtual int recv_message(Json &output);
74 private:
75 ssize_t read(std::string &data);
76 ssize_t write(const std::string &data);
77 void reconnect();
78 std::map<std::string,std::string> options;
79 int fd;
80 std::string path;
81 bool connected;
82 int timeout;
83 };
84
85 class HTTPConnector: public Connector {
86 public:
87
88 HTTPConnector(std::map<std::string,std::string> options);
89 ~HTTPConnector();
90
91 virtual int send_message(const Json &input);
92 virtual int recv_message(Json &output);
93 private:
94 std::string d_url;
95 std::string d_url_suffix;
96 std::string d_data;
97 int timeout;
98 bool d_post;
99 bool d_post_json;
100 void restful_requestbuilder(const std::string &method, const Json &parameters, YaHTTP::Request& req);
101 void post_requestbuilder(const Json &input, YaHTTP::Request& req);
102 void addUrlComponent(const Json &parameters, const string& element, std::stringstream& ss);
103 std::string buildMemberListArgs(std::string prefix, const Json& args);
104 std::unique_ptr<Socket> d_socket;
105 ComboAddress d_addr;
106 std::string d_host;
107 uint16_t d_port;
108 };
109
110 #ifdef REMOTEBACKEND_ZEROMQ
111 class ZeroMQConnector: public Connector {
112 public:
113 ZeroMQConnector(std::map<std::string,std::string> options);
114 virtual ~ZeroMQConnector();
115 virtual int send_message(const Json &input);
116 virtual int recv_message(Json &output);
117 private:
118 void connect();
119 std::string d_endpoint;
120 int d_timeout;
121 int d_timespent;
122 std::map<std::string,std::string> d_options;
123 std::unique_ptr<void, int(*)(void*)> d_ctx;
124 std::unique_ptr<void, int(*)(void*)> d_sock;
125 };
126 #endif
127
128 class PipeConnector: public Connector {
129 public:
130
131 PipeConnector(std::map<std::string,std::string> options);
132 ~PipeConnector();
133
134 virtual int send_message(const Json &input);
135 virtual int recv_message(Json &output);
136
137 private:
138
139 void launch();
140 bool checkStatus();
141
142 std::string command;
143 std::map<std::string,std::string> options;
144
145 int d_fd1[2], d_fd2[2];
146 int d_pid;
147 int d_timeout;
148 std::unique_ptr<FILE, int(*)(FILE*)> d_fp{nullptr, fclose};
149 };
150
151 class RemoteBackend : public DNSBackend
152 {
153 public:
154 RemoteBackend(const std::string &suffix="");
155 ~RemoteBackend();
156
157 void lookup(const QType &qtype, const DNSName& qdomain, int zoneId=-1, DNSPacket *pkt_p=nullptr) override;
158 bool get(DNSResourceRecord &rr) override;
159 bool list(const DNSName& target, int domain_id, bool include_disabled=false) override;
160
161 bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta) override;
162 bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta) override;
163 bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys) override;
164 bool getTSIGKey(const DNSName& name, DNSName* algorithm, std::string* content) override;
165 bool getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) override;
166 bool setDomainMetadata(const DNSName& name, const string& kind, const std::vector<std::basic_string<char> >& meta) override;
167 bool removeDomainKey(const DNSName& name, unsigned int id) override;
168 bool addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) override;
169 bool activateDomainKey(const DNSName& name, unsigned int id) override;
170 bool deactivateDomainKey(const DNSName& name, unsigned int id) override;
171 bool publishDomainKey(const DNSName& name, unsigned int id) override;
172 bool unpublishDomainKey(const DNSName& name, unsigned int id) override;
173 bool getDomainInfo(const DNSName& domain, DomainInfo& di, bool getSerial=true ) override;
174 void setNotified(uint32_t id, uint32_t serial) override;
175 bool doesDNSSEC() override;
176 bool superMasterBackend(const string &ip, const DNSName& domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **ddb) override;
177 bool createSlaveDomain(const string &ip, const DNSName& domain, const string& nameserver, const string &account) override;
178 bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) override;
179 bool feedRecord(const DNSResourceRecord &r, const DNSName &ordername, bool ordernameIsNSEC3=false) override;
180 bool feedEnts(int domain_id, map<DNSName,bool>& nonterm) override;
181 bool feedEnts3(int domain_id, const DNSName& domain, map<DNSName,bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
182 bool startTransaction(const DNSName& domain, int domain_id) override;
183 bool commitTransaction() override;
184 bool abortTransaction() override;
185 bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) override;
186 bool deleteTSIGKey(const DNSName& name) override;
187 bool getTSIGKeys(std::vector< struct TSIGKey > &keys) override;
188 string directBackendCmd(const string& querystr) override;
189 bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result) override;
190 bool searchComments(const string &pattern, int maxResults, vector<Comment>& result) override;
191 void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false) override;
192 void getUpdatedMasters(vector<DomainInfo>* domains) override;
193 void alsoNotifies(const DNSName &domain, set<string> *ips) override;
194 void getUnfreshSlaveInfos(vector<DomainInfo>* domains) override;
195 void setFresh(uint32_t domain_id) override;
196
197 static DNSBackend *maker();
198
199 private:
200 int build();
201 std::unique_ptr<Connector> connector;
202 bool d_dnssec;
203 Json d_result;
204 int d_index;
205 int64_t d_trxid;
206 std::string d_connstr;
207
208 bool send(Json &value);
209 bool recv(Json &value);
210
211 string asString(const Json& value) {
212 if (value.is_number()) return std::to_string(value.int_value());
213 if (value.is_bool()) return (value.bool_value()?"1":"0");
214 if (value.is_string()) return value.string_value();
215 throw JsonException("Json value not convertible to String");
216 };
217
218 bool asBool(const Json& value) {
219 if (value.is_bool()) return value.bool_value();
220 try {
221 string val = asString(value);
222 if (val == "0") return false;
223 if (val == "1") return true;
224 } catch (const JsonException&) {};
225 throw JsonException("Json value not convertible to boolean");
226 };
227
228 void parseDomainInfo(const json11::Json &obj, DomainInfo &di);
229 };