blob: 65e14328e26f5a3bce95574f2175fa6593033685 [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"
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -070017#include "shill/minijail.h"
Darin Petkov50308cd2011-06-01 18:25:07 -070018
19namespace shill {
20
Chris Masone19e30402011-07-19 15:48:47 -070021class ControlInterface;
Darin Petkovd1b715b2011-06-02 21:21:22 -070022class DHCPProvider;
23class DHCPProxyInterface;
Darin Petkova7b89492011-07-27 12:48:17 -070024class EventDispatcher;
Darin Petkov3258a812011-06-23 11:28:45 -070025class GLib;
Darin Petkovab565bb2011-10-06 02:55:51 -070026class ProxyFactory;
Darin Petkovd1b715b2011-06-02 21:21:22 -070027
Paul Stewartd408fdf2012-05-07 17:15:57 -070028// This class provides a DHCP client instance for the device |device_name|.
29// If |request_hostname| is non-empty, it asks the DHCP server to register
30// this hostname on our behalf, for purposes of administration or creating
31// a dynamic DNS entry.
32//
33// The DHPCConfig instance asks the DHCP client to create a lease file
34// containing the name |lease_file_suffix|. If this suffix is the same as
35// |device_name|, the lease is considered to be ephemeral, and the lease
36// file is removed whenever this DHCPConfig instance is no longer needed.
37// Otherwise, the lease file persists and will be re-used in future attempts.
Eric Shienbrood9a245532012-03-07 14:20:39 -050038class DHCPConfig : public IPConfig {
Darin Petkov50308cd2011-06-01 18:25:07 -070039 public:
Darin Petkove7cb7f82011-06-03 13:21:51 -070040 typedef std::map<std::string, DBus::Variant> Configuration;
41
Darin Petkov14c29ec2012-03-02 11:34:19 +010042 static const int kMinMTU;
43
Chris Masone19e30402011-07-19 15:48:47 -070044 DHCPConfig(ControlInterface *control_interface,
Darin Petkova7b89492011-07-27 12:48:17 -070045 EventDispatcher *dispatcher,
Chris Masone19e30402011-07-19 15:48:47 -070046 DHCPProvider *provider,
Darin Petkovf65e9282011-06-21 14:29:56 -070047 const std::string &device_name,
Paul Stewartd32f4842012-01-11 16:08:13 -080048 const std::string &request_hostname,
Paul Stewartd408fdf2012-05-07 17:15:57 -070049 const std::string &lease_file_suffix,
50 bool arp_gateway,
Darin Petkov3258a812011-06-23 11:28:45 -070051 GLib *glib);
Darin Petkov50308cd2011-06-01 18:25:07 -070052 virtual ~DHCPConfig();
53
Darin Petkovd1b715b2011-06-02 21:21:22 -070054 // Inherited from IPConfig.
Darin Petkov92c43902011-06-09 20:46:06 -070055 virtual bool RequestIP();
56 virtual bool RenewIP();
57 virtual bool ReleaseIP();
Darin Petkovd1b715b2011-06-02 21:21:22 -070058
59 // If |proxy_| is not initialized already, sets it to a new D-Bus proxy to
60 // |service|.
Darin Petkova7b89492011-07-27 12:48:17 -070061 void InitProxy(const std::string &service);
Darin Petkovd1b715b2011-06-02 21:21:22 -070062
Darin Petkove7cb7f82011-06-03 13:21:51 -070063 // Processes an Event signal from dhcpcd.
64 void ProcessEventSignal(const std::string &reason,
65 const Configuration &configuration);
66
mukesh agrawalcc0fded2012-05-09 13:40:58 -070067 protected:
68 // Overrides base clase implementation.
69 virtual void UpdateProperties(const Properties &properties, bool success);
70
Darin Petkov50308cd2011-06-01 18:25:07 -070071 private:
Darin Petkov98dd6a02011-06-10 15:12:57 -070072 friend class DHCPConfigTest;
Darin Petkove7cb7f82011-06-03 13:21:51 -070073 FRIEND_TEST(DHCPConfigTest, GetIPv4AddressString);
Darin Petkova7b89492011-07-27 12:48:17 -070074 FRIEND_TEST(DHCPConfigTest, InitProxy);
Darin Petkove7cb7f82011-06-03 13:21:51 -070075 FRIEND_TEST(DHCPConfigTest, ParseConfiguration);
Darin Petkovf9b0ca82011-06-20 12:10:23 -070076 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalFail);
77 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalSuccess);
78 FRIEND_TEST(DHCPConfigTest, ProcessEventSignalUnknown);
Darin Petkov98dd6a02011-06-10 15:12:57 -070079 FRIEND_TEST(DHCPConfigTest, ReleaseIP);
Paul Stewarta02ee492012-05-16 10:04:53 -070080 FRIEND_TEST(DHCPConfigTest, ReleaseIPArpGW);
Darin Petkov98dd6a02011-06-10 15:12:57 -070081 FRIEND_TEST(DHCPConfigTest, RenewIP);
82 FRIEND_TEST(DHCPConfigTest, RequestIP);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070083 FRIEND_TEST(DHCPConfigTest, RequestIPTimeout);
Darin Petkov98dd6a02011-06-10 15:12:57 -070084 FRIEND_TEST(DHCPConfigTest, Restart);
85 FRIEND_TEST(DHCPConfigTest, RestartNoClient);
Darin Petkov92c43902011-06-09 20:46:06 -070086 FRIEND_TEST(DHCPConfigTest, StartFail);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070087 FRIEND_TEST(DHCPConfigTest, StartTimeout);
Paul Stewartd32f4842012-01-11 16:08:13 -080088 FRIEND_TEST(DHCPConfigTest, StartWithHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070089 FRIEND_TEST(DHCPConfigTest, StartWithoutArpGateway);
Paul Stewartd32f4842012-01-11 16:08:13 -080090 FRIEND_TEST(DHCPConfigTest, StartWithoutHostname);
Paul Stewartd408fdf2012-05-07 17:15:57 -070091 FRIEND_TEST(DHCPConfigTest, StartWithoutLeaseSuffix);
Darin Petkov98dd6a02011-06-10 15:12:57 -070092 FRIEND_TEST(DHCPConfigTest, Stop);
mukesh agrawalcc0fded2012-05-09 13:40:58 -070093 FRIEND_TEST(DHCPConfigTest, StopDuringRequestIP);
Darin Petkov98dd6a02011-06-10 15:12:57 -070094 FRIEND_TEST(DHCPProviderTest, CreateConfig);
Darin Petkove7cb7f82011-06-03 13:21:51 -070095
Darin Petkovf9b0ca82011-06-20 12:10:23 -070096 static const char kConfigurationKeyBroadcastAddress[];
97 static const char kConfigurationKeyDNS[];
98 static const char kConfigurationKeyDomainName[];
99 static const char kConfigurationKeyDomainSearch[];
100 static const char kConfigurationKeyIPAddress[];
101 static const char kConfigurationKeyMTU[];
102 static const char kConfigurationKeyRouters[];
103 static const char kConfigurationKeySubnetCIDR[];
104
Thieu Le94eed562012-02-21 15:57:29 -0800105 static const int kDHCPCDExitPollMilliseconds;
106 static const int kDHCPCDExitWaitMilliseconds;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700107 static const char kDHCPCDPath[];
Darin Petkov92c43902011-06-09 20:46:06 -0700108 static const char kDHCPCDPathFormatLease[];
109 static const char kDHCPCDPathFormatPID[];
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700110 static const int kDHCPTimeoutSeconds;
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700111 static const char kDHCPCDUser[];
Darin Petkovd1b715b2011-06-02 21:21:22 -0700112
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700113 static const char kReasonBound[];
Paul Stewarta02ee492012-05-16 10:04:53 -0700114 static const char kReasonGatewayArp[];
Darin Petkovf9b0ca82011-06-20 12:10:23 -0700115 static const char kReasonFail[];
116 static const char kReasonRebind[];
117 static const char kReasonReboot[];
118 static const char kReasonRenew[];
119
Chris Masone0756f232011-07-21 17:24:00 -0700120 static const char kType[];
121
Darin Petkovd1b715b2011-06-02 21:21:22 -0700122 // Starts dhcpcd, returns true on success and false otherwise.
123 bool Start();
124
Darin Petkov92c43902011-06-09 20:46:06 -0700125 // Stops dhcpcd if running.
126 void Stop();
127
Darin Petkov98dd6a02011-06-10 15:12:57 -0700128 // Stops dhcpcd if already running and then starts it. Returns true on success
129 // and false otherwise.
130 bool Restart();
131
Darin Petkove7cb7f82011-06-03 13:21:51 -0700132 // Parses |configuration| into |properties|. Returns true on success, and
133 // false otherwise.
134 bool ParseConfiguration(const Configuration& configuration,
135 IPConfig::Properties *properties);
136
137 // Returns the string representation of the IP address |address|, or an
138 // empty string on failure.
139 std::string GetIPv4AddressString(unsigned int address);
140
Darin Petkov92c43902011-06-09 20:46:06 -0700141 // Called when the dhcpcd client process exits.
142 static void ChildWatchCallback(GPid pid, gint status, gpointer data);
143
Darin Petkov98dd6a02011-06-10 15:12:57 -0700144 // Cleans up remaining state from a running client, if any, including freeing
145 // its GPid, exit watch callback, and state files.
Darin Petkov92c43902011-06-09 20:46:06 -0700146 void CleanupClientState();
147
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700148 // Initialize a callback that will invoke ProcessDHCPTimeout if we
149 // do not get a lease in a reasonable amount of time.
150 void StartDHCPTimeout();
151 // Cancel callback created by StartDHCPTimeout. One-liner included
152 // for symmetry.
153 void StopDHCPTimeout();
154 // Called if we do not get a DHCP lease in a reasonable amount of time.
155 // Informs upper layers of the failure.
156 void ProcessDHCPTimeout();
157
Darin Petkovab565bb2011-10-06 02:55:51 -0700158 // Store cached copies of singletons for speed/ease of testing.
159 ProxyFactory *proxy_factory_;
160
Darin Petkovd1b715b2011-06-02 21:21:22 -0700161 DHCPProvider *provider_;
162
Paul Stewartd32f4842012-01-11 16:08:13 -0800163 // Hostname to be used in the request. This will be passed to the DHCP
164 // server in the request.
165 std::string request_hostname_;
166
Paul Stewartd408fdf2012-05-07 17:15:57 -0700167 // DHCP lease file suffix, used to differentiate the lease of one interface
168 // or network from another.
169 std::string lease_file_suffix_;
170
171 // Specifies whether to supply an argument to the DHCP client to validate
172 // the acquired IP address using an ARP request to the gateway IP address.
173 bool arp_gateway_;
174
Darin Petkovd1b715b2011-06-02 21:21:22 -0700175 // The PID of the spawned DHCP client. May be 0 if no client has been spawned
176 // yet or the client has died.
Darin Petkov92c43902011-06-09 20:46:06 -0700177 int pid_;
178
179 // Child exit watch callback source tag.
180 unsigned int child_watch_tag_;
Darin Petkovd1b715b2011-06-02 21:21:22 -0700181
182 // The proxy for communicating with the DHCP client.
183 scoped_ptr<DHCPProxyInterface> proxy_;
184
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700185 // Called if we fail to get a DHCP lease in a timely manner.
186 base::CancelableClosure lease_acquisition_timeout_callback_;
187
188 // Time to wait for a DHCP lease. Represented as field so that it
189 // can be overriden in tests.
190 unsigned int lease_acquisition_timeout_seconds_;
191
Darin Petkov92c43902011-06-09 20:46:06 -0700192 // Root file path, used for testing.
193 FilePath root_;
194
mukesh agrawalcc0fded2012-05-09 13:40:58 -0700195 base::WeakPtrFactory<DHCPConfig> weak_ptr_factory_;
Darin Petkova7b89492011-07-27 12:48:17 -0700196 EventDispatcher *dispatcher_;
Darin Petkov3258a812011-06-23 11:28:45 -0700197 GLib *glib_;
Darin Petkovf7897bc2011-06-08 17:13:36 -0700198
Jorge Lucangeli Obesad43cc62012-04-11 16:25:43 -0700199 Minijail *minijail_;
200
Darin Petkov50308cd2011-06-01 18:25:07 -0700201 DISALLOW_COPY_AND_ASSIGN(DHCPConfig);
202};
203
204} // namespace shill
205
206#endif // SHILL_DHCP_CONFIG_