blob: 3a2f4c7287da59d66666ae1eb8b2772617c1357e [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 GARNET_BIN_MDNS_SERVICE_MDNS_TRANSCEIVER_H_
#define GARNET_BIN_MDNS_SERVICE_MDNS_TRANSCEIVER_H_
#include <fuchsia/netstack/cpp/fidl.h>
#include <lib/fit/function.h>
#include <netinet/in.h>
#include <memory>
#include <unordered_map>
#include <vector>
#include "garnet/bin/mdns/service/mdns_interface_transceiver.h"
#include "lib/fxl/macros.h"
namespace mdns {
// Sends and receives mDNS messages on any number of interfaces.
class MdnsTransceiver {
public:
using InboundMessageCallback =
fit::function<void(std::unique_ptr<DnsMessage>, const ReplyAddress&)>;
MdnsTransceiver();
~MdnsTransceiver();
// Starts the transceiver.
void Start(fuchsia::netstack::NetstackPtr netstack,
fit::closure link_change_callback,
InboundMessageCallback inbound_message_callback);
// Stops the transceiver.
void Stop();
// Determines if this transceiver has interfaces.
bool has_interfaces() { return !interface_transceivers_by_address_.empty(); }
// Sends a messaage to the specified address. A V6 interface will send to
// |MdnsAddresses::kV6Multicast| if |reply_address.socket_address()| is
// |MdnsAddresses::kV4Multicast|.
void SendMessage(DnsMessage* message, const ReplyAddress& reply_address);
// Writes log messages describing lifetime traffic.
void LogTraffic();
private:
// Returns the interface transceiver with address |address| if it exists,
// nullptr if not.
MdnsInterfaceTransceiver* GetInterfaceTransceiver(
const inet::IpAddress& address);
// Handles |OnInterfaceChanged| events from |Netstack|.
void InterfacesChanged(
std::vector<fuchsia::netstack::NetInterface> interfaces);
// Ensures that an interface transciever exists for |address| if |address|
// is valid. Returns true if a change was made, false otherwise.
bool EnsureInterfaceTransceiver(
const inet::IpAddress& address, const inet::IpAddress& alternate_address,
uint32_t id, const std::string& name,
std::unordered_map<inet::IpAddress,
std::unique_ptr<MdnsInterfaceTransceiver>>* prev);
fuchsia::netstack::NetstackPtr netstack_;
fit::closure link_change_callback_;
InboundMessageCallback inbound_message_callback_;
std::string host_full_name_;
std::unordered_map<inet::IpAddress, std::unique_ptr<MdnsInterfaceTransceiver>>
interface_transceivers_by_address_;
FXL_DISALLOW_COPY_AND_ASSIGN(MdnsTransceiver);
};
} // namespace mdns
#endif // GARNET_BIN_MDNS_SERVICE_MDNS_TRANSCEIVER_H_