Trojan Rust

Architecture

Relay chain architecture and handshake protocol

Connection Flow

Given chain.nodes = [B1, B2] and rule.dest = C:

  1. A to B1 (using B1's transport/SNI config). Sends relay handshake with B1's password, target set to B2's address, and metadata specifying B2's transport and SNI.
  2. B1 to B2 (using metadata from handshake). Sends relay handshake with B2's password, target set to C, and metadata specifying plain transport.
  3. B2 to C (plain TCP). Tunnel is ready.
  4. Client to C (through tunnel). End-to-end TLS and Trojan auth.

The last hop to the exit server always uses plain TCP. The client performs end-to-end TLS through the tunnel.

For direct chains (nodes = []), the entry node connects directly to the destination via plain TCP.

Relay Handshake Protocol

Relay nodes communicate using a text-based handshake protocol:

+----------------------------+---------+-------------------+---------+
| hex(SHA224(relay_password)) |  CRLF   | target_addr:port  |  CRLF   |
+----------------------------+---------+-------------------+---------+
|            56              | X'0D0A' |     Variable      | X'0D0A' |
+-----------------------------------------------------------+---------+
|               metadata (key=value,...)                     |  CRLF   |
+-----------------------------------------------------------+---------+

Fields

FieldDescription
Password hashSHA-224 of the relay password, 56 hex chars
TargetNext hop address in host:port format
MetadataComma-separated key=value pairs (or empty for defaults)

Metadata Keys

KeyValuesDescription
transporttls, plainOutbound transport to use
snidomain stringTLS SNI for outbound connection

Example

e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b\r\n
relay-la.example.com:8080\r\n
transport=plain\r\n

Crate Dependencies

trojan-relay
├── trojan-core (relay, I/O utilities)
└── trojan-transport
    ├── TLS transport (auto-generated self-signed certs)
    ├── Plain TCP transport
    └── WebSocket transport

On this page