blob: 260c61987c5bda460066e04d3e48fa2aca15c71d [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.
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "garnet/bin/netconnector/ip_port.h"
#include "garnet/bin/netconnector/mdns/mdns_agent.h"
#include "lib/fxl/time/time_delta.h"
#include "lib/netconnector/fidl/mdns.fidl.h"
namespace netconnector {
namespace mdns {
// Dynamically publishes an instance of a service type.
class InstanceResponder : public MdnsAgent {
public:
using PublishCallback = std::function<void(MdnsResult result)>;
// Creates an |InstanceResponder|. Subtypes in |announced_subtypes| are
// announced initially. The |MdnsResponder| referenced by |responder_handle|
// is consulted to determine how queries are handled.
InstanceResponder(MdnsAgent::Host* host,
const std::string& service_name,
const std::string& instance_name,
fidl::InterfaceHandle<MdnsResponder> responder_handle);
// Creates an |InstanceResponder|. No subtypes are announced. Queries for
// |service_name| are responded to using the information in |publication|.
// Queries for subtypes of |service_name| are ignored.
InstanceResponder(MdnsAgent::Host* host,
const std::string& service_name,
const std::string& instance_name,
MdnsPublicationPtr publication,
const PublishCallback& callback);
~InstanceResponder() override;
// MdnsAgent overrides.
void Start(const std::string& host_full_name) override;
void ReceiveQuestion(const DnsQuestion& question,
const ReplyAddress& reply_address) override;
void Quit() override;
// Updates the status.
void UpdateStatus(MdnsResult result);
// Sets the subtypes to publish.
void SetSubtypes(std::vector<std::string> subtypes);
// Reannounces the service instance.
void Reannounce();
private:
static constexpr fxl::TimeDelta kInitialAnnouncementInterval =
fxl::TimeDelta::FromSeconds(1);
static constexpr fxl::TimeDelta kMaxAnnouncementInterval =
fxl::TimeDelta::FromSeconds(4);
// Sends an announcement and schedules the next announcement, as appropriate.
void SendAnnouncement();
// Gets an |MdnsPublication| from |mdns_responder_| and, if not null, sends
// it. An empty |subtype| indicates no subtype.
void GetAndSendPublication(bool query,
const std::string& subtype = "",
const ReplyAddress& reply_address =
MdnsAddresses::kV4MulticastReply) const;
// Sends a publication. An empty |subtype| indicates no subtype.
void SendPublication(const MdnsPublication& publication,
const std::string& subtype = "",
const ReplyAddress& reply_address =
MdnsAddresses::kV4MulticastReply) const;
// Sends a subtype PTR record for this instance.
void SendSubtypePtrRecord(const std::string& subtype,
uint32_t ttl = DnsResource::kShortTimeToLive,
const ReplyAddress& reply_address =
MdnsAddresses::kV4MulticastReply) const;
// Turns |publication| into a goodbye by setting the TTLs to zero and sends
// it via multicast.
void SendGoodbye(MdnsPublicationPtr publication) const;
std::string host_full_name_;
std::string service_name_;
std::string instance_name_;
std::string instance_full_name_;
std::vector<std::string> subtypes_;
MdnsResponderPtr mdns_responder_;
MdnsPublicationPtr publication_;
PublishCallback callback_;
fxl::TimeDelta announcement_interval_ = kInitialAnnouncementInterval;
bool should_quit_ = false;
};
} // namespace mdns
} // namespace netconnector