1 // Copyright 2013 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_UTILITY_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ 6 #define CHROME_UTILITY_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 std::string GetServiceType() const OVERRIDE; 64 65 virtual void OnRecordUpdate(net::MDnsListener::UpdateType update, 66 const net::RecordParsed* record) OVERRIDE; 67 68 virtual void OnNsecRecord(const std::string& name, unsigned rrtype) OVERRIDE; 69 70 virtual void OnCachePurged() OVERRIDE; 71 72 virtual void OnTransactionResponse( 73 scoped_ptr<net::MDnsTransaction>* transaction, 74 net::MDnsTransaction::Result result, 75 const net::RecordParsed* record); 76 77 private: 78 struct ServiceListeners { 79 ServiceListeners(const std::string& service_name, 80 ServiceWatcherImpl* watcher, 81 net::MDnsClient* mdns_client); 82 ~ServiceListeners(); 83 bool Start(); 84 85 void set_update_pending(bool update_pending) { 86 update_pending_ = update_pending; 87 } 88 89 bool update_pending() { return update_pending_; } 90 private: 91 scoped_ptr<net::MDnsListener> srv_listener_; 92 scoped_ptr<net::MDnsListener> txt_listener_; 93 bool update_pending_; 94 }; 95 96 typedef std::map<std::string, linked_ptr<ServiceListeners> > 97 ServiceListenersMap; 98 99 void ReadCachedServices(); 100 void AddService(const std::string& service); 101 void RemoveService(const std::string& service); 102 bool CreateTransaction(bool active, bool alert_existing_services, 103 bool force_refresh, 104 scoped_ptr<net::MDnsTransaction>* transaction); 105 106 void DeferUpdate(ServiceWatcher::UpdateType update_type, 107 const std::string& service_name); 108 void DeliverDeferredUpdate(ServiceWatcher::UpdateType update_type, 109 const std::string& service_name); 110 111 void ScheduleQuery(int timeout_seconds); 112 113 void SendQuery(int next_timeout_seconds, bool force_update); 114 115 std::string service_type_; 116 ServiceListenersMap services_; 117 scoped_ptr<net::MDnsTransaction> transaction_network_; 118 scoped_ptr<net::MDnsTransaction> transaction_cache_; 119 scoped_ptr<net::MDnsListener> listener_; 120 121 ServiceWatcher::UpdatedCallback callback_; 122 bool started_; 123 124 net::MDnsClient* mdns_client_; 125 126 DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImpl); 127 }; 128 129 class ServiceResolverImpl 130 : public ServiceResolver, 131 public base::SupportsWeakPtr<ServiceResolverImpl> { 132 public: 133 ServiceResolverImpl(const std::string& service_name, 134 const ServiceResolver::ResolveCompleteCallback& callback, 135 net::MDnsClient* mdns_client); 136 137 virtual ~ServiceResolverImpl(); 138 139 // ServiceResolver implementation: 140 virtual void StartResolving() OVERRIDE; 141 142 virtual std::string GetName() const OVERRIDE; 143 144 private: 145 // Respond to transaction finishing for SRV records. 146 void SrvRecordTransactionResponse(net::MDnsTransaction::Result status, 147 const net::RecordParsed* record); 148 149 // Respond to transaction finishing for TXT records. 150 void TxtRecordTransactionResponse(net::MDnsTransaction::Result status, 151 const net::RecordParsed* record); 152 153 // Respond to transaction finishing for A records. 154 void ARecordTransactionResponse(net::MDnsTransaction::Result status, 155 const net::RecordParsed* record); 156 157 void AlertCallbackIfReady(); 158 159 void ServiceNotFound(RequestStatus status); 160 161 // Convert a TXT record to a vector of strings (metadata). 162 const std::vector<std::string>& RecordToMetadata( 163 const net::RecordParsed* record) const; 164 165 // Convert an SRV record to a host and port pair. 166 net::HostPortPair RecordToAddress( 167 const net::RecordParsed* record) const; 168 169 // Convert an A record to an IP address. 170 const net::IPAddressNumber& RecordToIPAddress( 171 const net::RecordParsed* record) const; 172 173 // Convert an MDns status to a service discovery status. 174 RequestStatus MDnsStatusToRequestStatus( 175 net::MDnsTransaction::Result status) const; 176 177 bool CreateTxtTransaction(); 178 bool CreateSrvTransaction(); 179 void CreateATransaction(); 180 181 std::string service_name_; 182 ResolveCompleteCallback callback_; 183 184 bool has_resolved_; 185 186 bool metadata_resolved_; 187 bool address_resolved_; 188 189 scoped_ptr<net::MDnsTransaction> txt_transaction_; 190 scoped_ptr<net::MDnsTransaction> srv_transaction_; 191 scoped_ptr<net::MDnsTransaction> a_transaction_; 192 193 ServiceDescription service_staging_; 194 195 net::MDnsClient* mdns_client_; 196 197 DISALLOW_COPY_AND_ASSIGN(ServiceResolverImpl); 198 }; 199 200 class LocalDomainResolverImpl : public LocalDomainResolver { 201 public: 202 LocalDomainResolverImpl(const std::string& domain, 203 net::AddressFamily address_family, 204 const IPAddressCallback& callback, 205 net::MDnsClient* mdns_client); 206 virtual ~LocalDomainResolverImpl(); 207 208 virtual void Start() OVERRIDE; 209 210 const std::string& domain() { return domain_; } 211 212 private: 213 void OnTransactionComplete( 214 net::MDnsTransaction::Result result, 215 const net::RecordParsed* record); 216 217 scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type); 218 219 bool IsSuccess(); 220 221 void SendResolvedAddresses(); 222 223 std::string domain_; 224 net::AddressFamily address_family_; 225 IPAddressCallback callback_; 226 227 scoped_ptr<net::MDnsTransaction> transaction_a_; 228 scoped_ptr<net::MDnsTransaction> transaction_aaaa_; 229 230 int transactions_finished_; 231 232 net::MDnsClient* mdns_client_; 233 234 net::IPAddressNumber address_ipv4_; 235 net::IPAddressNumber address_ipv6_; 236 237 base::CancelableCallback<void()> timeout_callback_; 238 239 DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverImpl); 240 }; 241 242 243 } // namespace local_discovery 244 245 #endif // CHROME_UTILITY_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ 246