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