]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/protobuf.cc
rec: ensure correct service user on debian
[thirdparty/pdns.git] / pdns / protobuf.cc
CommitLineData
d9d3f9c1 1
4898a348
RG
2#include "gettime.hh"
3#include "dnsparser.hh"
d9d3f9c1
RG
4#include "protobuf.hh"
5#include "dnsparser.hh"
6#include "gettime.hh"
7
4898a348 8void DNSProtoBufMessage::setType(DNSProtoBufMessageType type)
d9d3f9c1
RG
9{
10#ifdef HAVE_PROTOBUF
4898a348
RG
11 switch(type) {
12 case DNSProtoBufMessage::DNSProtoBufMessageType::Query:
13 d_message.set_type(PBDNSMessage_Type_DNSQueryType);
14 break;
15 case DNSProtoBufMessage::DNSProtoBufMessageType::Response:
16 d_message.set_type(PBDNSMessage_Type_DNSResponseType);
17 break;
18 case DNSProtoBufMessage::DNSProtoBufMessageType::OutgoingQuery:
19 d_message.set_type(PBDNSMessage_Type_DNSOutgoingQueryType);
20 break;
21 case DNSProtoBufMessage::DNSProtoBufMessageType::IncomingResponse:
22 d_message.set_type(PBDNSMessage_Type_DNSIncomingResponseType);
23 break;
24 default:
25 throw std::runtime_error("Unsupported protobuf type: "+std::to_string(type));
26 }
d9d3f9c1
RG
27#endif /* HAVE_PROTOBUF */
28}
29
4898a348
RG
30DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type)
31{
32 setType(type);
33}
34
d9d3f9c1
RG
35void DNSProtoBufMessage::setQuestion(const DNSName& qname, uint16_t qtype, uint16_t qclass)
36{
37#ifdef HAVE_PROTOBUF
38 PBDNSMessage_DNSQuestion* question = d_message.mutable_question();
39 if (question) {
da5bcd9d 40 if(!qname.empty())
41 question->set_qname(qname.toString());
d9d3f9c1
RG
42 question->set_qtype(qtype);
43 question->set_qclass(qclass);
44 }
45#endif /* HAVE_PROTOBUF */
46}
47
48void DNSProtoBufMessage::setBytes(size_t bytes)
49{
50#ifdef HAVE_PROTOBUF
51 d_message.set_inbytes(bytes);
52#endif /* HAVE_PROTOBUF */
53}
54
55void DNSProtoBufMessage::setResponseCode(uint8_t rcode)
56{
57#ifdef HAVE_PROTOBUF
58 PBDNSMessage_DNSResponse* response = d_message.mutable_response();
59 if (response) {
60 response->set_rcode(rcode);
61 }
62#endif /* HAVE_PROTOBUF */
63}
64
65void DNSProtoBufMessage::setTime(time_t sec, uint32_t usec)
66{
67#ifdef HAVE_PROTOBUF
68 d_message.set_timesec(sec);
69 d_message.set_timeusec(usec);
70#endif /* HAVE_PROTOBUF */
71}
72
58307a85
RG
73void DNSProtoBufMessage::setQueryTime(time_t sec, uint32_t usec)
74{
75#ifdef HAVE_PROTOBUF
76 PBDNSMessage_DNSResponse* response = d_message.mutable_response();
77 if (response) {
78 response->set_querytimesec(sec);
79 response->set_querytimeusec(usec);
80 }
81#endif /* HAVE_PROTOBUF */
82}
83
a94bc5d7 84void DNSProtoBufMessage::setEDNSSubnet(const Netmask& subnet, uint8_t mask)
d9d3f9c1
RG
85{
86#ifdef HAVE_PROTOBUF
87 if (!subnet.empty()) {
a94bc5d7
RG
88 ComboAddress ca(subnet.getNetwork());
89 ca.truncate(mask);
d9d3f9c1
RG
90 if (ca.sin4.sin_family == AF_INET) {
91 d_message.set_originalrequestorsubnet(&ca.sin4.sin_addr.s_addr, sizeof(ca.sin4.sin_addr.s_addr));
92 }
93 else if (ca.sin4.sin_family == AF_INET6) {
94 d_message.set_originalrequestorsubnet(&ca.sin6.sin6_addr.s6_addr, sizeof(ca.sin6.sin6_addr.s6_addr));
95 }
96 }
97#endif /* HAVE_PROTOBUF */
98}
99
e6956c91 100void DNSProtoBufMessage::addTag(const std::string& strValue)
26a6373d
SO
101{
102#ifdef HAVE_PROTOBUF
103
104 PBDNSMessage_DNSResponse* response = d_message.mutable_response();
105 if (!response)
106 return;
107
e6956c91 108 response->add_tags(strValue);
26a6373d
SO
109
110#endif /* HAVE_PROTOBUF */
111}
112
ff09c374 113void DNSProtoBufMessage::addRR(const DNSName& qname, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob)
26a6373d
SO
114{
115#ifdef HAVE_PROTOBUF
116
117 PBDNSMessage_DNSResponse* response = d_message.mutable_response();
118 if (!response)
119 return;
26a6373d 120 PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
29cd61cc 121 if (rr) {
ff09c374 122 rr->set_name(qname.toString());
29cd61cc
SO
123 rr->set_type(uType);
124 rr->set_class_(uClass);
125 rr->set_ttl(uTTL);
c959e01a 126 rr->set_rdata(strBlob.c_str(), strBlob.size());
29cd61cc 127 }
26a6373d
SO
128
129#endif /* HAVE_PROTOBUF */
130}
26a6373d 131
165c9030 132void DNSProtoBufMessage::addRRsFromPacket(const char* packet, const size_t len, bool includeCNAME)
d9d3f9c1
RG
133{
134#ifdef HAVE_PROTOBUF
135 if (len < sizeof(struct dnsheader))
136 return;
137
138 const struct dnsheader* dh = (const struct dnsheader*) packet;
139
140 if (ntohs(dh->ancount) == 0)
141 return;
142
143 if (ntohs(dh->qdcount) == 0)
144 return;
145
146 PBDNSMessage_DNSResponse* response = d_message.mutable_response();
147 if (!response)
148 return;
149
78f56b38
RG
150 std::string packetStr(packet, len);
151 PacketReader pr(packetStr);
d9d3f9c1
RG
152
153 size_t idx = 0;
154 DNSName rrname;
155 uint16_t qdcount = ntohs(dh->qdcount);
156 uint16_t ancount = ntohs(dh->ancount);
157 uint16_t rrtype;
158 uint16_t rrclass;
159 string blob;
160 struct dnsrecordheader ah;
161
162 rrname = pr.getName();
163 rrtype = pr.get16BitInt();
164 rrclass = pr.get16BitInt();
165
166 /* consume remaining qd if any */
167 if (qdcount > 1) {
168 for(idx = 1; idx < qdcount; idx++) {
169 rrname = pr.getName();
170 rrtype = pr.get16BitInt();
171 rrclass = pr.get16BitInt();
172 (void) rrtype;
173 (void) rrclass;
174 }
175 }
176
177 /* parse AN */
178 for (idx = 0; idx < ancount; idx++) {
179 rrname = pr.getName();
180 pr.getDnsrecordheader(ah);
181
d9d3f9c1 182 if (ah.d_type == QType::A || ah.d_type == QType::AAAA) {
165c9030
RG
183 pr.xfrBlob(blob);
184
d9d3f9c1
RG
185 PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
186 if (rr) {
187 rr->set_name(rrname.toString());
188 rr->set_type(ah.d_type);
189 rr->set_class_(ah.d_class);
190 rr->set_ttl(ah.d_ttl);
191 rr->set_rdata(blob.c_str(), blob.length());
192 }
165c9030
RG
193 } else if (ah.d_type == QType::CNAME && includeCNAME) {
194 PBDNSMessage_DNSResponse_DNSRR* rr = response->add_rrs();
195 if (rr) {
196 rr->set_name(rrname.toString());
197 rr->set_type(ah.d_type);
198 rr->set_class_(ah.d_class);
199 rr->set_ttl(ah.d_ttl);
200 DNSName target;
201 pr.xfrName(target, true);
202 rr->set_rdata(target.toString());
203 }
204 }
205 else {
206 pr.xfrBlob(blob);
d9d3f9c1
RG
207 }
208 }
209#endif /* HAVE_PROTOBUF */
210}
211
a94673ea
RG
212void DNSProtoBufMessage::setRequestor(const std::string& requestor)
213{
214#ifdef HAVE_PROTOBUF
215 d_message.set_from(requestor);
216#endif /* HAVE_PROTOBUF */
217}
218
219void DNSProtoBufMessage::setRequestor(const ComboAddress& requestor)
220{
221#ifdef HAVE_PROTOBUF
222 if (requestor.sin4.sin_family == AF_INET) {
223 d_message.set_from(&requestor.sin4.sin_addr.s_addr, sizeof(requestor.sin4.sin_addr.s_addr));
224 }
225 else if (requestor.sin4.sin_family == AF_INET6) {
226 d_message.set_from(&requestor.sin6.sin6_addr.s6_addr, sizeof(requestor.sin6.sin6_addr.s6_addr));
227 }
228#endif /* HAVE_PROTOBUF */
229}
230
67e31ebe
RG
231void DNSProtoBufMessage::setRequestorId(const std::string& requestorId)
232{
233#ifdef HAVE_PROTOBUF
234 d_message.set_requestorid(requestorId);
235#endif /* HAVE_PROTOBUF */
236}
237
590388d2
NC
238void DNSProtoBufMessage::setDeviceId(const std::string& deviceId)
239{
240#ifdef HAVE_PROTOBUF
241 d_message.set_deviceid(deviceId);
242#endif /* HAVE_PROTOBUF */
243}
244
c165308b
RG
245void DNSProtoBufMessage::setServerIdentity(const std::string& serverId)
246{
247#ifdef HAVE_PROTOBUF
248 d_message.set_serveridentity(serverId);
249#endif /* HAVE_PROTOBUF */
250}
251
a94673ea
RG
252void DNSProtoBufMessage::setResponder(const std::string& responder)
253{
254#ifdef HAVE_PROTOBUF
b3261c20 255 d_message.set_to(responder);
a94673ea
RG
256#endif /* HAVE_PROTOBUF */
257}
258
259void DNSProtoBufMessage::setResponder(const ComboAddress& responder)
260{
261#ifdef HAVE_PROTOBUF
262 if (responder.sin4.sin_family == AF_INET) {
b3261c20 263 d_message.set_to(&responder.sin4.sin_addr.s_addr, sizeof(responder.sin4.sin_addr.s_addr));
a94673ea
RG
264 }
265 else if (responder.sin4.sin_family == AF_INET6) {
b3261c20 266 d_message.set_to(&responder.sin6.sin6_addr.s6_addr, sizeof(responder.sin6.sin6_addr.s6_addr));
a94673ea
RG
267 }
268#endif /* HAVE_PROTOBUF */
269}
270
d9d3f9c1
RG
271void DNSProtoBufMessage::serialize(std::string& data) const
272{
273#ifdef HAVE_PROTOBUF
274 d_message.SerializeToString(&data);
275#endif /* HAVE_PROTOBUF */
276}
277
278std::string DNSProtoBufMessage::toDebugString() const
279{
280#ifdef HAVE_PROTOBUF
281 return d_message.DebugString();
121c28e9
RG
282#else
283 return std::string();
d9d3f9c1
RG
284#endif /* HAVE_PROTOBUF */
285}
286
287#ifdef HAVE_PROTOBUF
288
289void DNSProtoBufMessage::setUUID(const boost::uuids::uuid& uuid)
290{
291 std::string* messageId = d_message.mutable_messageid();
292 messageId->resize(uuid.size());
293 std::copy(uuid.begin(), uuid.end(), messageId->begin());
294}
295
4898a348
RG
296void DNSProtoBufMessage::setInitialRequestID(const boost::uuids::uuid& uuid)
297{
298 std::string* messageId = d_message.mutable_initialrequestid();
299 messageId->resize(uuid.size());
300 std::copy(uuid.begin(), uuid.end(), messageId->begin());
301}
302
d9d3f9c1
RG
303void DNSProtoBufMessage::update(const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, bool isTCP, uint16_t id)
304{
305 struct timespec ts;
306 gettime(&ts, true);
307 setTime(ts.tv_sec, ts.tv_nsec / 1000);
308
309 setUUID(uuid);
310 d_message.set_id(ntohs(id));
311
4898a348
RG
312 if (requestor) {
313 d_message.set_socketfamily(requestor->sin4.sin_family == AF_INET ? PBDNSMessage_SocketFamily_INET : PBDNSMessage_SocketFamily_INET6);
314 }
315 else if (responder) {
316 d_message.set_socketfamily(responder->sin4.sin_family == AF_INET ? PBDNSMessage_SocketFamily_INET : PBDNSMessage_SocketFamily_INET6);
317 }
318
d9d3f9c1
RG
319 d_message.set_socketprotocol(isTCP ? PBDNSMessage_SocketProtocol_TCP : PBDNSMessage_SocketProtocol_UDP);
320
321 if (responder) {
a94673ea 322 setResponder(*responder);
d9d3f9c1
RG
323 }
324 if (requestor) {
a94673ea 325 setRequestor(*requestor);
d9d3f9c1
RG
326 }
327}
328
329
4898a348 330DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type, const boost::uuids::uuid& uuid, const ComboAddress* requestor, const ComboAddress* responder, const DNSName& domain, int qtype, uint16_t qclass, uint16_t qid, bool isTCP, size_t bytes)
d9d3f9c1 331{
4898a348 332 update(uuid, requestor, responder, isTCP, qid);
d9d3f9c1 333
4898a348 334 setType(type);
d9d3f9c1
RG
335
336 setBytes(bytes);
337 setQuestion(domain, qtype, qclass);
338}
339
29478011
RG
340void DNSProtoBufMessage::copyFrom(const DNSProtoBufMessage& msg)
341{
342 d_message.CopyFrom(msg.d_message);
343}
344
d9d3f9c1 345#endif /* HAVE_PROTOBUF */