Amnezia-Client Architecture: Main Components, Layer Structure, and Source Code Organization

Amnezia Client uses a layered, cross-platform architecture separating the QML user interface, core application logic, VPN engine, protocol implementations, and a privileged background service that communicates via local IPC sockets.

The amnezia-vpn/amnezia-client repository implements this modular design in C++ and Qt, enabling consistent behavior across Windows, macOS, Linux, Android, and iOS while maintaining strict separation between UI concerns and system-level VPN operations.

User Interface Layer (QML Controllers)

The UI layer consists of QML front-end files backed by thin C++ controllers that expose core objects to the declarative interface. This layer handles all user interactions, settings management, and connection status displays without directly accessing networking APIs.

Key implementations reside in:

These controllers register as QML singletons during application startup, allowing QML code to invoke C++ methods while keeping the interface responsive on the main thread.

Core Application Layer

The Application Core coordinates between the UI, persistent settings, and the VPN engine. The entry point at client/amneziaApplication.cpp bootstraps the Qt application, registers QML types, and instantiates the primary coordinator.

The CoreController (client/core/controllers/coreController.cpp) serves as the central hub:

  • Creates and manages the VpnConnection object
  • Handles protocol selection and container configuration
  • Registers singleton helpers for protocol metadata, container management, and QR-code generation

This layer maintains the application state machine and ensures thread-safe communication between the UI thread and background VPN operations.

VPN Engine and Protocol Implementations

The VPN Engine centers on the VpnConnection class defined in client/vpnConnection.h. This class runs the selected VPN protocol in a dedicated thread, emitting state change signals that propagate back to the UI through the CoreController.

Concrete protocol implementations live in client/core/protocols/:

Each protocol implementation knows how to start and stop its underlying daemon, parse connection logs, and translate low-level events into the application's standardized state machine.

Configuration Management (Configurators)

Configurators generate the protocol-specific configuration files required by each daemon. Located in client/core/configurators/, these helpers translate user settings from the UI into valid daemon configurations:

These components pull data from the UI models, apply user-selected transport or obfuscation options, and write the final configuration to the service directory before the daemon launches.

Background Service and IPC Layer

The Background Service (amneziavpn-service) is a separate privileged executable that runs the actual VPN containers, manages routing tables, enforces kill-switch rules, and performs other operations requiring elevated privileges.

Key service files:

The IPC Layer (ipc/ipcserver.cpp and ipc/ipcserverprocess.cpp) provides local-socket based message passing between the UI process and the service. The UI sends action requests (start VPN, stop VPN, fetch logs) through this channel, and the service responds with status updates.

Platform Abstraction Layer

Platform-specific helpers isolate OS-dependent functionality in client/platforms/:

These wrappers normalize firewall manipulation, route table updates, and network monitoring across operating systems while presenting a unified interface to the core VPN engine.

Utilities and Build System

Supporting infrastructure includes:

Component Interaction Flow

Understanding the data flow clarifies how these layers interact:

  1. UI invokes methods on CoreController (registered as QML singleton)
  2. CoreController creates a VpnConnection thread and selects the appropriate Protocol implementation
  3. Protocol uses a Configurator to generate daemon config files, then instructs the Service via IPC to launch the daemon
  4. Service runs the daemon, applies routing/firewall rules through platform helpers, and reports status back through IPC

This separation ensures that UI crashes or terminations do not affect the active VPN tunnel, as the privileged service maintains the connection independently.

Code Examples

Starting a VPN connection from QML using the exposed CoreController:

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import CoreController 1.0

Button {
    text: "Connect"
    onClicked: {
        // "0" is the index of the first server in the list
        CoreController.openConnectionByIndex(0)
    }
}

The C++ side forwards this call to the ConnectionController, which instantiates VpnConnection, selects the protocol, generates configuration via the appropriate configurator, and signals the service to start the daemon.

Using the low-level VpnConnection class directly for headless operation or testing:

#include "client/vpnConnection.h"
#include "client/core/controllers/connectionController.h"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    // Create a VPN connection object (no UI)
    auto vpn = std::make_unique<VpnConnection>(nullptr, nullptr);
    ConnectionController controller(vpn.get());

    // Choose WireGuard protocol and start it
    controller.selectProtocol(ProtocolEnumNS::Proto::WireGuard);
    controller.start();               // launches the daemon via WireGuardProtocol
    
    QObject::connect(vpn.get(), &VpnConnection::stateChanged,
                     [](VpnConnection::State s){ qDebug() << "State:" << s; });

    return app.exec();
}

Summary

  • Layered Architecture: Amnezia-client separates UI (QML), core logic (CoreController), VPN engine (VpnConnection), protocols, and system service through clean interfaces
  • Protocol Support: Modular protocol implementations in client/core/protocols/ support OpenVPN, WireGuard, XRay/VMess, and IKEv2 with platform-specific variants
  • Configuration Pipeline: Dedicated configurators translate UI settings into daemon-specific configs before service launch
  • Privilege Separation: The UI process communicates with a privileged background service via IPC, isolating dangerous operations from the user interface
  • Cross-Platform: Platform abstraction layers in client/platforms/ handle OS-specific firewall and routing logic while sharing common protocol code

Frequently Asked Questions

What programming languages does amnezia-client use?

The codebase is primarily C++ (Qt framework) for the engine and service, QML (Qt Meta Language) for the user interface, and CMake for the build system. Platform-specific components may use Objective-C++ on macOS/iOS or Java/Kotlin integrations on Android, but the core VPN logic remains portable C++.

How does the UI communicate with the VPN service?

Communication occurs through a local socket IPC layer implemented in ipc/ipcserver.cpp. The UI process sends serialized command messages (start, stop, status queries) to the amneziavpn-service daemon, which executes privileged operations and returns state updates asynchronously.

Where are the VPN protocol implementations located?

Protocol implementations reside in client/core/protocols/, with each protocol having its own translation unit. For example, WireGuard logic is in client/core/protocols/wireGuardProtocol.cpp, while XRay/VMess handling lives in client/core/protocols/xrayProtocol.cpp. These classes inherit from a common base and implement virtual methods for starting, stopping, and monitoring the respective daemons.

Is amnezia-client cross-platform?

Yes. The architecture uses platform abstraction layers in client/platforms/ to isolate OS-specific code (firewall rules, route management, service installation) while keeping the core VPN engine and UI code platform-agnostic. The same VpnConnection and protocol classes compile for Windows, macOS, Linux, Android, and iOS with appropriate platform helpers linked at build time.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →