blob: e66ee985a529a3617b2e0cd368ad36445c00b39b [file] [log] [blame]
Thieu Le94eed562012-02-21 15:57:29 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov50308cd2011-06-01 18:25:07 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_DHCP_CONFIG_
6#define SHILL_DHCP_CONFIG_
7
mukesh agrawalcc0fded2012-05-09 13:40:58 -07008#include <base/cancelable_callback.h>
Darin Petkov92c43902011-06-09 20:46:06 -07009#include <base/file_path.h>
Darin Petkovd1b715b2011-06-02 21:21:22 -070010#include <base/memory/scoped_ptr.h>
mukesh agrawalcc0fded2012-05-09 13:40:58 -070011#include <base/memory/weak_ptr.h>
Darin Petkovaceede32011-07-18 15:32:38 -070012#include <dbus-c++/types.h>
Darin Petkov92c43902011-06-09 20:46:06 -070013#include <glib.h>
Darin Petkove7cb7f82011-06-03 13:21:51 -070014#include <gtest/gtest_prod.h> // for FRIEND_TEST
Darin Petkovd1b715b2011-06-02 21:21:22 -070015
Darin Petkov50308cd2011-06-01 18:25:07 -070016#include "shill/ipconfig.h"
17
18namespace shill {
19
Chris Masone19e30402011-07-19 15:48:47 -070020class ControlInterface;
Darin Petkovd1b715b2011-06-02 21:21:22 -070021class DHCPProvider;
22class DHCPProxyInterface;
Darin Petkova7b89492011-07-27 12:48:17 -070023class EventDispatcher;
Darin Petkov3258a812011-06-23 11:28:45 -070024class GLib;
Darin Petkovab565bb2011-10-06 02:55:51 -070025class ProxyFactory;
Darin Petkovd1b715b2011-06-02 21:21:22 -070026
Paul Stewartd408fdf2012-05-07 17:15:57 -070027// This class provides a DHCP client instance for the device |device_name|.
28// If |request_hostname| is non-empty, it asks the DHCP server to register
29// this hostname on our behalf, for purposes of administration or creating
30// a dynamic DNS entry.
31//
32// The DHPCConfig instance asks the DHCP client to create a lease file
33// containing the name |lease_file_suffix|. If this suffix is the same as
34// |device_name|, the lease is considered to be ephemeral, and the lease
35// file is removed whenever this DHCPConfig instance is no longer needed.
36// Otherwise, the lease file persists and will be re-used in future attempts.
Eric Shienbrood9a245532012-03-07 14:20:39 -050037class DHCPConfig : public IPConfig {
Darin Petkov50308cd2011-06-01 18:25:07 -070038 public:
Darin Petkove7cb7f82011-06-03 13:21:51 -070039 typedef std::map<std::string, DBus::Variant> Configuration;
40
Darin Petkov14c29ec2012-03-02 11:34:19 +010041 static const int kMinMTU;
42
Chris Masone19e30402011-07-19 15:48:47 -070043 DHCPConfig(ControlInterface *control_interface,
Darin Petkova7b89492011-07-27 12:48:17 -070044 EventDispatcher *dispatcher,
Chris Masone19e30402011-07-19 15:48:47 -070045 DHCPProvider *provider,
Darin Petkovf65e9282011-06-21 14:29:56 -070046 const std::string &device_name,
Paul Stewartd32f4842012-01-11 16:08:13 -080047 const std::string &request_hostname,
Paul Stewartd408fdf2012-05-07 17:15:57 -070048 const std::string &lease_file_suffix,
49 bool arp_gateway,
Darin Petkov3258a812011-06-23 11:28:45 -070050 GLib *glib);
Darin Petkov50308cd2011-06-01 18:25:07 -070051 virtual ~DHCPConfig();
52
Darin Petkovd1b715b2011-06-02 21:21:22 -070053 // Inherited from IPConfig.
Darin Petkov92c43902011-06-09 20:46:06 -070054 virtual bool RequestIP();
55 virtual bool RenewIP();
56 virtual bool ReleaseIP();
Darin Petkovd1b715b2011-06-02 21:21:22 -070057
58 // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to
59 // |service|.
Darin Petkova7b89492011-07-27 12:48:17 -070060 void InitProxy(const std::string &service);
Darin Petkovd1b715b2011-06-02 21:21:22 -070061
Darin Petkove7cb7f82011-06-03 13:21:51 -070062 // Processes an Event signal from dhcpcd.
63 void ProcessEventSignal(const std::string &reason,
64 const Configuration &configuration);
65
mukesh agrawalcc0fded2012-05-09 13:40:58 -070066 protected:
67 // Overrides base clase implementation.
68 virtual void UpdateProperties(const Properties &properties, bool success);
69
Darin Petkov50308cd2011-06-01 18:25:07 -070070 private:
Darin Petkov98dd6a02011-06-10 15:12:57 -070071 friend class DHCPConfigTest;
Darin Petkove7cb7f82011-06-03 13:21:51 -070072 FRIEND_TEST(DHCPConfigTest, GetIPv4AddressString);
Darin Petkova7b89492011-07-27 12:48:17 -070073 FRIEND_TEST(DHCPConfigTest, InitProxy);
Darin Petkove7cb7f82011-06-03 13:21:51 -070074 FRIEND_TEST(DHCPConfigTest, ParseConfiguration);
Darin Petkovf9b0ca82011-06-20 12:10:23 -070075 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalFail);
76 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalSuccess);
77 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalUnknown);
Darin Petkov98dd6a02011-06-10 15:12:57 -070078 FRIEND_TEST(DHCPConfigTest, ReleaseIP);
79 FRIEND_TEST(DHCPConfigTest, RenewIP);
80 FRIEND_TEST(DHCPConfigTest, RequestIP);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070081 FRIEND_TEST(DHCPConfigTest, RequestIPTimeout);
Darin Petkov98dd6a02011-06-10 15:12:57 -070082 FRIEND_TEST(DHCPConfigTest, Restart);
83 FRIEND_TEST(DHCPConfigTest, RestartNoClient);
Darin Petkov92c43902011-06-09 20:46:06 -070084 FRIEND_TEST(DHCPConfigTest, StartFail);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070085 FRIEND_TEST(DHCPConfigTest, StartTimeout);
Paul Stewartd32f4842012-01-11 16:08:13 -080086 FRIEND_TEST(DHCPConfigTest, StartWithHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070087 FRIEND_TEST(DHCPConfigTest, StartWithoutArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -080088 FRIEND_TEST(DHCPConfigTest, StartWithoutHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070089 FRIEND_TEST(DHCPConfigTest, StartWithoutLeaseSuffix);
Darin Petkov98dd6a02011-06-10 15:12:57 -070090 FRIEND_TEST(DHCPConfigTest, Stop);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070091 FRIEND_TEST(DHCPConfigTest, StopDuringRequestIP);
Darin Petkov98dd6a02011-06-10 15:12:57 -070092 FRIEND_TEST(DHCPProviderTest, CreateConfig);
Darin Petkove7cb7f82011-06-03 13:21:51 -070093
Darin Petkovf9b0ca82011-06-20 12:10:23 -070094 static const char kConfigurationKeyBroadcastAddress[];
95 static const char kConfigurationKeyDNS[];
96 static const char kConfigurationKeyDomainName[];
97 static const char kConfigurationKeyDomainSearch[];
98 static const char kConfigurationKeyIPAddress[];
99 static const char kConfigurationKeyMTU[];
100 static const char kConfigurationKeyRouters[];
101 static const char kConfigurationKeySubnetCIDR[];
102
Thieu Le94eed562012-02-21 15:57:29 -0800103 static const int kDHCPCDExitPollMilliseconds;
104 static const int kDHCPCDExitWaitMilliseconds;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700105 static const char kDHCPCDPath[];
Darin Petkov92c43902011-06-09 20:46:06 -0700106 static const char kDHCPCDPathFormatLease[];
107 static const char kDHCPCDPathFormatPID[];
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700108 static const int kDHCPTimeoutSeconds;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700109
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700110 static const char kReasonBound[];
111 static const char kReasonFail[];
112 static const char kReasonRebind[];
113 static const char kReasonReboot[];
114 static const char kReasonRenew[];
115
Chris Masone0756f232011-07-21 17:24:00 -0700116 static const char kType[];
117
Darin Petkovd1b715b2011-06-02 21:21:22 -0700118 // Starts dhcpcd, returns true on success and false otherwise.
119 bool Start();
120
Darin Petkov92c43902011-06-09 20:46:06 -0700121 // Stops dhcpcd if running.
122 void Stop();
123
Darin Petkov98dd6a02011-06-10 15:12:57 -0700124 // Stops dhcpcd if already running and then starts it. Returns true on success
125 // and false otherwise.
126 bool Restart();
127
Darin Petkove7cb7f82011-06-03 13:21:51 -0700128 // Parses |configuration| into |properties|. Returns true on success, and
129 // false otherwise.
130 bool ParseConfiguration(const Configuration& configuration,
131 IPConfig::Properties *properties);
132
133 // Returns the string representation of the IP address |address|, or an
134 // empty string on failure.
135 std::string GetIPv4AddressString(unsigned int address);
136
Darin Petkov92c43902011-06-09 20:46:06 -0700137 // Called when the dhcpcd client process exits.
138 static void ChildWatchCallback(GPid pid, gint status, gpointer data);
139
Darin Petkov98dd6a02011-06-10 15:12:57 -0700140 // Cleans up remaining state from a running client, if any, including freeing
141 // its GPid, exit watch callback, and state files.
Darin Petkov92c43902011-06-09 20:46:06 -0700142 void CleanupClientState();
143
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700144 // Initialize a callback that will invoke ProcessDHCPTimeout if we
145 // do not get a lease in a reasonable amount of time.
146 void StartDHCPTimeout();
147 // Cancel callback created by StartDHCPTimeout. One-liner included
148 // for symmetry.
149 void StopDHCPTimeout();
150 // Called if we do not get a DHCP lease in a reasonable amount of time.
151 // Informs upper layers of the failure.
152 void ProcessDHCPTimeout();
153
Darin Petkovab565bb2011-10-06 02:55:51 -0700154 // Store cached copies of singletons for speed/ease of testing.
155 ProxyFactory *proxy_factory_;
156
Darin Petkovd1b715b2011-06-02 21:21:22 -0700157 DHCPProvider *provider_;
158
Paul Stewartd32f4842012-01-11 16:08:13 -0800159 // Hostname to be used in the request. This will be passed to the DHCP
160 // server in the request.
161 std::string request_hostname_;
162
Paul Stewartd408fdf2012-05-07 17:15:57 -0700163 // DHCP lease file suffix, used to differentiate the lease of one interface
164 // or network from another.
165 std::string lease_file_suffix_;
166
167 // Specifies whether to supply an argument to the DHCP client to validate
168 // the acquired IP address using an ARP request to the gateway IP address.
169 bool arp_gateway_;
170
Darin Petkovd1b715b2011-06-02 21:21:22 -0700171 // The PID of the spawned DHCP client. May be 0 if no client has been spawned
172 // yet or the client has died.
Darin Petkov92c43902011-06-09 20:46:06 -0700173 int pid_;
174
175 // Child exit watch callback source tag.
176 unsigned int child_watch_tag_;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700177
178 // The proxy for communicating with the DHCP client.
179 scoped_ptr<DHCPProxyInterface> proxy_;
180
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700181 // Called if we fail to get a DHCP lease in a timely manner.
182 base::CancelableClosure lease_acquisition_timeout_callback_;
183
184 // Time to wait for a DHCP lease. Represented as field so that it
185 // can be overriden in tests.
186 unsigned int lease_acquisition_timeout_seconds_;
187
Darin Petkov92c43902011-06-09 20:46:06 -0700188 // Root file path, used for testing.
189 FilePath root_;
190
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700191 base::WeakPtrFactory<DHCPConfig> weak_ptr_factory_;
Darin Petkova7b89492011-07-27 12:48:17 -0700192 EventDispatcher *dispatcher_;
Darin Petkov3258a812011-06-23 11:28:45 -0700193 GLib *glib_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700194
Darin Petkov50308cd2011-06-01 18:25:07 -0700195 DISALLOW_COPY_AND_ASSIGN(DHCPConfig);
196};
197
198} // namespace shill
199
200#endif // SHILL_DHCP_CONFIG_