// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SERVICES_NETWORK_MDNS_RESPONDER_H_
#define SERVICES_NETWORK_MDNS_RESPONDER_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "net/dns/dns_query.h"
#include "net/dns/dns_response.h"
#include "services/network/public/mojom/mdns_responder.mojom.h"

namespace base {
class TickClock;
}  // namespace base

namespace net {
class IOBufferWithSize;
class IPAddress;
class MDnsSocketFactory;
}  // namespace net

namespace network {

class MdnsResponder;

namespace mdns_helper {

// Creates an mDNS response, of which the Answer section contains the address
// records for |name_addr_map|, and the Additional section contains the
// corresponding NSEC records that assert the existence of only address
// records in the Answer section.
COMPONENT_EXPORT(NETWORK_SERVICE)
scoped_refptr<net::IOBufferWithSize> CreateResolutionResponse(
    const base::TimeDelta& ttl,
    const std::map<std::string, net::IPAddress>& name_addr_map);
// Creates an mDNS response, of which the Answer section contains NSEC records
// that assert the existence of only address records for |name_addr_map|, and
// the Additional section contains the corresponding address records.
COMPONENT_EXPORT(NETWORK_SERVICE)
scoped_refptr<net::IOBufferWithSize> CreateNegativeResponse(
    const std::map<std::string, net::IPAddress>& name_addr_map);
// Creates an mDNS response to an mDNS name generator service query.
//
// An mDNS name generator service query is a query for TXT records associated
// with the name "Generated-Names._mdns_name_generator._udp.local". It is
// similar to the service query defined in DNS-SD but is not an implementation
// of the specification in RFC 6763. The Answer section of the response contains
// a TXT record for the list of |mdns_names|. The cache-flush bit is set in the
// TXT record if |cached_flush| is true.
COMPONENT_EXPORT(NETWORK_SERVICE)
scoped_refptr<net::IOBufferWithSize>
CreateResponseToMdnsNameGeneratorServiceQuery(
    const base::TimeDelta& ttl,
    const std::set<std::string>& mdns_names);

}  // namespace mdns_helper

// Options to configure the transmission of mDNS responses.
struct COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponseSendOption
    : public base::RefCounted<MdnsResponseSendOption> {
 public:
  enum class ResponseClass {
    UNSPECIFIED,
    ANNOUNCEMENT,
    PROBE_RESOLUTION,
    REGULAR_RESOLUTION,
    NEGATIVE,
    GOODBYE,
  };

  MdnsResponseSendOption();
  // As a shorthand, an empty set denotes all interfaces.
  std::set<uint16_t> send_socket_handler_ids;
  // Used for rate limiting.
  base::flat_set<std::string> names_for_rate_limit;
  // Used for retry after send failure.
  ResponseClass klass = ResponseClass::UNSPECIFIED;
  // The number of retries done for the same response due to send failure.
  uint8_t num_send_retries_done = 0;
  // Indicates if the response includes a resource record that is a member of a
  // shared resource record set.
  bool shared_result = false;
  // If not nullopt, returns true if the response to send is cancelled.
  base::Optional<base::RepeatingCallback<bool()>> cancelled_callback;

 private:
  friend class RefCounted<MdnsResponseSendOption>;

  ~MdnsResponseSendOption();
};

// The responder manager creates and manages responder instances spawned for
// each Mojo binding. It also manages the underlying network IO by delegating
// the IO task to socket handlers of each interface. When there is a network
// stack error or a Mojo binding error, the manager also offers the
// corresponding error handling.
class COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponderManager {
 public:
  // Wraps a name generation method that can be configured in tests via
  // SetNameGeneratorForTesting below.
  //
  // The generated name by |CreateName| must be no more than 245 characters.
  class NameGenerator {
   public:
    virtual ~NameGenerator() = default;
    virtual std::string CreateName() = 0;
  };

  // Used in histograms to measure the service health.
  enum class ServiceError {
    // Fail to start the MdnsResponderManager after all socket handlers fail to
    // start on each interface.
    kFailToStartManager = 0,
    // Fail to create a MdnsResponder after all socket handlers fail to start on
    // each interface.
    kFailToCreateResponder = 1,
    // All socket handlers have encountered read errors and failed. Imminent to
    // restart the MdnsResponderManager.
    kFatalSocketHandlerError = 2,
    // An invalid IP address is given to register an mDNS name for.
    kInvalidIpToRegisterName = 3,
    // A record is received from the network such that it resolves a name
    // created
    // by the service to a different address.
    kConflictingNameResolution = 4,

