Home | History | Annotate | Download | only in local_discovery
      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