You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
6.2 KiB
152 lines
6.2 KiB
4 months ago
|
// Copyright 2019 The Chromium 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 DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_
|
||
|
#define DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_
|
||
|
|
||
|
#include <memory>
|
||
|
#include <utility>
|
||
|
#include <vector>
|
||
|
|
||
|
#include "discovery/mdns/mdns_domain_confirmed_provider.h"
|
||
|
#include "discovery/mdns/mdns_probe.h"
|
||
|
#include "discovery/mdns/mdns_records.h"
|
||
|
#include "platform/base/error.h"
|
||
|
#include "platform/base/ip_address.h"
|
||
|
|
||
|
namespace openscreen {
|
||
|
|
||
|
class TaskRunner;
|
||
|
|
||
|
namespace discovery {
|
||
|
|
||
|
class MdnsQuerier;
|
||
|
class MdnsRandom;
|
||
|
class MdnsSender;
|
||
|
|
||
|
// Interface for maintaining ownership of mDNS Domains.
|
||
|
class MdnsProbeManager {
|
||
|
public:
|
||
|
virtual ~MdnsProbeManager();
|
||
|
|
||
|
// Returns whether the provided domain name has been claimed as owned by this
|
||
|
// mDNS Probe Manager.
|
||
|
virtual bool IsDomainClaimed(const DomainName& domain) const = 0;
|
||
|
|
||
|
// |message| is a message received from another host which contains a query
|
||
|
// from some domain. It is a considered a probe query for a specific domain if
|
||
|
// it contains a query for a specific domain which is answered by mDNS Records
|
||
|
// in the 'authority records' section of |message|. If a probe for the
|
||
|
// provided domain name is ongoing, an MdnsMessage is sent to the provided
|
||
|
// endpoint as described in RFC 6762 section 8.2 to allow for conflict
|
||
|
// resolution. If the requested name has already been claimed, a message to
|
||
|
// specify this will be sent as described in RFC 6762 section 8.1. The |src|
|
||
|
// argument is the address from which the message was originally sent, so that
|
||
|
// the response message may be sent as a unicast response.
|
||
|
virtual void RespondToProbeQuery(const MdnsMessage& message,
|
||
|
const IPEndpoint& src) = 0;
|
||
|
};
|
||
|
|
||
|
// This class is responsible for managing all ongoing probes for claiming domain
|
||
|
// names, as described in RFC 6762 Section 8.1's probing phase. If one such
|
||
|
// probe fails due to a conflict detection, this class will modify the domain
|
||
|
// name as described in RFC 6762 section 9 and re-initiate probing for the new
|
||
|
// name.
|
||
|
class MdnsProbeManagerImpl : public MdnsProbe::Observer,
|
||
|
public MdnsProbeManager {
|
||
|
public:
|
||
|
// |sender|, |receiver|, |random_delay|, and |task_runner|, must all persist
|
||
|
// for the duration of this object's lifetime.
|
||
|
MdnsProbeManagerImpl(MdnsSender* sender,
|
||
|
MdnsReceiver* receiver,
|
||
|
MdnsRandom* random_delay,
|
||
|
TaskRunner* task_runner,
|
||
|
ClockNowFunctionPtr now_function);
|
||
|
MdnsProbeManagerImpl(const MdnsProbeManager& other) = delete; // NOLINT
|
||
|
MdnsProbeManagerImpl(MdnsProbeManager&& other) = delete; // NOLINT
|
||
|
~MdnsProbeManagerImpl() override;
|
||
|
|
||
|
MdnsProbeManagerImpl& operator=(const MdnsProbeManagerImpl& other) = delete;
|
||
|
MdnsProbeManagerImpl& operator=(MdnsProbeManagerImpl&& other) = delete;
|
||
|
|
||
|
// Starts probing for a valid domain name based on the given one. This may
|
||
|
// only be called once per MdnsProbe instance. |observer| must persist until
|
||
|
// a valid domain is discovered and the observer's OnDomainFound method is
|
||
|
// called.
|
||
|
// NOTE: |address| is used to generate a 'fake' address record to use for the
|
||
|
// probe query. See MdnsProbe::PerformProbeIteration() for further details.
|
||
|
Error StartProbe(MdnsDomainConfirmedProvider* callback,
|
||
|
DomainName requested_name,
|
||
|
IPAddress address);
|
||
|
|
||
|
// Stops probing for the requested domain name.
|
||
|
Error StopProbe(const DomainName& requested_name);
|
||
|
|
||
|
// MdnsDomainOwnershipManager overrides.
|
||
|
bool IsDomainClaimed(const DomainName& domain) const override;
|
||
|
void RespondToProbeQuery(const MdnsMessage& message,
|
||
|
const IPEndpoint& src) override;
|
||
|
|
||
|
private:
|
||
|
friend class TestMdnsProbeManager;
|
||
|
|
||
|
// Resolves simultaneous probe queries as described in RFC 6762 section 8.2.
|
||
|
void TiebreakSimultaneousProbes(const MdnsMessage& message);
|
||
|
|
||
|
virtual std::unique_ptr<MdnsProbe> CreateProbe(DomainName name,
|
||
|
IPAddress address) {
|
||
|
return std::make_unique<MdnsProbeImpl>(sender_, receiver_, random_delay_,
|
||
|
task_runner_, now_function_, this,
|
||
|
std::move(name), std::move(address));
|
||
|
}
|
||
|
|
||
|
// Owns an in-progress MdnsProbe. When the probe starts, an instance of this
|
||
|
// struct is created. Upon successful completion of the probe, this instance
|
||
|
// is deleted and the owned |probe| instance is moved to |completed_probes|.
|
||
|
// Upon failure, the instance is updated with a new MdnsProbe object and this
|
||
|
// process is repeated.
|
||
|
struct OngoingProbe {
|
||
|
OngoingProbe(std::unique_ptr<MdnsProbe> probe,
|
||
|
DomainName name,
|
||
|
MdnsDomainConfirmedProvider* callback);
|
||
|
|
||
|
// NOTE: unique_ptr objects are used to avoid issues when the container
|
||
|
// holding this object is resized.
|
||
|
std::unique_ptr<MdnsProbe> probe;
|
||
|
DomainName requested_name;
|
||
|
MdnsDomainConfirmedProvider* callback;
|
||
|
int num_probes_failed = 0;
|
||
|
};
|
||
|
|
||
|
// MdnsProbe::Observer overrides.
|
||
|
void OnProbeSuccess(MdnsProbe* probe) override;
|
||
|
void OnProbeFailure(MdnsProbe* probe) override;
|
||
|
|
||
|
// Helpers to find ongoing and completed probes.
|
||
|
std::vector<std::unique_ptr<MdnsProbe>>::const_iterator FindCompletedProbe(
|
||
|
const DomainName& name) const;
|
||
|
std::vector<OngoingProbe>::iterator FindOngoingProbe(const DomainName& name);
|
||
|
std::vector<OngoingProbe>::iterator FindOngoingProbe(MdnsProbe* probe);
|
||
|
|
||
|
MdnsSender* const sender_;
|
||
|
MdnsReceiver* const receiver_;
|
||
|
MdnsRandom* const random_delay_;
|
||
|
TaskRunner* const task_runner_;
|
||
|
ClockNowFunctionPtr now_function_;
|
||
|
|
||
|
// The set of all probes which have completed successfully. This set is
|
||
|
// expected to remain small. unique_ptrs are used for storing the probes to
|
||
|
// avoid issues when the vector is resized.
|
||
|
std::vector<std::unique_ptr<MdnsProbe>> completed_probes_;
|
||
|
|
||
|
// The set of all currently ongoing probes. This set is expected to remain
|
||
|
// small.
|
||
|
std::vector<OngoingProbe> ongoing_probes_;
|
||
|
};
|
||
|
|
||
|
} // namespace discovery
|
||
|
} // namespace openscreen
|
||
|
|
||
|
#endif // DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_
|