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