blob: b8e4cb2fa84ba63b203399b220b840600336f8bd [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_INSTANCE_REQUESTOR_H_
#define SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_INSTANCE_REQUESTOR_H_
#include <lib/zx/time.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include "src/connectivity/network/mdns/service/mdns.h"
#include "src/connectivity/network/mdns/service/mdns_agent.h"
#include "src/lib/inet/socket_address.h"
namespace mdns {
// Searches for instances of a service type.
class InstanceRequestor : public MdnsAgent {
public:
// Creates an |InstanceRequestor|.
InstanceRequestor(MdnsAgent::Host* host, const std::string& service_name);
~InstanceRequestor() override;
// Adds the subscriber.
void AddSubscriber(Mdns::Subscriber* subscriber);
// Removes the subscriber. If it's the last subscriber, this
// |InstanceRequestor| is destroyed.
void RemoveSubscriber(Mdns::Subscriber* subscriber);
// MdnsAgent overrides.
void Start(const std::string& host_full_name, const MdnsAddresses& addresses) override;
void ReceiveResource(const DnsResource& resource, MdnsResourceSection section) override;
void EndOfMessage() override;
private:
struct InstanceInfo {
std::string instance_name_;
std::string target_;
inet::IpPort port_;
std::vector<std::string> text_;
uint16_t srv_priority_ = 0;
uint16_t srv_weight_ = 0;
bool new_ = true;
bool dirty_ = true;
};
struct TargetInfo {
inet::IpAddress v4_address_;
inet::IpAddress v6_address_;
bool keep_ = false;
bool dirty_ = false;
};
// Report all known instances to the indicated subscriber.
void ReportAllDiscoveries(Mdns::Subscriber* subscriber);
// Sends a query for instances and schedules the next query, as appropriate.
void SendQuery();
void ReceivePtrResource(const DnsResource& resource, MdnsResourceSection section);
void ReceiveSrvResource(const DnsResource& resource, MdnsResourceSection section,
InstanceInfo* instance_info);
void ReceiveTxtResource(const DnsResource& resource, MdnsResourceSection section,
InstanceInfo* instance_info);
void ReceiveAResource(const DnsResource& resource, MdnsResourceSection section,
TargetInfo* target_info);
void ReceiveAaaaResource(const DnsResource& resource, MdnsResourceSection section,
TargetInfo* target_info);
void RemoveInstance(const std::string& instance_full_name);
std::string service_name_;
std::string service_full_name_;
std::unordered_set<Mdns::Subscriber*> subscribers_;
std::unordered_map<std::string, InstanceInfo> instance_infos_by_full_name_;
std::unordered_map<std::string, TargetInfo> target_infos_by_full_name_;
zx::duration query_delay_;
std::shared_ptr<DnsQuestion> question_;
public:
// Disallow copy, assign and move.
InstanceRequestor(const InstanceRequestor&) = delete;
InstanceRequestor(InstanceRequestor&&) = delete;
InstanceRequestor& operator=(const InstanceRequestor&) = delete;
InstanceRequestor& operator=(InstanceRequestor&&) = delete;
};
} // namespace mdns
#endif // SRC_CONNECTIVITY_NETWORK_MDNS_SERVICE_INSTANCE_REQUESTOR_H_