Skip to content

TUIC Protocol

MasakiMu319

Version

0x05

Overview

The TUIC protocol relies on a multiplex-able TLS-encrypted stream. All relaying tasks are negotiated by the Header in Commands.

The protocol doesn’t care about the underlying transport. However, it is mainly designed to be used with QUIC. See Protocol Flow for detailed mechanism.

All fields are in Big Endian unless otherwise noted.

Command

+-----+------+----------+
| VER | TYPE |   OPT    |
+-----+------+----------+
|  1  |  1   | Variable |
+-----+------+----------+

where:

Command Types

There are five types of command:

Command Connect and Packet carry payload (stream / packet fragment).

Command Type Specific Data

Authenticate

+------+-------+
| UUID | TOKEN |
+------+-------+
|  16  |  32   |
+------+-------+

where:

Connect

+----------+
|   ADDR   |
+----------+
| Variable |
+----------+

where:

Packet

+----------+--------+------------+---------+------+----------+
| ASSOC_ID | PKT_ID | FRAG_TOTAL | FRAG_ID | SIZE |   ADDR   |
+----------+--------+------------+---------+------+----------+
|    2     |   2    |     1      |    1    |  2   | Variable |
+----------+--------+------------+---------+------+----------+

where:

Dissociate

+----------+
| ASSOC_ID |
+----------+
|    2     |
+----------+

where:

Heartbeat

+-+
| |
+-+
| |
+-+

Address

Address is a variable-length field that encodes network addresses.

+------+----------+----------+
| TYPE |   ADDR   |   PORT   |
+------+----------+----------+
|  1   | Variable |    2     |
+------+----------+----------+

where:

The address type can be one of the following:

Address type None is used in Packet commands that are not the first fragment of a UDP packet.

The port number is encoded in 2 bytes after the domain name / IP address.

Protocol Flow

This section describes protocol flow in detail with QUIC as underlying transport.

The protocol itself does not enforce how transport is managed. It can even be integrated into existing services such as HTTP/3.

Here is a typical TUIC flow over a QUIC connection:

Authentication

The client opens a unidirectional_stream and sends an Authenticate command. This can be parallelized with other commands.

The server verifies token. If valid, connection is authenticated and ready for relay tasks.

If server receives other commands before authentication, it should parse command headers and pause. After authentication succeeds, paused tasks should resume.

TCP relaying

Connect initializes a TCP relay.

Client opens a bidirectional_stream and sends Connect. Once command header transmission completes, client may begin relaying immediately without waiting for server response.

Server receives Connect, opens TCP stream to target address, then relays data between TCP stream and QUIC bidirectional stream.

UDP relaying

TUIC achieves 0-RTT full-cone UDP forwarding by syncing UDP session ID (ASSOC_ID) between client and server.

Both sides maintain a UDP session table per QUIC connection, mapping each ASSOC_ID to an associated UDP socket.

ASSOC_ID is a client-generated 16-bit unsigned integer. If client wants server to reuse same UDP socket, it reuses same ASSOC_ID.

When server receives a Packet, it checks whether ASSOC_ID already exists. If not, allocate a UDP socket for that association. The server uses this socket to send requested outbound UDP traffic and to receive inbound UDP packets from any destination, wrap them in Packet headers, and send back to client.

A UDP packet can be fragmented into multiple Packet commands. PKT_ID, FRAG_TOTAL, and FRAG_ID identify and reassemble fragments.

As a client, Packet can be sent via:

When server receives the first Packet in an association, it should use the same mode for downstream packets.

A UDP session can be dissociated by client sending Dissociate through QUIC unidirectional_stream. Server then removes session and releases associated UDP socket.

Heartbeat

When any relay task is ongoing, client should periodically send Heartbeat over QUIC datagram to keep connection alive.

Error Handling

No command has a standardized response. If server receives invalid commands or encounters processing errors (for example unreachable target, auth failure), there is no protocol-level standard behavior. Handling is implementation-defined: server may close QUIC connection or ignore command.

For example, if server receives Connect with unreachable target, it may close the corresponding bidirectional_stream as failure signal.

In-depth Protocol Analysis

After deeper analysis, TUIC shows a modern high-performance design that leverages QUIC and TLS effectively. At the same time, its minimal spec places significant responsibility on implementers.

Executive Summary

TUIC is a compact, secure, low-latency-oriented proxy protocol. It uses simple command structures over multiplexed TLS streams (ideally QUIC), and delegates encryption/reliability complexity to lower layers.

Its highlight is efficient 0-RTT full-cone UDP relaying, making it suitable for real-time workloads.

The primary trade-off is non-standardized, implementation-defined error handling. This keeps spec simple but shifts burden to developers for robustness, security, and interoperability.

Key Strengths

  1. Outstanding performance

    • TCP: client starts data transfer immediately after sending Connect.
    • UDP: ASSOC_ID design enables 0-RTT full-cone forwarding.
    • Efficiency: QUIC datagrams for heartbeat and native UDP mode reduce overhead.
  2. Robust security

  3. Design elegance

    • protocol stays focused and simple;
    • command framing is easy to parse;
    • avoids duplicating transport-layer responsibilities.

Critical Implementation Challenges & Recommendations

1. UDP ASSOC_ID lifecycle management (DoS risk)

2. UDP fragment buffer management (DoS risk)

3. Standardize error handling

Conclusion

TUIC is a strong and practical protocol for secure low-latency mixed TCP/UDP tunneling. But minimal spec does not mean simple production implementation. Production-grade TUIC requires careful state lifecycle design, resource governance, and explicit failure semantics to close gaps not fully specified by protocol text.

Previous
Next-generation large language model interface architecture
Next
Deep Analysis of Context Engineering for AI Agents: Balancing Performance and Robustness