xref: /aosp_15_r20/external/openscreen/discovery/mdns/mdns_probe_manager.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
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