blob: b2734cfa6fca196b67d55977134d415660aa5d74 [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_AGENT_H_
#define GARNET_BIN_MDNS_SERVICE_MDNS_AGENT_H_
#include <memory>
#include <lib/fit/function.h>
#include "garnet/bin/mdns/service/dns_message.h"
#include "garnet/bin/mdns/service/mdns_addresses.h"
#include "garnet/lib/inet/socket_address.h"
#include "lib/fxl/time/time_point.h"
namespace mdns {
// kExpired is used when distributing resource expirations. It's not a real
// resource section.
enum class MdnsResourceSection { kAnswer, kAuthority, kAdditional, kExpired };
// Base class for objects that drive mDNS question and record traffic.
class MdnsAgent : public std::enable_shared_from_this<MdnsAgent> {
public:
class Host {
public:
virtual ~Host() {}
// Posts a task to be executed at the specified time. Scheduled tasks posted
// by agents that have since been removed are not executed.
virtual void PostTaskForTime(MdnsAgent* agent, fit::closure task,
fxl::TimePoint target_time) = 0;
// Sends a question to the multicast address.
virtual void SendQuestion(std::shared_ptr<DnsQuestion> question) = 0;
// Sends a resource to the specified address. The default |reply_address|
// |kV4MulticastReply| sends the resource to the V4 or V6
// multicast address.
virtual void SendResource(std::shared_ptr<DnsResource> resource,
MdnsResourceSection section,
const ReplyAddress& reply_address) = 0;
// Sends address resources to the specified address. The default
// |reply_address| |kV4MulticastReply| sends the addresses to the V4 or V6
// multicast address.
virtual void SendAddresses(MdnsResourceSection section,
const ReplyAddress& reply_address) = 0;
// Registers the resource for renewal. See |MdnsAgent::Renew|.
virtual void Renew(const DnsResource& resource) = 0;
// Removes the specified agent. |published_instance_full_name| is used for
// instance publishers only and indicates the full name of a published
// instance.
virtual void RemoveAgent(
const MdnsAgent* agent,
const std::string& published_instance_full_name) = 0;
};
virtual ~MdnsAgent() {}
// Starts the agent. This method is never called before a shared pointer to
// the agent is created, so |shared_from_this| is safe to call.
virtual void Start(const std::string& host_full_name) {}
// Presents a received question. This agent must not call |RemoveSelf| during
// a call to this method.
virtual void ReceiveQuestion(const DnsQuestion& question,
const ReplyAddress& reply_address){};
// Presents a received resource. This agent must not call |RemoveSelf| during
// a call to this method.
virtual void ReceiveResource(const DnsResource& resource,
MdnsResourceSection section){};
// Signals the end of a message. This agent must not call |RemoveSelf| during
// a call to this method.
virtual void EndOfMessage(){};
// Tells the agent to quit. The agent should call |RemoveSelf| shortly
// thereafter. The default calls |RemoveSelf|.
virtual void Quit() { RemoveSelf(); }
protected:
MdnsAgent(Host* host) : host_(host) { FXL_DCHECK(host_); }
// Posts a task to be executed at the specified time. Scheduled tasks posted
// by agents that have since been removed are not executed.
void PostTaskForTime(fit::closure task, fxl::TimePoint target_time) {
host_->PostTaskForTime(this, std::move(task), target_time);
}
// Sends a question to the multicast address.
void SendQuestion(std::shared_ptr<DnsQuestion> question) const {
host_->SendQuestion(question);
}
// Sends a resource to the specified address. The default |reply_address|
// |kV4MulticastReply| sends the resource to the V4 or V6
// multicast address.
void SendResource(std::shared_ptr<DnsResource> resource,
MdnsResourceSection section,
const ReplyAddress& reply_address =
MdnsAddresses::kV4MulticastReply) const {
host_->SendResource(resource, section, reply_address);
}
// Sends address resources to the specified address. The default
// |reply_address| |kV4MulticastReply| sends the addresses to the V4 or V6
// multicast address.
void SendAddresses(MdnsResourceSection section,
const ReplyAddress& reply_address =
MdnsAddresses::kV4MulticastReply) const {
host_->SendAddresses(section, reply_address);
}
// Registers the resource for renewal. Before the resource's TTL expires,
// an attempt will be made to renew the resource by issuing queries for it.
// If the renewal is successful, the agent will receive the renewed resource
// (via |ReceiveResource|) and may choose to renew the resource again.
// If the renewal fails, the agent will receive a resource record with the
// same name and type but with a TTL of zero. The section parameter
// accompanying that resource record will be kExpired.
//
// The effect if this call is transient, and there is no way to cancel the
// renewal. When an agent loses interest in a particular resource, it should
// simply refrain from renewing the incoming records.
void Renew(const DnsResource& resource) const { host_->Renew(resource); }
// Removes this agent. |published_instance_full_name| is used for instance
// publishers only and indicates the full name of a published instance.
void RemoveSelf(const std::string& published_instance_full_name = "") const {
host_->RemoveAgent(this, published_instance_full_name);
}
private:
Host* host_;
};
} // namespace mdns
#endif // GARNET_BIN_MDNS_SERVICE_MDNS_AGENT_H_