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_RESPONDER_H_ 6*3f982cf4SFabien Sanglard #define DISCOVERY_MDNS_MDNS_RESPONDER_H_ 7*3f982cf4SFabien Sanglard 8*3f982cf4SFabien Sanglard #include <map> 9*3f982cf4SFabien Sanglard #include <memory> 10*3f982cf4SFabien Sanglard #include <vector> 11*3f982cf4SFabien Sanglard 12*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h" 13*3f982cf4SFabien Sanglard #include "platform/api/time.h" 14*3f982cf4SFabien Sanglard #include "platform/base/macros.h" 15*3f982cf4SFabien Sanglard #include "util/alarm.h" 16*3f982cf4SFabien Sanglard 17*3f982cf4SFabien Sanglard namespace openscreen { 18*3f982cf4SFabien Sanglard 19*3f982cf4SFabien Sanglard struct IPEndpoint; 20*3f982cf4SFabien Sanglard class TaskRunner; 21*3f982cf4SFabien Sanglard 22*3f982cf4SFabien Sanglard namespace discovery { 23*3f982cf4SFabien Sanglard 24*3f982cf4SFabien Sanglard struct Config; 25*3f982cf4SFabien Sanglard class MdnsMessage; 26*3f982cf4SFabien Sanglard class MdnsProbeManager; 27*3f982cf4SFabien Sanglard class MdnsRandom; 28*3f982cf4SFabien Sanglard class MdnsReceiver; 29*3f982cf4SFabien Sanglard class MdnsRecordChangedCallback; 30*3f982cf4SFabien Sanglard class MdnsSender; 31*3f982cf4SFabien Sanglard class MdnsQuerier; 32*3f982cf4SFabien Sanglard 33*3f982cf4SFabien Sanglard // This class is responsible for responding to any incoming mDNS Queries 34*3f982cf4SFabien Sanglard // received via the OnMessageReceived() method. When responding, the generated 35*3f982cf4SFabien Sanglard // MdnsMessage will contain the requested record(s) in the answers section, or 36*3f982cf4SFabien Sanglard // an NSEC record to specify that the requested record was not found in the case 37*3f982cf4SFabien Sanglard // of a query with DnsType aside from ANY. In the case where records are found, 38*3f982cf4SFabien Sanglard // the additional records field may be populated with additional records, as 39*3f982cf4SFabien Sanglard // specified in RFCs 6762 and 6763. 40*3f982cf4SFabien Sanglard class MdnsResponder { 41*3f982cf4SFabien Sanglard public: 42*3f982cf4SFabien Sanglard // Class to handle querying for existing records. 43*3f982cf4SFabien Sanglard class RecordHandler { 44*3f982cf4SFabien Sanglard public: 45*3f982cf4SFabien Sanglard virtual ~RecordHandler(); 46*3f982cf4SFabien Sanglard 47*3f982cf4SFabien Sanglard // Returns whether this service has one or more records matching the 48*3f982cf4SFabien Sanglard // provided name, type, and class. 49*3f982cf4SFabien Sanglard virtual bool HasRecords(const DomainName& name, 50*3f982cf4SFabien Sanglard DnsType type, 51*3f982cf4SFabien Sanglard DnsClass clazz) = 0; 52*3f982cf4SFabien Sanglard 53*3f982cf4SFabien Sanglard // Returns all records owned by this service with name, type, and class 54*3f982cf4SFabien Sanglard // matching the provided values. 55*3f982cf4SFabien Sanglard virtual std::vector<MdnsRecord::ConstRef> GetRecords(const DomainName& name, 56*3f982cf4SFabien Sanglard DnsType type, 57*3f982cf4SFabien Sanglard DnsClass clazz) = 0; 58*3f982cf4SFabien Sanglard 59*3f982cf4SFabien Sanglard // Enumerates all PTR records owned by this service. 60*3f982cf4SFabien Sanglard virtual std::vector<MdnsRecord::ConstRef> GetPtrRecords(DnsClass clazz) = 0; 61*3f982cf4SFabien Sanglard }; 62*3f982cf4SFabien Sanglard 63*3f982cf4SFabien Sanglard // |record_handler|, |sender|, |receiver|, |task_runner|, |random_delay|, and 64*3f982cf4SFabien Sanglard // |config| are expected to persist for the duration of this instance's 65*3f982cf4SFabien Sanglard // lifetime. 66*3f982cf4SFabien Sanglard MdnsResponder(RecordHandler* record_handler, 67*3f982cf4SFabien Sanglard MdnsProbeManager* ownership_handler, 68*3f982cf4SFabien Sanglard MdnsSender* sender, 69*3f982cf4SFabien Sanglard MdnsReceiver* receiver, 70*3f982cf4SFabien Sanglard TaskRunner* task_runner, 71*3f982cf4SFabien Sanglard ClockNowFunctionPtr now_function, 72*3f982cf4SFabien Sanglard MdnsRandom* random_delay, 73*3f982cf4SFabien Sanglard const Config& config); 74*3f982cf4SFabien Sanglard ~MdnsResponder(); 75*3f982cf4SFabien Sanglard 76*3f982cf4SFabien Sanglard OSP_DISALLOW_COPY_AND_ASSIGN(MdnsResponder); 77*3f982cf4SFabien Sanglard 78*3f982cf4SFabien Sanglard private: 79*3f982cf4SFabien Sanglard // Class which handles processing and responding to queries segmented into 80*3f982cf4SFabien Sanglard // multiple messages. 81*3f982cf4SFabien Sanglard class TruncatedQuery { 82*3f982cf4SFabien Sanglard public: 83*3f982cf4SFabien Sanglard // |responder| and |task_runner| are expected to persist for the duration of 84*3f982cf4SFabien Sanglard // this instance's lifetime. 85*3f982cf4SFabien Sanglard TruncatedQuery(MdnsResponder* responder, 86*3f982cf4SFabien Sanglard TaskRunner* task_runner, 87*3f982cf4SFabien Sanglard ClockNowFunctionPtr now_function, 88*3f982cf4SFabien Sanglard IPEndpoint src, 89*3f982cf4SFabien Sanglard const MdnsMessage& message, 90*3f982cf4SFabien Sanglard const Config& config); 91*3f982cf4SFabien Sanglard TruncatedQuery(const TruncatedQuery& other) = delete; 92*3f982cf4SFabien Sanglard TruncatedQuery(TruncatedQuery&& other) = delete; 93*3f982cf4SFabien Sanglard 94*3f982cf4SFabien Sanglard TruncatedQuery& operator=(const TruncatedQuery& other) = delete; 95*3f982cf4SFabien Sanglard TruncatedQuery& operator=(TruncatedQuery&& other) = delete; 96*3f982cf4SFabien Sanglard 97*3f982cf4SFabien Sanglard // Sets the query associated with this instance. Must only be called if no 98*3f982cf4SFabien Sanglard // query has already been set, here or through the ctor. 99*3f982cf4SFabien Sanglard void SetQuery(const MdnsMessage& message); 100*3f982cf4SFabien Sanglard 101*3f982cf4SFabien Sanglard // Adds additional known answers. 102*3f982cf4SFabien Sanglard void AddKnownAnswers(const std::vector<MdnsRecord>& records); 103*3f982cf4SFabien Sanglard 104*3f982cf4SFabien Sanglard // Responds to the stored queries. 105*3f982cf4SFabien Sanglard void SendResponse(); 106*3f982cf4SFabien Sanglard src()107*3f982cf4SFabien Sanglard const IPEndpoint& src() const { return src_; } questions()108*3f982cf4SFabien Sanglard const std::vector<MdnsQuestion>& questions() const { return questions_; } known_answers()109*3f982cf4SFabien Sanglard const std::vector<MdnsRecord>& known_answers() const { 110*3f982cf4SFabien Sanglard return known_answers_; 111*3f982cf4SFabien Sanglard } 112*3f982cf4SFabien Sanglard 113*3f982cf4SFabien Sanglard private: 114*3f982cf4SFabien Sanglard void RescheduleSend(); 115*3f982cf4SFabien Sanglard 116*3f982cf4SFabien Sanglard // The number of messages received so far associated with this known answer 117*3f982cf4SFabien Sanglard // query. 118*3f982cf4SFabien Sanglard int messages_received_so_far = 0; 119*3f982cf4SFabien Sanglard 120*3f982cf4SFabien Sanglard const int max_allowed_messages_; 121*3f982cf4SFabien Sanglard const int max_allowed_records_; 122*3f982cf4SFabien Sanglard const IPEndpoint src_; 123*3f982cf4SFabien Sanglard MdnsResponder* const responder_; 124*3f982cf4SFabien Sanglard 125*3f982cf4SFabien Sanglard std::vector<MdnsQuestion> questions_; 126*3f982cf4SFabien Sanglard std::vector<MdnsRecord> known_answers_; 127*3f982cf4SFabien Sanglard Alarm alarm_; 128*3f982cf4SFabien Sanglard }; 129*3f982cf4SFabien Sanglard 130*3f982cf4SFabien Sanglard // Called when a new MdnsMessage is received. 131*3f982cf4SFabien Sanglard void OnMessageReceived(const MdnsMessage& message, const IPEndpoint& src); 132*3f982cf4SFabien Sanglard 133*3f982cf4SFabien Sanglard // Responds a truncated query for which all known answers have been received. 134*3f982cf4SFabien Sanglard void RespondToTruncatedQuery(TruncatedQuery* query); 135*3f982cf4SFabien Sanglard 136*3f982cf4SFabien Sanglard // Processes a message associated with a multi-packet truncated query. 137*3f982cf4SFabien Sanglard void ProcessMultiPacketTruncatedMessage(const MdnsMessage& message, 138*3f982cf4SFabien Sanglard const IPEndpoint& src); 139*3f982cf4SFabien Sanglard 140*3f982cf4SFabien Sanglard // Processes queries provided. 141*3f982cf4SFabien Sanglard void ProcessQueries(const IPEndpoint& src, 142*3f982cf4SFabien Sanglard const std::vector<MdnsQuestion>& questions, 143*3f982cf4SFabien Sanglard const std::vector<MdnsRecord>& known_answers); 144*3f982cf4SFabien Sanglard 145*3f982cf4SFabien Sanglard // Sends the response to the provided query. 146*3f982cf4SFabien Sanglard void SendResponse(const MdnsQuestion& question, 147*3f982cf4SFabien Sanglard const std::vector<MdnsRecord>& known_answers, 148*3f982cf4SFabien Sanglard std::function<void(const MdnsMessage&)> send_response, 149*3f982cf4SFabien Sanglard bool is_exclusive_owner); 150*3f982cf4SFabien Sanglard 151*3f982cf4SFabien Sanglard // Set of all truncated queries received so far. Per RFC 6762 section 7.1, 152*3f982cf4SFabien Sanglard // matching of a query with additional known answers should be done based on 153*3f982cf4SFabien Sanglard // the source address. 154*3f982cf4SFabien Sanglard // NOTE: unique_ptrs used because TruncatedQuery is not movable. 155*3f982cf4SFabien Sanglard std::map<IPEndpoint, std::unique_ptr<TruncatedQuery>> truncated_queries_; 156*3f982cf4SFabien Sanglard 157*3f982cf4SFabien Sanglard RecordHandler* const record_handler_; 158*3f982cf4SFabien Sanglard MdnsProbeManager* const ownership_handler_; 159*3f982cf4SFabien Sanglard MdnsSender* const sender_; 160*3f982cf4SFabien Sanglard MdnsReceiver* const receiver_; 161*3f982cf4SFabien Sanglard TaskRunner* const task_runner_; 162*3f982cf4SFabien Sanglard const ClockNowFunctionPtr now_function_; 163*3f982cf4SFabien Sanglard MdnsRandom* const random_delay_; 164*3f982cf4SFabien Sanglard const Config& config_; 165*3f982cf4SFabien Sanglard 166*3f982cf4SFabien Sanglard friend class MdnsResponderTest; 167*3f982cf4SFabien Sanglard }; 168*3f982cf4SFabien Sanglard 169*3f982cf4SFabien Sanglard } // namespace discovery 170*3f982cf4SFabien Sanglard } // namespace openscreen 171*3f982cf4SFabien Sanglard 172*3f982cf4SFabien Sanglard #endif // DISCOVERY_MDNS_MDNS_RESPONDER_H_ 173