mirror of
https://github.com/TrustTunnel/TrustTunnel.git
synced 2026-04-18 00:43:52 +00:00
Squashed commit of the following: commit571b4f7534Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Wed Mar 4 14:55:12 2026 +0300 Apply review suggestions commit147cd9dcd3Author: Sergey Fionov <sfionov@adguard.com> Date: Wed Mar 4 10:49:59 2026 +0000 Applied suggestion v2 commitd4a52de99eAuthor: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Wed Mar 4 12:11:32 2026 +0300 Fix commitdfc4a8be07Author: Sergey Fionov <sfionov@adguard.com> Date: Wed Mar 4 09:10:07 2026 +0000 Applied suggestion commit4daca8112dAuthor: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Wed Mar 4 11:39:02 2026 +0300 Change deep-link format from tt:// to tt://?
TrustTunnel Deep-Link Library
A standalone Rust library for encoding and decoding TrustTunnel configuration deep-links using the tt URI scheme.
Features
- Complete TLV encoding/decoding - Implements the full TrustTunnel deep-link specification
- Error handling - Comprehensive error types with helpful messages
- Base64url encoding - URL-safe, compact representation
- Certificate support - PEM/DER conversion utilities
- Property-based testing - Verified with proptest for correctness
Installation
Add to your Cargo.toml:
[dependencies]
trusttunnel-deeplink = { git = "https://github.com/TrustTunnel/TrustTunnel/" }
Quick Start
Encoding a Configuration
use trusttunnel_deeplink::{encode, DeepLinkConfig};
use std::net::SocketAddr;
let config = DeepLinkConfig::builder()
.hostname("vpn.example.com".to_string())
.addresses(vec!["1.2.3.4:443".parse::<SocketAddr>().unwrap()])
.username("alice".to_string())
.password("secret123".to_string())
.build()
.unwrap();
let uri = encode(&config).unwrap();
println!("Deep-link: {}", uri);
// Output: tt://?AQ92cG4uZXhhbXBsZS5jb20CAzEuMi4zLjQ6NDQzBQVhbGljZQYJc2VjcmV0MTIz
Decoding a Deep-Link
use trusttunnel_deeplink::decode;
let uri = "tt://?AQ92cG4uZXhhbXBsZS5jb20CAzEuMi4zLjQ6NDQzBQVhbGljZQYJc2VjcmV0MTIz";
let config = decode(uri).unwrap();
println!("Hostname: {}", config.hostname);
println!("Username: {}", config.username);
Configuration Fields
The DeepLinkConfig struct supports the following fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
hostname |
String |
Yes | - | Server hostname |
addresses |
Vec<SocketAddr> |
Yes | - | Server addresses (IP:port) |
username |
String |
Yes | - | Authentication username |
password |
String |
Yes | - | Authentication password |
custom_sni |
Option<String> |
No | None | Custom SNI for TLS |
has_ipv6 |
bool |
No | true |
IPv6 support enabled |
skip_verification |
bool |
No | false |
Skip certificate verification |
certificate |
Option<Vec<u8>> |
No | None | DER-encoded certificate chain |
upstream_protocol |
Protocol |
No | Http2 |
Upstream protocol (HTTP/2 or HTTP/3) |
anti_dpi |
bool |
No | false |
Anti-DPI measures enabled |
Advanced Usage
Working with Certificates
use trusttunnel_deeplink::cert::{pem_to_der, der_to_pem};
// Convert PEM certificate to DER
let pem = "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----";
let der = pem_to_der(pem).unwrap();
// Convert DER back to PEM
let pem_again = der_to_pem(&der).unwrap();
Builder Pattern
use trusttunnel_deeplink::{DeepLinkConfig, Protocol};
let config = DeepLinkConfig::builder()
.hostname("vpn.example.com".to_string())
.addresses(vec!["1.2.3.4:443".parse().unwrap()])
.username("user".to_string())
.password("pass".to_string())
.custom_sni(Some("cdn.example.org".to_string()))
.has_ipv6(false)
.upstream_protocol(Protocol::Http3)
.anti_dpi(true)
.build()
.unwrap();
Error Handling
The library uses a custom DeepLinkError type with specific error variants:
use trusttunnel_deeplink::{decode, DeepLinkError};
match decode("invalid://uri") {
Ok(config) => println!("Success!"),
Err(DeepLinkError::InvalidScheme(scheme)) => {
println!("Invalid URI scheme: {}", scheme);
}
Err(DeepLinkError::MissingRequiredField(field)) => {
println!("Missing required field: {}", field);
}
Err(e) => println!("Other error: {}", e),
}
Testing
Run the test suite:
# Unit tests
cargo test -p trusttunnel-deeplink
# Integration tests (roundtrip)
cargo test -p trusttunnel-deeplink --test roundtrip
# Python compatibility tests
cargo test -p trusttunnel-deeplink --test python_compat
# Property-based tests
cargo test -p trusttunnel-deeplink --test proptest