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