// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef DISCOVERY_MDNS_MDNS_PROBE_H_ #define DISCOVERY_MDNS_MDNS_PROBE_H_ #include #include "discovery/mdns/mdns_receiver.h" #include "discovery/mdns/mdns_records.h" #include "platform/api/time.h" #include "platform/base/ip_address.h" #include "util/alarm.h" namespace openscreen { class TaskRunner; namespace discovery { class MdnsQuerier; class MdnsRandom; class MdnsSender; // Implements the probing method as described in RFC 6762 section 8.1 to claim a // provided domain name. In place of the MdnsRecord(s) that will be published, a // 'fake' mDNS record of type A or AAAA will be generated from provided endpoint // variable with TTL 2 seconds. 0 or 1 seconds are not used because these // constants are used as part of goodbye records, so poorly written receivers // may handle these cases in unexpected ways. Caching of probe queries is not // supported for mDNS probes (else, in a probe which failed, invalid records // would be cached). If for some reason this did occur, though, it should be a // non-issue because the probe record will expire after 2 seconds. // // During probe query conflict resolution, these fake records will be compared // with the records provided by another mDNS endpoint. As 2 different mDNS // endpoints of the same service type cannot have the same endpoint, these // fake mDNS records should never match the real or fake records provided by // the other mDNS endpoint, so lexicographic comparison as described in RFC // 6762 section 8.2.1 can proceed as described. class MdnsProbe : public MdnsReceiver::ResponseClient { public: // The observer class is responsible for returning the result of an ongoing // probe query to the caller. class Observer { public: virtual ~Observer(); // Called once the probing phase has been completed successfully. |probe| is // expected to be stopped at the time of this call. virtual void OnProbeSuccess(MdnsProbe* probe) = 0; // Called once the probing phase fails. |probe| is expected to be stopped at // the time of this call. virtual void OnProbeFailure(MdnsProbe* probe) = 0; }; MdnsProbe(DomainName target_name, IPAddress address); virtual ~MdnsProbe(); // Postpones the current probe operation by |delay|, after which the probing // process is re-initialized. virtual void Postpone(std::chrono::seconds delay) = 0; const DomainName& target_name() const { return target_name_; } const IPAddress& address() const { return address_; } const MdnsRecord address_record() const { return address_record_; } private: const DomainName target_name_; const IPAddress address_; const MdnsRecord address_record_; }; class MdnsProbeImpl : public MdnsProbe { public: // |sender|, |receiver|, |random_delay|, |task_runner|, and |observer| must // all persist for the duration of this object's lifetime. MdnsProbeImpl(MdnsSender* sender, MdnsReceiver* receiver, MdnsRandom* random_delay, TaskRunner* task_runner, ClockNowFunctionPtr now_function, Observer* observer, DomainName target_name, IPAddress address); MdnsProbeImpl(const MdnsProbeImpl& other) = delete; MdnsProbeImpl(MdnsProbeImpl&& other) = delete; ~MdnsProbeImpl() override; MdnsProbeImpl& operator=(const MdnsProbeImpl& other) = delete; MdnsProbeImpl& operator=(MdnsProbeImpl&& other) = delete; // MdnsProbe overrides. void Postpone(std::chrono::seconds delay) override; private: friend class MdnsProbeTests; // Performs the probe query as described in the class-level comment. void ProbeOnce(); // Stops this probe. void Stop(); // MdnsReceiver::ResponseClient overrides. void OnMessageReceived(const MdnsMessage& message) override; MdnsRandom* const random_delay_; TaskRunner* const task_runner_; ClockNowFunctionPtr now_function_; Alarm alarm_; // NOTE: Access to all below variables should only be done from the task // runner thread. MdnsSender* const sender_; MdnsReceiver* const receiver_; Observer* const observer_; int successful_probe_queries_ = 0; bool is_running_ = true; }; } // namespace discovery } // namespace openscreen #endif // DISCOVERY_MDNS_MDNS_PROBE_H_