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