// tunnelmanager.h — Platform-agnostic interface for the WireGuard tunnel. // // Platform implementations: // tunnelmanager_mac.mm — macOS (utun + boringtun, no root for TUN open) // tunnelmanager_linux.cpp — Linux (/dev/net/tun + boringtun userspace, // requires CAP_NET_ADMIN or root) // tunnelmanager_win.cpp — Windows (Wintun + boringtun, requires Admin) // // The QML layer talks to TunnelManager indirectly via DragonRelayBackend. // All signals are emitted on the QObject's thread (the Qt main thread). #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 for tunnelUp() / tunnelError() to observe the result. /// /// Calling start() while already running silently stops the previous /// tunnel first (equivalent to stop() then start()). /// /// Returns false immediately and emits tunnelError() if cfg.isValid() is false. 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 once the tunnel is ready to carry traffic. /// The argument is the local WireGuard IP (e.g. "10.99.0.2"). /// /// On macOS this fires after a short post-handshake delay; on Linux and /// Windows it fires once the kernel TUN/Wintun adapter is configured and /// boringtun reports a successful handshake. void tunnelUp(const QString &localIP); /// Emitted when the tunnel is fully torn down. void tunnelDown(); /// 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(); };