| // Copyright 2018 The ChromiumOS Authors |
| // 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 <memory> |
| #include <string> |
| #include <string_view> |
| #include <utility> |
| #include <vector> |
| |
| #include <base/cancelable_callback.h> |
| #include <base/memory/weak_ptr.h> |
| #include <gtest/gtest_prod.h> // for FRIEND_TEST |
| #include <net-base/network_config.h> |
| #include <net-base/process_manager.h> |
| |
| #include "shill/callbacks.h" |
| #include "shill/eap_credentials.h" |
| #include "shill/metrics.h" |
| #include "shill/mockable.h" |
| #include "shill/store/key_value_store.h" |
| #include "shill/vpn/vpn_end_reason.h" |
| #include "shill/vpn/vpn_metrics.h" |
| #include "shill/vpn/vpn_types.h" |
| |
| namespace shill { |
| |
| class ControlInterface; |
| class Error; |
| class EventDispatcher; |
| class Manager; |
| 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 class DefaultPhysicalServiceEvent { |
| // The default physical service becomes online from any other state. |
| kUp, |
| // There is no online physical service any more. |
| kDown, |
| // The default physical service changed from an online service to another |
| // online service. |
| kChanged, |
| }; |
| |
| // 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. GetNetworkConfig() 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(VPNEndReason failure, |
| std::string_view 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::Seconds(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 std::unique_ptr<net_base::NetworkConfig> GetNetworkConfig() 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); |
| virtual bool Save(StoreInterface* storage, |
| const std::string& storage_id, |
| bool save_credentials); |
| virtual void UnloadCredentials(); |
| |
| // Power management events. |
| virtual void OnBeforeSuspend(ResultCallback callback); |
| virtual void OnAfterResume(); |
| virtual void OnDefaultPhysicalServiceEvent(DefaultPhysicalServiceEvent event); |
| |
| std::string GetHost() const; |
| |
| VPNType vpn_type() const { return vpn_type_; } |
| KeyValueStore* args() { return &args_; } |
| const KeyValueStore* const_args() const { return &args_; } |
| const EapCredentials* eap_credentials() const { |
| return eap_credentials_.get(); |
| } |
| |
| VPNDriverMetrics* driver_metrics() { return driver_metrics_.get(); } |
| void set_driver_metrics_for_testing( |
| std::unique_ptr<VPNDriverMetrics> driver_metrics) { |
| driver_metrics_ = std::move(driver_metrics); |
| } |
| |
| 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. |
| kWriteOnly = 1 << 2, // Never read over RPC. |
| kReadOnly = 1 << 3, // Never write over RPC. |
| kArray = 1 << 4, // Property is an array of strings. |
| }; |
| |
| const char* property; |
| int flags; |
| }; |
| |
| VPNDriver(Manager* manager, |
| net_base::ProcessManager* process_manager, |
| VPNType vpn_type, |
| const Property* properties, |
| size_t property_count, |
| bool use_eap = false); |
| VPNDriver(const VPNDriver&) = delete; |
| VPNDriver& operator=(const VPNDriver&) = delete; |
| |
| ControlInterface* control_interface() const; |
| EventDispatcher* dispatcher() const; |
| Metrics* metrics() const; |
| Manager* manager() const { return manager_; } |
| net_base::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; |
| |
| // The property with `kCredential` will be saved with this prefix in the |
| // storage. We need this prefix because historically the property is stored in |
| // another format. See crbug.com/1084279 for the context. |
| static constexpr char kCredentialPrefix[] = "Credential."; |
| |
| 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_; |
| net_base::ProcessManager* process_manager_; |
| |
| const VPNType vpn_type_; |
| const Property* const properties_; |
| const size_t property_count_; |
| |
| std::unique_ptr<VPNDriverMetrics> driver_metrics_; |
| KeyValueStore args_; |
| |
| std::unique_ptr<EapCredentials> eap_credentials_; |
| }; |
| |
| } // namespace shill |
| |
| #endif // SHILL_VPN_VPN_DRIVER_H_ |