mdns_responder.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef SERVICES_NETWORK_MDNS_RESPONDER_H_
  5. #define SERVICES_NETWORK_MDNS_RESPONDER_H_
  6. #include <map>
  7. #include <memory>
  8. #include <set>
  9. #include <string>
  10. #include <vector>
  11. #include "base/callback.h"
  12. #include "base/containers/flat_set.h"
  13. #include "base/containers/unique_ptr_adapters.h"
  14. #include "base/memory/raw_ptr.h"
  15. #include "base/memory/weak_ptr.h"
  16. #include "base/time/default_tick_clock.h"
  17. #include "base/time/time.h"
  18. #include "mojo/public/cpp/bindings/pending_receiver.h"
  19. #include "mojo/public/cpp/bindings/receiver.h"
  20. #include "net/dns/dns_query.h"
  21. #include "net/dns/dns_response.h"
  22. #include "services/network/public/mojom/mdns_responder.mojom.h"
  23. #include "third_party/abseil-cpp/absl/types/optional.h"
  24. namespace net {
  25. class IOBufferWithSize;
  26. class IPAddress;
  27. class MDnsSocketFactory;
  28. } // namespace net
  29. namespace network {
  30. class MdnsResponder;
  31. namespace mdns_helper {
  32. // Creates an mDNS response, of which the Answer section contains the address
  33. // records for |name_addr_map|, and the Additional section contains the
  34. // corresponding NSEC records that assert the existence of only address
  35. // records in the Answer section.
  36. COMPONENT_EXPORT(NETWORK_SERVICE)
  37. scoped_refptr<net::IOBufferWithSize> CreateResolutionResponse(
  38. const base::TimeDelta& ttl,
  39. const std::map<std::string, net::IPAddress>& name_addr_map);
  40. // Creates an mDNS response, of which the Answer section contains NSEC records
  41. // that assert the existence of only address records for |name_addr_map|, and
  42. // the Additional section contains the corresponding address records.
  43. COMPONENT_EXPORT(NETWORK_SERVICE)
  44. scoped_refptr<net::IOBufferWithSize> CreateNegativeResponse(
  45. const std::map<std::string, net::IPAddress>& name_addr_map);
  46. // Creates an mDNS response to an mDNS name generator service query.
  47. //
  48. // An mDNS name generator service query is a query for TXT records associated
  49. // with the name "Generated-Names._mdns_name_generator._udp.local". It is
  50. // similar to the service query defined in DNS-SD but is not an implementation
  51. // of the specification in RFC 6763. The Answer section of the response contains
  52. // a TXT record for the list of |mdns_names|. The cache-flush bit is set in the
  53. // TXT record if |cached_flush| is true.
  54. COMPONENT_EXPORT(NETWORK_SERVICE)
  55. scoped_refptr<net::IOBufferWithSize>
  56. CreateResponseToMdnsNameGeneratorServiceQuery(
  57. const base::TimeDelta& ttl,
  58. const std::set<std::string>& mdns_names);
  59. } // namespace mdns_helper
  60. // Options to configure the transmission of mDNS responses.
  61. struct COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponseSendOption
  62. : public base::RefCounted<MdnsResponseSendOption> {
  63. public:
  64. enum class ResponseClass {
  65. UNSPECIFIED,
  66. ANNOUNCEMENT,
  67. PROBE_RESOLUTION,
  68. REGULAR_RESOLUTION,
  69. NEGATIVE,
  70. GOODBYE,
  71. };
  72. MdnsResponseSendOption();
  73. // As a shorthand, an empty set denotes all interfaces.
  74. std::set<uint16_t> send_socket_handler_ids;
  75. // Used for rate limiting.
  76. base::flat_set<std::string> names_for_rate_limit;
  77. // Used for retry after send failure.
  78. ResponseClass klass = ResponseClass::UNSPECIFIED;
  79. // The number of retries done for the same response due to send failure.
  80. uint8_t num_send_retries_done = 0;
  81. // Indicates if the response includes a resource record that is a member of a
  82. // shared resource record set.
  83. bool shared_result = false;
  84. // If not nullopt, returns true if the response to send is cancelled.
  85. absl::optional<base::RepeatingCallback<bool()>> cancelled_callback;
  86. private:
  87. friend class base::RefCounted<MdnsResponseSendOption>;
  88. ~MdnsResponseSendOption();
  89. };
  90. // The responder manager creates and manages responder instances spawned for
  91. // each Mojo binding. It also manages the underlying network IO by delegating
  92. // the IO task to socket handlers of each interface. When there is a network
  93. // stack error or a Mojo binding error, the manager also offers the
  94. // corresponding error handling.
  95. class COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponderManager {
  96. public:
  97. // Wraps a name generation method that can be configured in tests via
  98. // SetNameGeneratorForTesting below.
  99. //
  100. // The generated name by |CreateName| must be no more than 245 characters.
  101. class NameGenerator {
  102. public:
  103. virtual ~NameGenerator() = default;
  104. virtual std::string CreateName() = 0;
  105. };
  106. // Used in histograms to measure the service health.
  107. enum class ServiceError {
  108. // Fail to start the MdnsResponderManager after all socket handlers fail to
  109. // start on each interface.
  110. kFailToStartManager = 0,
  111. // Fail to create a MdnsResponder after all socket handlers fail to start on
  112. // each interface.
  113. kFailToCreateResponder = 1,
  114. // All socket handlers have encountered read errors and failed. Imminent to
  115. // restart the MdnsResponderManager.
  116. kFatalSocketHandlerError = 2,
  117. // An invalid IP address is given to register an mDNS name for.
  118. kInvalidIpToRegisterName = 3,
  119. // A record is received from the network such that it resolves a name
  120. // created
  121. // by the service to a different address.
  122. kConflictingNameResolution = 4,
  123. kMaxValue = kConflictingNameResolution,
  124. };
  125. // Delay between throttled attempts to start the `MdnsResponderManager`.
  126. constexpr static base::TimeDelta kManagerStartThrottleDelay =
  127. base::Seconds(1);
  128. MdnsResponderManager();
  129. explicit MdnsResponderManager(net::MDnsSocketFactory* socket_factory);
  130. MdnsResponderManager(const MdnsResponderManager&) = delete;
  131. MdnsResponderManager& operator=(const MdnsResponderManager&) = delete;
  132. ~MdnsResponderManager();
  133. // Creates an instance of MdnsResponder for the receiver.
  134. void CreateMdnsResponder(
  135. mojo::PendingReceiver<mojom::MdnsResponder> receiver);
  136. // The methods below are used to bookkeep names owned by responders, and
  137. // also for the extra uniqueness validation of these names. By default,
  138. // we use the RandomUuidNameGenerator (see mdns_responder.cc), which
  139. // probabilistically guarantees the uniqueness of generated names.
  140. //
  141. // Adds a name to the set of all existing names generated by all responders
  142. // (i.e., names owned by an instance of responder). Return true if the name is
  143. // not in the set before the addition; false otherwise.
  144. bool AddName(const std::string& name) {
  145. auto result = names_.insert(name);
  146. return result.second;
  147. }
  148. // Removes a name from the set of all existing names generated by all
  149. // responders. Return true if the name exists in the set before the removal;
  150. // false otherwise.
  151. bool RemoveName(const std::string& name) { return names_.erase(name) == 1; }
  152. // Sends an mDNS response in the wire format given by |buf|. See
  153. // MdnsResponseSendOption for configurable options in |option|.
  154. //
  155. // Sending responses is rate-limited, and this method returns true if the
  156. // response is successfully scheduled to send on all successfully bound
  157. // interfaces specified in |option.send_socket_handler_ids|, and false
  158. // otherwise.
  159. bool Send(scoped_refptr<net::IOBufferWithSize> buf,
  160. scoped_refptr<MdnsResponseSendOption> option);
  161. // The error handler that is invoked when the Mojo binding of |responder| is
  162. // closed (e.g. the InterfacePtr on the client side is destroyed) or
  163. // encounters an error. It removes this responder instance, which further
  164. // clears the existing name-address associations owned by this responder in
  165. // the local network.
  166. void OnMojoConnectionError(MdnsResponder* responder);
  167. // Called when an external mDNS response is received and it contains address
  168. // records of names generated by an owned MdnsResponder instance.
  169. void HandleAddressNameConflictIfAny(
  170. const std::map<std::string, std::set<net::IPAddress>>&
  171. external_address_maps);
  172. // Called when an external mDNS response is received and it contains a TXT
  173. // record for the mDNS name generator service instance name with the
  174. // cache-flush bit set.
  175. void HandleTxtNameConflict();
  176. NameGenerator* name_generator() const { return name_generator_.get(); }
  177. // Sets the name generator that is shared by all MdnsResponder instances.
  178. // Changing the name generator affects all existing responder instances and
  179. // also the ones spawned in the future.
  180. //
  181. // Used for tests only.
  182. void SetNameGeneratorForTesting(
  183. std::unique_ptr<NameGenerator> name_generator);
  184. // Sets the tick clock that is used for rate limiting of mDNS responses, and
  185. // also resets the internal schedule for rate limiting.
  186. //
  187. // Used for tests only.
  188. void SetTickClockForTesting(const base::TickClock* tick_clock);
  189. private:
  190. enum class SocketHandlerStartResult {
  191. UNSPECIFIED,
  192. // Handlers started for all interfaces.
  193. ALL_SUCCESS,
  194. // Handlers started for a subset of interfaces.
  195. PARTIAL_SUCCESS,
  196. // No handler started.
  197. ALL_FAILURE,
  198. };
  199. // Handles the underlying sending and receiving of mDNS messages on each
  200. // interface available. The implementation mostly resembles
  201. // net::MdnsConnection::SocketHandler.
  202. class SocketHandler;
  203. // Initializes socket handlers and sets `start_result_`. Safe to call multiple
  204. // times after success or failure (and will noop after success). As a
  205. // protection against spammy network usage this will also noop if called too
  206. // soon after the last failure.
  207. void StartIfNeeded();
  208. // Dispatches a parsed query from a socket handler to each responder instance.
  209. void OnMdnsQueryReceived(const net::DnsQuery& query,
  210. uint16_t recv_socket_handler_id);
  211. void OnSocketHandlerReadError(uint16_t socket_handler_id, int result);
  212. bool IsFatalError(int result);
  213. // Called when an mDNS name service query is received. The manager fills a
  214. // list of registered names in a TXT record in the response.
  215. void HandleMdnsNameGeneratorServiceQuery(const net::DnsQuery& query,
  216. uint16_t recv_socket_handler_id);
  217. // Sends a zero-TTL mDNS response with a TXT record of mDNS names from the
  218. // last generator service response sent. No-op if no generator service
  219. // response sent previously.
  220. void SendGoodbyePacketForMdnsNameGeneratorServiceIfNecessary();
  221. std::unique_ptr<net::MDnsSocketFactory> owned_socket_factory_;
  222. raw_ptr<net::MDnsSocketFactory> socket_factory_;
  223. // Only the socket handlers that have successfully bound and started are kept.
  224. std::map<uint16_t, std::unique_ptr<SocketHandler>> socket_handler_by_id_;
  225. SocketHandlerStartResult start_result_ =
  226. SocketHandlerStartResult::UNSPECIFIED;
  227. // Used to bookkeep all names owned by |responders_| for
  228. // 1. the extra uniqueness validation of names generated by responders;
  229. // 2. generating responses to the mDNS name generator service queries.
  230. std::set<std::string> names_;
  231. std::unique_ptr<NameGenerator> name_generator_;
  232. // The names used to create the last response to a generator service query.
  233. std::set<std::string> names_in_last_generator_response_;
  234. bool should_respond_to_generator_service_query_ = true;
  235. std::set<std::unique_ptr<MdnsResponder>, base::UniquePtrComparator>
  236. responders_;
  237. raw_ptr<const base::TickClock> tick_clock_ =
  238. base::DefaultTickClock::GetInstance();
  239. // If not `base::TimeTicks()`, represents the end of the throttling period for
  240. // calls to `StartIfNeeded()`.
  241. base::TimeTicks throttled_start_end_;
  242. base::WeakPtrFactory<MdnsResponderManager> weak_factory_{this};
  243. };
  244. // Implementation of the mDNS service that can provide utilities of an mDNS
  245. // responder.
  246. class COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponder
  247. : public mojom::MdnsResponder {
  248. public:
  249. MdnsResponder(mojo::PendingReceiver<mojom::MdnsResponder> receiver,
  250. MdnsResponderManager* manager);
  251. MdnsResponder(const MdnsResponder&) = delete;
  252. MdnsResponder& operator=(const MdnsResponder&) = delete;
  253. // When destroyed, clears all existing name-address associations owned by this
  254. // responder in the local network by sending out goodbye packets. See
  255. // SendGoodbyePacketForNameAddressMap below.
  256. ~MdnsResponder() override;
  257. // mojom::MdnsResponder overrides.
  258. void CreateNameForAddress(
  259. const net::IPAddress& address,
  260. mojom::MdnsResponder::CreateNameForAddressCallback callback) override;
  261. void RemoveNameForAddress(
  262. const net::IPAddress& address,
  263. mojom::MdnsResponder::RemoveNameForAddressCallback callback) override;
  264. // Processes the given query and generates a response if the query contains an
  265. // mDNS name that this responder has a mapped IP address.
  266. void OnMdnsQueryReceived(const net::DnsQuery& query,
  267. uint16_t recv_socket_handler_id);
  268. bool HasConflictWithExternalResolution(
  269. const std::string& name,
  270. const std::set<net::IPAddress>& external_mapped_addreses);
  271. void SetNameGeneratorForTesting(
  272. MdnsResponderManager::NameGenerator* name_generator) {
  273. name_generator_ = name_generator;
  274. }
  275. private:
  276. // Returns true if the response is successfully scheduled to send on all
  277. // successfully bound interfaces after rate limiting, and false otherwise. See
  278. // also MdnsResponderManager::Send.
  279. bool SendMdnsResponse(scoped_refptr<net::IOBufferWithSize> response,
  280. scoped_refptr<MdnsResponseSendOption> option);
  281. // RFC 6761, Section 10.1 "Goodbye Packets".
  282. //
  283. // The responder should send out an unsolicited mDNS response with an resource
  284. // record of zero TTL to clear the name-to-address mapping in neighboring
  285. // hosts, when the mapping is no longer valid.
  286. //
  287. // Returns true if the goodbye message is successfully scheduled to send on
  288. // all interfaces after rate limiting, and false otherwise. See also
  289. // MdnsResponderManager::Send.
  290. bool SendGoodbyePacketForNameAddressMap(
  291. const std::map<std::string, net::IPAddress>& name_addr_map);
  292. std::map<std::string, net::IPAddress>::iterator FindNameCreatedForAddress(
  293. const net::IPAddress& address);
  294. mojo::Receiver<network::mojom::MdnsResponder> receiver_;
  295. // A back pointer to the responder manager that owns this responder. The
  296. // responder should be destroyed before |manager_| becomes invalid or a weak
  297. // reference should be used to access the manager when there is no such
  298. // guarantee in an operation.
  299. const raw_ptr<MdnsResponderManager> manager_;
  300. std::map<std::string, net::IPAddress> name_addr_map_;
  301. std::map<std::string, uint16_t> name_refcount_map_;
  302. raw_ptr<MdnsResponderManager::NameGenerator> name_generator_;
  303. };
  304. } // namespace network
  305. #endif // SERVICES_NETWORK_MDNS_RESPONDER_H_