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