Index: chrome/common/local_discovery/service_discovery_client_impl.h |
diff --git a/chrome/common/local_discovery/service_discovery_client_impl.h b/chrome/common/local_discovery/service_discovery_client_impl.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c9b7b7bf06685c0b736c55f9d82db81a568954c1 |
--- /dev/null |
+++ b/chrome/common/local_discovery/service_discovery_client_impl.h |
@@ -0,0 +1,273 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ |
+#define CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ |
+ |
+#include <map> |
+#include <string> |
+#include <vector> |
+ |
+#include "base/callback.h" |
+#include "base/cancelable_callback.h" |
+#include "base/memory/linked_ptr.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/message_loop/message_loop.h" |
+#include "chrome/common/local_discovery/service_discovery_client.h" |
+#include "net/dns/mdns_client.h" |
+ |
+namespace local_discovery { |
+ |
+class ServiceDiscoveryClientImpl : public ServiceDiscoveryClient { |
+ public: |
+ // |mdns_client| must outlive the Service Discovery Client. |
+ explicit ServiceDiscoveryClientImpl(net::MDnsClient* mdns_client); |
+ virtual ~ServiceDiscoveryClientImpl(); |
+ |
+ // ServiceDiscoveryClient implementation: |
+ virtual scoped_ptr<ServiceWatcher> CreateServiceWatcher( |
+ const std::string& service_type, |
+ const ServiceWatcher::UpdatedCallback& callback) OVERRIDE; |
+ |
+ virtual scoped_ptr<ServiceResolver> CreateServiceResolver( |
+ const std::string& service_name, |
+ const ServiceResolver::ResolveCompleteCallback& callback) OVERRIDE; |
+ |
+ virtual scoped_ptr<LocalDomainResolver> CreateLocalDomainResolver( |
+ const std::string& domain, |
+ net::AddressFamily address_family, |
+ const LocalDomainResolver::IPAddressCallback& callback) OVERRIDE; |
+ |
+ private: |
+ net::MDnsClient* mdns_client_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ServiceDiscoveryClientImpl); |
+}; |
+ |
+class ServiceWatcherImpl : public ServiceWatcher, |
+ public net::MDnsListener::Delegate, |
+ public base::SupportsWeakPtr<ServiceWatcherImpl> { |
+ public: |
+ ServiceWatcherImpl(const std::string& service_type, |
+ const ServiceWatcher::UpdatedCallback& callback, |
+ net::MDnsClient* mdns_client); |
+ // Listening will automatically stop when the destructor is called. |
+ virtual ~ServiceWatcherImpl(); |
+ |
+ // ServiceWatcher implementation: |
+ virtual void Start() OVERRIDE; |
+ |
+ virtual void DiscoverNewServices(bool force_update) OVERRIDE; |
+ |
+ virtual void SetActivelyRefreshServices( |
+ bool actively_refresh_services) OVERRIDE; |
+ |
+ virtual std::string GetServiceType() const OVERRIDE; |
+ |
+ virtual void OnRecordUpdate(net::MDnsListener::UpdateType update, |
+ const net::RecordParsed* record) OVERRIDE; |
+ |
+ virtual void OnNsecRecord(const std::string& name, unsigned rrtype) OVERRIDE; |
+ |
+ virtual void OnCachePurged() OVERRIDE; |
+ |
+ virtual void OnTransactionResponse( |
+ scoped_ptr<net::MDnsTransaction>* transaction, |
+ net::MDnsTransaction::Result result, |
+ const net::RecordParsed* record); |
+ |
+ private: |
+ struct ServiceListeners { |
+ ServiceListeners(const std::string& service_name, |
+ ServiceWatcherImpl* watcher, |
+ net::MDnsClient* mdns_client); |
+ ~ServiceListeners(); |
+ bool Start(); |
+ void SetActiveRefresh(bool auto_update); |
+ |
+ void set_update_pending(bool update_pending) { |
+ update_pending_ = update_pending; |
+ } |
+ |
+ bool update_pending() { return update_pending_; } |
+ |
+ void set_has_ptr(bool has_ptr) { |
+ has_ptr_ = has_ptr; |
+ } |
+ |
+ void set_has_srv(bool has_srv); |
+ |
+ bool has_ptr_or_srv() { return has_ptr_ || has_srv_; } |
+ |
+ private: |
+ void OnSRVRecord(net::MDnsTransaction::Result result, |
+ const net::RecordParsed* record); |
+ |
+ void DoQuerySRV(); |
+ |
+ scoped_ptr<net::MDnsListener> srv_listener_; |
+ scoped_ptr<net::MDnsListener> txt_listener_; |
+ scoped_ptr<net::MDnsTransaction> srv_transaction_; |
+ |
+ std::string service_name_; |
+ net::MDnsClient* mdns_client_; |
+ bool update_pending_; |
+ |
+ bool has_ptr_; |
+ bool has_srv_; |
+ }; |
+ |
+ typedef std::map<std::string, linked_ptr<ServiceListeners> > |
+ ServiceListenersMap; |
+ |
+ void ReadCachedServices(); |
+ void AddService(const std::string& service); |
+ void RemovePTR(const std::string& service); |
+ void RemoveSRV(const std::string& service); |
+ void AddSRV(const std::string& service); |
+ bool CreateTransaction(bool active, bool alert_existing_services, |
+ bool force_refresh, |
+ scoped_ptr<net::MDnsTransaction>* transaction); |
+ |
+ void DeferUpdate(ServiceWatcher::UpdateType update_type, |
+ const std::string& service_name); |
+ void DeliverDeferredUpdate(ServiceWatcher::UpdateType update_type, |
+ const std::string& service_name); |
+ |
+ void ScheduleQuery(int timeout_seconds); |
+ |
+ void SendQuery(int next_timeout_seconds, bool force_update); |
+ |
+ std::string service_type_; |
+ ServiceListenersMap services_; |
+ scoped_ptr<net::MDnsTransaction> transaction_network_; |
+ scoped_ptr<net::MDnsTransaction> transaction_cache_; |
+ scoped_ptr<net::MDnsListener> listener_; |
+ |
+ ServiceWatcher::UpdatedCallback callback_; |
+ bool started_; |
+ bool actively_refresh_services_; |
+ |
+ net::MDnsClient* mdns_client_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ServiceWatcherImpl); |
+}; |
+ |
+class ServiceResolverImpl |
+ : public ServiceResolver, |
+ public base::SupportsWeakPtr<ServiceResolverImpl> { |
+ public: |
+ ServiceResolverImpl(const std::string& service_name, |
+ const ServiceResolver::ResolveCompleteCallback& callback, |
+ net::MDnsClient* mdns_client); |
+ |
+ virtual ~ServiceResolverImpl(); |
+ |
+ // ServiceResolver implementation: |
+ virtual void StartResolving() OVERRIDE; |
+ |
+ virtual std::string GetName() const OVERRIDE; |
+ |
+ private: |
+ // Respond to transaction finishing for SRV records. |
+ void SrvRecordTransactionResponse(net::MDnsTransaction::Result status, |
+ const net::RecordParsed* record); |
+ |
+ // Respond to transaction finishing for TXT records. |
+ void TxtRecordTransactionResponse(net::MDnsTransaction::Result status, |
+ const net::RecordParsed* record); |
+ |
+ // Respond to transaction finishing for A records. |
+ void ARecordTransactionResponse(net::MDnsTransaction::Result status, |
+ const net::RecordParsed* record); |
+ |
+ void AlertCallbackIfReady(); |
+ |
+ void ServiceNotFound(RequestStatus status); |
+ |
+ // Convert a TXT record to a vector of strings (metadata). |
+ const std::vector<std::string>& RecordToMetadata( |
+ const net::RecordParsed* record) const; |
+ |
+ // Convert an SRV record to a host and port pair. |
+ net::HostPortPair RecordToAddress( |
+ const net::RecordParsed* record) const; |
+ |
+ // Convert an A record to an IP address. |
+ const net::IPAddressNumber& RecordToIPAddress( |
+ const net::RecordParsed* record) const; |
+ |
+ // Convert an MDns status to a service discovery status. |
+ RequestStatus MDnsStatusToRequestStatus( |
+ net::MDnsTransaction::Result status) const; |
+ |
+ bool CreateTxtTransaction(); |
+ bool CreateSrvTransaction(); |
+ void CreateATransaction(); |
+ |
+ std::string service_name_; |
+ ResolveCompleteCallback callback_; |
+ |
+ bool has_resolved_; |
+ |
+ bool metadata_resolved_; |
+ bool address_resolved_; |
+ |
+ scoped_ptr<net::MDnsTransaction> txt_transaction_; |
+ scoped_ptr<net::MDnsTransaction> srv_transaction_; |
+ scoped_ptr<net::MDnsTransaction> a_transaction_; |
+ |
+ ServiceDescription service_staging_; |
+ |
+ net::MDnsClient* mdns_client_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ServiceResolverImpl); |
+}; |
+ |
+class LocalDomainResolverImpl : public LocalDomainResolver { |
+ public: |
+ LocalDomainResolverImpl(const std::string& domain, |
+ net::AddressFamily address_family, |
+ const IPAddressCallback& callback, |
+ net::MDnsClient* mdns_client); |
+ virtual ~LocalDomainResolverImpl(); |
+ |
+ virtual void Start() OVERRIDE; |
+ |
+ const std::string& domain() { return domain_; } |
+ |
+ private: |
+ void OnTransactionComplete( |
+ net::MDnsTransaction::Result result, |
+ const net::RecordParsed* record); |
+ |
+ scoped_ptr<net::MDnsTransaction> CreateTransaction(uint16 type); |
+ |
+ bool IsSuccess(); |
+ |
+ void SendResolvedAddresses(); |
+ |
+ std::string domain_; |
+ net::AddressFamily address_family_; |
+ IPAddressCallback callback_; |
+ |
+ scoped_ptr<net::MDnsTransaction> transaction_a_; |
+ scoped_ptr<net::MDnsTransaction> transaction_aaaa_; |
+ |
+ int transactions_finished_; |
+ |
+ net::MDnsClient* mdns_client_; |
+ |
+ net::IPAddressNumber address_ipv4_; |
+ net::IPAddressNumber address_ipv6_; |
+ |
+ base::CancelableCallback<void()> timeout_callback_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(LocalDomainResolverImpl); |
+}; |
+ |
+ |
+} // namespace local_discovery |
+ |
+#endif // CHROME_COMMON_LOCAL_DISCOVERY_SERVICE_DISCOVERY_CLIENT_IMPL_H_ |