1 // Copyright 2018 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 OSP_IMPL_TESTING_FAKE_MDNS_RESPONDER_ADAPTER_H_
6 #define OSP_IMPL_TESTING_FAKE_MDNS_RESPONDER_ADAPTER_H_
7 
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
12 
13 #include "osp/impl/discovery/mdns/mdns_responder_adapter.h"
14 
15 namespace openscreen {
16 namespace osp {
17 
18 class FakeMdnsResponderAdapter;
19 
20 PtrEvent MakePtrEvent(const std::string& service_instance,
21                       const std::string& service_type,
22                       const std::string& service_protocol,
23                       UdpSocket* socket);
24 
25 SrvEvent MakeSrvEvent(const std::string& service_instance,
26                       const std::string& service_type,
27                       const std::string& service_protocol,
28                       const std::string& hostname,
29                       uint16_t port,
30                       UdpSocket* socket);
31 
32 TxtEvent MakeTxtEvent(const std::string& service_instance,
33                       const std::string& service_type,
34                       const std::string& service_protocol,
35                       const std::vector<std::string>& txt_lines,
36                       UdpSocket* socket);
37 
38 AEvent MakeAEvent(const std::string& hostname,
39                   IPAddress address,
40                   UdpSocket* socket);
41 
42 AaaaEvent MakeAaaaEvent(const std::string& hostname,
43                         IPAddress address,
44                         UdpSocket* socket);
45 
46 void AddEventsForNewService(FakeMdnsResponderAdapter* mdns_responder,
47                             const std::string& service_instance,
48                             const std::string& service_name,
49                             const std::string& service_protocol,
50                             const std::string& hostname,
51                             uint16_t port,
52                             const std::vector<std::string>& txt_lines,
53                             const IPAddress& address,
54                             UdpSocket* socket);
55 
56 class FakeMdnsResponderAdapter final : public MdnsResponderAdapter {
57  public:
58   struct RegisteredInterface {
59     InterfaceInfo interface_info;
60     IPSubnet interface_address;
61     UdpSocket* socket;
62   };
63 
64   struct RegisteredService {
65     std::string service_instance;
66     std::string service_name;
67     std::string service_protocol;
68     DomainName target_host;
69     uint16_t target_port;
70     std::map<std::string, std::string> txt_data;
71   };
72 
73   class LifetimeObserver {
74    public:
75     virtual ~LifetimeObserver() = default;
76 
77     virtual void OnDestroyed() = 0;
78   };
79 
80   ~FakeMdnsResponderAdapter() override;
81 
SetLifetimeObserver(LifetimeObserver * observer)82   void SetLifetimeObserver(LifetimeObserver* observer) { observer_ = observer; }
83 
84   void AddPtrEvent(PtrEvent&& ptr_event);
85   void AddSrvEvent(SrvEvent&& srv_event);
86   void AddTxtEvent(TxtEvent&& txt_event);
87   void AddAEvent(AEvent&& a_event);
88   void AddAaaaEvent(AaaaEvent&& aaaa_event);
89 
registered_interfaces()90   const std::vector<RegisteredInterface>& registered_interfaces() {
91     return registered_interfaces_;
92   }
registered_services()93   const std::vector<RegisteredService>& registered_services() {
94     return registered_services_;
95   }
96   bool ptr_queries_empty() const;
97   bool srv_queries_empty() const;
98   bool txt_queries_empty() const;
99   bool a_queries_empty() const;
100   bool aaaa_queries_empty() const;
running()101   bool running() const { return running_; }
102 
103   // UdpSocket::Client overrides.
104   void OnRead(UdpSocket* socket, ErrorOr<UdpPacket> packet) override;
105   void OnSendError(UdpSocket* socket, Error error) override;
106   void OnError(UdpSocket* socket, Error error) override;
107   void OnBound(UdpSocket* socket) override;
108 
109   // MdnsResponderAdapter overrides.
110   Error Init() override;
111   void Close() override;
112 
113   Error SetHostLabel(const std::string& host_label) override;
114 
115   // TODO(btolsch): Reject/OSP_CHECK events that don't match any registered
116   // interface?
117   Error RegisterInterface(const InterfaceInfo& interface_info,
118                           const IPSubnet& interface_address,
119                           UdpSocket* socket) override;
120   Error DeregisterInterface(UdpSocket* socket) override;
121 
122   Clock::duration RunTasks() override;
123 
124   std::vector<PtrEvent> TakePtrResponses() override;
125   std::vector<SrvEvent> TakeSrvResponses() override;
126   std::vector<TxtEvent> TakeTxtResponses() override;
127   std::vector<AEvent> TakeAResponses() override;
128   std::vector<AaaaEvent> TakeAaaaResponses() override;
129 
130   MdnsResponderErrorCode StartPtrQuery(UdpSocket* socket,
131                                        const DomainName& service_type) override;
132   MdnsResponderErrorCode StartSrvQuery(
133       UdpSocket* socket,
134       const DomainName& service_instance) override;
135   MdnsResponderErrorCode StartTxtQuery(
136       UdpSocket* socket,
137       const DomainName& service_instance) override;
138   MdnsResponderErrorCode StartAQuery(UdpSocket* socket,
139                                      const DomainName& domain_name) override;
140   MdnsResponderErrorCode StartAaaaQuery(UdpSocket* socket,
141                                         const DomainName& domain_name) override;
142 
143   MdnsResponderErrorCode StopPtrQuery(UdpSocket* socket,
144                                       const DomainName& service_type) override;
145   MdnsResponderErrorCode StopSrvQuery(
146       UdpSocket* socket,
147       const DomainName& service_instance) override;
148   MdnsResponderErrorCode StopTxtQuery(
149       UdpSocket* socket,
150       const DomainName& service_instance) override;
151   MdnsResponderErrorCode StopAQuery(UdpSocket* socket,
152                                     const DomainName& domain_name) override;
153   MdnsResponderErrorCode StopAaaaQuery(UdpSocket* socket,
154                                        const DomainName& domain_name) override;
155 
156   MdnsResponderErrorCode RegisterService(
157       const std::string& service_instance,
158       const std::string& service_name,
159       const std::string& service_protocol,
160       const DomainName& target_host,
161       uint16_t target_port,
162       const std::map<std::string, std::string>& txt_data) override;
163   MdnsResponderErrorCode DeregisterService(
164       const std::string& service_instance,
165       const std::string& service_name,
166       const std::string& service_protocol) override;
167   MdnsResponderErrorCode UpdateTxtData(
168       const std::string& service_instance,
169       const std::string& service_name,
170       const std::string& service_protocol,
171       const std::map<std::string, std::string>& txt_data) override;
172 
173  private:
174   struct InterfaceQueries {
175     std::set<DomainName, DomainNameComparator> a_queries;
176     std::set<DomainName, DomainNameComparator> aaaa_queries;
177     std::set<DomainName, DomainNameComparator> ptr_queries;
178     std::set<DomainName, DomainNameComparator> srv_queries;
179     std::set<DomainName, DomainNameComparator> txt_queries;
180   };
181 
182   bool running_ = false;
183   LifetimeObserver* observer_ = nullptr;
184 
185   std::map<UdpSocket*, InterfaceQueries> queries_;
186   // NOTE: One of many simplifications here is that there is no cache.  This
187   // means that calling StartQuery, StopQuery, StartQuery will only return an
188   // event the first time, unless the test also adds the event a second time.
189   std::vector<PtrEvent> ptr_events_;
190   std::vector<SrvEvent> srv_events_;
191   std::vector<TxtEvent> txt_events_;
192   std::vector<AEvent> a_events_;
193   std::vector<AaaaEvent> aaaa_events_;
194 
195   std::vector<RegisteredInterface> registered_interfaces_;
196   std::vector<RegisteredService> registered_services_;
197 };
198 
199 }  // namespace osp
200 }  // namespace openscreen
201 
202 #endif  // OSP_IMPL_TESTING_FAKE_MDNS_RESPONDER_ADAPTER_H_
203