1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef DNS_RESPONDER_H
19 #define DNS_RESPONDER_H
20 
21 #include <arpa/nameser.h>
22 
23 #include <atomic>
24 #include <condition_variable>
25 #include <mutex>
26 #include <string>
27 #include <thread>
28 #include <unordered_map>
29 #include <vector>
30 
31 #include <android-base/thread_annotations.h>
32 #include "android-base/unique_fd.h"
33 
34 // Default TTL of the DNS answer record.
35 constexpr unsigned kAnswerRecordTtlSec = 5;
36 
37 // The maximum UDP response size in bytes the DNS responder allows to send. It is used in non-EDNS
38 // case. See RFC 1035 section 4.2.1.
39 constexpr unsigned kMaximumUdpSize = 512;
40 
41 namespace test {
42 
43 struct DNSName {
44     std::string name;
45     const char* read(const char* buffer, const char* buffer_end);
46     char* write(char* buffer, const char* buffer_end) const;
47 
48   private:
49     const char* parseField(const char* buffer, const char* buffer_end, bool* last);
50 };
51 
52 struct DNSQuestion {
53     DNSName qname;
54     unsigned qtype;
55     unsigned qclass;
56     const char* read(const char* buffer, const char* buffer_end);
57     char* write(char* buffer, const char* buffer_end) const;
58     std::string toString() const;
59 };
60 
61 struct DNSRecord {
62     DNSName name;
63     unsigned rtype;
64     unsigned rclass;
65     unsigned ttl;
66     std::vector<char> rdata;
67     const char* read(const char* buffer, const char* buffer_end);
68     char* write(char* buffer, const char* buffer_end) const;
69     std::string toString() const;
70 
71   private:
72     struct IntFields {
73         uint16_t rtype;
74         uint16_t rclass;
75         uint32_t ttl;
76         uint16_t rdlen;
77     } __attribute__((__packed__));
78 
79     const char* readIntFields(const char* buffer, const char* buffer_end, unsigned* rdlen);
80     char* writeIntFields(unsigned rdlen, char* buffer, const char* buffer_end) const;
81 };
82 
83 // TODO: Perhaps rename to DNSMessage. Per RFC 1035 section 4.1, struct DNSHeader more likes a
84 // message because it has not only header section but also question section and other RRs.
85 struct DNSHeader {
86     unsigned id;
87     bool ra;
88     uint8_t rcode;
89     bool qr;
90     uint8_t opcode;
91     bool aa;
92     bool tr;
93     bool rd;
94     bool ad;
95     std::vector<DNSQuestion> questions;
96     std::vector<DNSRecord> answers;
97     std::vector<DNSRecord> authorities;
98     std::vector<DNSRecord> additionals;
99     const char* read(const char* buffer, const char* buffer_end);
100     char* write(char* buffer, const char* buffer_end) const;
101     bool write(std::vector<uint8_t>* out) const;
102     std::string toString() const;
103 
104   private:
105     struct Header {
106         uint16_t id;
107         uint8_t flags0;
108         uint8_t flags1;
109         uint16_t qdcount;
110         uint16_t ancount;
111         uint16_t nscount;
112         uint16_t arcount;
113     } __attribute__((__packed__));
114 
115     const char* readHeader(const char* buffer, const char* buffer_end, unsigned* qdcount,
116                            unsigned* ancount, unsigned* nscount, unsigned* arcount);
117 };
118 
119 inline const std::string kDefaultListenAddr = "127.0.0.3";
120 inline const std::string kDefaultListenService = "53";
121 inline const ns_rcode kDefaultErrorCode = ns_rcode::ns_r_servfail;
122 
123 /*
124  * Simple DNS responder, which replies to queries with the registered response
125  * for that type. Class is assumed to be IN. If no response is registered, the
126  * default error response code is returned.
127  */
128 class DNSResponder {
129   public:
130     enum class Edns {
131         ON,
132         FORMERR_ON_EDNS,  // DNS server not supporting EDNS will reply FORMERR.
133         FORMERR_UNCOND,   // DNS server reply FORMERR unconditionally
134         DROP              // DNS server not supporting EDNS will not do any response.
135     };
136     // Indicate which mapping the DNS server used to build the response.
137     // See also addMapping{, DnsHeader, BinaryPacket}, removeMapping{, DnsHeader, BinaryPacket},
138     // makeResponse{, FromDnsHeader, FromBinaryPacket}.
139     // TODO: Perhaps break class DNSResponder for each mapping.
140     enum class MappingType {
141         ADDRESS_OR_HOSTNAME,  // Use the mapping from (name, type) to (address or hostname)
142         DNS_HEADER,           // Use the mapping from (name, type) to (DNSHeader)
143         BINARY_PACKET,        // Use the mapping from (query packet) to (response packet)
144     };
145 
146     struct QueryInfo {
147         std::string name;
148         ns_type type;
149         int protocol;  // Either IPPROTO_TCP or IPPROTO_UDP
150     };
151 
152     DNSResponder(std::string listen_address = kDefaultListenAddr,
153                  std::string listen_service = kDefaultListenService,
154                  ns_rcode error_rcode = kDefaultErrorCode,
155                  DNSResponder::MappingType mapping_type = MappingType::ADDRESS_OR_HOSTNAME);
156 
DNSResponder(ns_rcode error_rcode)157     DNSResponder(ns_rcode error_rcode)
158         : DNSResponder(kDefaultListenAddr, kDefaultListenService, error_rcode){};
159 
DNSResponder(MappingType mapping_type)160     DNSResponder(MappingType mapping_type)
161         : DNSResponder(kDefaultListenAddr, kDefaultListenService, kDefaultErrorCode,
162                        mapping_type){};
163 
164     ~DNSResponder();
165 
166     // Functions used for accessing mapping {ADDRESS_OR_HOSTNAME, DNS_HEADER, BINARY_PACKET}.
167     void addMapping(const std::string& name, ns_type type, const std::string& addr);
168     void addMappingDnsHeader(const std::string& name, ns_type type, const DNSHeader& header);
169     void addMappingBinaryPacket(const std::vector<uint8_t>& query,
170                                 const std::vector<uint8_t>& response);
171     void removeMapping(const std::string& name, ns_type type);
172     void removeMappingDnsHeader(const std::string& name, ns_type type);
173     void removeMappingBinaryPacket(const std::vector<uint8_t>& query);
174 
175     void setResponseProbability(double response_probability);
176     void setResponseProbability(double response_probability, int protocol);
177     void setResponseDelayMs(unsigned);
178     void setEdns(Edns edns);
179     void setTtl(unsigned ttl);
180     bool running() const;
181     bool startServer();
182     bool stopServer();
listen_address()183     const std::string& listen_address() const { return listen_address_; }
listen_service()184     const std::string& listen_service() const { return listen_service_; }
185     std::vector<QueryInfo> queries() const;
186     std::string dumpQueries() const;
187     void clearQueries();
getCv()188     std::condition_variable& getCv() { return cv; }
getCvMutex()189     std::mutex& getCvMutex() { return cv_mutex_; }
190     void setDeferredResp(bool deferred_resp);
191     static bool fillRdata(const std::string& rdatastr, DNSRecord& record);
192 
193     // TODO: Make DNSResponder record unknown queries in a vector for improving the debugging.
194     // Unit test could dump the unexpected query for further debug if any unexpected failure.
195 
196   private:
197     // Key used for accessing mappings.
198     struct QueryKey {
199         std::string name;
200         unsigned type;
201 
QueryKeyQueryKey202         QueryKey(std::string n, unsigned t) : name(move(n)), type(t) {}
203         bool operator==(const QueryKey& o) const { return name == o.name && type == o.type; }
204         bool operator<(const QueryKey& o) const {
205             if (name < o.name) return true;
206             if (name > o.name) return false;
207             return type < o.type;
208         }
209     };
210 
211     struct QueryKeyHash {
operatorQueryKeyHash212         size_t operator()(const QueryKey& key) const {
213             return std::hash<std::string>()(key.name) + static_cast<size_t>(key.type);
214         }
215     };
216 
217     // Used for generating combined hash value of a vector.
218     // std::hash<T> doesn't provide a specialization for std::vector<T>.
219     struct QueryKeyVectorHash {
operatorQueryKeyVectorHash220         std::size_t operator()(const std::vector<uint8_t>& v) const {
221             std::size_t combined = 0;
222             for (const uint8_t i : v) {
223                 // Hash combination comes from boost::hash_combine
224                 // See also system/extras/simpleperf/utils.h
225                 combined ^=
226                         std::hash<uint8_t>{}(i) + 0x9e3779b9 + (combined << 6) + (combined >> 2);
227             }
228             return combined;
229         }
230     };
231 
232     void requestHandler();
233 
234     // Check if any OPT Pseudo RR in the additional section.
235     bool hasOptPseudoRR(DNSHeader* header) const;
236 
237     // Parses and generates a response message for incoming DNS requests.
238     // Returns false to ignore the request, which might be due to either parsing error
239     // or unresponsiveness.
240     bool handleDNSRequest(const char* buffer, ssize_t buffer_len, int protocol, char* response,
241                           size_t* response_len) const;
242 
243     bool addAnswerRecords(const DNSQuestion& question, std::vector<DNSRecord>* answers) const;
244 
245     bool generateErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
246                                size_t* response_len) const;
247 
248     // TODO: Change writePacket, makeErrorResponse, makeTruncatedResponse and
249     // makeResponse{, FromAddressOrHostname, FromDnsHeader, FromBinaryPacket} to use C++ containers
250     // instead of the unsafe pointer + length buffer.
251     bool writePacket(const DNSHeader* header, char* response, size_t* response_len) const;
252     // Build an error response with a given rcode.
253     bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
254                            size_t* response_len) const;
255     // Build a truncated response.
256     bool makeTruncatedResponse(DNSHeader* header, char* response, size_t* response_len) const;
257     // Build a response.
258     bool makeResponse(DNSHeader* header, int protocol, char* response, size_t* response_len) const;
259     // Helper for building a response from mapping {ADDRESS_OR_HOSTNAME, DNS_HEADER, BINARY_PACKET}.
260     bool makeResponseFromAddressOrHostname(DNSHeader* header, char* response,
261                                            size_t* response_len) const;
262     bool makeResponseFromDnsHeader(DNSHeader* header, char* response, size_t* response_len) const;
263     bool makeResponseFromBinaryPacket(DNSHeader* header, char* response,
264                                       size_t* response_len) const;
265 
266     // Add a new file descriptor to be polled by the handler thread.
267     bool addFd(int fd, uint32_t events);
268 
269     // Read the query sent from the client and send the answer back to the client. It
270     // makes sure the I/O communicated with the client is correct.
271     void handleQuery(int protocol);
272 
273     // Trigger the handler thread to terminate.
274     bool sendToEventFd();
275 
276     // Used in the handler thread for the termination signal.
277     void handleEventFd();
278 
279     // TODO: Move createListeningSocket to resolv_test_utils.h
280     android::base::unique_fd createListeningSocket(int socket_type);
281 
282     double getResponseProbability(int protocol) const;
283 
284     // Address and service to listen on TCP and UDP.
285     const std::string listen_address_;
286     const std::string listen_service_;
287     // Error code to return for requests for an unknown name.
288     const ns_rcode error_rcode_;
289     // Mapping type the DNS server used to build the response.
290     const MappingType mapping_type_;
291     // Probability that a valid response on TCP is being sent instead of
292     // returning error_rcode_ or no response.
293     std::atomic<double> response_probability_tcp_ = 1.0;
294     // Probability that a valid response on UDP is being sent instead of
295     // returning error_rcode_ or no response.
296     std::atomic<double> response_probability_udp_ = 1.0;
297 
298     std::atomic<unsigned> answer_record_ttl_sec_ = kAnswerRecordTtlSec;
299 
300     std::atomic<unsigned> response_delayed_ms_ = 0;
301 
302     // Maximum number of fds for epoll.
303     const int EPOLL_MAX_EVENTS = 2;
304 
305     // Control how the DNS server behaves when it receives the requests containing OPT RR.
306     // If it's set Edns::ON, the server can recognize and reply the response; if it's set
307     // Edns::FORMERR_ON_EDNS, the server behaves like an old DNS server that doesn't support EDNS0,
308     // and replying FORMERR; if it's Edns::DROP, the server doesn't support EDNS0 either, and
309     // ignoring the requests.
310     std::atomic<Edns> edns_ = Edns::ON;
311 
312     // Mappings used for building the DNS response by registered mapping items. |mapping_type_|
313     // decides which mapping is used. See also makeResponse{, FromDnsHeader}.
314     // - mappings_: Mapping from (name, type) to (address or hostname).
315     // - dnsheader_mappings_: Mapping from (name, type) to (DNSHeader).
316     // - packet_mappings_: Mapping from (query packet) to (response packet).
317     std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_ GUARDED_BY(mappings_mutex_);
318     std::unordered_map<QueryKey, DNSHeader, QueryKeyHash> dnsheader_mappings_
319             GUARDED_BY(mappings_mutex_);
320     std::unordered_map<std::vector<uint8_t>, std::vector<uint8_t>, QueryKeyVectorHash>
321             packet_mappings_ GUARDED_BY(mappings_mutex_);
322 
323     mutable std::mutex mappings_mutex_;
324     // Query names received so far and the corresponding mutex.
325     mutable std::vector<QueryInfo> queries_ GUARDED_BY(queries_mutex_);
326     mutable std::mutex queries_mutex_;
327     // Socket on which the server is listening.
328     android::base::unique_fd udp_socket_;
329     android::base::unique_fd tcp_socket_;
330     // File descriptor for epoll.
331     android::base::unique_fd epoll_fd_;
332     // Eventfd used to signal for the handler thread termination.
333     android::base::unique_fd event_fd_;
334     // Thread for handling incoming threads.
335     std::thread handler_thread_ GUARDED_BY(update_mutex_);
336     std::mutex update_mutex_;
337     std::condition_variable cv;
338     std::mutex cv_mutex_;
339 
340     std::condition_variable cv_for_deferred_resp_;
341     std::mutex cv_mutex_for_deferred_resp_;
342     bool deferred_resp_ GUARDED_BY(cv_mutex_for_deferred_resp_) = false;
343 };
344 
345 }  // namespace test
346 
347 #endif  // DNS_RESPONDER_H
348