1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved. 2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be 3*3f982cf4SFabien Sanglard // found in the LICENSE file. 4*3f982cf4SFabien Sanglard 5*3f982cf4SFabien Sanglard #ifndef DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_ 6*3f982cf4SFabien Sanglard #define DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <memory> 9*3f982cf4SFabien Sanglard #include <utility> 10*3f982cf4SFabien Sanglard #include <vector> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_domain_confirmed_provider.h" 13*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_probe.h" 14*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h" 15*3f982cf4SFabien Sanglard #include "platform/base/error.h" 16*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h" 17*3f982cf4SFabien Sanglard 18*3f982cf4SFabien Sanglard namespace openscreen { 19*3f982cf4SFabien Sanglard 20*3f982cf4SFabien Sanglard class TaskRunner; 21*3f982cf4SFabien Sanglard 22*3f982cf4SFabien Sanglard namespace discovery { 23*3f982cf4SFabien Sanglard 24*3f982cf4SFabien Sanglard class MdnsQuerier; 25*3f982cf4SFabien Sanglard class MdnsRandom; 26*3f982cf4SFabien Sanglard class MdnsSender; 27*3f982cf4SFabien Sanglard 28*3f982cf4SFabien Sanglard // Interface for maintaining ownership of mDNS Domains. 29*3f982cf4SFabien Sanglard class MdnsProbeManager { 30*3f982cf4SFabien Sanglard public: 31*3f982cf4SFabien Sanglard virtual ~MdnsProbeManager(); 32*3f982cf4SFabien Sanglard 33*3f982cf4SFabien Sanglard // Returns whether the provided domain name has been claimed as owned by this 34*3f982cf4SFabien Sanglard // mDNS Probe Manager. 35*3f982cf4SFabien Sanglard virtual bool IsDomainClaimed(const DomainName& domain) const = 0; 36*3f982cf4SFabien Sanglard 37*3f982cf4SFabien Sanglard // |message| is a message received from another host which contains a query 38*3f982cf4SFabien Sanglard // from some domain. It is a considered a probe query for a specific domain if 39*3f982cf4SFabien Sanglard // it contains a query for a specific domain which is answered by mDNS Records 40*3f982cf4SFabien Sanglard // in the 'authority records' section of |message|. If a probe for the 41*3f982cf4SFabien Sanglard // provided domain name is ongoing, an MdnsMessage is sent to the provided 42*3f982cf4SFabien Sanglard // endpoint as described in RFC 6762 section 8.2 to allow for conflict 43*3f982cf4SFabien Sanglard // resolution. If the requested name has already been claimed, a message to 44*3f982cf4SFabien Sanglard // specify this will be sent as described in RFC 6762 section 8.1. The |src| 45*3f982cf4SFabien Sanglard // argument is the address from which the message was originally sent, so that 46*3f982cf4SFabien Sanglard // the response message may be sent as a unicast response. 47*3f982cf4SFabien Sanglard virtual void RespondToProbeQuery(const MdnsMessage& message, 48*3f982cf4SFabien Sanglard const IPEndpoint& src) = 0; 49*3f982cf4SFabien Sanglard }; 50*3f982cf4SFabien Sanglard 51*3f982cf4SFabien Sanglard // This class is responsible for managing all ongoing probes for claiming domain 52*3f982cf4SFabien Sanglard // names, as described in RFC 6762 Section 8.1's probing phase. If one such 53*3f982cf4SFabien Sanglard // probe fails due to a conflict detection, this class will modify the domain 54*3f982cf4SFabien Sanglard // name as described in RFC 6762 section 9 and re-initiate probing for the new 55*3f982cf4SFabien Sanglard // name. 56*3f982cf4SFabien Sanglard class MdnsProbeManagerImpl : public MdnsProbe::Observer, 57*3f982cf4SFabien Sanglard public MdnsProbeManager { 58*3f982cf4SFabien Sanglard public: 59*3f982cf4SFabien Sanglard // |sender|, |receiver|, |random_delay|, and |task_runner|, must all persist 60*3f982cf4SFabien Sanglard // for the duration of this object's lifetime. 61*3f982cf4SFabien Sanglard MdnsProbeManagerImpl(MdnsSender* sender, 62*3f982cf4SFabien Sanglard MdnsReceiver* receiver, 63*3f982cf4SFabien Sanglard MdnsRandom* random_delay, 64*3f982cf4SFabien Sanglard TaskRunner* task_runner, 65*3f982cf4SFabien Sanglard ClockNowFunctionPtr now_function); 66*3f982cf4SFabien Sanglard MdnsProbeManagerImpl(const MdnsProbeManager& other) = delete; // NOLINT 67*3f982cf4SFabien Sanglard MdnsProbeManagerImpl(MdnsProbeManager&& other) = delete; // NOLINT 68*3f982cf4SFabien Sanglard ~MdnsProbeManagerImpl() override; 69*3f982cf4SFabien Sanglard 70*3f982cf4SFabien Sanglard MdnsProbeManagerImpl& operator=(const MdnsProbeManagerImpl& other) = delete; 71*3f982cf4SFabien Sanglard MdnsProbeManagerImpl& operator=(MdnsProbeManagerImpl&& other) = delete; 72*3f982cf4SFabien Sanglard 73*3f982cf4SFabien Sanglard // Starts probing for a valid domain name based on the given one. This may 74*3f982cf4SFabien Sanglard // only be called once per MdnsProbe instance. |observer| must persist until 75*3f982cf4SFabien Sanglard // a valid domain is discovered and the observer's OnDomainFound method is 76*3f982cf4SFabien Sanglard // called. 77*3f982cf4SFabien Sanglard // NOTE: |address| is used to generate a 'fake' address record to use for the 78*3f982cf4SFabien Sanglard // probe query. See MdnsProbe::PerformProbeIteration() for further details. 79*3f982cf4SFabien Sanglard Error StartProbe(MdnsDomainConfirmedProvider* callback, 80*3f982cf4SFabien Sanglard DomainName requested_name, 81*3f982cf4SFabien Sanglard IPAddress address); 82*3f982cf4SFabien Sanglard 83*3f982cf4SFabien Sanglard // Stops probing for the requested domain name. 84*3f982cf4SFabien Sanglard Error StopProbe(const DomainName& requested_name); 85*3f982cf4SFabien Sanglard 86*3f982cf4SFabien Sanglard // MdnsDomainOwnershipManager overrides. 87*3f982cf4SFabien Sanglard bool IsDomainClaimed(const DomainName& domain) const override; 88*3f982cf4SFabien Sanglard void RespondToProbeQuery(const MdnsMessage& message, 89*3f982cf4SFabien Sanglard const IPEndpoint& src) override; 90*3f982cf4SFabien Sanglard 91*3f982cf4SFabien Sanglard private: 92*3f982cf4SFabien Sanglard friend class TestMdnsProbeManager; 93*3f982cf4SFabien Sanglard 94*3f982cf4SFabien Sanglard // Resolves simultaneous probe queries as described in RFC 6762 section 8.2. 95*3f982cf4SFabien Sanglard void TiebreakSimultaneousProbes(const MdnsMessage& message); 96*3f982cf4SFabien Sanglard CreateProbe(DomainName name,IPAddress address)97*3f982cf4SFabien Sanglard virtual std::unique_ptr<MdnsProbe> CreateProbe(DomainName name, 98*3f982cf4SFabien Sanglard IPAddress address) { 99*3f982cf4SFabien Sanglard return std::make_unique<MdnsProbeImpl>(sender_, receiver_, random_delay_, 100*3f982cf4SFabien Sanglard task_runner_, now_function_, this, 101*3f982cf4SFabien Sanglard std::move(name), std::move(address)); 102*3f982cf4SFabien Sanglard } 103*3f982cf4SFabien Sanglard 104*3f982cf4SFabien Sanglard // Owns an in-progress MdnsProbe. When the probe starts, an instance of this 105*3f982cf4SFabien Sanglard // struct is created. Upon successful completion of the probe, this instance 106*3f982cf4SFabien Sanglard // is deleted and the owned |probe| instance is moved to |completed_probes|. 107*3f982cf4SFabien Sanglard // Upon failure, the instance is updated with a new MdnsProbe object and this 108*3f982cf4SFabien Sanglard // process is repeated. 109*3f982cf4SFabien Sanglard struct OngoingProbe { 110*3f982cf4SFabien Sanglard OngoingProbe(std::unique_ptr<MdnsProbe> probe, 111*3f982cf4SFabien Sanglard DomainName name, 112*3f982cf4SFabien Sanglard MdnsDomainConfirmedProvider* callback); 113*3f982cf4SFabien Sanglard 114*3f982cf4SFabien Sanglard // NOTE: unique_ptr objects are used to avoid issues when the container 115*3f982cf4SFabien Sanglard // holding this object is resized. 116*3f982cf4SFabien Sanglard std::unique_ptr<MdnsProbe> probe; 117*3f982cf4SFabien Sanglard DomainName requested_name; 118*3f982cf4SFabien Sanglard MdnsDomainConfirmedProvider* callback; 119*3f982cf4SFabien Sanglard int num_probes_failed = 0; 120*3f982cf4SFabien Sanglard }; 121*3f982cf4SFabien Sanglard 122*3f982cf4SFabien Sanglard // MdnsProbe::Observer overrides. 123*3f982cf4SFabien Sanglard void OnProbeSuccess(MdnsProbe* probe) override; 124*3f982cf4SFabien Sanglard void OnProbeFailure(MdnsProbe* probe) override; 125*3f982cf4SFabien Sanglard 126*3f982cf4SFabien Sanglard // Helpers to find ongoing and completed probes. 127*3f982cf4SFabien Sanglard std::vector<std::unique_ptr<MdnsProbe>>::const_iterator FindCompletedProbe( 128*3f982cf4SFabien Sanglard const DomainName& name) const; 129*3f982cf4SFabien Sanglard std::vector<OngoingProbe>::iterator FindOngoingProbe(const DomainName& name); 130*3f982cf4SFabien Sanglard std::vector<OngoingProbe>::iterator FindOngoingProbe(MdnsProbe* probe); 131*3f982cf4SFabien Sanglard 132*3f982cf4SFabien Sanglard MdnsSender* const sender_; 133*3f982cf4SFabien Sanglard MdnsReceiver* const receiver_; 134*3f982cf4SFabien Sanglard MdnsRandom* const random_delay_; 135*3f982cf4SFabien Sanglard TaskRunner* const task_runner_; 136*3f982cf4SFabien Sanglard ClockNowFunctionPtr now_function_; 137*3f982cf4SFabien Sanglard 138*3f982cf4SFabien Sanglard // The set of all probes which have completed successfully. This set is 139*3f982cf4SFabien Sanglard // expected to remain small. unique_ptrs are used for storing the probes to 140*3f982cf4SFabien Sanglard // avoid issues when the vector is resized. 141*3f982cf4SFabien Sanglard std::vector<std::unique_ptr<MdnsProbe>> completed_probes_; 142*3f982cf4SFabien Sanglard 143*3f982cf4SFabien Sanglard // The set of all currently ongoing probes. This set is expected to remain 144*3f982cf4SFabien Sanglard // small. 145*3f982cf4SFabien Sanglard std::vector<OngoingProbe> ongoing_probes_; 146*3f982cf4SFabien Sanglard }; 147*3f982cf4SFabien Sanglard 148*3f982cf4SFabien Sanglard } // namespace discovery 149*3f982cf4SFabien Sanglard } // namespace openscreen 150*3f982cf4SFabien Sanglard 151*3f982cf4SFabien Sanglard #endif // DISCOVERY_MDNS_MDNS_PROBE_MANAGER_H_ 152