diff --git a/app/vpn/tunnelmanager.h b/app/vpn/tunnelmanager.h new file mode 100644 index 0000000..53b12c1 --- /dev/null +++ b/app/vpn/tunnelmanager.h @@ -0,0 +1,71 @@ +// tunnelmanager.h — Platform-agnostic interface for the WireGuard tunnel. +// +// Platform implementations: +// tunnelmanager_mac.mm — macOS (utun + boringtun, no root required for TUN open) +// tunnelmanager_linux.cpp — Linux (kernel WireGuard via wgctrl, future) +// tunnelmanager_win.cpp — Windows (Wintun + boringtun, future) + +#pragma once + +#include +#include + +#include "wireguardconfig.h" + +class TunnelManager : public QObject +{ + Q_OBJECT + +public: + explicit TunnelManager(QObject *parent = nullptr); + ~TunnelManager() override; + + // ── Control ──────────────────────────────────────────────────────────── + + /// Bring up the WireGuard tunnel described by cfg. + /// + /// This call returns quickly; the tunnel comes up asynchronously. + /// Listen to connected() / error() for status. The first thing that + /// happens is a handshake initiation — if the server is reachable the + /// connected() signal fires within ~500 ms. + /// + /// Calling start() while already running silently stops the previous tunnel + /// first (equivalent to stop() then start()). + /// + /// @return false immediately if cfg.isValid() == false (error() is also emitted). + bool start(const WireGuardConfig &cfg); + + /// Tear down the tunnel synchronously. Safe to call when not running. + void stop(); + + // ── State ────────────────────────────────────────────────────────────── + + bool isRunning() const { return m_running; } + QString errorString() const { return m_error; } + + /// The bare WireGuard IP assigned to this peer, e.g. "10.99.0.2". + /// Empty string when not connected. + QString localAddress() const { return m_localAddr; } + +signals: + /// Emitted after the first successful handshake with the server. + void connected(); + + /// Emitted when the tunnel is fully torn down. + void disconnected(); + + /// Emitted on any non-recoverable error. The tunnel is stopped. + void tunnelError(const QString &message); + +private: + bool m_running = false; + QString m_error; + QString m_localAddr; + + // Opaque platform-specific state (owned by platform implementation). + void *m_priv = nullptr; + + // Implemented in the platform-specific .mm / .cpp file. + bool platformStart(const WireGuardConfig &cfg); + void platformStop(); +};