Architecture
Relay chain architecture and handshake protocol
Connection Flow
Given chain.nodes = [B1, B2] and rule.dest = C:
- 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.
- B1 to B2 (using metadata from handshake). Sends relay handshake with B2's password, target set to C, and metadata specifying plain transport.
- B2 to C (plain TCP). Tunnel is ready.
- 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
| Field | Description |
|---|---|
| Password hash | SHA-224 of the relay password, 56 hex chars |
| Target | Next hop address in host:port format |
| Metadata | Comma-separated key=value pairs (or empty for defaults) |
Metadata Keys
| Key | Values | Description |
|---|---|---|
transport | tls, plain | Outbound transport to use |
sni | domain string | TLS SNI for outbound connection |
Example
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b\r\n
relay-la.example.com:8080\r\n
transport=plain\r\nCrate Dependencies
trojan-relay
├── trojan-core (relay, I/O utilities)
└── trojan-transport
├── TLS transport (auto-generated self-signed certs)
├── Plain TCP transport
└── WebSocket transport