// Copyright 2018 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 OSP_IMPL_DISCOVERY_MDNS_MDNS_RESPONDER_ADAPTER_IMPL_H_ #define OSP_IMPL_DISCOVERY_MDNS_MDNS_RESPONDER_ADAPTER_IMPL_H_ #include #include #include #include #include "osp/impl/discovery/mdns/mdns_responder_adapter.h" #include "platform/api/udp_socket.h" #include "platform/base/error.h" #include "third_party/mDNSResponder/src/mDNSCore/mDNSEmbeddedAPI.h" namespace openscreen { namespace osp { class MdnsResponderAdapterImpl final : public MdnsResponderAdapter { public: static constexpr int kRrCacheSize = 500; MdnsResponderAdapterImpl(); ~MdnsResponderAdapterImpl() override; Error Init() override; void Close() override; Error SetHostLabel(const std::string& host_label) override; Error RegisterInterface(const InterfaceInfo& interface_info, const IPSubnet& interface_address, UdpSocket* socket) override; Error DeregisterInterface(UdpSocket* socket) override; void OnRead(UdpSocket* socket, ErrorOr packet) override; void OnSendError(UdpSocket* socket, Error error) override; void OnError(UdpSocket* socket, Error error) override; void OnBound(UdpSocket* socket) override; Clock::duration RunTasks() override; std::vector TakePtrResponses() override; std::vector TakeSrvResponses() override; std::vector TakeTxtResponses() override; std::vector TakeAResponses() override; std::vector TakeAaaaResponses() override; MdnsResponderErrorCode StartPtrQuery(UdpSocket* socket, const DomainName& service_type) override; MdnsResponderErrorCode StartSrvQuery( UdpSocket* socket, const DomainName& service_instance) override; MdnsResponderErrorCode StartTxtQuery( UdpSocket* socket, const DomainName& service_instance) override; MdnsResponderErrorCode StartAQuery(UdpSocket* socket, const DomainName& domain_name) override; MdnsResponderErrorCode StartAaaaQuery(UdpSocket* socket, const DomainName& domain_name) override; MdnsResponderErrorCode StopPtrQuery(UdpSocket* socket, const DomainName& service_type) override; MdnsResponderErrorCode StopSrvQuery( UdpSocket* socket, const DomainName& service_instance) override; MdnsResponderErrorCode StopTxtQuery( UdpSocket* socket, const DomainName& service_instance) override; MdnsResponderErrorCode StopAQuery(UdpSocket* socket, const DomainName& domain_name) override; MdnsResponderErrorCode StopAaaaQuery(UdpSocket* socket, const DomainName& domain_name) override; MdnsResponderErrorCode RegisterService( const std::string& service_instance, const std::string& service_name, const std::string& service_protocol, const DomainName& target_host, uint16_t target_port, const std::map& txt_data) override; MdnsResponderErrorCode DeregisterService( const std::string& service_instance, const std::string& service_name, const std::string& service_protocol) override; MdnsResponderErrorCode UpdateTxtData( const std::string& service_instance, const std::string& service_name, const std::string& service_protocol, const std::map& txt_data) override; private: struct Questions { std::map a; std::map aaaa; std::map ptr; std::map srv; std::map txt; }; static void AQueryCallback(mDNS* m, DNSQuestion* question, const ResourceRecord* answer, QC_result added); static void AaaaQueryCallback(mDNS* m, DNSQuestion* question, const ResourceRecord* answer, QC_result added); static void PtrQueryCallback(mDNS* m, DNSQuestion* question, const ResourceRecord* answer, QC_result added); static void SrvQueryCallback(mDNS* m, DNSQuestion* question, const ResourceRecord* answer, QC_result added); static void TxtQueryCallback(mDNS* m, DNSQuestion* question, const ResourceRecord* answer, QC_result added); static void ServiceCallback(mDNS* m, ServiceRecordSet* service_record, mStatus result); void AdvertiseInterfaces(); void DeadvertiseInterfaces(); void RemoveQuestionsIfEmpty(UdpSocket* socket); CacheEntity rr_cache_[kRrCacheSize]; // The main context structure for mDNSResponder. mDNS mdns_; // Our own storage that is placed inside |mdns_|. The intent in C is to allow // us access to our own state during callbacks. Here we just use it to group // platform sockets. mDNS_PlatformSupport platform_storage_; std::map socket_to_questions_; std::map responder_interface_info_; std::vector a_responses_; std::vector aaaa_responses_; std::vector ptr_responses_; std::vector srv_responses_; std::vector txt_responses_; // A list of services we are advertising. ServiceRecordSet is an // mDNSResponder structure which holds all the resource record data // (PTR/SRV/TXT/A and misc.) that is necessary to advertise a service. std::vector> service_records_; }; } // namespace osp } // namespace openscreen #endif // OSP_IMPL_DISCOVERY_MDNS_MDNS_RESPONDER_ADAPTER_IMPL_H_