| // Copyright 2018 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SHILL_VPN_VPN_DRIVER_H_ |
| #define SHILL_VPN_VPN_DRIVER_H_ |
| |
| #include <string> |
| #include <vector> |
| |
| #include <base/cancelable_callback.h> |
| #include <base/macros.h> |
| #include <base/memory/weak_ptr.h> |
| #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| |
| #include "shill/callbacks.h" |
| #include "shill/key_value_store.h" |
| #include "shill/mockable.h" |
| #include "shill/service.h" |
| |
| namespace shill { |
| |
| class ControlInterface; |
| class Error; |
| class EventDispatcher; |
| class Manager; |
| class Metrics; |
| class ProcessManager; |
| class PropertyStore; |
| class StoreInterface; |
| |
| class VPNDriver { |
| public: |
| // Note that the Up and Down events are triggered by whether the default |
| // physical service is online. This works in most cases, but in some |
| // scenarios, we may want to connect to a VPN service when the service is not |
| // online but only connected (e.g., the VPN server is in the same IP prefix on |
| // the LAN), events based on the connected state is more meaningful in those |
| // cases. |
| enum DefaultPhysicalServiceEvent { |
| // The default physical service becomes online from any other state. |
| kDefaultPhysicalServiceUp, |
| // There is no online physical service any more. |
| kDefaultPhysicalServiceDown, |
| // The default physical service changed from an online service to another |
| // online service. |
| kDefaultPhysicalServiceChanged, |
| }; |
| |
| // Passed in and registered in ConnectAsync(). Currently implemented by |
| // VPNService. |
| class EventHandler { |
| public: |
| // Invoked on connection or reconnection done. The interface name and index |
| // of the VPN interface are passed via parameters. GetIPProperties() is |
| // ready now. |
| virtual void OnDriverConnected(const std::string& if_name, |
| int if_index) = 0; |
| |
| // When a failure happens, the driver will clean up its internal state. This |
| // event is supposed to be triggered only once before the next call of |
| // ConnectAsync(). |
| virtual void OnDriverFailure(Service::ConnectFailure failure, |
| const std::string& error_details) = 0; |
| |
| // Indicates the driver is trying reconnecting now. Note that this event |
| // might be triggered multiple times before OnConnected or OnFailure |
| // happens. |timeout| suggests the handler how long this connection attempt |
| // might take at maximum. |
| virtual void OnDriverReconnecting(base::TimeDelta timeout) = 0; |
| |
| protected: |
| ~EventHandler() = default; |
| }; |
| |
| // Might be returned by ConnectAsync() or OnDriverReconnecting(). Indicates |
| // the VPNService should not set a timeout for this connection attempt. |
| static constexpr base::TimeDelta kTimeoutNone = |
| base::TimeDelta::FromSeconds(0); |
| |
| virtual ~VPNDriver(); |
| |
| // When this function is called, a VPNDriver is responsible for 1) creating |
| // the network interface (either by interacting with DeviceInfo or by letting |
| // another program do this), 2) starting and configuring the VPN tunnel, and |
| // 3) after VPN is connected and the network interface is known by DeviceInfo, |
| // invoking callbacks in |handler| to notify the VPNService of connection |
| // success (or other events). |
| // Returns a timeout value which suggests the handler how long this connection |
| // attempt might take at maximum. |
| virtual base::TimeDelta ConnectAsync(EventHandler* handler) = 0; |
| virtual void Disconnect() = 0; |
| virtual IPConfig::Properties GetIPProperties() const = 0; |
| virtual std::string GetProviderType() const = 0; |
| |
| // Makes the VPN driver fail because of the connection timeout. The driver |
| // will clean up its internal state, and invokes OnDriverFailure to notify the |
| // event handler of the failure reason. |
| virtual void OnConnectTimeout() = 0; |
| |
| // Registers properties with |store|. These properties are exposed and can be |
| // read and/or written via RPC. The list of properties is controlled by: 1) |
| // all properties in |properties| are included, 2) GetProvider() provides a |
| // read-only "Provider" property, 3) the inherited class can override this |
| // function to register more properties. |
| virtual void InitPropertyStore(PropertyStore* store); |
| |
| // This group of functions control the interaction between persistent |
| // |storage| and |args_|. Also see the function with the same names in Service |
| // and VPNService. |
| virtual bool Load(const StoreInterface* storage, |
| const std::string& storage_id); |
| void MigrateDeprecatedStorage(StoreInterface* storage, |
| const std::string& storage_id); |
| virtual bool Save(StoreInterface* storage, |
| const std::string& storage_id, |
| bool save_credentials); |
| mockable void UnloadCredentials(); |
| |
| // Power management events. |
| virtual void OnBeforeSuspend(const ResultCallback& callback); |
| virtual void OnAfterResume(); |
| virtual void OnDefaultPhysicalServiceEvent(DefaultPhysicalServiceEvent event); |
| |
| mockable std::string GetHost() const; |
| |
| KeyValueStore* args() { return &args_; } |
| const KeyValueStore* const_args() const { return &args_; } |
| |
| protected: |
| // Represents a property in |args_|, which can be read and/or written over |
| // RPC, and loaded from and/or saved to storage (the accessibility is |
| // controlled by flags). Each inherited class should define the list of |
| // properties it has, and pass this list to the constructor of this class. |
| struct Property { |
| enum Flags { |
| kEphemeral = 1 << 0, // Never load or save. |
| kCredential = 1 << 1, // Save if saving credentials (crypted). |
| kWriteOnly = 1 << 2, // Never read over RPC. |
| kArray = 1 << 3, // Property is an array of strings. |
| }; |
| |
| const char* property; |
| int flags; |
| }; |
| |
| VPNDriver(Manager* manager, |
| ProcessManager* process_manager, |
| const Property* properties, |
| size_t property_count); |
| VPNDriver(const VPNDriver&) = delete; |
| VPNDriver& operator=(const VPNDriver&) = delete; |
| |
| ControlInterface* control_interface() const; |
| EventDispatcher* dispatcher() const; |
| Metrics* metrics() const; |
| Manager* manager() const { return manager_; } |
| ProcessManager* process_manager() const { return process_manager_; } |
| |
| // Registered for "Provider" property, which can be read over RPC. All |
| // accessible properties defined in |properties_| are included. |
| virtual KeyValueStore GetProvider(Error* error); |
| |
| private: |
| friend class VPNDriverTest; |
| |
| static const char kCredentialPrefix[]; |
| |
| void ClearMappedStringProperty(const size_t& index, Error* error); |
| void ClearMappedStringsProperty(const size_t& index, Error* error); |
| std::string GetMappedStringProperty(const size_t& index, Error* error); |
| std::vector<std::string> GetMappedStringsProperty(const size_t& index, |
| Error* error); |
| bool SetMappedStringProperty(const size_t& index, |
| const std::string& value, |
| Error* error); |
| bool SetMappedStringsProperty(const size_t& index, |
| const std::vector<std::string>& value, |
| Error* error); |
| |
| Manager* manager_; |
| ProcessManager* process_manager_; |
| |
| const Property* const properties_; |
| const size_t property_count_; |
| KeyValueStore args_; |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_VPN_VPN_DRIVER_H_ |