TrustTunnel/lib
Aleksei Zhavoronkov 3e1514f7c7 Pull request 197: Fix H3 tests on Linux
Squashed commit of the following:

commit 48d9c29974987510d6a3b95d1d16aee1a1ee48fe
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Tue Apr 21 13:09:14 2026 +0300

    Refresh quic conn deadline on flush

commit 2895ec6b5405d67780ccae6ad94bb205b0774c60
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 14:03:05 2026 +0300

    Revert "trace log"
    
    This reverts commit e51d86f0d807f2f6360ccc6e9910b13eb10b41d9.

commit 71428bfaa127a5c6413ed52cdeb75ec832a106f3
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 14:03:04 2026 +0300

    Revert "hypothesis testing"
    
    This reverts commit 603f743d4309a17e21d2cd9176a88374add83404.

commit 9ed2bd63a46d2b1b1da1c479703312562558c6e8
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 14:03:03 2026 +0300

    Revert "add more aggressive logging"
    
    This reverts commit a3eb5d093a4573784ea95ed1cfd63d4f35557618.

commit ecc867e464c40fbad2878a5c59ba48170c011d3d
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 14:03:00 2026 +0300

    Revert "log even more"
    
    This reverts commit bcdc945620bfa10873168c6797bd334e9384d9dc.

commit b2226b51dd06f97f4957b7ba9f2fe8993f0f190a
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 11:53:55 2026 +0300

    try fix

commit bcdc945620bfa10873168c6797bd334e9384d9dc
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 11:27:01 2026 +0300

    log even more

commit a3eb5d093a4573784ea95ed1cfd63d4f35557618
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 11:02:16 2026 +0300

    add more aggressive logging

commit 603f743d4309a17e21d2cd9176a88374add83404
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 10:08:33 2026 +0300

    hypothesis testing

commit e51d86f0d807f2f6360ccc6e9910b13eb10b41d9
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Mon Apr 20 09:05:15 2026 +0300

    trace log

commit d1e5b9874fb60a5fb8ec7127abab149ee95ad8fe
Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com>
Date:   Sun Apr 19 22:46:14 2026 +0300

    Fix H3 tests on Linux
    
    Loss-recovery on_timeout() was never invoked when the loss-detection deadline elapsed without a packet arriving,
    so lost packets were never retransmitted and large H3 transfers stalled until the server idle timeout.
    Removed H3 tests from MacOS-only section.
2026-04-27 08:00:44 +00:00
..
src Pull request 197: Fix H3 tests on Linux 2026-04-27 08:00:44 +00:00
tests Pull request 197: Fix H3 tests on Linux 2026-04-27 08:00:44 +00:00
build.rs Pull request #13: Turn the project structure inside out 2022-05-24 12:49:06 +03:00
Cargo.toml Pull request 186: TRUST-427 add client random prefix rule generator 2026-03-23 09:04:49 +00:00
README.md Remove all changes related to token-gated tunnel routing 2026-03-06 14:05:30 +03:00

TrustTunnel endpoint

Building the library

Prerequisites

Building

Execute the following commands in the Terminal:

cargo build

to build the debug version, or

cargo build --release

to build the release version.

Features description

Traffic forwarding

As for now, the endpoint can demultiplex client's connections multiplexed in either HTTP/1, or HTTP/2, or HTTP/3 session. An application can set up how the endpoint forwards the demultiplexed client's connection by setting Settings.forward_protocol. The available options (see settings.ForwardProtocolSettings) are:

  • routing a connection directly to its target host
  • routing a connection though a SOCKS5 proxy

ICMP forwarding

As an optional feature, the endpoint can also forward ICMP packets from a client. This feature can be set up by setting Settings.icmp. An application MUST set up an interface name to bind the ICMP socket to, and MAY tweak some other settings, like the timeouts and message queue size.

Reverse proxy

Client's connection is treated as a reverse proxy stream in the following cases:

  1. A TLS session or QUIC connection has the SNI set to the host name equal to one from TlsHostsSettings.reverse_proxy.
  2. If a request path starts with ReverseProxySettings.path_mask, it is routed to reverse proxy.
  3. Otherwise, routing is defined by ping_path and speedtest_path configuration. Requests that do not match ping, speedtest, or reverse proxy rules are treated as tunnel requests.

