Skip to content

Commit 92e1afa

Browse files
authored
[connect-tcp] Add FINAL_DATA and discuss shutdown sequence
2 parents 9c980c3 + 4441310 commit 92e1afa

File tree

1 file changed

+92
-8
lines changed

1 file changed

+92
-8
lines changed

draft-ietf-httpbis-connect-tcp.md

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,13 @@ This specification describes an alternative mechanism for proxying TCP in HTTP.
6565

6666
A template-driven TCP transport proxy for HTTP is identified by a URI Template {{!RFC6570}} containing variables named "target_host" and "target_port". This URI Template and its variable values MUST meet all the same requirements as for UDP proxying ({{!RFC9298, Section 2}}), and are subject to the same validation rules. The client MUST substitute the destination host and port number into this template to produce the request URI. The derived URI serves as the destination of a Capsule Protocol connection using the Upgrade Token "connect-tcp" (see registration in {{new-upgrade-token}}).
6767

68-
When using "connect-tcp", TCP payload data is sent in the payload of a new Capsule Type named DATA (see registration in {{data-capsule}}). The ordered concatenation of DATA capsule payloads represents the TCP payload data.
68+
When using "connect-tcp", TCP payload data is sent in the payload of new Capsule Types named DATA and FINAL_DATA (see registrations in {{data-capsule}}). The ordered concatenation of these capsule payloads represents the TCP payload data. A FINAL_DATA capsule additionally indicates that the sender has closed this stream, semantically equivalent to TCP FIN. After sending a FINAL_DATA capsule, an endpoint MUST NOT send any more DATA or FINAL_DATA capsules on this data stream. (See {{closing-connections}} for related requirements.)
6969

70-
An intermediary MAY merge and split successive DATA capsules, subject to the following requirements:
70+
An intermediary MAY merge and split successive DATA and FINAL_DATA capsules, subject to the following requirements:
7171

7272
* There are no intervening capsules of other types.
7373
* The order of payload content is preserved.
74+
* The final emitted capsule uses the same capsule type (DATA or FINAL_DATA) as the final input capsule, and all others use the DATA capsule type.
7475

7576
## In HTTP/1.1
7677

@@ -156,11 +157,69 @@ Clients SHOULD assume that all proxy resources generated by a single template sh
156157

157158
## Closing Connections
158159

159-
In each HTTP version, any requirements related to closing connections in Classic HTTP CONNECT also apply to "connect-tcp", with the following modifications:
160-
161-
* In HTTP/1.1, endpoints SHOULD close the connection in an error state to indicate receipt of a TCP connection error (e.g., a TCP RST or timeout). Acceptable error states include sending an incomplete DATA capsule (as defined in {{Section 3.3 of !RFC9297}}), a TLS Error Alert ({{!RFC8446, Section 6.2}}), or a TCP RST (if TLS is not in use). When a connection is terminated in an error state, the receiving endpoint SHOULD send a TCP RST if the underlying TCP implementation permits it.
162-
* In HTTP/2 and HTTP/3, senders MAY use an incomplete DATA capsule to indicate a TCP connection error, instead of (or in addition to) the signals defined for TCP connection errors in Classic HTTP CONNECT. Recipients MUST recognize any incomplete capsule as a TCP connection error.
163-
* Intermediaries MUST propagate connection shutdown errors, including when translating between different HTTP versions.
160+
Connection termination is essentially symmetrical for proxies and their clients. In this section, we use the term "endpoint" to describe an implementation of this specification in either role.
161+
162+
When closing connections, endpoints are subject to the following requirements:
163+
164+
* When an endpoint receives a valid TCP FIN, it MUST send a FINAL_DATA capsule.
165+
* When an endpoint receives a valid FINAL_DATA capsule, it MUST send a TCP FIN.
166+
* When a TCP connection reaches the TIME-WAIT or CLOSED state, the associated endpoint MUST close its send stream.
167+
- If the connection closed gracefully, the endpoint MUST close the send stream gracefully.
168+
- Otherwise, the endpoint SHOULD close the send stream abruptly, using a mechanism appropriate to the HTTP version:
169+
- HTTP/3: RESET_STREAM with H3_CONNECT_ERROR
170+
- HTTP/2: RST_STREAM with CONNECT_ERROR
171+
- HTTP/1.1 over TLS: a TLS Error Alert
172+
- HTTP/1.1 (insecure): TCP RST.
173+
* When the receive stream is closed abruptly or without a FINAL_DATA capsule received, the endpoint SHOULD send a TCP RST if the TCP subsystem permits it.
174+
175+
The mandatory behaviors above enable endpoints to detect any truncation of incoming TCP data. The recommended behaviors propagate any TCP errors through the proxy connection.
176+
177+
~~~ aasvg
178+
+-------+ +------------+ +------------+ +-------+
179+
| TCP A | | Endpoint A | | Endpoint B | | TCP B |
180+
+-+-----+ +-+----------+ +----------+-+ +-----+-+
181+
+---"abc"--->+-------DATA{"abc"}------->+---"abc"--->|
182+
+----FIN---->+------FINAL_DATA{""}----->+----FIN---->|
183+
|<---FIN-----+<-----FINAL_DATA{""}------+<---FIN-----+
184+
| |<----QUIC.STREAM{FIN}-----+ |
185+
+---FINACK-->+-----QUIC.STREAM{FIN}---->| |
186+
| | | |
187+
~~~
188+
{: title="Simple graceful termination example (HTTP/3)"}
189+
190+
~~~ aasvg
191+
+-------+ +------------+ +------------+ +-------+
192+
| TCP A | | Endpoint A | | Endpoint B | | TCP B |
193+
+-+-----+ +-+----------+ +----------+-+ +-----+-+
194+
+----RST---->+---RST_STREAM{CON_ERR}--->+----RST---->|
195+
| | | |
196+
~~~
197+
{: title="Simple TCP RST termination example (HTTP/2)"}
198+
199+
~~~ aasvg
200+
+-------+ +------------+ +------------+ +-------+
201+
| TCP A | | Endpoint A | | Endpoint B | | TCP B |
202+
+-+-----+ +-+----------+ +----------+-+ +-----+-+
203+
+---"abc"--->+-------DATA{"abc"}------->+---"abc"--->|
204+
| | (... timeout @ A ...) | |
205+
| +--------TLS Alert-------->+----RST---->|
206+
| | | |
207+
~~~
208+
{: title="Timeout example (HTTP/1.1)"}
209+
210+
~~~ aasvg
211+
+-------+ +------------+ +------------+ +-------+
212+
| TCP A | | Endpoint A | | Endpoint B | | TCP B |
213+
+-+-----+ +-+----------+ +----------+-+ +-----+-+
214+
+-----FIN--->+-------FINAL_DATA{""}---->+-----FIN--->|
215+
| | | |
216+
| (FIN) | | (FIN) |
217+
|<---"abc"---+<----FINAL_DATA{"abc"}----+<---"abc"---+
218+
| |<----QUIC.STREAM{FIN}-----+ |
219+
+-----RST--->+-----H3_CONNECT_ERROR---->+-----RST--->|
220+
| | | |
221+
~~~
222+
{: title="RST after FIN example (HTTP/3)"}
164223