    kMaxValue = kConflictingNameResolution,
  };

  MdnsResponderManager();
  explicit MdnsResponderManager(net::MDnsSocketFactory* socket_factory);
  ~MdnsResponderManager();

  // Creates an instance of MdnsResponder for the binding request from an
  // InterfacePtr.
  void CreateMdnsResponder(mojom::MdnsResponderRequest request);
  // The methods below are used to bookkeep names owned by responders, and
  // also for the extra uniqueness validation of these names. By default,
  // we use the RandomUuidNameGenerator (see mdns_responder.cc), which
  // probabilistically guarantees the uniqueness of generated names.
  //
  // Adds a name to the set of all existing names generated by all responders
  // (i.e., names owned by an instance of responder). Return true if the name is
  // not in the set before the addition; false otherwise.
  bool AddName(const std::string& name) {
    auto result = names_.insert(name);
    return result.second;
  }
  // Removes a name from the set of all existing names generated by all
  // responders. Return true if the name exists in the set before the removal;
  // false otherwise.
  bool RemoveName(const std::string& name) { return names_.erase(name) == 1; }
  // Sends an mDNS response in the wire format given by |buf|. See
  // MdnsResponseSendOption for configurable options in |option|.
  //
  // Sending responses is rate-limited, and this method returns true if the
  // response is successfully scheduled to send on all successfully bound
  // interfaces specified in |option.send_socket_handler_ids|, and false
  // otherwise.
  bool Send(scoped_refptr<net::IOBufferWithSize> buf,
            scoped_refptr<MdnsResponseSendOption> option);
  // The error handler that is invoked when the Mojo binding of |responder| is
  // closed (e.g. the InterfacePtr on the client side is destroyed) or
  // encounters an error. It removes this responder instance, which further
  // clears the existing name-address associations owned by this responder in
  // the local network.
  void OnMojoConnectionError(MdnsResponder* responder);

  // Called when an external mDNS response is received and it contains address
  // records of names generated by an owned MdnsResponder instance.
  void HandleAddressNameConflictIfAny(
      const std::map<std::string, std::set<net::IPAddress>>&
          external_address_maps);
  // Called when an external mDNS response is received and it contains a TXT
  // record for the mDNS name generator service instance name with the
  // cache-flush bit set.
  void HandleTxtNameConflict();

  NameGenerator* name_generator() const { return name_generator_.get(); }
  // Sets the name generator that is shared by all MdnsResponder instances.
  // Changing the name generator affects all existing responder instances and
  // also the ones spawned in the future.
  //
  // Used for tests only.
  void SetNameGeneratorForTesting(
      std::unique_ptr<NameGenerator> name_generator);

  // Sets the tick clock that is used for rate limiting of mDNS responses, and
  // also resets the internal schedule for rate limiting.
  //
  // Used for tests only.
  void SetTickClockForTesting(const base::TickClock* tick_clock);

 private:
  enum class SocketHandlerStartResult {
    UNSPECIFIED,
    // Handlers started for all interfaces.
    ALL_SUCCESS,
    // Handlers started for a subset of interfaces.
    PARTIAL_SUCCESS,
    // No handler started.
    ALL_FAILURE,
  };
  // Handles the underlying sending and receiving of mDNS messages on each
  // interface available. The implementation mostly resembles
  // net::MdnsConnection::SocketHandler.
  class SocketHandler;

  // Initializes socket handlers and sets |start_result_|;
  void Start();
  // Dispatches a parsed query from a socket handler to each responder instance.
  void OnMdnsQueryReceived(const net::DnsQuery& query,
                           uint16_t recv_socket_handler_id);
  void OnSocketHandlerReadError(uint16_t socket_handler_id, int result);
  bool IsFatalError(int result);
  // Called when an mDNS name service query is received. The manager fills a
  // list of registered names in a TXT record in the response.
  void HandleMdnsNameGeneratorServiceQuery(const net::DnsQuery& query,
                                           uint16_t recv_socket_handler_id);
  // Sends a zero-TTL mDNS response with a TXT record of mDNS names from the
  // last generator service response sent. No-op if no generator service
  // response sent previously.
  void SendGoodbyePacketForMdnsNameGeneratorServiceIfNecessary();

