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 89 void set_update_pending(bool update_pending) { 90 update_pending_ = update_pending; 91 } 92 93 bool update_pending() { return update_pending_; } 94 95 void set_has_ptr(bool has_ptr) { 96 has_ptr_ = has_ptr; 97 } 98 99 void set_has_srv(bool has_srv); 100 101 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 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