#ifndef VPNCONNECTION_H #define VPNCONNECTION_H #include #include #include #include #include #include #include #include "core/protocols/vpnProtocol.h" #include "core/utils/errorCodes.h" #include "core/utils/routeModes.h" #include "core/utils/commonStructs.h" #include "core/repositories/secureServersRepository.h" #include "core/repositories/secureAppSettingsRepository.h" #include "core/vpnTrafficGuard.h" #include "core/tunnel.h" #ifdef Q_OS_ANDROID #include "core/protocols/androidVpnProtocol.h" #endif using namespace amnezia; class VpnConnection : public QObject { Q_OBJECT public: explicit VpnConnection(SecureServersRepository* serversRepository, SecureAppSettingsRepository* appSettingsRepository, QObject* parent = nullptr); ~VpnConnection() override; static QString bytesPerSecToText(quint64 bytes); ErrorCode lastError() const; Vpn::ConnectionState connectionState() const; QSharedPointer vpnProtocol() const; const QString &remoteAddress() const { return m_remoteAddress; } #ifdef Q_OS_ANDROID void restoreConnection(); #endif public slots: void setRepositories(SecureServersRepository* serversRepository, SecureAppSettingsRepository* appSettingsRepository); void connectToVpn(const QString &serverId, DockerContainer container, const QJsonObject &vpnConfiguration); void reconnectToVpn(); void disconnectFromVpn(); void onKillSwitchModeChanged(bool enabled); void disconnectSlots(); void setConnectionState(Vpn::ConnectionState state); signals: void bytesChanged(quint64 receivedBytes, quint64 sentBytes); void connectionStateChanged(Vpn::ConnectionState state); void vpnProtocolError(amnezia::ErrorCode error); void serverSwitchFailed(); void serviceIsNotReady(); protected slots: void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onConnectionStateChanged(Vpn::ConnectionState state); protected: QSharedPointer m_vpnProtocol; private: SecureServersRepository* m_serversRepository; SecureAppSettingsRepository* m_appSettingsRepository; QScopedPointer m_trafficGuard; QJsonObject m_vpnConfiguration; QString m_remoteAddress; Tunnel* m_active = nullptr; Tunnel* m_staging = nullptr; QSet m_ifnamesInUse; // Only for iOS for now, check counters QTimer m_checkTimer; #ifdef Q_OS_ANDROID AndroidVpnProtocol* androidVpnProtocol = nullptr; AndroidVpnProtocol* createDefaultAndroidVpnProtocol(); void createAndroidConnections(); #endif Vpn::ConnectionState m_connectionState; void createProtocolConnections(); void wireTunnelSignals(Tunnel* tunnel, bool isActive); void wireDaemonReconnectSignals(); QString allocateIfname(); void releaseIfname(const QString& ifname); void appendSplitTunnelingConfig(QJsonObject &config); void appendKillSwitchConfig(QJsonObject &config); void startTunnelSwitch(DockerContainer container, const QJsonObject &vpnConfiguration, const QString &resolvedRemote, const QString &stagingIfname); private slots: void onTunnelPrepared(); void onTunnelActivated(); void onTunnelFailed(amnezia::ErrorCode error); }; #endif // VPNCONNECTION_H