blob: a461a5a6f2450fe4a5f1c4c8ba0202e465fc6ecb [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.
#include <lib/zx/time.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "src/connectivity/network/mdns/service/mdns.h"
#include "src/connectivity/network/mdns/service/mdns_agent.h"
#include "src/lib/inet/ip_port.h"
namespace mdns {
// Dynamically publishes an instance of a service type.
class InstanceResponder : public MdnsAgent {
// Creates an |InstanceResponder|. The publisher is consulted to determine
// how queries are handled.
InstanceResponder(MdnsAgent::Host* host, const std::string& service_name,
const std::string& instance_name, Mdns::Publisher* publisher);
~InstanceResponder() override;
// MdnsAgent overrides.
void Start(const std::string& host_full_name, const MdnsAddresses& addresses) override;
void ReceiveQuestion(const DnsQuestion& question, const ReplyAddress& reply_address,
const ReplyAddress& sender_address) override;
void Quit() override;
// Reports whether the publication attempt was successful. Publication can
// fail if the service instance is currently be published by another device
// on the subnet.
void ReportSuccess(bool success);
// Sets the subtypes to publish.
void SetSubtypes(std::vector<std::string> subtypes);
// Reannounces the service instance.
void Reannounce();
static constexpr zx::duration kInitialAnnouncementInterval = zx::sec(1);
static constexpr zx::duration kMaxAnnouncementInterval = zx::sec(4);
static constexpr zx::duration kMinMulticastInterval = zx::sec(1);
static constexpr zx::duration kIdleCheckInterval = zx::sec(60);
static constexpr zx::time kThrottleStateIdle = zx::time::infinite_past();
static constexpr zx::time kThrottleStatePending = zx::time::infinite();
static constexpr size_t kMaxSenderAddresses = 64;
// Logs a sender address for a future |GetPublication| call.
void LogSenderAddress(const ReplyAddress& sender_address);
// Sends an announcement and schedules the next announcement, as appropriate.
void SendAnnouncement();
// Sends a reply to a query for any service.
void SendAnyServiceResponse(const ReplyAddress& reply_address);
// Calls |GetAndSendPublication| with |query| set to true after first determining if the send
// should be throttled.
void MaybeGetAndSendPublication(const std::string& subtype, const ReplyAddress& reply_address);
// Gets an |Mdns::Publication| 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);
// Sends a publication. An empty |subtype| indicates no subtype.
void SendPublication(const Mdns::Publication& publication, const std::string& subtype,
const ReplyAddress& reply_address) const;
// Sends a subtype PTR record for this instance.
void SendSubtypePtrRecord(const std::string& subtype, uint32_t ttl,
const ReplyAddress& reply_address) const;
// Sends a publication with zero ttls, indicating the service instance is
// no longer published.
void SendGoodbye() const;
// Frees resources associated with |subtype| if they're no longer required.
void IdleCheck(const std::string& subtype);
std::string host_full_name_;
std::string service_name_;
std::string instance_name_;
std::string instance_full_name_;
Mdns::Publisher* publisher_;
std::vector<std::string> subtypes_;
zx::duration announcement_interval_ = kInitialAnnouncementInterval;
std::unordered_map<std::string, zx::time> throttle_state_by_subtype_;
std::vector<inet::SocketAddress> sender_addresses_;
// Disallow copy, assign and move.
InstanceResponder(const InstanceResponder&) = delete;
InstanceResponder(InstanceResponder&&) = delete;
InstanceResponder& operator=(const InstanceResponder&) = delete;
InstanceResponder& operator=(InstanceResponder&&) = delete;
} // namespace mdns