]>
Commit | Line | Data |
---|---|---|
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 | 8 | void 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 |
30 | DNSProtoBufMessage::DNSProtoBufMessage(DNSProtoBufMessageType type) |
31 | { | |
32 | setType(type); | |
33 | } | |
34 | ||
d9d3f9c1 RG |
35 | void 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 | ||
48 | void DNSProtoBufMessage::setBytes(size_t bytes) | |
49 | { | |
50 | #ifdef HAVE_PROTOBUF | |
51 | d_message.set_inbytes(bytes); | |
52 | #endif /* HAVE_PROTOBUF */ | |
53 | } | |
54 | ||
55 | void 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 | ||
65 | void 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 |
73 | void 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 | 84 | void 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 | 100 | void 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 | 113 | void 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 | 132 | void 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 |
212 | void DNSProtoBufMessage::setRequestor(const std::string& requestor) |
213 | { | |
214 | #ifdef HAVE_PROTOBUF | |
215 | d_message.set_from(requestor); | |
216 | #endif /* HAVE_PROTOBUF */ | |
217 | } | |
218 | ||
219 | void 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 |
231 | void 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 |
238 | void 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 |
245 | void 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 |
252 | void 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 | ||
259 | void 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 |
271 | void DNSProtoBufMessage::serialize(std::string& data) const |
272 | { | |
273 | #ifdef HAVE_PROTOBUF | |
274 | d_message.SerializeToString(&data); | |
275 | #endif /* HAVE_PROTOBUF */ | |
276 | } | |
277 | ||
278 | std::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 | ||
289 | void 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 |
296 | void 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 |
303 | void 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 | 330 | DNSProtoBufMessage::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 |
340 | void DNSProtoBufMessage::copyFrom(const DNSProtoBufMessage& msg) |
341 | { | |
342 | d_message.CopyFrom(msg.d_message); | |
343 | } | |
344 | ||
d9d3f9c1 | 345 | #endif /* HAVE_PROTOBUF */ |