Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations
Extracted elements (26)
Data connections carry raw application data with no encapsulation or framing, and TURN messaging is prohibited on them after ConnectionBind. This design provides a transparent TCP relay while keeping the control plane strictly separate, preventing general-purpose server use of relayed addresses.
End-to-end flow control is maintained by the relay: if the relay cannot write data to the destination, it stops reading from the source. Combined with the requirement to adjust the TCP receive window based on buffer occupancy, this prevents unbounded memory use at the relay.
Establishing a relayed TCP connection is intentionally a two-step process (Allocate, then Connect) rather than combined into one. Between steps, the client communicates the relayed transport address to the peer out-of-band (e.g., via ICE) so the peer can prepare by opening firewall holes, attempting simultaneous TCP open, etc.
TURN-TCP uses separate control and data connections. The control connection carries only TURN messaging, while each data connection carries only raw application data after a ConnectionBind. This strict separation prevents TURN messaging on data connections and application data on the control connection.
TURN-TCP provides no mechanism for keeping NAT bindings alive on client or peer data connections. Applications that require this must implement it themselves at a higher layer in the application protocol tunneled inside TURN-TCP. TCP keep-alives MAY be used to keep NAT bindings on the client data connection alive.
After a successful Connect response, the client MUST initiate a new TCP connection to the server using a different local transport address, authenticate using the same credentials as the control connection, and send a ConnectionBind request including the CONNECTION-ID echoed from the Connect response.
After a successful outgoing or incoming TCP connection (peer data connection), the server MUST buffer data received from the peer and adjust its advertised TCP receive window to reflect available buffer space. The Connect success response MUST include a CONNECTION-ID attribute uniquely identifying the peer data connection.
After ConnectionBind is received, data on the client data connection MUST be forwarded as-is to the peer data connection and vice versa, including data buffered before ConnectionBind was received. No encapsulation or framing is applied.
For a Connect request, if the server is already processing or has already successfully processed a Connect request for the same allocation and XOR-PEER-ADDRESS with pending or active data connections, the server MUST return 446 (Connection Already Exists). This enforces a maximum of one connection per peer transport address per allocation.
If a Connect request results in error 447 (Connection Timeout or Failure), the client MAY retry with the same XOR-PEER-ADDRESS but MUST wait at least 10 seconds before doing so.
If no ConnectionBind request associated with a peer data connection is received within 30 seconds of a successful Connect response or ConnectionAttempt indication, the server MUST close the peer data connection.
The Allocate request for a TCP allocation MUST contain a REQUESTED-TRANSPORT attribute with value 6 (TCP), and MUST NOT include DONT-FRAGMENT, RESERVATION-TOKEN, or EVEN-PORT attributes, as those features are UDP-specific.
The Refresh request MUST be sent on the control connection. The client MUST refresh the allocation for as long as it wants to keep any associated data connections alive.
The server MUST initiate an outgoing TCP connection for a Connect request; the timeout value MUST be at least 30 seconds. If connection fails or times out, the server MUST return 447 (Connection Timeout or Failure).
The server MUST reject a TCP Allocate request with 400 (Bad Request) if the client connection transport is not TCP or TLS, or if the request contains DONT-FRAGMENT, EVEN-PORT, or RESERVATION-TOKEN attributes.
To accept an incoming peer connection, the client MUST initiate a new TCP connection to the server using a different local transport address and MUST send a ConnectionBind request with the CONNECTION-ID from the ConnectionAttempt indication. Authentication MUST use the same method and credentials as the control connection.
To create a TCP allocation, a client MUST initiate a new TCP or TLS connection to its TURN server. TCP allocations cannot be obtained using a UDP association between client and server.
To initiate a connection to a peer, a client MUST send a Connect request over the control connection including an XOR-PEER-ADDRESS attribute. Connect requests with the same XOR-PEER-ADDRESS MUST NOT be sent simultaneously.
When a client data connection is closed, the server MUST close the corresponding peer data connection, and vice versa. If the allocation associated with a data connection expires, the data connection MUST be closed.
When an incoming TCP connection arrives on a relayed transport address, the server MUST accept it. If no permission for the peer is installed, the server MUST immediately close the accepted connection. If a permission exists, the server sends a ConnectionAttempt indication over the control connection with XOR-PEER-ADDRESS and CONNECTION-ID.
Three new STUN methods are defined: Connect (0x000a) — client requests outgoing TCP connection to a peer; ConnectionBind (0x000b) — client binds a new TCP connection to a peer data connection; ConnectionAttempt (0x000c) — server indication to client of an incoming peer TCP connection.
This document registers three new STUN methods (Connect 0x000a, ConnectionBind 0x000b, ConnectionAttempt 0x000c), one new STUN attribute (CONNECTION-ID 0x002a), and two new STUN error codes (446 Connection Already Exists, 447 Connection Timeout or Failure) in the STUN Parameters registry.
All security considerations applicable to STUN (RFC 5389) and TURN (RFC 5766) apply equally to this extension, including authentication, message integrity, and replay protection mechanisms.
Between a successful peer TCP connection and receipt of a ConnectionBind request, the server buffers all data received from the peer. The server SHOULD drop the connection if the buffer size is about to exceed a locally defined limit to prevent memory exhaustion. This guards against resource-consumption attacks (see RFC 4732 Section 2.1.3).
A peer data connection transitions through: (1) initiated/accepted (pending) — after a successful TCP connection to/from a peer but before ConnectionBind; (2) active — after a ConnectionBind request binds a client data connection to it; (3) closed — on timeout (30s without ConnectionBind), allocation expiry, or corresponding connection closure.
The CONNECTION-ID attribute (0x002a) is a 32-bit unsigned integer that uniquely identifies a peer data connection. It is included in Connect success responses, ConnectionAttempt indications, and echoed in ConnectionBind requests.