Internet-Draft Comparing ALPS and Half-RTT Data December 2020
Benjamin Expires 6 June 2021 [Page]
Intended Status:
D. Benjamin
Google LLC

Comparing ALPS and Half-RTT Data


This document compares the Application Layer Protocols Settings extension with the half-RTT feature in TLS 1.3.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 6 June 2021.

Table of Contents

1. Introduction

An application-layer protocol often starts with both parties negotiating parameters under which the protocol operates; for instance, HTTP/2 [RFC7540] and HTTP/3 [I-D.ietf-quic-http] use a SETTINGS frame to exchange the list of protocol parameters supported by each endpoint. This can achieved by waiting for TLS handshake [RFC8446] to complete and then performing the application-layer handshake within the application protocol itself.

This approach, however, means application protocols must wait for a secondary negotiation to complete, often incurring network round-trip. HTTP/2 and HTTP/3 mitigate this with a best-effort negotiation scheme: clients do not wait for server SETTINGS before sending a request. But then, by the time the client applies the setting, it has already sent the first request based on the default values. This limits the kinds of extensions possible. For example, the SETTINGS frame cannot support negotiate header compression [QUIC-3622] or a different static table [HTTP2-788] without changing the protocol to disable compression by default and switch partway through.

Protocol selection is another example of application-level negotiation with these trade-offs. The Application Layer Protocol Negotiation (ALPN) extension [RFC7301] adds protocol selection into the TLS handshake. ALPN is instead consistently ordered before all application data, including TLS 1.3 early data, without either a round-trip penalty or the need to send initial pre-negotiation data (see Section 3.2 of [RFC7540]).

The Application Layer Protocol Settings (ALPS) extension [I-D.vvv-tls-alps] implements [QUIC-3086-COMMENT] and adds a similar mechanism for settings within the protocol. It sends ALPN-specific protocol settings strings in the handshake, which can be ordered correctly relative to application data and integrated with TLS 1.3 early data negotiation.

As an alternative, Section 4.4.4 of [RFC8446] allows a server to send application data after the server Finished message, often referred to as half-RTT data. Half-RTT data is not a complete solution to the settings problem, however. This document describes the other changes necessary and compares the approach to ALPS.

2. Using Half-RTT Data

Although not currently widely-implemented, half-RTT data can be used to deliver HTTP/2 SETTINGS and other values at the right round-trip. This would result in a handshake flow like the following.

    Client                                              Server

    ClientHello               -------->
                              <--------       [HTTP/2 SETTINGS]
    [HTTP/2 SETTINGS]         -------->
    [HTTP/2 requests]         <------->      [HTTP/2 responses]

The approach, however, requires a number of additional changes and protocol interactions to work correctly.

2.1. Half-RTT Delimiter

In this design, the client waits to receive the HTTP/2 SETTINGS frame before sending requests. However, HTTP/2 servers are not required to send SETTINGS in half-data today, and most existing ones do not. [[TODO: Did I ever write this down anywhere I can link to? When I probed TLS 1.3 HTTP/2 servers, I found none that send half-RTT data.]] Without a new signal to the client, waiting would add a latency penalty to existing servers. TLS 1.3 does not include a delimiter between half-RTT data and the rest of the server application stream, so the client does not know a priori when it is done reading.

One option would be a TLS extension that adds a delimiter between half-RTT and normal server application data. The client would then wait for that delimiter without round-trip penalty and proceed. This would not work in QUIC because QUIC does not use TLS for application data at all. Instead, half-RTT data would need to be lifted into the handshake, which is the ALPS extension.

Alternatively, the client could rely on application protocol semantics, and assume the protocol defines exactly what is sent in half-RTT. However, HTTP/2 does not do this today. This would require defining new HTTP/2.1 and HTTP/3.1 protocols with a MUST-level requirement to send half-RTT SETTINGS. HTTP/2.1 and HTTP/3.1 would be negotiated via ALPN. Note both HTTP/2 and HTTP/3 must be updated because, per Section 3.2 of [I-D.ietf-quic-http], connectivity problems can break QUIC and clients are encouraged to fall back to a TCP-based version of HTTP.

2.2. Non-Integer HTTP Settings

The HTTP/2 and HTTP/3 SETTINGS frame can only carry integer values, but extensions may need to carry variable-length data. For example, [I-D.davidben-http-client-hint-reliability] uses a string value.

[I-D.bishop-httpbis-extended-settings] proposes an EXTENDED_SETTINGS frame to fix this. If defining HTTP/2.1 and HTTP/3.1, EXTENDED_SETTINGS can be added as a mandatory component of the new protocols.

If EXTENDED_SETTINGS is left optional, the client needs to know whether to expect a half-RTT EXTENDED_SETTINGS frame after half-RTT SETTINGS, to avoid the issues discussed in Section 2.1. Thus SETTINGS would need to contain a SETTINGS_EXTENDED_SETTINGS setting to indicate more half-RTT frames are coming.

