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_CONFIG_H_ 18 #define SHILL_DHCP_DHCP_CONFIG_H_ 19 20 #include <map> 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 #include <base/cancelable_callback.h> 26 #include <base/files/file_path.h> 27 #include <base/memory/weak_ptr.h> 28 #include <gtest/gtest_prod.h> // for FRIEND_TEST 29 30 #include "shill/ipconfig.h" 31 #include "shill/key_value_store.h" 32 33 namespace shill { 34 35 class ControlInterface; 36 class DHCPProvider; 37 class DHCPProxyInterface; 38 class EventDispatcher; 39 class Metrics; 40 class ProcessManager; 41 42 // This class provides a DHCP client instance for the device |device_name|. 43 // 44 // The DHPCConfig instance asks the DHCP client to create a lease file 45 // containing the name |lease_file_suffix|. If this suffix is the same as 46 // |device_name|, the lease is considered to be ephemeral, and the lease 47 // file is removed whenever this DHCPConfig instance is no longer needed. 48 // Otherwise, the lease file persists and will be re-used in future attempts. 49 class DHCPConfig : public IPConfig { 50 public: 51 DHCPConfig(ControlInterface* control_interface, 52 EventDispatcher* dispatcher, 53 DHCPProvider* provider, 54 const std::string& device_name, 55 const std::string& type, 56 const std::string& lease_file_suffix); 57 ~DHCPConfig() override; 58 59 // Inherited from IPConfig. 60 bool RequestIP() override; 61 bool RenewIP() override; 62 bool ReleaseIP(ReleaseReason reason) override; 63 64 // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to 65 // |service|. 66 void InitProxy(const std::string& service); 67 68 // Processes an Event signal from dhcpcd. 69 virtual void ProcessEventSignal(const std::string& reason, 70 const KeyValueStore& configuration) = 0; 71 72 // Processes an Status Change signal from dhcpcd. 73 virtual void ProcessStatusChangeSignal(const std::string& status) = 0; 74 75 // Set the minimum MTU that this configuration will respect. set_minimum_mtu(const int minimum_mtu)76 virtual void set_minimum_mtu(const int minimum_mtu) { 77 minimum_mtu_ = minimum_mtu; 78 } 79 80 protected: 81 // Overrides base clase implementation. 82 void UpdateProperties(const Properties& properties, 83 bool new_lease_acquired) override; 84 void NotifyFailure() override; 85 minimum_mtu()86 int minimum_mtu() const { return minimum_mtu_; } 87 set_is_lease_active(bool active)88 void set_is_lease_active(bool active) { is_lease_active_ = active; } 89 90 // Return true if the lease file is ephermeral, which means the lease file 91 // should be deleted during cleanup. 92 bool IsEphemeralLease() const; 93 94 // Cleans up remaining state from a running client, if any, including freeing 95 // its GPid, exit watch callback, and state files. 96 // The file path for the lease file and pid file is different for IPv4 97 // and IPv6. So make this function virtual to have the derived class delete 98 // the files accordingly. 99 virtual void CleanupClientState(); 100 101 // Return true if we should treat acquisition timeout as failure. ShouldFailOnAcquisitionTimeout()102 virtual bool ShouldFailOnAcquisitionTimeout() { return true; } 103 104 // Return true if we should keep the lease on disconnect. ShouldKeepLeaseOnDisconnect()105 virtual bool ShouldKeepLeaseOnDisconnect() { return false; } 106 107 // Return the list of flags used to start dhcpcd. 108 virtual std::vector<std::string> GetFlags(); 109 root()110 base::FilePath root() const { return root_; } 111 112 private: 113 friend class DHCPConfigTest; 114 friend class DHCPv4ConfigTest; 115 friend class DHCPv6ConfigTest; 116 FRIEND_TEST(DHCPConfigCallbackTest, NotifyFailure); 117 FRIEND_TEST(DHCPConfigCallbackTest, ProcessAcquisitionTimeout); 118 FRIEND_TEST(DHCPConfigCallbackTest, RequestIPTimeout); 119 FRIEND_TEST(DHCPConfigCallbackTest, StartTimeout); 120 FRIEND_TEST(DHCPConfigCallbackTest, StoppedDuringFailureCallback); 121 FRIEND_TEST(DHCPConfigCallbackTest, StoppedDuringSuccessCallback); 122 FRIEND_TEST(DHCPConfigTest, InitProxy); 123 FRIEND_TEST(DHCPConfigTest, KeepLeaseOnDisconnect); 124 FRIEND_TEST(DHCPConfigTest, ReleaseIP); 125 FRIEND_TEST(DHCPConfigTest, ReleaseIPStaticIPWithLease); 126 FRIEND_TEST(DHCPConfigTest, ReleaseIPStaticIPWithoutLease); 127 FRIEND_TEST(DHCPConfigTest, ReleaseLeaseOnDisconnect); 128 FRIEND_TEST(DHCPConfigTest, RenewIP); 129 FRIEND_TEST(DHCPConfigTest, RequestIP); 130 FRIEND_TEST(DHCPConfigTest, Restart); 131 FRIEND_TEST(DHCPConfigTest, RestartNoClient); 132 FRIEND_TEST(DHCPConfigTest, StartFail); 133 FRIEND_TEST(DHCPConfigTest, StartWithoutLeaseSuffix); 134 FRIEND_TEST(DHCPConfigTest, Stop); 135 FRIEND_TEST(DHCPConfigTest, StopDuringRequestIP); 136 FRIEND_TEST(DHCPProviderTest, CreateIPv4Config); 137 138 static const int kAcquisitionTimeoutSeconds; 139 140 static const int kDHCPCDExitPollMilliseconds; 141 static const int kDHCPCDExitWaitMilliseconds; 142 static const char kDHCPCDPath[]; 143 static const char kDHCPCDUser[]; 144 static const char kDHCPCDGroup[]; 145 146 // Starts dhcpcd, returns true on success and false otherwise. 147 bool Start(); 148 149 // Stops dhcpcd if running. 150 void Stop(const char* reason); 151 152 // Stops dhcpcd if already running and then starts it. Returns true on success 153 // and false otherwise. 154 bool Restart(); 155 156 // Called when the dhcpcd client process exits. 157 void OnProcessExited(int exit_status); 158 159 // Initialize a callback that will invoke ProcessAcquisitionTimeout if we 160 // do not get a lease in a reasonable amount of time. 161 void StartAcquisitionTimeout(); 162 // Cancel callback created by StartAcquisitionTimeout. One-liner included 163 // for symmetry. 164 void StopAcquisitionTimeout(); 165 // Called if we do not get a DHCP lease in a reasonable amount of time. 166 // Informs upper layers of the failure. 167 void ProcessAcquisitionTimeout(); 168 169 // Initialize a callback that will invoke ProcessExpirationTimeout if we 170 // do not renew a lease in a |lease_duration_seconds|. 171 void StartExpirationTimeout(uint32_t lease_duration_seconds); 172 // Cancel callback created by StartExpirationTimeout. One-liner included 173 // for symmetry. 174 void StopExpirationTimeout(); 175 // Called if we do not renew a DHCP lease by the time the lease expires. 176 // Informs upper layers of the expiration and restarts the DHCP client. 177 void ProcessExpirationTimeout(); 178 179 // Kills DHCP client process. 180 void KillClient(); 181 182 ControlInterface* control_interface_; 183 184 DHCPProvider* provider_; 185 186 // DHCP lease file suffix, used to differentiate the lease of one interface 187 // or network from another. 188 std::string lease_file_suffix_; 189 190 // The PID of the spawned DHCP client. May be 0 if no client has been spawned 191 // yet or the client has died. 192 int pid_; 193 194 // Whether a lease has been acquired from the DHCP server or gateway ARP. 195 bool is_lease_active_; 196 197 // The proxy for communicating with the DHCP client. 198 std::unique_ptr<DHCPProxyInterface> proxy_; 199 200 // Called if we fail to get a DHCP lease in a timely manner. 201 base::CancelableClosure lease_acquisition_timeout_callback_; 202 203 // Time to wait for a DHCP lease. Represented as field so that it 204 // can be overriden in tests. 205 unsigned int lease_acquisition_timeout_seconds_; 206 207 // Called if a DHCP lease expires. 208 base::CancelableClosure lease_expiration_callback_; 209 210 // The minimum MTU value this configuration will respect. 211 int minimum_mtu_; 212 213 // Root file path, used for testing. 214 base::FilePath root_; 215 216 base::WeakPtrFactory<DHCPConfig> weak_ptr_factory_; 217 EventDispatcher* dispatcher_; 218 ProcessManager* process_manager_; 219 Metrics* metrics_; 220 221 DISALLOW_COPY_AND_ASSIGN(DHCPConfig); 222 }; 223 224 } // namespace shill 225 226 #endif // SHILL_DHCP_DHCP_CONFIG_H_ 227