vpn: add TunnelManager cross-platform interface

This commit is contained in:
Zac Gaetano 2026-05-06 18:58:52 -04:00
parent b8901e04d0
commit b388da6e77

71
app/vpn/tunnelmanager.h Normal file
View file

@ -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 <QObject>
#include <QString>
#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();
};