xref: /aosp_15_r20/external/openscreen/discovery/mdns/mdns_probe.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_H_
6*3f982cf4SFabien Sanglard #define DISCOVERY_MDNS_MDNS_PROBE_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <vector>
9*3f982cf4SFabien Sanglard 
10*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_receiver.h"
11*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h"
12*3f982cf4SFabien Sanglard #include "platform/api/time.h"
13*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
14*3f982cf4SFabien Sanglard #include "util/alarm.h"
15*3f982cf4SFabien Sanglard 
16*3f982cf4SFabien Sanglard namespace openscreen {
17*3f982cf4SFabien Sanglard 
18*3f982cf4SFabien Sanglard class TaskRunner;
19*3f982cf4SFabien Sanglard 
20*3f982cf4SFabien Sanglard namespace discovery {
21*3f982cf4SFabien Sanglard 
22*3f982cf4SFabien Sanglard class MdnsQuerier;
23*3f982cf4SFabien Sanglard class MdnsRandom;
24*3f982cf4SFabien Sanglard class MdnsSender;
25*3f982cf4SFabien Sanglard 
26*3f982cf4SFabien Sanglard // Implements the probing method as described in RFC 6762 section 8.1 to claim a
27*3f982cf4SFabien Sanglard // provided domain name. In place of the MdnsRecord(s) that will be published, a
28*3f982cf4SFabien Sanglard // 'fake' mDNS record of type A or AAAA will be generated from provided endpoint
29*3f982cf4SFabien Sanglard // variable with TTL 2 seconds. 0 or 1 seconds are not used because these
30*3f982cf4SFabien Sanglard // constants are used as part of goodbye records, so poorly written receivers
31*3f982cf4SFabien Sanglard // may handle these cases in unexpected ways. Caching of probe queries is not
32*3f982cf4SFabien Sanglard // supported for mDNS probes (else, in a probe which failed, invalid records
33*3f982cf4SFabien Sanglard // would be cached). If for some reason this did occur, though, it should be a
34*3f982cf4SFabien Sanglard // non-issue because the probe record will expire after 2 seconds.
35*3f982cf4SFabien Sanglard //
36*3f982cf4SFabien Sanglard // During probe query conflict resolution, these fake records will be compared
37*3f982cf4SFabien Sanglard // with the records provided by another mDNS endpoint. As 2 different mDNS
38*3f982cf4SFabien Sanglard // endpoints of the same service type cannot have the same endpoint, these
39*3f982cf4SFabien Sanglard // fake mDNS records should never match the real or fake records provided by
40*3f982cf4SFabien Sanglard // the other mDNS endpoint, so lexicographic comparison as described in RFC
41*3f982cf4SFabien Sanglard // 6762 section 8.2.1 can proceed as described.
42*3f982cf4SFabien Sanglard class MdnsProbe : public MdnsReceiver::ResponseClient {
43*3f982cf4SFabien Sanglard  public:
44*3f982cf4SFabien Sanglard   // The observer class is responsible for returning the result of an ongoing
45*3f982cf4SFabien Sanglard   // probe query to the caller.
46*3f982cf4SFabien Sanglard   class Observer {
47*3f982cf4SFabien Sanglard    public:
48*3f982cf4SFabien Sanglard     virtual ~Observer();
49*3f982cf4SFabien Sanglard 
50*3f982cf4SFabien Sanglard     // Called once the probing phase has been completed successfully. |probe| is
51*3f982cf4SFabien Sanglard     // expected to be stopped at the time of this call.
52*3f982cf4SFabien Sanglard     virtual void OnProbeSuccess(MdnsProbe* probe) = 0;
53*3f982cf4SFabien Sanglard 
54*3f982cf4SFabien Sanglard     // Called once the probing phase fails. |probe| is expected to be stopped at
55*3f982cf4SFabien Sanglard     // the time of this call.
56*3f982cf4SFabien Sanglard     virtual void OnProbeFailure(MdnsProbe* probe) = 0;
57*3f982cf4SFabien Sanglard   };
58*3f982cf4SFabien Sanglard 
59*3f982cf4SFabien Sanglard   MdnsProbe(DomainName target_name, IPAddress address);
60*3f982cf4SFabien Sanglard   virtual ~MdnsProbe();
61*3f982cf4SFabien Sanglard 
62*3f982cf4SFabien Sanglard   // Postpones the current probe operation by |delay|, after which the probing
63*3f982cf4SFabien Sanglard   // process is re-initialized.
64*3f982cf4SFabien Sanglard   virtual void Postpone(std::chrono::seconds delay) = 0;
65*3f982cf4SFabien Sanglard 
target_name()66*3f982cf4SFabien Sanglard   const DomainName& target_name() const { return target_name_; }
address()67*3f982cf4SFabien Sanglard   const IPAddress& address() const { return address_; }
address_record()68*3f982cf4SFabien Sanglard   const MdnsRecord address_record() const { return address_record_; }
69*3f982cf4SFabien Sanglard 
70*3f982cf4SFabien Sanglard  private:
71*3f982cf4SFabien Sanglard   const DomainName target_name_;
72*3f982cf4SFabien Sanglard   const IPAddress address_;
73*3f982cf4SFabien Sanglard   const MdnsRecord address_record_;
74*3f982cf4SFabien Sanglard };
75*3f982cf4SFabien Sanglard 
76*3f982cf4SFabien Sanglard class MdnsProbeImpl : public MdnsProbe {
77*3f982cf4SFabien Sanglard  public:
78*3f982cf4SFabien Sanglard   // |sender|, |receiver|, |random_delay|, |task_runner|, and |observer| must
79*3f982cf4SFabien Sanglard   // all persist for the duration of this object's lifetime.
80*3f982cf4SFabien Sanglard   MdnsProbeImpl(MdnsSender* sender,
81*3f982cf4SFabien Sanglard                 MdnsReceiver* receiver,
82*3f982cf4SFabien Sanglard                 MdnsRandom* random_delay,
83*3f982cf4SFabien Sanglard                 TaskRunner* task_runner,
84*3f982cf4SFabien Sanglard                 ClockNowFunctionPtr now_function,
85*3f982cf4SFabien Sanglard                 Observer* observer,
86*3f982cf4SFabien Sanglard                 DomainName target_name,
87*3f982cf4SFabien Sanglard                 IPAddress address);
88*3f982cf4SFabien Sanglard   MdnsProbeImpl(const MdnsProbeImpl& other) = delete;
89*3f982cf4SFabien Sanglard   MdnsProbeImpl(MdnsProbeImpl&& other) = delete;
90*3f982cf4SFabien Sanglard   ~MdnsProbeImpl() override;
91*3f982cf4SFabien Sanglard 
92*3f982cf4SFabien Sanglard   MdnsProbeImpl& operator=(const MdnsProbeImpl& other) = delete;
93*3f982cf4SFabien Sanglard   MdnsProbeImpl& operator=(MdnsProbeImpl&& other) = delete;
94*3f982cf4SFabien Sanglard 
95*3f982cf4SFabien Sanglard   // MdnsProbe overrides.
96*3f982cf4SFabien Sanglard   void Postpone(std::chrono::seconds delay) override;
97*3f982cf4SFabien Sanglard 
98*3f982cf4SFabien Sanglard  private:
99*3f982cf4SFabien Sanglard   friend class MdnsProbeTests;
100*3f982cf4SFabien Sanglard 
101*3f982cf4SFabien Sanglard   // Performs the probe query as described in the class-level comment.
102*3f982cf4SFabien Sanglard   void ProbeOnce();
103*3f982cf4SFabien Sanglard 
104*3f982cf4SFabien Sanglard   // Stops this probe.
105*3f982cf4SFabien Sanglard   void Stop();
106*3f982cf4SFabien Sanglard 
107*3f982cf4SFabien Sanglard   // MdnsReceiver::ResponseClient overrides.
108*3f982cf4SFabien Sanglard   void OnMessageReceived(const MdnsMessage& message) override;
109*3f982cf4SFabien Sanglard 
110*3f982cf4SFabien Sanglard   MdnsRandom* const random_delay_;
111*3f982cf4SFabien Sanglard   TaskRunner* const task_runner_;
112*3f982cf4SFabien Sanglard   ClockNowFunctionPtr now_function_;
113*3f982cf4SFabien Sanglard 
114*3f982cf4SFabien Sanglard   Alarm alarm_;
115*3f982cf4SFabien Sanglard 
116*3f982cf4SFabien Sanglard   // NOTE: Access to all below variables should only be done from the task
117*3f982cf4SFabien Sanglard   // runner thread.
118*3f982cf4SFabien Sanglard   MdnsSender* const sender_;
119*3f982cf4SFabien Sanglard   MdnsReceiver* const receiver_;
120*3f982cf4SFabien Sanglard   Observer* const observer_;
121*3f982cf4SFabien Sanglard 
122*3f982cf4SFabien Sanglard   int successful_probe_queries_ = 0;
123*3f982cf4SFabien Sanglard   bool is_running_ = true;
124*3f982cf4SFabien Sanglard };
125*3f982cf4SFabien Sanglard 
126*3f982cf4SFabien Sanglard }  // namespace discovery
127*3f982cf4SFabien Sanglard }  // namespace openscreen
128*3f982cf4SFabien Sanglard 
129*3f982cf4SFabien Sanglard #endif  // DISCOVERY_MDNS_MDNS_PROBE_H_
130