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 std::string service_type_; 112 ServiceListenersMap services_; 113 scoped_ptr<net::MDnsTransaction> transaction_network_; 114 scoped_ptr<net::MDnsTransaction> transaction_cache_; 115 scoped_ptr<net::MDnsListener> listener_; 116 117 ServiceWatcher::UpdatedCallback callback_; 118 bool started_; 119 120 net::MDnsClient* mdns_client_; 121 122 DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImpl); 123 }; 124 125 class ServiceResolverImpl 126 : public ServiceResolver, 127 public base::SupportsWeakPtr<ServiceResolverImpl> { 128 public: 129 ServiceResolverImpl(const std::string& service_name, 130 const ServiceResolver::ResolveCompleteCallback& callback, 131 net::MDnsClient* mdns_client); 132 133 virtual ~ServiceResolverImpl(); 134 135 // ServiceResolver implementation: 136 virtual void StartResolving() OVERRIDE; 137 138 virtual std::string GetName() const OVERRIDE; 139 140 private: 141 // Respond to transaction finishing for SRV records. 142 void SrvRecordTransactionResponse(net::MDnsTransaction::Result status, 143 const net::RecordParsed* record); 144 145 // Respond to transaction finishing for TXT records. 146 void TxtRecordTransactionResponse(net::MDnsTransaction::Result status, 147 const net::RecordParsed* record); 148 149 // Respond to transaction finishing for A records. 150 void ARecordTransactionResponse(net::MDnsTransaction::Result status, 151 const net::RecordParsed* record); 152 153 void AlertCallbackIfReady(); 154 155 void ServiceNotFound(RequestStatus status); 156 157 // Convert a TXT record to a vector of strings (metadata). 158 const std::vector<std::string>& RecordToMetadata( 159 const net::RecordParsed* record) const; 160 161 // Convert an SRV record to a host and port pair. 162 net::HostPortPair RecordToAddress( 163 const net::RecordParsed* record) const; 164 165 // Convert an A record to an IP address. 166 const net::IPAddressNumber& RecordToIPAddress( 167 const net::RecordParsed* record) const; 168 169 // Convert an MDns status to a service discovery status. 170 RequestStatus MDnsStatusToRequestStatus( 171 net::MDnsTransaction::Result status) const; 172 173 bool CreateTxtTransaction(); 174 bool CreateSrvTransaction(); 175 void CreateATransaction(); 176 177 std::string service_name_; 178 ResolveCompleteCallback callback_; 179 180 bool has_resolved_; 181 182 bool metadata_resolved_; 183 bool address_resolved_; 184 185 scoped_ptr<net::MDnsTransaction> txt_transaction_; 186 scoped_ptr<net::MDnsTransaction> srv_transaction_; 187 scoped_ptr<net::MDnsTransaction> a_transaction_; 188 189 ServiceDescription service_staging_; 190 191 net::MDnsClient* mdns_client_; 192 193 DISALLOW_COPY_AND_ASSIGN(ServiceResolverImpl); 194 }; 195 196 class LocalDomainResolverImpl : public LocalDomainResolver { 197 public: 198 LocalDomainResolverImpl(const std::string& domain, 199 net::AddressFamily address_family, 200 const IPAddressCallback& callback, 201 net::MDnsClient* mdns_client); 202 virtual ~LocalDomainResolverImpl(); 203 204 virtual void Start() OVERRIDE; 205 206 const std::string& domain() { return domain_; } 207 208 private: 209 void OnTransactionComplete( 210 net::MDnsTransaction::Result result, 211 const net::RecordParsed* record); 212 213 scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type); 214 215 std::string domain_; 216 net::AddressFamily address_family_; 217 IPAddressCallback callback_; 218 219 scoped_ptr<net::MDnsTransaction> transaction_a_; 220 scoped_ptr<net::MDnsTransaction> transaction_aaaa_; 221 222 int transaction_failures_; 223 224 net::MDnsClient* mdns_client_; 225 226 DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverImpl); 227 }; 228 229 230 } // namespace local_discovery 231 232 #endif // CHROME_UTILITY_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ 233