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 requied 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 namespace test { 35 36 struct DNSHeader; 37 struct DNSQuestion; 38 struct DNSRecord; 39 40 inline const std::string kDefaultListenAddr = "127.0.0.3"; 41 inline const std::string kDefaultListenService = "53"; 42 inline const int kDefaultPollTimoutMillis = -1; 43 44 /* 45 * Simple DNS responder, which replies to queries with the registered response 46 * for that type. Class is assumed to be IN. If no response is registered, the 47 * default error response code is returned. 48 */ 49 class DNSResponder { 50 public: 51 DNSResponder(std::string listen_address = kDefaultListenAddr, 52 std::string listen_service = kDefaultListenService, 53 int poll_timeout_ms = kDefaultPollTimoutMillis, 54 ns_rcode error_rcode = ns_rcode::ns_r_servfail); 55 ~DNSResponder(); 56 57 enum class Edns : uint8_t { 58 ON, 59 FORMERR_ON_EDNS, // DNS server not supporting EDNS will reply FORMERR. 60 FORMERR_UNCOND, // DNS server reply FORMERR unconditionally 61 DROP // DNS server not supporting EDNS will not do any response. 62 }; 63 64 void addMapping(const std::string& name, ns_type type, const std::string& addr); 65 void removeMapping(const std::string& name, ns_type type); 66 void setResponseProbability(double response_probability); 67 void setEdns(Edns edns); 68 bool running() const; 69 bool startServer(); 70 bool stopServer(); listen_address()71 const std::string& listen_address() const { 72 return listen_address_; 73 } listen_service()74 const std::string& listen_service() const { 75 return listen_service_; 76 } 77 std::vector<std::pair<std::string, ns_type>> queries() const; 78 std::string dumpQueries() const; 79 void clearQueries(); getCv()80 std::condition_variable& getCv() { return cv; } getCvMutex()81 std::mutex& getCvMutex() { return cv_mutex_; } 82 void setDeferredResp(bool deferred_resp); 83 84 private: 85 // Key used for accessing mappings. 86 struct QueryKey { 87 std::string name; 88 unsigned type; 89 QueryKeyQueryKey90 QueryKey(std::string n, unsigned t) : name(move(n)), type(t) {} 91 bool operator == (const QueryKey& o) const { 92 return name == o.name && type == o.type; 93 } 94 bool operator < (const QueryKey& o) const { 95 if (name < o.name) return true; 96 if (name > o.name) return false; 97 return type < o.type; 98 } 99 }; 100 101 struct QueryKeyHash { operatorQueryKeyHash102 size_t operator() (const QueryKey& key) const { 103 return std::hash<std::string>()(key.name) + 104 static_cast<size_t>(key.type); 105 } 106 }; 107 108 void requestHandler(); 109 110 // Parses and generates a response message for incoming DNS requests. 111 // Returns false to ignore the request, which might be due to either parsing error 112 // or unresponsiveness. 113 bool handleDNSRequest(const char* buffer, ssize_t buffer_len, 114 char* response, size_t* response_len) const; 115 116 bool addAnswerRecords(const DNSQuestion& question, std::vector<DNSRecord>* answers) const; 117 118 bool fillAnswerRdata(const std::string& rdatastr, DNSRecord& record) const; 119 120 bool generateErrorResponse(DNSHeader* header, ns_rcode rcode, 121 char* response, size_t* response_len) const; 122 bool makeErrorResponse(DNSHeader* header, ns_rcode rcode, char* response, 123 size_t* response_len) const; 124 125 // Add a new file descriptor to be polled by the handler thread. 126 bool addFd(int fd, uint32_t events); 127 128 // Read the query sent from the client and send the answer back to the client. It 129 // makes sure the I/O communicated with the client is correct. 130 void handleQuery(); 131 132 // Trigger the handler thread to terminate. 133 bool sendToEventFd(); 134 135 // Used in the handler thread for the termination signal. 136 void handleEventFd(); 137 138 // Address and service to listen on, currently limited to UDP. 139 const std::string listen_address_; 140 const std::string listen_service_; 141 // epoll_wait() timeout in ms. 142 const int poll_timeout_ms_; 143 // Error code to return for requests for an unknown name. 144 const ns_rcode error_rcode_; 145 // Probability that a valid response is being sent instead of being sent 146 // instead of returning error_rcode_. 147 std::atomic<double> response_probability_ = 1.0; 148 // Maximum number of fds for epoll. 149 const int EPOLL_MAX_EVENTS = 2; 150 151 // Control how the DNS server behaves when it receives the requests containing OPT RR. 152 // If it's set Edns::ON, the server can recognize and reply the response; if it's set 153 // Edns::FORMERR_ON_EDNS, the server behaves like an old DNS server that doesn't support EDNS0, 154 // and replying FORMERR; if it's Edns::DROP, the server doesn't support EDNS0 either, and 155 // ignoring the requests. 156 std::atomic<Edns> edns_ = Edns::ON; 157 158 // Mappings from (name, type) to registered response and the 159 // mutex protecting them. 160 std::unordered_map<QueryKey, std::string, QueryKeyHash> mappings_ 161 GUARDED_BY(mappings_mutex_); 162 mutable std::mutex mappings_mutex_; 163 // Query names received so far and the corresponding mutex. 164 mutable std::vector<std::pair<std::string, ns_type>> queries_ 165 GUARDED_BY(queries_mutex_); 166 mutable std::mutex queries_mutex_; 167 // Socket on which the server is listening. 168 android::base::unique_fd socket_; 169 // File descriptor for epoll. 170 android::base::unique_fd epoll_fd_; 171 // Eventfd used to signal for the handler thread termination. 172 android::base::unique_fd event_fd_; 173 // Thread for handling incoming threads. 174 std::thread handler_thread_ GUARDED_BY(update_mutex_); 175 std::mutex update_mutex_; 176 std::condition_variable cv; 177 std::mutex cv_mutex_; 178 179 std::condition_variable cv_for_deferred_resp_; 180 std::mutex cv_mutex_for_deferred_resp_; 181 bool deferred_resp_ GUARDED_BY(cv_mutex_for_deferred_resp_) = false; 182 }; 183 184 } // namespace test 185 186 #endif // DNS_RESPONDER_H 187