Squashed commit of the following: commit d42104fb3d981c63b7fd43dc737dd6ee892c084e Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri May 1 00:00:36 2026 +0500 Add missing tcp buffer fields to test initializer commit e6621d489e473bbe0622b80a9171b912ca5d5722 Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Thu Apr 30 23:38:18 2026 +0500 Fix dead_code warning in setup_wizard template commit bb55ad9f624db71d6dc693d2d083f40595e75423 Merge: 3d9054bc07ea7045Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Thu Apr 30 23:34:51 2026 +0500 Merge branch 'master' into AG-45460-investigate-a-possible-memory-leakage-in-tcp-ip-exacerbated-by-a-large-tcp_wnd # Conflicts: # CHANGELOG.md commit 3d9054bc25d2ead3666e56580b3b1508e9883f70 Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Thu Apr 30 23:32:37 2026 +0500 Update CHANGELOG, README, and setup_wizard template with new fields commit 280303cb0620ef836a9d498d645553be21c78918 Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri Apr 24 21:12:09 2026 +0500 Increase trimming interval to 30 minutes commit 32f5b6dea2a48e26b7c4fdcf59d1de860ad77fe3 Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri Apr 24 15:54:22 2026 +0500 Remove tcp_active_pcbs guard commit 61c2fdb9bf98a26dd3802b9332069c541ecf742e Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Mon Apr 20 21:39:57 2026 +0500 Use runtime GetProcAddress for HeapSetInformation on Windows commitf63455eee7Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Thu Apr 16 17:07:00 2026 +0500 Set trim interval to 3 minutes commitae95ade304Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Thu Apr 16 14:22:07 2026 +0500 Fix build commitc9cbda67d1Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 15 20:43:14 2026 +0500 Use proper Windows way to reclaim memory commit313925709fAuthor: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 15 16:55:51 2026 +0500 Add cross-platform heap trimming (macOS, Windows) commit0ba49793d7Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Tue Apr 14 22:59:47 2026 +0500 Use proper glibc guard commit70b9583348Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Tue Apr 14 21:00:16 2026 +0500 Add runtime TCP buffer size configuration commit29f93f4275Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Mon Apr 13 23:05:10 2026 +0500 Increase TCP buffer sizes from 32KB to 256KB commit8120df6fafAuthor: Ilia Zhirov <i.zhirov@adguard.com> Date: Mon Apr 13 21:14:58 2026 +0500 Call malloc_trim to release heap pages after TCP connections close
11 KiB
TrustTunnel CLI Client
TrustTunnel CLI Client is an application built on top of the TrustTunnel Client Libraries. It provides an easy-to-use interface to configure and connect to a TrustTunnel endpoint. The client supports Linux, macOS, and Windows platforms.
Building
To build the TrustTunnel CLI Client, follow
development instructions.
The built executable will be available in the
<project_root>/build/trusttunnel_client directory.
Configuration
The TrustTunnel CLI Client accepts a TOML-formatted configuration file. You can use the setup wizard tool to generate a basic configuration file.
Setup Wizard Tool
Usage
For quick setup, please follow Getting Started instructions.
For a more customized configuration experience, follow the steps below:
-
Build the setup wizard tool.
-
Launch the setup wizard:
./setup_wizardThe setup wizard will guide you through the configuration process, allowing you to customize the settings according to your preferences.
Note: The configuration file created by the setup wizard contains all available settings, including descriptions. Feel free to modify them if you have a good understanding of the configuration.
Setup Wizard CLI Options
Usage: setup_wizard [OPTIONS]
Options:
-m, --mode <mode> Wizard running mode [default: interactive]
* interactive - guided setup with prompts
* non-interactive - automated setup from CLI args
-a, --address <address> Endpoint address (can be specified multiple times)
-n, --hostname <host> Endpoint hostname for TLS session
-c, --creds <creds> Credentials as <username>:<password>
--cert <cert> Path to endpoint certificate file
--settings <settings> Output path for settings file (required in non-interactive mode)
-e, --endpoint_config <path>
Path to config generated by endpoint (conflicts with -a, -n, -c)
-h, --help Print help
Examples
Interactive mode (guided setup):
./setup_wizard
Non-interactive with endpoint config (recommended):
./setup_wizard --mode non-interactive \
--endpoint_config <endpoint_config.toml> \
--settings trusttunnel_client.toml
Non-interactive with manual parameters:
./setup_wizard --mode non-interactive \
--address 192.168.1.100:443 \
--hostname vpn.example.com \
--creds myuser:mypassword \
--cert server.pem \
--settings trusttunnel_client.toml
Configuration Reference
The configuration file uses TOML format. Below are all available settings.
Top-Level Settings
| Variable | Type | Default | Description |
|---|---|---|---|
loglevel |
string | "info" |
Logging level: info, debug, trace |
vpn_mode |
string | "general" |
Routing policy: general (route all except exclusions) or selective (route only exclusions) |
killswitch_enabled |
bool | true |
Block traffic when VPN connection is lost |
killswitch_allow_ports |
array[int] | [] |
Local ports to allow inbound connections when kill switch is active |
post_quantum_group_enabled |
bool | true |
Enable post-quantum key exchange in TLS handshakes |
exclusions |
array[string] | [] |
Domains/IPs to route specially based on vpn_mode |
dns_upstreams |
array[string] | [] |
Legacy. Kept only for backward compatibility with old configs; prefer [endpoint].dns_upstreams instead |
Endpoint Settings ([endpoint])
| Variable | Type | Default | Description |
|---|---|---|---|
hostname |
string | required | Endpoint hostname for TLS session establishment |
addresses |
array[string] | required | Endpoint addresses as IP:port or hostname:port (pinger selects best) |
has_ipv6 |
bool | true |
Whether IPv6 traffic can be routed through endpoint |
username |
string | required | Authorization username |
password |
string | required | Authorization password |
client_random |
string | "" |
TLS client random prefix and mask (hex, format: prefix[/mask]) |
skip_verification |
bool | false |
Skip endpoint certificate verification (accepts any cert) |
certificate |
string | null |
Endpoint certificate in PEM format (uses system store if empty) |
upstream_protocol |
string | "http2" |
Protocol: http2 or http3 |
anti_dpi |
bool | false |
Enable anti-DPI (Deep Packet Inspection) measures |
dns_upstreams |
array[string] | [] |
DNS resolvers for queries routed through VPN. If empty, AdGuard DNS unfiltered is used |
TUN Listener Settings ([listener.tun])
| Variable | Type | Default | Description |
|---|---|---|---|
bound_if |
string | auto-detected | Network interface for VPN client connections (Linux/Windows/macOS: auto) |
included_routes |
array[string] | ["0.0.0.0/0", "2000::/3"] |
Routes in CIDR notation to set to the virtual interface |
excluded_routes |
array[string] | ["0.0.0.0/8", "10.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16", "224.0.0.0/3"] |
Routes in CIDR notation to exclude from VPN routing |
mtu_size |
int | 1280 |
MTU size on the virtual interface |
tcp_recv_buf_size |
int | 0 |
TCP receive window size in bytes. 0 = optimized default (256 KB). Adjust only for constrained environments |
tcp_send_buf_size |
int | 0 |
TCP send buffer size in bytes. 0 = optimized default (256 KB). Adjust only for constrained environments |
change_system_dns |
bool | true |
Allow changing system DNS servers |
device_name |
string | "" |
On Linux, the TUN interface name (empty = kernel-assigned). On Windows, the Wintun adapter name (empty = auto-generated from hostname). On macOS, request a specific utun<N> unit (empty = kernel-assigned). |
use_existing |
bool | false |
Attach to a pre-existing TUN device named device_name instead of creating one. Requires device_name. Linux only. |
To disable route management on any supported platform, set included_routes = [].
On Linux this also suppresses cleanup of table 880 and the associated ip rule
entries; on Windows, DNS-only route handling remains controlled by change_system_dns.
SOCKS Listener Settings ([listener.socks])
| Variable | Type | Default | Description |
|---|---|---|---|
address |
string | "127.0.0.1:1080" |
IP address and port to bind the SOCKS5 proxy |
username |
string | null |
Username for SOCKS authentication (optional) |
password |
string | null |
Password for SOCKS authentication (optional) |
Exclusions Syntax
The exclusions array supports the following formats:
- Domain name:
example.com— matchesexample.comandwww.example.com - Wildcard domain:
*.example.com— matches any subdomain (e.g.,sub.example.com), but not the domain itself - IPv4 address:
192.168.1.1or192.168.1.1:443(port optional) - IPv6 address:
[::1]or[::1]:443or2001:db8::1 - CIDR range:
192.168.0.0/16or2001:db8::/32 - Wildcard port:
*:80— matches any connection to the specified port regardless of destination address
DNS Upstreams Syntax
The dns_upstreams array supports the following formats:
- Plain DNS:
8.8.8.8:53 - DNS over TCP:
tcp://8.8.8.8:53 - DNS over TLS:
tls://1.1.1.1 - DNS over HTTPS:
https://dns.adguard.com/dns-query - DNS over QUIC:
quic://dns.adguard.com:8853 - DNS Stamp:
sdns://...(see DNS Stamps specification)
Example Configuration
loglevel = "info"
vpn_mode = "general"
killswitch_enabled = true
killswitch_allow_ports = []
post_quantum_group_enabled = true
exclusions = []
[endpoint]
hostname = "vpn.example.com"
addresses = ["192.168.1.100:443"]
has_ipv6 = true
username = "myuser"
password = "mypassword"
client_random = ""
skip_verification = false
certificate = ""
dns_upstreams = ["tls://1.1.1.1"]
upstream_protocol = "http2"
anti_dpi = false
[listener.tun]
bound_if = ""
# For OpenWrt with external policy routing (`pbr`, `mwan3`):
# device_name = "tt0"
# use_existing = true
# included_routes = []
included_routes = ["0.0.0.0/0", "2000::/3"]
excluded_routes = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
mtu_size = 1280
# Uncomment to tune TCP window size (bytes). Default 0 uses optimized values (256 KB).
# It is recommended to leave defaults unless you have specific requirements.
# tcp_recv_buf_size = 0
# tcp_send_buf_size = 0
Usage
Windows specific: For tunnel listener to work,
wintun.dllmust be in the DLL search path. Basically, you could download it, extract the file (from the folder matching your architecture, likeamd64) and place it into the same directory astrusttunnel_clientexecutable.
To run the TrustTunnel CLI Client, execute the following command:
./trusttunnel_client --config <path/to/configuration/file.toml>
Replace <path/to/configuration/file.toml> with the actual path to your
configuration file. You may need to run the command with superuser privileges
if a TUN device is selected.
Windows Service (Windows Only)
The TrustTunnel CLI Client can be installed as a Windows service, allowing it to run in the background without requiring an interactive console session.
Note
: Both install and uninstall commands require Administrator privileges. Run the command from an elevated Command Prompt or PowerShell.
Installing the Service
trusttunnel_client --service-install --config <path/to/trusttunnel_client.toml>
The command validates the configuration file before registering the service. If validation fails, the service is not installed. The config path is resolved to an absolute path and baked into the service registration — the service will always start with that config file.
The service is registered with automatic start type
(SERVICE_AUTO_START) and is started immediately after installation.
Starting and Stopping the Service
After installation, use the standard Windows service management commands:
cmd.exe:
sc start TrustTunnelClient
sc stop TrustTunnelClient
PowerShell:
Start-Service TrustTunnelClient
Stop-Service TrustTunnelClient
Querying Service Status
cmd.exe:
sc query TrustTunnelClient
PowerShell:
Get-Service TrustTunnelClient
Disabling Auto-Start
To switch the service to manual start:
cmd.exe:
sc config TrustTunnelClient start= demand
PowerShell:
Set-Service TrustTunnelClient -StartupType Manual
Uninstalling the Service
trusttunnel_client --service-uninstall
If the service is currently running, it will be stopped automatically before removal.
Notes
- If the configuration file is moved or deleted after installation, the service will fail to start. Reinstall the service with the new config path.
- The
--service-installand--service-uninstalloptions are only available on Windows builds.