This is reposoitory TrustTunnelClient, which contains libraries and command-line client for TrustTunnel protocol. The protocol is compatible with HTTP/1.1, HTTP/2, and QUIC, and supports tunneling TCP, UDP, and ICMP traffic. The libraries run on Linux, macOS, and Windows.
See README.md for full product details and DEVELOPMENT.md for prerequisite setup.
- C++20 (primary), C11 — core libraries
- Rust 1.95 —
trusttunnel/setup_wizard/,trusttunnel/settings/,trusttunnel/deeplink-ffi/ - Kotlin — Android platform adapter
- Swift / Objective-C — Apple platform adapter
- Dart (Flutter) — test app (
platform/testapp/) - CMake 3.24+ — build system
- Conan 2.0.5+ — C++ package manager
- Ninja — build backend
- Clang / LLVM 21+ — compiler and tooling
(Windows builds use MSVC
cl.exe, not clang) - clang-format 21+ — required by
make lint-cpp/make clang-format - Python 3 —
scripts/bootstrap_conan_deps.py, Conan wrappers (requirements.txt) - Ruby / Fastlane — iOS/Android release automation (
Gemfile,fastlane/)
| Directory | Purpose |
|---|---|
common/ |
Shared utilities used across all modules: FSM, event loop, platform abstractions, settings |
core/ |
Core VPN logic: tunnel, upstream connectors (HTTP/2, HTTP/3), DNS, SOCKS listener, TUN device |
net/ |
Network layer: HTTP sessions, TLS, QUIC, sockets, OS tunnel, DNS management, pinger |
tcpip/ |
TCP/IP stack: lwIP integration, TCP/UDP/ICMP raw handling, packet pool |
trusttunnel/ |
CLI client app, config parsing; contains Rust sub-crates: deeplink-ffi/, settings/, setup_wizard/ |
platform/android/ |
Android adapter (Kotlin/Gradle) |
platform/apple/ |
Apple adapter (Swift/ObjC, CocoaPods, XCFramework) |
platform/windows/ |
Windows adapter (C++/CMake) |
platform/testapp/ |
Flutter test application for platform adapters |
third-party/ |
Vendored dependencies: lwip, pcap_savefile, wintun |
scripts/ |
Build helpers, Conan export, version increment, git hooks |
cmake/ |
CMake modules: unit test helper, Conan bootstrapping/provider |
bamboo-specs/ |
CI/CD pipeline definitions (Bamboo) |
integration-tests/ |
Docker-based integration test harness |
conan/ |
Conan user settings and build profiles |
fastlane/ |
iOS/Android release automation (Fastfile, Matchfile) |
.devcontainer/ |
Docker-based remote debugging environment (see below) |
.github/ |
GitHub Actions workflows and PR/issue templates |
common ← core ← trusttunnel (CLI client)
common ← net ← core
common ← tcpip ← core
platform/* adapters wrap core for their respective OS.
Run make init once after cloning to set up git hooks.
Running make with no arguments runs the init target — use make all (or
make build_libs) to actually build.
| Command | What It Does |
|---|---|
make init |
Configure git hooks path to ./scripts/hooks |
make bootstrap_deps |
Export AdGuard Conan recipes to local cache (prerequisite of most build targets) |
make setup_cmake |
CMake configure only (accepts SKIP_BOOTSTRAP=1) |
make build_libs |
Bootstrap Conan deps → CMake configure → build vpnlibs_core |
make build_trusttunnel_client |
Build the CLI client binary (depends on build_libs) |
make build_wizard |
Build the setup wizard binary |
make build_and_export_bin |
Build binaries and copy to $(EXPORT_DIR) (default bin/) |
make all |
Build all binaries (client + wizard) |
make test |
Run all tests (test-cpp + test-rust) |
make test-cpp |
Build libs → build test targets → run ctest |
make test-rust |
cargo test on the setup_wizard workspace |
make lint |
Run all linters (lint-md + lint-rust + lint-cpp) |
make lint-cpp |
clang-format check + clangd-tidy |
make clang-format |
Explicit clang-format check only |
make clang-tidy / make clangd-tidy |
Run C++ static analysis only |
make lint-rust |
cargo clippy + cargo fmt --check |
make lint-md |
markdownlint . |
make lint-fix |
Auto-fix all fixable linter issues |
make lint-fix-cpp / lint-fix-rust / lint-fix-md |
Granular auto-fix targets |
make list-deps-dirs |
List Conan package directories (for finding dep headers) |
make compile_commands |
Generate compile_commands.json for IDE integration |
make clean |
Clean build artifacts |
Set BUILD_TYPE=debug for debug builds (default is release →
RelWithDebInfo).
- LLVM-based style, 4-space indent, 120-column limit (see
.clang-format) - Pointers and references:
*and&bind to the identifier (right side), e.g.int *ptr,const std::string &ref(LLVM convention) - Line continuations (wrapped arguments, conditions) indent 8 spaces
- No short functions/blocks on a single line
- Constructor initializers break before comma
- Binary operators break before the operator (non-assignment)
- Extensive static analysis via
.clang-tidy, all warnings are errors - Naming conventions (from
.clang-tidy):lower_case: variables, functions, methods, namespacesCamelCase: classes, structs, enums, typedefs, template type parametersUPPER_CASE: constants,constexprlocals, static constants- Private/protected members prefixed with
m_, globals withg_
- Use
libc++(notlibstdc++) - Use static storage duration instead of anonymous namespaces for internal linkage where possible
- (e.g.
static const int VALUE = 42;instead of putting it in an anonymous namespace)
- (e.g.
- Function descriptions are written in imperative language
- e.g. "Calculate the sum of two numbers" instead of "Calculates the sum of two numbers"
- Standard
rustfmtformatting, enforced bycargo fmt clippywith-D warnings(all warnings are errors)
-
Linted with
markdownlint(config in.markdownlint.json) -
Unordered lists use dashes (
-), indented 4 spaces -
No line-length limit
-
Markdown table formatting (MD060): When the Markdownlint MD060 rule triggers, switch to tight table formatting with spaces. Example:
| Column1 | Column2 | | --- | --- | | Value 1 | Value 2 |
Do NOT use extra padding or alignment characters beyond single spaces.
- Prefer existing patterns over inventing new ones
- Keep changes minimal and focused
- Tests live in
test/subdirectories alongside the module they cover - Logging guidelines:
- Use
DEBUGlevel for verbose debug info,INFOfor high-level events,WARNfor recoverable issues, andERRORfor critical (unrecoverable) errors - Very frequent events (e.g. every packet) should be logged at
DEBUGlevel, while important state changes (e.g. connection established, error occurred) should be atINFOor higher - Include relevant context in log messages (e.g. connection ID, error code)
- Avoid logging sensitive information (e.g. IP addresses, payload data)
- Use
The .devcontainer/ directory provides a Docker-based remote debugging setup
(copy devcontainer.json.example to devcontainer.json to enable it).
- Image: Ubuntu 24.04 with clang, cmake, ninja, rust, conan, lldb
- Purpose: Remote LLDB debugging, especially for Linux debugging from macOS
- Start:
docker-compose -f .devcontainer/docker-compose.yml up -d --build - Build inside:
docker-compose -f .devcontainer/docker-compose.yml exec trusttunnel-debug bash -c "cd /workspace && SKIP_VENV=1 BUILD_TYPE=debug make build_trusttunnel_client build_wizard" - Debug: Connect to
lldb-serveron port 12345
See DEVELOPMENT.md for full instructions.
Managed via Conan. Key libraries:
- dns-libs, native_libs_common — AdGuard shared libraries
- libevent — async event loop
- nghttp2 — HTTP/2
- quiche — HTTP/3 / QUIC (disabled on MIPS)
- openssl (BoringSSL; MIPS falls back to
openssl/3.1.5-quic1@adguard/oss) — TLS - nlohmann_json, tomlplusplus — config parsing
- cxxopts — CLI argument parsing
- magic_enum — enum reflection
- gtest — unit testing
Local conan cache is populated by make bootstrap_deps which is dependency for many other make commands.
To find headers for dns-libs and native_libs_common (e.g. when
resolving symbols or includes), run make list-deps-dirs to list Conan package
directories, then look in each directory's include/ subdirectory.
You MUST follow the following rules for EVERY task that you perform:
-
You MUST verify it with linter, formatter, and C++/Rust compilers.
Use the following commands:
make allto check if code builds (baremakeonly runsinit)make testto build and run unit testsmake lintto run the lintersmake lint-fixto fix linting issues that can be fixed automaticallymake clang-formatto check the formatting
-
You MUST update the unit tests for changed code.
-
You MUST run tests with the
make testscript to verify that your changes do not break existing functionality. -
When making changes to the project structure, ensure the Project structure section in
AGENTS.mdis updated and remains valid. -
If the prompt essentially asks you to refactor or improve existing code, check if you can phrase it as a code guideline. If it's possible, add it to the relevant Code Guidelines section in
AGENTS.md. -
After completing the task you MUST verify that the code you've written follows the Code Guidelines in this file.