[HTTPWG-COMMENT] suggested tabling EXTENDED_SETTINGS in favor of extensions defining new HTTP frames. That would not work here, absent each extension additionally defining an analog to SETTINGS_EXTENDED_SETTINGS, to signal to the client to expect a new frame.

2.3. Early Data and Session Tickets

TLS 1.3 introduces early data, which allows clients to send application data before receiving a ServerHello from the server. [RFC8470] describes how to use it in HTTP.

Application-level connection properties additionally must be established before the client sends early data. Otherwise if, for instance, HPACK static tables are negotiated, the client will not be able to encode the early request. Note Section 2 of [RFC8470] says early data in HTTP is conceptually concatenated with other application data, so early data and 1-RTT data in HTTP must share decoding rules.

Early data is sent before any response from the server, so connection properties are typically carried over from the ticket. Section 4.2.10 of [RFC8446] describes the mechanism for the ALPN extension: Each PSK has an associated ALPN protocol, determined from the previous connection. The client sends early data assuming that protocol was used. If the server negotiates a different value, it rejects early data.

Reliably-ordered protocol settings would require a similar construction. However TLS does not define ALPN's early data behavior generally, so every application protocol would need to define it themselves and, when implementing, rely on various callback interfaces in the TLS implementation.

This also introduces a dependency between NewSessionTicket and the server application data stream: the NewSessionTicket is not meaningful without part of the server application data (here, the SETTINGS and EXTENDED_SETTINGS frames). Moreover, in QUIC and DTLS, post-handshake messages are not ordered relative to application data, so the client may receive NewSessionTicket messages in the wrong order. The client then cannot store sessions in the TLS session until some application-defined point. This requires further integration between TLS and the application protocol.

See related discussion in [QUIC-436], [QUIC-2790], and [QUIC-2945]. Note HTTP/3 addressed the ordering issue by making associating settings with the ticket optional on the client [QUIC-2972], while a solution to this problem makes it mandatory.

2.4. Client Certificates

TLS APIs are often structured around the following sequence of operations:

  1. The calling application configures TLS parameters. This may include preferred cipher suites, client certificate requirements, callbacks to defer some configuration, etc.
  2. The calling application runs the handshake to some notion of completion. Before the handshake completes, connection properties are not established, the peer is not authenticated, and the application does not read or write data.
  3. The calling application queries handshake properties. It may query the negotiated ALPN protocol to determine how to proceed in the application protocol. It may query the peer certificate for application-level access checks.
  4. The calling application reads and writes data according to the application protocol.

This is analogous to many TCP socket APIs, where there is a "connect" or "accept" operation that completes before "recv" and "send" operations are available.

In server connections that do not resume a session, the TLS 1.3 half-RTT point has different semantics from a complete TLS handshake. The client's identity has not been established yes, so TLS implementations cannot transparently report the connection as ready to the calling application. Doing so risks security issues (the application's client certificate requirements are not yet checked) and compatibility breaks (the application cannot usefully query the peer certificate).

Instead, the TLS implementation might expose a separate interface for an earlier partial completion state. The application would then write half-RTT data, knowing that client authentication requirements are not yet met. This complicates the interface and the above structure. Alternatively, the TLS implementation may require the application configure a byte string to send as half-RTT data during the handshake, but note this risks the deadlocks described in Section 2.6.

2.5. TLS Terminators

Some server deployments use a TLS terminator which then makes a TCP connection to some backend application server. These deployments would need to preserve any MUST-level requirements to send SETTINGS in half-RTT data. A TLS terminator which completes the handshake and then proxies data from the backend server would inadvertently add a round-trip delay to the SETTINGS frame, delaying HTTP requests. However, a TLS terminator which begins proxying data at the half-RTT point instead risks skipping client certificate authentication.

Instead, the TLS terminator must coordinate with the backend server to determine what data may be sent early to unauthenticated clients, and what data is bulk application traffic.

2.6. TCP Flow Control

If not implemented properly, this design risks deadlocks with TCP flow control [TCP-TLS]. It is possible for both the client Finished flight and the server half-RTT data to exceed transport buffers. The server must read the client Finished flight and complete the handshake, even if the half-RTT data has not been written to the wire.

In particular, a TLS implementation may try to avoid the issues in Section 2.4 by treating half-RTT as a configured string sent as part of the handshake, rather than exposing a writable stream to the calling application. This strategy must still write half-RTT data in parallel with completing the handshake to avoid a deadlock. Many TLS implementations are layered on top of non-blocking TCP socket APIs, which means the calling application would still be responsible for driving these parallel operations. This changes the I/O patterns the application expects from TLS.

3. Using ALPS