  std::unique_ptr<net::MDnsSocketFactory> owned_socket_factory_;
  net::MDnsSocketFactory* socket_factory_;
  // Only the socket handlers that have successfully bound and started are kept.
  std::map<uint16_t, std::unique_ptr<SocketHandler>> socket_handler_by_id_;
  SocketHandlerStartResult start_result_ =
      SocketHandlerStartResult::UNSPECIFIED;
  // Used to bookkeep all names owned by |responders_| for
  // 1. the extra uniqueness validation of names generated by responders;
  // 2. generating responses to the mDNS name generator service queries.
  std::set<std::string> names_;
  std::unique_ptr<NameGenerator> name_generator_;
  // The names used to create the last response to a generator service query.
  std::set<std::string> names_in_last_generator_response_;
  bool should_respond_to_generator_service_query_ = true;

  std::set<std::unique_ptr<MdnsResponder>, base::UniquePtrComparator>
      responders_;

  base::WeakPtrFactory<MdnsResponderManager> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(MdnsResponderManager);
};

// Implementation of the mDNS service that can provide utilities of an mDNS
// responder.
class COMPONENT_EXPORT(NETWORK_SERVICE) MdnsResponder
    : public mojom::MdnsResponder {
 public:
  MdnsResponder(mojom::MdnsResponderRequest request,
                MdnsResponderManager* manager);
  // When destroyed, clears all existing name-address associations owned by this
  // responder in the local network by sending out goodbye packets. See
  // SendGoodbyePacketForNameAddressMap below.
  ~MdnsResponder() override;

  // mojom::MdnsResponder overrides.
  void CreateNameForAddress(
      const net::IPAddress& address,
      mojom::MdnsResponder::CreateNameForAddressCallback callback) override;
  void RemoveNameForAddress(
      const net::IPAddress& address,
      mojom::MdnsResponder::RemoveNameForAddressCallback callback) override;

  // Processes the given query and generates a response if the query contains an
  // mDNS name that this responder has a mapped IP address.
  void OnMdnsQueryReceived(const net::DnsQuery& query,
                           uint16_t recv_socket_handler_id);

  bool HasConflictWithExternalResolution(
      const std::string& name,
      const std::set<net::IPAddress>& external_mapped_addreses);

  void SetNameGeneratorForTesting(
      MdnsResponderManager::NameGenerator* name_generator) {
    name_generator_ = name_generator;
  }

 private:
  // Returns true if the response is successfully scheduled to send on all
  // successfully bound interfaces after rate limiting, and false otherwise. See
  // also MdnsResponderManager::Send.
  bool SendMdnsResponse(scoped_refptr<net::IOBufferWithSize> response,
                        scoped_refptr<MdnsResponseSendOption> option);
  // RFC 6761, Section 10.1 "Goodbye Packets".
  //
  // The responder should send out an unsolicited mDNS response with an resource
  // record of zero TTL to clear the name-to-address mapping in neighboring
  // hosts, when the mapping is no longer valid.
  //
  // Returns true if the goodbye message is successfully scheduled to send on
  // all interfaces after rate limiting, and false otherwise. See also
  // MdnsResponderManager::Send.
  bool SendGoodbyePacketForNameAddressMap(
      const std::map<std::string, net::IPAddress>& name_addr_map);

  std::map<std::string, net::IPAddress>::iterator FindNameCreatedForAddress(
      const net::IPAddress& address);

  mojo::Binding<network::mojom::MdnsResponder> binding_;
  // A back pointer to the responder manager that owns this responder. The
  // responder should be destroyed before |manager_| becomes invalid or a weak
  // reference should be used to access the manager when there is no such
  // guarantee in an operation.
  MdnsResponderManager* const manager_;
  std::map<std::string, net::IPAddress> name_addr_map_;
  std::map<std::string, uint16_t> name_refcount_map_;
  MdnsResponderManager::NameGenerator* name_generator_;

  DISALLOW_COPY_AND_ASSIGN(MdnsResponder);
};

}  // namespace network

#endif  // SERVICES_NETWORK_MDNS_RESPONDER_H_
