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);
setErrorRcode(ns_rcode error_rcode)178     void setErrorRcode(ns_rcode error_rcode) { error_rcode_ = error_rcode; }
179     void setEdns(Edns edns);
180     void setTtl(unsigned ttl);
181     bool running() const;
182     bool startServer();
183     bool stopServer();
listen_address()184     const std::string& listen_address() const { return listen_address_; }
listen_service()185     const std::string& listen_service() const { return listen_service_; }
186     std::vector<QueryInfo> queries() const;
187     std::string dumpQueries() const;
188     void clearQueries();
getCv()189     std::condition_variable& getCv() { return cv; }
getCvMutex()190     std::mutex& getCvMutex() { return cv_mutex_; }
191     void setDeferredResp(bool deferred_resp);
192     static bool fillRdata(const std::string& rdatastr, DNSRecord& record);
193 
194     // These functions are helpers for binding the listening sockets to a specific network, which
195     // is necessary only for multinetwork tests. Since binding sockets to a network requires
196     // the dependency of libnetd_client, and DNSResponder is also widely used in other tests like
197     // resolv_unit_test which doesn't need that dependency, so expose the socket fds to let the
198     // callers perform binding operations by themselves. Callers MUST not close the fds.
setNetwork(unsigned netId)199     void setNetwork(unsigned netId) { mNetId = netId; }
getNetwork()200     std::optional<unsigned> getNetwork() const { return mNetId; }
getUdpSocket()201     int getUdpSocket() const { return udp_socket_.get(); }
getTcpSocket()202     int getTcpSocket() const { return tcp_socket_.get(); }
203 
204     // TODO: Make DNSResponder record unknown queries in a vector for improving the debugging.
205     // Unit test could dump the unexpected query for further debug if any unexpected failure.
206 
207   private:
208     // Key used for accessing mappings.
209     struct QueryKey {
210         std::string name;
211         unsigned type;
212 
QueryKeyQueryKey213         QueryKey(std::string n, unsigned t) : name(move(n)), type(t) {}
214         bool operator==(const QueryKey& o) const { return name == o.name && type == o.type; }
215         bool operator<(const QueryKey& o) const {
216             if (name < o.name) return true;
217             if (name > o.name) return false;
218             return type < o.type;
219         }
220     };
221 
222     struct QueryKeyHash {
operatorQueryKeyHash223         size_t operator()(const QueryKey& key) const {
224             return std::hash<std::string>()(key.name) + static_cast<size_t>(key.type);
225         }
226     };
227 
228     // Used for generating combined hash value of a vector.
229     // std::hash<T> doesn't provide a specialization for std::vector<T>.
230     struct QueryKeyVectorHash {
operatorQueryKeyVectorHash231         std::size_t operator()(const std::vector<uint8_t>& v) const {
232             std::size_t combined = 0;
233             for (const uint8_t i : v) {
234                 // Hash combination comes from boost::hash_combine
235                 // See also system/extras/simpleperf/utils.h
236                 combined ^=
237                         std::hash<uint8_t>{}(i) + 0x9e3779b9 + (combined << 6) + (combined >> 2);
238             }
239             return combined;
240         }
241     };
242 
243     void requestHandler();
244 
245     // Check if any OPT Pseudo RR in the additional section.
246     bool hasOptPseudoRR(DNSHeader* header) const;
247 
248     // Parses and generates a response message for incoming DNS requests.
249     // Returns false to ignore the request, which might be due to either parsing error
250     // or unresponsiveness.
251     bool handleDNSRequest(const char* buffer, ssize_t buffer_len, int protocol, char* response,
252                           size_t* response_len) const;
253 
254     bool addAnswerRecords(const DNSQuestion& question, std::vector<DNSRecord>* answers) const;
255 
256     bool generateErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
257                                size_t* response_len) const;
258 
259     // TODO: Change writePacket, makeErrorResponse, makeTruncatedResponse and
260     // makeResponse{, FromAddressOrHostname, FromDnsHeader, FromBinaryPacket} to use C++ containers
261     // instead of the unsafe pointer + length buffer.
262     bool writePacket(const DNSHeader* header, char* response, size_t* response_len) const;
263     // Build an error response with a given rcode.
264     bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response,
265                            size_t* response_len) const;
266     // Build a truncated response.
267     bool makeTruncatedResponse(DNSHeader* header, char* response, size_t* response_len) const;
268     // Build a response.
269     bool makeResponse(DNSHeader* header, int protocol, char* response, size_t* response_len) const;
270     // Helper for building a response from mapping {ADDRESS_OR_HOSTNAME, DNS_HEADER, BINARY_PACKET}.
271     bool makeResponseFromAddressOrHostname(DNSHeader* header, char* response,
272                                            size_t* response_len) const;
273     bool makeResponseFromDnsHeader(DNSHeader* header, char* response, size_t* response_len) const;
274     bool makeResponseFromBinaryPacket(DNSHeader* header, char* response,
275                                       size_t* response_len) const;
276 
277     // Add a new file descriptor to be polled by the handler thread.
278     bool addFd(int fd, uint32_t events);
279 
280     // Read the query sent from the client and send the answer back to the client. It
281     // makes sure the I/O communicated with the client is correct.
282     void handleQuery(int protocol);
283 
284     // Trigger the handler thread to terminate.
285     bool sendToEventFd();
286 
287     // Used in the handler thread for the termination signal.
288     void handleEventFd();
289 
290     // TODO: Move createListeningSocket to resolv_test_utils.h
291     android::base::unique_fd createListeningSocket(int socket_type);
292 
293     double getResponseProbability(int protocol) const;
294 
295     // Address and service to listen on TCP and UDP.
296     const std::string listen_address_;
297     const std::string listen_service_;
298 
299     // TODO: Consider refactoring atomic members of this class to a single big mutex.
300     // Error code to return for requests for an unknown name.
301     ns_rcode error_rcode_;
302     // Mapping type the DNS server used to build the response.
303     const MappingType mapping_type_;
304     // Probability that a valid response on TCP is being sent instead of
305     // returning error_rcode_ or no response.
306     std::atomic<double> response_probability_tcp_ = 1.0;
307     // Probability that a valid response on UDP is being sent instead of
308     // returning error_rcode_ or no response.
309     std::atomic<double> response_probability_udp_ = 1.0;
310 
311     std::atomic<unsigned> answer_record_ttl_sec_ = kAnswerRecordTtlSec;
312 
313     std::atomic<unsigned> response_delayed_ms_ = 0;
314 
315     // Maximum number of fds for epoll.
316     const int EPOLL_MAX_EVENTS = 2;
317 
318     // Control how the DNS server behaves when it receives the requests containing OPT RR.
319     // If it's set Edns::ON, the server can recognize and reply the response; if it's set
320     // Edns::FORMERR_ON_EDNS, the server behaves like an old DNS server that doesn't support EDNS0,
321     // and replying FORMERR; if it's Edns::DROP, the server doesn't support EDNS0 either, and
322     // ignoring the requests.
323     std::atomic<Edns> edns_ = Edns::ON;
324 
325     // Mappings used for building the DNS response by registered mapping items. |mapping_type_|
326     // decides which mapping is used. See also makeResponse{, FromDnsHeader}.
327     // - mappings_: Mapping from (name, type) to (address or hostname).
328     // - dnsheader_mappings_: Mapping from (name, type) to (DNSHeader).
329     // - packet_mappings_: Mapping from (query packet) to (response packet).
330     std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_ GUARDED_BY(mappings_mutex_);
331     std::unordered_map<QueryKey, DNSHeader, QueryKeyHash> dnsheader_mappings_
332             GUARDED_BY(mappings_mutex_);
333     std::unordered_map<std::vector<uint8_t>, std::vector<uint8_t>, QueryKeyVectorHash>
334             packet_mappings_ GUARDED_BY(mappings_mutex_);
335 
336     mutable std::mutex mappings_mutex_;
337     // Query names received so far and the corresponding mutex.
338     mutable std::vector<QueryInfo> queries_ GUARDED_BY(queries_mutex_);
339     mutable std::mutex queries_mutex_;
340     // Socket on which the server is listening.
341     android::base::unique_fd udp_socket_;
342     android::base::unique_fd tcp_socket_;
343     // File descriptor for epoll.
344     android::base::unique_fd epoll_fd_;
345     // Eventfd used to signal for the handler thread termination.
346     android::base::unique_fd event_fd_;
347     // Thread for handling incoming threads.
348     std::thread handler_thread_ GUARDED_BY(update_mutex_);
349     std::mutex update_mutex_;
350     std::condition_variable cv;
351     std::mutex cv_mutex_;
352 
353     std::condition_variable cv_for_deferred_resp_;
354     std::mutex cv_mutex_for_deferred_resp_;
355     bool deferred_resp_ GUARDED_BY(cv_mutex_for_deferred_resp_) = false;
356 
357     // The network to which the listening sockets will be bound.
358     std::optional<unsigned> mNetId;
359 };
360 
361 }  // namespace test
362 
363 #endif  // DNS_RESPONDER_H
364