The ALPS strategy is described in [I-D.vvv-tls-alps] and [I-D.vvv-httpbis-alps]. It implements [QUIC-3086-COMMENT], sending application settings in the EncryptedExtensions on both client and server. The client half is not strictly necessary (TLS 1.3 is always writable on the client first), but simplifies server implementations in QUIC, where application data streams are not ordered relative to each other.

    Client                                               Server

    ClientHello               -------->
                                        + alps(HTTP/2 SETTINGS)
                              <--------              {Finished}
    + alps(HTTP/2 SETTINGS)
    [HTTP/2 requests]         <------->      [HTTP/2 responses]

3.1. Half-RTT Delimiter

ALPS does not require a half-RTT delimiter. The entire payload is sent in the EncryptedExtensions message, which includes a common framing for extension values.

3.2. Non-Integer HTTP Settings

As in half-RTT data, an ALPS mechanism for HTTP/2 and HTTP/3 must handle the SETTINGS frame limitations. [I-D.vvv-httpbis-alps] allows the ALPS payload to contain multiple frames, so either the [I-D.bishop-httpbis-extended-settings] or [HTTPWG-COMMENT] strategies may be used. The payload is already framed in EncryptedExtensions, so there is no need for an indicator value like SETTINGS_EXTENDED_SETTINGS.

3.3. Early Data and Session Tickets

As in the half-RTT strategy, ALPS requires early data and session ticket integration. However, this behavior is part of the extension itself, so, like ALPN, there is no need to specify and implement this additional logic for each application protocol.

Unlike the application-level integration for half-RTT data, this TLS-level integration for ALPS does not have ordering issues with NewSessionTicket. NewSessionTicket messages are ordered relative to the handshake, so the ALPS values will always be available before a NewSessionTicket.

3.4. Client Certificates

As in ALPN and the half-RTT strategy, the server ALPS value is sent before receiving the client certificate. In ALPS, this would be part of the extension semantics exposed to application protocols, just as ALPN configuration is not protected by client certificates.

3.5. TLS Terminators

As in the half-RTT solution, ALPS requires a TLS terminator deployment to coordinate with its backend server to separate the early, unauthenticated SETTINGS data from the rest of the stream. However, the payload is already naturally kept separate from the rest of the application stream. Instead, the settings values are an analog of the ALPN value, which already requires coordination.

3.6. TCP Flow Control

ALPS sends the settings values in-band in the TLS handshake, rather than afterwards, so the deadlock risks described in [TCP-TLS] do not apply. The client will read the entire EncryptedExtensions message (and more) before trying to send the client Certificate, CertificateVerify, and Finished.

4. Security Considerations

Any server information delivered in time for the client's first application data records must be sent before checking client certificates. Section 2.4 and Section 3.4 discuss strategies for ensuring the calling application does not inadvertently reveal sensitive information to unauthenticated clients.

5. IANA Considerations

This document has no IANA considerations.

6. Informative References

"Update the HPACK static table", , <>.
Thomson, M., "draft-bishop-httpbis-extended-settings-00 comments", , <>.
Bishop, M., "HTTP/2 Extended SETTINGS Extension", Work in Progress, Internet-Draft, draft-bishop-httpbis-extended-settings-01, , <>.
Benjamin, D., "Client Hint Reliability", Work in Progress, Internet-Draft, draft-davidben-http-client-hint-reliability-02, , <>.
Bishop, M., "Hypertext Transfer Protocol Version 3 (HTTP/3)", Work in Progress, Internet-Draft, draft-ietf-quic-http-32, , <>.
Vasiliev, V., "Using TLS Application-Layer Protocol Settings (ALPS) in HTTP", Work in Progress, Internet-Draft, draft-vvv-httpbis-alps-00, , <>.
Benjamin, D. and V. Vasiliev, "TLS Application-Layer Protocol Settings Extension", Work in Progress, Internet-Draft, draft-vvv-tls-alps-01, , <>.
Thomson, M., "Binding settings into session tickets", , <>.
Oku, K., "When to send the SETTINGS frame", , <>.
Bishop, M., "Send complete SETTINGS", , <>.
Bishop, M., "Add application parameters to QUIC handshake and use it for H3 SETTINGS (comment)", , <>.
"Make using static table and Huffman encoding in QPACK opt-in", , <>.
Rescorla, E., "Move SETTINGS into TLS Handshake", , <>.
Friedl, S., Popov, A., Langley, A., and E. Stephan, "Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension", RFC 7301, DOI 10.17487/RFC7301, , <>.
Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, , <>.
Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, , <>.
Thomson, M., Nottingham, M., and W. Tarreau, "Using Early Data in HTTP", RFC 8470, DOI 10.17487/RFC8470, , <>.
Benjamin, D., "TLS 1.3 and TCP interactions", , <>.


This document has benefited from contributions and suggestions from Victor Vasiliev.

Author's Address

David Benjamin
Google LLC