The stream is used for mutual client and endpoint notifications and some control messages. The endpoint does TLS termination on such connections and translates HTTP/x traffic into HTTP/1.1 protocol towards the server and back into original HTTP/x towards the client. Like this:

(client) TLS(HTTP/x) <--(endpoint)--> (server) HTTP/1.1

The translated HTTP/1.1 requests have the custom header X-Original-Protocol appended. For now, its value can be HTTP1, HTTP2, or HTTP3.

Note: HTTP/3 reverse proxy handling keeps the write side open when the client finishes sending the request body, to avoid truncating large responses.

Authentication

Client authentication options

SNI authentication

A client connects to the endpoint with SNI set to hash.domain_name, where:

  • hash - md5(application_id + ':' + token + ':' + credentials)
  • domain_name - the endpoint's original domain name (e.g. myvpn.org)
Proxy authentication

A client connects to the endpoint using the proxy HTTP authentication mechanism with the "basic" scheme: Proxy-Authorization: Basic base64(token + ':' + credentials).

Endpoint authentication methods

An application can set up the authentication method being used by the endpoint by setting Settings.authenticator. The application can provide its own authenticator implementation (see the authentication.Authenticator trait), or use one of the implementations provided by the library:

  • authentication.DummyAuthenticator - authenticates any request
  • authentication.file_based.FileBasedAuthenticator - authenticates a request basing on the file containing credentials (see here)
  • SOCKS5 authentication - delegates authentication to the SOCKS5 forwarder (see here)

Please note, that the first 2 are very simple authenticator implementations which are intended mostly for testing purposes and do not respect network security practices.

File based authenticator

The file must contain an application id (applicationId: <string>), token (token: <string>), and credentials (credentials: <string>). Each one must be on a new line. The order does not matter.

SOCKS5 authenticator
Standard authentication

In case Socks5ForwarderSettings.extended_auth is set to false, the endpoint performs the standard authentication procedure according to the RFC 1929.

Depending on the client-side authentication way, the username and password are as follows:

Extended authentication

The extended authentication uses 0x80 as an authentication method. After a server selects this authentication method, a client sends an authentication request in the following format:

+-----+-----------+-----+--------+
| VER |   EXT(0)  |     | EXT(n) |
+-----+-----------+ ... +--------+
|  1  | see below |     |        |
+-----+-----------+-----+--------+

Where:

  • VER - the current extended authentication version: 0x01

  • EXT[i] - an extension in the following format:

    +------+--------+----------+
    | TYPE | LENGTH |   VALUE  |
    +------+--------+----------+
    |  1   |    2   | Variable |
    +------+--------+----------+
    

    Where:

    • TYPE - a type of the extension value (see [ExtendedAuthenticationValue])
    • LENGTH - the length of the extension value
    • VALUE - the extension value

Available extensions:

  • TERM: type = 0x00, length = 0 - terminating extension, marks a message end
  • DOMAIN: type = 0x01, length = (0..MAX], value = UTF-8 string - hostname which a client used for the TLS session (SNI)
  • CLIENT_ADDRESS: type = 0x02, length = [4|16], value = Bytes - public IP address of the VPN client
  • USER_AGENT: type = 0x03, length = (0..MAX], value = UTF-8 string - user agent of the VPN client
  • PROXY_AUTH: type = 0x04, length = (0..MAX], value = base64 string - <credentials> part of the Proxy-Authorization header
  • SNI_AUTH: type = 0x05, length = 0 - marks that the VPN client tries to authenticate using SNI

A message MUST end with the TERM extension.

The server responds with a standard message as in the RFC.

Metrics collecting

In order to collect some metrics of a running endpoint, an application can set up it to listen for the metrics collecting requests (see Settings.metrics). An endpoint running with this feature will listen on the configured address (MetricsSettings.address) for plain HTTP/1 requests. The following paths are available:

  • /health-check - used for pinging the endpoint, so it will respond with 200 OK
  • /metrics - used for metrics collecting, so it will respond with a bunch of values according to the prometheus specification

License

Apache 2.0