• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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 CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
6 #define CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
7 
8 #include <map>
9 #include <string>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/cancelable_callback.h"
14 #include "base/memory/linked_ptr.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "chrome/common/local_discovery/service_discovery_client.h"
18 #include "net/dns/mdns_client.h"
19 
20 namespace local_discovery {
21 
22 class ServiceDiscoveryClientImpl : public ServiceDiscoveryClient {
23  public:
24   // |mdns_client| must outlive the Service Discovery Client.
25   explicit ServiceDiscoveryClientImpl(net::MDnsClient* mdns_client);
26   virtual ~ServiceDiscoveryClientImpl();
27 
28   // ServiceDiscoveryClient implementation:
29   virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher(
30       const std::string& service_type,
31       const ServiceWatcher::UpdatedCallback& callback) OVERRIDE;
32 
33   virtual scoped_ptr<ServiceResolver> CreateServiceResolver(
34       const std::string& service_name,
35       const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE;
36 
37   virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver(
38       const std::string& domain,
39       net::AddressFamily address_family,
40       const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE;
41 
42  private:
43   net::MDnsClient* mdns_client_;
44 
45   DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientImpl);
46 };
47 
48 class ServiceWatcherImpl : public ServiceWatcher,
49                            public net::MDnsListener::Delegate,
50                            public base::SupportsWeakPtr<ServiceWatcherImpl> {
51  public:
52   ServiceWatcherImpl(const std::string& service_type,
53                      const ServiceWatcher::UpdatedCallback& callback,
54                      net::MDnsClient* mdns_client);
55   // Listening will automatically stop when the destructor is called.
56   virtual ~ServiceWatcherImpl();
57 
58   // ServiceWatcher implementation:
59   virtual void Start() OVERRIDE;
60 
61   virtual void DiscoverNewServices(bool force_update) OVERRIDE;
62 
63   virtual void SetActivelyRefreshServices(
64       bool actively_refresh_services) OVERRIDE;
65 
66   virtual std::string GetServiceType() const OVERRIDE;
67 
68   virtual void OnRecordUpdate(net::MDnsListener::UpdateType update,
69                               const net::RecordParsed* record) OVERRIDE;
70 
71   virtual void OnNsecRecord(const std::string& name, unsigned rrtype) OVERRIDE;
72 
73   virtual void OnCachePurged() OVERRIDE;
74 
75   virtual void OnTransactionResponse(
76       scoped_ptr<net::MDnsTransaction>* transaction,
77       net::MDnsTransaction::Result result,
78       const net::RecordParsed* record);
79 
80  private:
81   struct ServiceListeners {
82     ServiceListeners(const std::string& service_name,
83                      ServiceWatcherImpl* watcher,
84                      net::MDnsClient* mdns_client);
85     ~ServiceListeners();
86     bool Start();
87     void SetActiveRefresh(bool auto_update);
88 
set_update_pendingServiceListeners89     void set_update_pending(bool update_pending) {
90       update_pending_ = update_pending;
91     }
92 
update_pendingServiceListeners93     bool update_pending() { return update_pending_; }
94 
set_has_ptrServiceListeners95     void set_has_ptr(bool has_ptr) {
96       has_ptr_ = has_ptr;
97     }
98 
99     void set_has_srv(bool has_srv);
100 
has_ptr_or_srvServiceListeners101     bool has_ptr_or_srv() { return has_ptr_ || has_srv_; }
102 
103    private:
104     void OnSRVRecord(net::MDnsTransaction::Result result,
105                      const net::RecordParsed* record);
106 
107     void DoQuerySRV();
108 
109     scoped_ptr<net::MDnsListener> srv_listener_;
110     scoped_ptr<net::MDnsListener> txt_listener_;
111     scoped_ptr<net::MDnsTransaction> srv_transaction_;
112 
113     std::string service_name_;
114     net::MDnsClient* mdns_client_;
115     bool update_pending_;
116 
117     bool has_ptr_;
118     bool has_srv_;
119   };
120 
121   typedef std::map<std::string, linked_ptr<ServiceListeners> >
122       ServiceListenersMap;
123 
124   void ReadCachedServices();
125   void AddService(const std::string& service);
126   void RemovePTR(const std::string& service);
127   void RemoveSRV(const std::string& service);
128   void AddSRV(const std::string& service);
129   bool CreateTransaction(bool active, bool alert_existing_services,
130                          bool force_refresh,
131                          scoped_ptr<net::MDnsTransaction>* transaction);
132 
133   void DeferUpdate(ServiceWatcher::UpdateType update_type,
134                    const std::string& service_name);
135   void DeliverDeferredUpdate(ServiceWatcher::UpdateType update_type,
136                              const std::string& service_name);
137 
138   void ScheduleQuery(int timeout_seconds);
139 
140   void SendQuery(int next_timeout_seconds, bool force_update);
141 
142   std::string service_type_;
143   ServiceListenersMap services_;
144   scoped_ptr<net::MDnsTransaction> transaction_network_;
145   scoped_ptr<net::MDnsTransaction> transaction_cache_;
146   scoped_ptr<net::MDnsListener> listener_;
147 
148   ServiceWatcher::UpdatedCallback callback_;
149   bool started_;
150   bool actively_refresh_services_;
151 
152   net::MDnsClient* mdns_client_;
153 
154   DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImpl);
155 };
156 
157 class ServiceResolverImpl
158     : public ServiceResolver,
159       public base::SupportsWeakPtr<ServiceResolverImpl> {
160  public:
161   ServiceResolverImpl(const std::string& service_name,
162                       const ServiceResolver::ResolveCompleteCallback& callback,
163                       net::MDnsClient* mdns_client);
164 
165   virtual ~ServiceResolverImpl();
166 
167   // ServiceResolver implementation:
168   virtual void StartResolving() OVERRIDE;
169 
170   virtual std::string GetName() const OVERRIDE;
171 
172  private:
173   // Respond to transaction finishing for SRV records.
174   void SrvRecordTransactionResponse(net::MDnsTransaction::Result status,
175                                     const net::RecordParsed* record);
176 
177   // Respond to transaction finishing for TXT records.
178   void TxtRecordTransactionResponse(net::MDnsTransaction::Result status,
179                                     const net::RecordParsed* record);
180 
181   // Respond to transaction finishing for A records.
182   void ARecordTransactionResponse(net::MDnsTransaction::Result status,
183                                   const net::RecordParsed* record);
184 
185   void AlertCallbackIfReady();
186 
187   void ServiceNotFound(RequestStatus status);
188 
189   // Convert a TXT record to a vector of strings (metadata).
190   const std::vector<std::string>& RecordToMetadata(
191       const net::RecordParsed* record) const;
192 
193   // Convert an SRV record to a host and port pair.
194   net::HostPortPair RecordToAddress(
195       const net::RecordParsed* record) const;
196 
197   // Convert an A record to an IP address.
198   const net::IPAddressNumber& RecordToIPAddress(
199       const net::RecordParsed* record) const;
200 
201   // Convert an MDns status to a service discovery status.
202   RequestStatus MDnsStatusToRequestStatus(
203       net::MDnsTransaction::Result status) const;
204 
205   bool CreateTxtTransaction();
206   bool CreateSrvTransaction();
207   void CreateATransaction();
208 
209   std::string service_name_;
210   ResolveCompleteCallback callback_;
211 
212   bool has_resolved_;
213 
214   bool metadata_resolved_;
215   bool address_resolved_;
216 
217   scoped_ptr<net::MDnsTransaction> txt_transaction_;
218   scoped_ptr<net::MDnsTransaction> srv_transaction_;
219   scoped_ptr<net::MDnsTransaction> a_transaction_;
220 
221   ServiceDescription service_staging_;
222 
223   net::MDnsClient* mdns_client_;
224 
225   DISALLOW_COPY_AND_ASSIGN(ServiceResolverImpl);
226 };
227 
228 class LocalDomainResolverImpl : public LocalDomainResolver {
229  public:
230   LocalDomainResolverImpl(const std::string& domain,
231                           net::AddressFamily address_family,
232                           const IPAddressCallback& callback,
233                           net::MDnsClient* mdns_client);
234   virtual ~LocalDomainResolverImpl();
235 
236   virtual void Start() OVERRIDE;
237 
domain()238   const std::string& domain() { return domain_; }
239 
240  private:
241   void OnTransactionComplete(
242       net::MDnsTransaction::Result result,
243       const net::RecordParsed* record);
244 
245   scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type);
246 
247   bool IsSuccess();
248 
249   void SendResolvedAddresses();
250 
251   std::string domain_;
252   net::AddressFamily address_family_;
253   IPAddressCallback callback_;
254 
255   scoped_ptr<net::MDnsTransaction> transaction_a_;
256   scoped_ptr<net::MDnsTransaction> transaction_aaaa_;
257 
258   int transactions_finished_;
259 
260   net::MDnsClient* mdns_client_;
261 
262   net::IPAddressNumber address_ipv4_;
263   net::IPAddressNumber address_ipv6_;
264 
265   base::CancelableCallback<void()> timeout_callback_;
266 
267   DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverImpl);
268 };
269 
270 
271 }  // namespace local_discovery
272 
273 #endif  // CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_
274