| // 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 <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #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<UdpPacket> 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<PtrEvent> TakePtrResponses() override; |
| std::vector<SrvEvent> TakeSrvResponses() override; |
| std::vector<TxtEvent> TakeTxtResponses() override; |
| std::vector<AEvent> TakeAResponses() override; |
| std::vector<AaaaEvent> 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<std::string, std::string>& 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<std::string, std::string>& txt_data) override; |
| |
| private: |
| struct Questions { |
| std::map<DomainName, DNSQuestion, DomainNameComparator> a; |
| std::map<DomainName, DNSQuestion, DomainNameComparator> aaaa; |
| std::map<DomainName, DNSQuestion, DomainNameComparator> ptr; |
| std::map<DomainName, DNSQuestion, DomainNameComparator> srv; |
| std::map<DomainName, DNSQuestion, DomainNameComparator> 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<UdpSocket*, Questions> socket_to_questions_; |
| |
| std::map<UdpSocket*, NetworkInterfaceInfo> responder_interface_info_; |
| |
| std::vector<AEvent> a_responses_; |
| std::vector<AaaaEvent> aaaa_responses_; |
| std::vector<PtrEvent> ptr_responses_; |
| std::vector<SrvEvent> srv_responses_; |
| std::vector<TxtEvent> 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<std::unique_ptr<ServiceRecordSet>> service_records_; |
| }; |
| |
| } // namespace osp |
| } // namespace openscreen |
| |
| #endif // OSP_IMPL_DISCOVERY_MDNS_MDNS_RESPONDER_ADAPTER_IMPL_H_ |