Home | History | Annotate | Download | only in dhcp
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_DHCP_DHCP_PROVIDER_H_
     18 #define SHILL_DHCP_DHCP_PROVIDER_H_
     19 
     20 #include <map>
     21 #include <memory>
     22 #include <set>
     23 #include <string>
     24 
     25 #include <base/files/file_path.h>
     26 #include <base/lazy_instance.h>
     27 #include <gtest/gtest_prod.h>  // for FRIEND_TEST
     28 
     29 #include "shill/dhcp_properties.h"
     30 #include "shill/refptr_types.h"
     31 
     32 namespace shill {
     33 
     34 class ControlInterface;
     35 class DHCPCDListenerInterface;
     36 class EventDispatcher;
     37 class Metrics;
     38 
     39 // DHCPProvider is a singleton providing the main DHCP configuration
     40 // entrypoint. Once the provider is initialized through its Init method, DHCP
     41 // configurations for devices can be obtained through its CreateConfig
     42 // method. For example, a single DHCP configuration request can be initiated as:
     43 //
     44 // DHCPProvider::GetInstance()->CreateIPv4Config(device_name,
     45 //                                               lease_file_suffix,
     46 //                                               arp_gateway,
     47 //                                               dhcp_props)->Request();
     48 class DHCPProvider {
     49  public:
     50   static constexpr char kDHCPCDPathFormatLease[] =
     51       "var/lib/dhcpcd/dhcpcd-%s.lease";
     52 #ifndef DISABLE_DHCPV6
     53   static constexpr char kDHCPCDPathFormatLease6[] =
     54       "var/lib/dhcpcd/dhcpcd-%s.lease6";
     55 #endif  // DISABLE_DHCPV6
     56 
     57   virtual ~DHCPProvider();
     58 
     59   // This is a singleton -- use DHCPProvider::GetInstance()->Foo().
     60   static DHCPProvider* GetInstance();
     61 
     62   // Initializes the provider singleton. This method hooks up a D-Bus signal
     63   // listener that catches signals from spawned DHCP clients and dispatches them
     64   // to the appropriate DHCP configuration instance.
     65   virtual void Init(ControlInterface* control_interface,
     66                     EventDispatcher* dispatcher,
     67                     Metrics* metrics);
     68 
     69   // Called on shutdown to release |listener_|.
     70   void Stop();
     71 
     72   // Creates a new DHCPv4Config for |device_name|. The DHCP configuration for
     73   // the device can then be initiated through DHCPConfig::Request and
     74   // DHCPConfig::Renew.  If |host_name| is not-empty, it is placed in the DHCP
     75   // request to allow the server to map the request to a specific user-named
     76   // origin.  The DHCP lease file will contain the suffix supplied
     77   // in |lease_file_suffix| if non-empty, otherwise |device_name|.  If
     78   // |arp_gateway| is true, the DHCP client will ARP for the gateway IP
     79   // address as an additional safeguard against the issued IP address being
     80   // in-use by another station.
     81   virtual DHCPConfigRefPtr CreateIPv4Config(
     82       const std::string& device_name,
     83       const std::string& lease_file_suffix,
     84       bool arp_gateway,
     85       const DhcpProperties& dhcp_props);
     86 
     87 #ifndef DISABLE_DHCPV6
     88   // Create a new DHCPv6Config for |device_name|.
     89   virtual DHCPConfigRefPtr CreateIPv6Config(
     90       const std::string& device_name, const std::string& lease_file_suffix);
     91 #endif
     92 
     93   // Returns the DHCP configuration associated with DHCP client |pid|. Return
     94   // nullptr if |pid| is not bound to a configuration.
     95   DHCPConfigRefPtr GetConfig(int pid);
     96 
     97   // Binds a |pid| to a DHCP |config|. When a DHCP config spawns a new DHCP
     98   // client, it binds itself to that client's |pid|.
     99   virtual void BindPID(int pid, const DHCPConfigRefPtr& config);
    100 
    101   // Unbinds a |pid|. This method is used by a DHCP config to signal the
    102   // provider that the DHCP client has been terminated. This may result in
    103   // destruction of the DHCP config instance if its reference count goes to 0.
    104   virtual void UnbindPID(int pid);
    105 
    106   // Destroy lease file associated with this |name|.
    107   virtual void DestroyLease(const std::string& name);
    108 
    109   // Returns true if |pid| was recently unbound from the provider.
    110   bool IsRecentlyUnbound(int pid);
    111 
    112  protected:
    113   DHCPProvider();
    114 
    115  private:
    116   friend struct base::DefaultLazyInstanceTraits<DHCPProvider>;
    117   friend class CellularTest;
    118   friend class DHCPProviderTest;
    119   friend class DeviceInfoTest;
    120   friend class DeviceTest;
    121   FRIEND_TEST(DHCPProviderTest, CreateIPv4Config);
    122   FRIEND_TEST(DHCPProviderTest, DestroyLease);
    123 
    124   typedef std::map<int, DHCPConfigRefPtr> PIDConfigMap;
    125 
    126   // Retire |pid| from the set of recently retired PIDs.
    127   void RetireUnboundPID(int pid);
    128 
    129   // A single listener is used to catch signals from all DHCP clients and
    130   // dispatch them to the appropriate DHCP configuration instance.
    131   std::unique_ptr<DHCPCDListenerInterface> listener_;
    132 
    133   // A map that binds PIDs to DHCP configuration instances.
    134   PIDConfigMap configs_;
    135 
    136   base::FilePath root_;
    137   ControlInterface* control_interface_;
    138   EventDispatcher* dispatcher_;
    139   Metrics* metrics_;
    140 
    141   // Track the set of PIDs recently unbound from the provider in case messages
    142   // arrive addressed from them.
    143   std::set<int> recently_unbound_pids_;
    144 
    145   DISALLOW_COPY_AND_ASSIGN(DHCPProvider);
    146 };
    147 
    148 }  // namespace shill
    149 
    150 #endif  // SHILL_DHCP_DHCP_PROVIDER_H_
    151