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