1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2012 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 1650308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 17675d0b0f04936050a357722f52dc078a3ab671d8Peter Qiu#ifndef SHILL_DHCP_DHCP_PROVIDER_H_ 18675d0b0f04936050a357722f52dc078a3ab671d8Peter Qiu#define SHILL_DHCP_DHCP_PROVIDER_H_ 1950308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 20d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov#include <map> 21cd47732488cd101eaf0d3558dde5a7d4e4fc260bBen Chan#include <memory> 22d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart#include <set> 23aceede399cc4e0fafb05776ba455ebdbe7e96397Darin Petkov#include <string> 24d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 25a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/files/file_path.h> 260d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart#include <base/lazy_instance.h> 27f7897bcadc2c1860af9469d7d13e223219f842aaDarin Petkov#include <gtest/gtest_prod.h> // for FRIEND_TEST 28d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 2915d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein#include "shill/dhcp_properties.h" 302b10554b6c736f3421102d483b74b70bb82f997cChris Masone#include "shill/refptr_types.h" 3150308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 3250308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkovnamespace shill { 3350308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 3419e30406a1d3123892007d20438527dc4b2f92c3Chris Masoneclass ControlInterface; 35820012496f8c171a7c5da4a4904a6ee93bfea2e9Peter Qiuclass DHCPCDListenerInterface; 36a7b8949f39e8c2ae2324dda16b9aa121cc3f7e8fDarin Petkovclass EventDispatcher; 373bdf1abfba480415a4714108e615649f422197e0Paul Stewartclass Metrics; 38d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 39d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov// DHCPProvider is a singleton providing the main DHCP configuration 40d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov// entrypoint. Once the provider is initialized through its Init method, DHCP 41d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov// configurations for devices can be obtained through its CreateConfig 42d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov// method. For example, a single DHCP configuration request can be initiated as: 43d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov// 448e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu// DHCPProvider::GetInstance()->CreateIPv4Config(device_name, 458e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu// lease_file_suffix, 4615d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein// arp_gateway, 4715d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein// dhcp_props)->Request(); 4850308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkovclass DHCPProvider { 4950308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov public: 5088fb16f17cafa2e2f25cdf12852983d705b31f38mukesh agrawal static constexpr char kDHCPCDPathFormatLease[] = 5188fb16f17cafa2e2f25cdf12852983d705b31f38mukesh agrawal "var/lib/dhcpcd/dhcpcd-%s.lease"; 52b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#ifndef DISABLE_DHCPV6 53b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu static constexpr char kDHCPCDPathFormatLease6[] = 54b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu "var/lib/dhcpcd/dhcpcd-%s.lease6"; 55b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#endif // DISABLE_DHCPV6 560e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk 570d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart virtual ~DHCPProvider(); 580d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart 59f407d5934100e6f2106aeeede46bafb0074cee35mukesh agrawal // This is a singleton -- use DHCPProvider::GetInstance()->Foo(). 600bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart static DHCPProvider* GetInstance(); 6150308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 62d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // Initializes the provider singleton. This method hooks up a D-Bus signal 63aceede399cc4e0fafb05776ba455ebdbe7e96397Darin Petkov // listener that catches signals from spawned DHCP clients and dispatches them 64aceede399cc4e0fafb05776ba455ebdbe7e96397Darin Petkov // to the appropriate DHCP configuration instance. 650bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart virtual void Init(ControlInterface* control_interface, 660bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart EventDispatcher* dispatcher, 670bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart Metrics* metrics); 68d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 698dc5e7b99920ab79d2bee7f99fec9fa5765fda68Paul Stewart // Called on shutdown to release |listener_|. 708dc5e7b99920ab79d2bee7f99fec9fa5765fda68Paul Stewart void Stop(); 718dc5e7b99920ab79d2bee7f99fec9fa5765fda68Paul Stewart 728e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu // Creates a new DHCPv4Config for |device_name|. The DHCP configuration for 738e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu // the device can then be initiated through DHCPConfig::Request and 74d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart // DHCPConfig::Renew. If |host_name| is not-empty, it is placed in the DHCP 75d32f484b91ab583ccc9a14b2a6b5182fda6958f0Paul Stewart // request to allow the server to map the request to a specific user-named 76d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart // origin. The DHCP lease file will contain the suffix supplied 77d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart // in |lease_file_suffix| if non-empty, otherwise |device_name|. If 78d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart // |arp_gateway| is true, the DHCP client will ARP for the gateway IP 79d408fdf69489e3199c63796a06f7cfbbb4513515Paul Stewart // address as an additional safeguard against the issued IP address being 80b108318d9554032feee1249d51c961e4f90f4561Paul Stewart // in-use by another station. 818e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu virtual DHCPConfigRefPtr CreateIPv4Config( 820bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart const std::string& device_name, 830bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart const std::string& lease_file_suffix, 8415d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein bool arp_gateway, 8515d5431798155cc83a3fcb8abe0d1a2d5128f7b6Rebecca Silberstein const DhcpProperties& dhcp_props); 86d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 87b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#ifndef DISABLE_DHCPV6 88b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu // Create a new DHCPv6Config for |device_name|. 89b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu virtual DHCPConfigRefPtr CreateIPv6Config( 900bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart const std::string& device_name, const std::string& lease_file_suffix); 91b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu#endif 92b255a76b77bbe54ed0ed8b50ba05a959acfda180Peter Qiu 93d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // Returns the DHCP configuration associated with DHCP client |pid|. Return 94cc225ef3b77b5e098cc12c661a947e1737480777Ben Chan // nullptr if |pid| is not bound to a configuration. 9598dd6a0c9facbd208c6f08ad4150f7d384a8a5eaDarin Petkov DHCPConfigRefPtr GetConfig(int pid); 96d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 97d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // Binds a |pid| to a DHCP |config|. When a DHCP config spawns a new DHCP 98d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // client, it binds itself to that client's |pid|. 990bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart virtual void BindPID(int pid, const DHCPConfigRefPtr& config); 100d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 101d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // Unbinds a |pid|. This method is used by a DHCP config to signal the 102d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // provider that the DHCP client has been terminated. This may result in 103d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // destruction of the DHCP config instance if its reference count goes to 0. 104d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart virtual void UnbindPID(int pid); 105d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 1060e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk // Destroy lease file associated with this |name|. 1070bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart virtual void DestroyLease(const std::string& name); 1080e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk 109d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart // Returns true if |pid| was recently unbound from the provider. 110d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart bool IsRecentlyUnbound(int pid); 111d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart 1120d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart protected: 1130d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart DHCPProvider(); 1140d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart 11550308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov private: 1160d2ada3971075e78fb9900d0753c9ad94c15add4Paul Stewart friend struct base::DefaultLazyInstanceTraits<DHCPProvider>; 11777cb681ab58c6623464a355e646138ab84d38573Darin Petkov friend class CellularTest; 11898dd6a0c9facbd208c6f08ad4150f7d384a8a5eaDarin Petkov friend class DHCPProviderTest; 119afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov friend class DeviceInfoTest; 120afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov friend class DeviceTest; 1218e0151e84f077cc9c0646d5bafd925ed235a1c12Peter Qiu FRIEND_TEST(DHCPProviderTest, CreateIPv4Config); 1220e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk FRIEND_TEST(DHCPProviderTest, DestroyLease); 123f7897bcadc2c1860af9469d7d13e223219f842aaDarin Petkov 12492c4390285270320f6145c8295de0abdcc315380Darin Petkov typedef std::map<int, DHCPConfigRefPtr> PIDConfigMap; 12550308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 126d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart // Retire |pid| from the set of recently retired PIDs. 127d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart void RetireUnboundPID(int pid); 128d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart 129d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // A single listener is used to catch signals from all DHCP clients and 130afa6fc4d31e884af8710deb14798c69b9c9a898eDarin Petkov // dispatch them to the appropriate DHCP configuration instance. 131820012496f8c171a7c5da4a4904a6ee93bfea2e9Peter Qiu std::unique_ptr<DHCPCDListenerInterface> listener_; 132d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 133d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov // A map that binds PIDs to DHCP configuration instances. 134d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov PIDConfigMap configs_; 135d1b715b403e17f4ce01ec15877ea1901fc21a885Darin Petkov 1360e1cdeae24dd678a5fe27c840802582c0ca45ec0Albert Chaulk base::FilePath root_; 1370bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart ControlInterface* control_interface_; 1380bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart EventDispatcher* dispatcher_; 1390bfabaae654ba3bf597a303b7517a0e14fd65089Paul Stewart Metrics* metrics_; 140f7897bcadc2c1860af9469d7d13e223219f842aaDarin Petkov 141d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart // Track the set of PIDs recently unbound from the provider in case messages 142d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart // arrive addressed from them. 143d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart std::set<int> recently_unbound_pids_; 144d1c7b413bf7e1f264d1acfdfb2f698413f6cf352Paul Stewart 14550308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov DISALLOW_COPY_AND_ASSIGN(DHCPProvider); 14650308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov}; 14750308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 14850308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov} // namespace shill 14950308cd0cc10594b9f50fc4191ba4e9bd1fec0e5Darin Petkov 150675d0b0f04936050a357722f52dc078a3ab671d8Peter Qiu#endif // SHILL_DHCP_DHCP_PROVIDER_H_ 151