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