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