blob: 2b4963eb5f685af170cdefa30f1bf423c31cc7e1 [file] [log] [blame]
// Copyright 2017 The Fuchsia 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 SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_TRANSPORT_MDNS_TRANSCEIVER_H_
#define SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_TRANSPORT_MDNS_TRANSCEIVER_H_
#include <fuchsia/net/interfaces/cpp/fidl.h>
#include <lib/fit/function.h>
#include <netinet/in.h>
#include <memory>
#include <unordered_map>
#include <vector>
#include "src/connectivity/network/lib/net_interfaces/cpp/net_interfaces.h"
#include "src/connectivity/network/mdns/service/mdns.h"
#include "src/connectivity/network/mdns/service/transport/mdns_interface_transceiver.h"
namespace mdns {
// Sends and receives mDNS messages on any number of interfaces.
class MdnsTransceiver : public Mdns::Transceiver {
public:
MdnsTransceiver();
~MdnsTransceiver();
// Mdns::Transceiver implementation.
void Start(fuchsia::net::interfaces::WatcherPtr watcher, fit::closure link_change_callback,
InboundMessageCallback inbound_message_callback,
InterfaceTransceiverCreateFunction transceiver_factory) override;
void Stop() override;
bool HasInterfaces() override;
void SendMessage(const DnsMessage& message, const ReplyAddress& reply_address) override;
void LogTraffic() override;
std::vector<HostAddress> LocalHostAddresses() override;
// Returns the interface transceiver with address |address| if it exists,
// nullptr if not.
// TODO(https://fxbug.dev/42126891): move this back to private after multi-network test
// is rewritten in Rust.
MdnsInterfaceTransceiver* GetInterfaceTransceiver(const inet::IpAddress& address);
private:
// Starts an interface transceiver for every address in |properties|.
// Returns true iff at least one interface transceiver was started.
bool StartInterfaceTransceivers(const net::interfaces::Properties& properties);
// Stops the interface transceiver on |address| if it exists.
// Returns true iff at least one interface transceiver was stopped.
bool StopInterfaceTransceiver(const inet::IpAddress& address);
// Handles a fuchsia.net.interfaces |Added| or |Existing| event (indicated by |event_type|) by
// starting interface transceivers if |discovered| indicates that the interface is online and not
// loopback. Returns true iff at least one interface transceiver was started.
bool OnInterfaceDiscovered(fuchsia::net::interfaces::Properties discovered,
const char* event_type);
// Handles a |fuchsia::net::interfaces::Event|.
void OnInterfacesEvent(fuchsia::net::interfaces::Event event);
// Ensures that an interface transceiver exists for |address| if |address|
// is valid. Returns true if a change was made, false otherwise.
bool EnsureInterfaceTransceiver(const inet::IpAddress& address,
const std::vector<inet::IpAddress>& interface_addresses,
uint32_t id, Media media, const std::string& name);
// Determines if |address| identifies one of the NICs in |interface_transceivers_by_address_|.
bool IsLocalInterfaceAddress(const inet::IpAddress& address);
fuchsia::net::interfaces::WatcherPtr interface_watcher_;
fit::closure link_change_callback_;
InboundMessageCallback inbound_message_callback_;
InterfaceTransceiverCreateFunction transceiver_factory_;
std::string local_host_full_name_;
std::unordered_map<inet::IpAddress, std::unique_ptr<MdnsInterfaceTransceiver>>
interface_transceivers_by_address_;
std::unordered_map<uint64_t, net::interfaces::Properties> interface_properties_;
public:
// Disallow copy, assign and move.
MdnsTransceiver(const MdnsTransceiver&) = delete;
MdnsTransceiver(MdnsTransceiver&&) = delete;
MdnsTransceiver& operator=(const MdnsTransceiver&) = delete;
MdnsTransceiver& operator=(MdnsTransceiver&&) = delete;
};
} // namespace mdns
#endif // SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_TRANSPORT_MDNS_TRANSCEIVER_H_