165224
# Additional Connection Setup Behaviors
166225

@@ -212,8 +271,32 @@ Template-driven TCP proxying is largely subject to the same security risks as cl
212271

213272
A small additional risk is posed by the use of a URI Template parser on the client side. The template input string could be crafted to exploit any vulnerabilities in the parser implementation. Client implementers should apply their usual precautions for code that processes untrusted inputs.
214273

274+
## Resource Exhaustion attacks
275+
276+
A malicious client can achieve cause highly asymmetric resource usage at the proxy by colluding with a destination server and violating the ordinary rules of TCP or HTTP. Some example attacks, and mitigations that proxies can apply:
277+
278+
* **Connection Pileup**: A malicious client can attempt to open a large number of proxy<->destination connections to exhaust the proxy's memory, port, or file descriptor limits. When using HTTP/2 or HTTP/3, each incremental TCP connection imposes a much higher cost on the proxy than on the attacker.
279+
- Mitigation: Limit the number of concurrent connections per client.
280+
* **Window Bloat**: An attacker can grow the receive window size by simulating a "long, fat network" {{?RFC7323}}, then fill the window (from the sender) and stop acknowledging it (at the receiver). This leaves the proxy buffering up to 1 GiB of TCP data until some timeout, while the attacker does not have to retain a large buffer.
281+
- Mitigation: Limit the maximum receive window for TCP and HTTP connections, and the size of userspace buffers used for proxying. Alternatively, monitor the connections' send queues and limit the total buffered data per client.
282+
* **WAIT Abuse**: An attacker can force the proxy into a TIME-WAIT, CLOSE-WAIT, or FIN-WAIT state until the timer expires, tying up a proxy<->destination 4-tuple for up to four minutes after the client's connection is closed.
283+
- Mitigation: Limit the number of connections for each client to each destination, even if those connections are in a waiting state and the corresponding CONNECT stream is closed. Alternatively, allocate a large range of IP addresses for TCP connections (especially in IPv6).
284+
215285
# Operational Considerations
216286

287+
## Avoiding HTTP/1.1
288+
289+
While this specification is fully functional under HTTP/1.1, performance-sensitive deployments SHOULD use HTTP/2 or HTTP/3 instead. When using HTTP/1.1:
290+
291+
* Each CONNECT request requires a new TCP and TLS connection, imposing a higher cost in setup latency, congestion control convergence, CPU time, and data transfer.
292+
* It may be difficult to implement the recommended unclean shutdown signals ({{closing-connections}}), as many TLS libraries do not support injecting TLS Alerts.
293+
* The number of active connections through each client may be limited by the number of available TCP client ports, especially if:
294+
- The client only has one IP address that can be used to reach the proxy.
295+
- The client is shared between many parties, such as when acting as a gateway or concentrator.
296+
- The proxied connections are often closed by the destination. This causes the client to initiate closure of the client<->proxy connection, leaving the client in a TIME-WAIT state for up to four minutes.
297+
298+
## Gateway Compatibility
299+
217300
Templated TCP proxies can make use of standard HTTP gateways and path-routing to ease implementation and allow use of shared infrastructure. However, current gateways might need modifications to support TCP proxy services. To be compatible, a gateway must:
218301

219302
* support Extended CONNECT (if acting as an HTTP/2 or HTTP/3 server).
@@ -250,8 +333,9 @@ IF APPROVED, IANA is requested to add the following entry to the "HTTP Capsule T
250333
| ----- | ------------ | --------- | ---------------------------------- | ----------------- | ------- |
251334
| Value | Capsule Type | Status | Reference | Change Controller | Contact |
252335
| (TBD) | DATA | permanent | (This document), {{specification}} | IETF | HTTPBIS |
336+
| (TBD) | FINAL_DATA | permanent | (This document), {{specification}} | IETF | HTTPBIS |
253337

254-
For this draft version of the protocol, the Capsule Type value `0x2028d7ee` shall be used provisionally for testing, under the name "DATA-07".
338+
For this draft version of the protocol, the Capsule Type values `0x2028d7ee` and `0x2028d7ef` shall be used provisionally for testing, under the names "DATA-07" and "FINAL_DATA-07".
255339

256340
--- back
257341

0 commit comments

Comments
 (0)