RFC 9621
Architecture and Requirements for Transport Services
Architecture and Requirements for Transport Services ๐
Okay bestie, here's the header tea โ. This is RFC 9621, published by the Internet Engineering Task Force (IETF) in January 2025. Its category is Standards Track, and its ISSN is 2070-1721. The editors are T. Pauly from Apple Inc. and B. Trammell from Google Switzerland GmbH. The other authors are A. Brunstrom from Karlstad University, G. Fairhurst from the University of Aberdeen, and C. S. Perkins from the University of Glasgow ๐. The header doesn't list anything it obsoletes or updates, so it isn't replacing or patching any older RFC ๐ .
Abstract ๐ฆ
So this doc is basically the blueprint for an architecture that shows transport protocol features to apps for network communication ๐ง. The Transport Services API is asynchronous and event-driven, and it uses Messages to represent data transfer to apps. It also explains how a Transport Services Implementation can use multiple IP addresses, multiple protocols, and multiple paths, and how it can provide multiple application streams ๐ฅ. The main event here is the architecture and requirements, plus a shared vocab for both the API and the Implementation. Literally iconic ๐.
Status of This Memo ๐
This is an Internet Standards Track document โจ.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 7841 ๐.
Info about the current status of this document, any errata, and how to give feedback on it is at https://www.rfc-editor.org/info/rfc9621 ๐.
Copyright Notice ๐ธ
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, because they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and are provided without warranty as described in the Revised BSD License.
Table of Contents ๐๏ธ
1. Introduction
1.1. Background
1.2. Overview
1.3. Specification of Requirements
1.4. Glossary of Key Terms
2. API Model
2.1. Event-Driven API
2.2. Data Transfer Using Messages
2.3. Flexible Implementation
2.4. Coexistence
3. API and Implementation Requirements
3.1. Provide Common APIs for Common Features
3.2. Allow Access to Specialized Features
3.3. Select Between Equivalent Protocol Stacks
3.4. Maintain Interoperability
3.5. Support Monitoring
4. Transport Services Architecture and Concepts
4.1. Transport Services API Concepts
4.1.1. Endpoint Objects
4.1.2. Connections and Related Objects
4.1.3. Preestablishment
4.1.4. Establishment Actions
4.1.5. Data Transfer Objects and Actions
4.1.6. Event Handling
4.1.7. Termination Actions
4.1.8. Connection Groups
4.2. Transport Services Implementation
4.2.1. Candidate Gathering
4.2.2. Candidate Racing
4.2.3. Separating Connection Contexts
5. IANA Considerations
6. Security and Privacy Considerations
7. References
7.1. Normative References
7.2. Informative References
Acknowledgements
Authors' Addresses
1. Introduction โจ
Tons of Application Programming Interfaces (APIs) have been deployed to give transport interfaces to networks. The most widely known and copied one is probably the Socket interface (Socket API) [POSIX]. The naming of objects and functions across these APIs isn't consistent, and it changes depending on the protocol being used. For example, the idea of sending and receiving streams of data is the same for an unencrypted Transmission Control Protocol (TCP) stream as it is for a Transport Layer Security (TLS) stream [RFC8446] over TCP. But apps can't use the same socket send() and recv() calls on both kinds of connections ๐ญ. Terminology for transport protocol implementation is also all over the place. Words like "flow", "stream", "message", and "connection" can mean a bunch of different things depending on the protocol. That variety can cause real confusion when you're trying to figure out how protocols are similar, how they're different, and how apps can use them well ๐.
The goal of the Transport Services System architecture is to provide a flexible, reusable system with a common interface for transport protocols ๐. An application uses the Transport Services System through an abstract Connection. (We capitalize that word to tell it apart from the underlying connections of, say, TCP.) This gives flexible Connection establishment, so an application can request or require a set of Properties.
As apps adopt this interface, they get a wide set of transport features that can evolve over time. The system providing the interface can also tune its behavior based on app requirements and network conditions, without apps needing any changes. That flexibility means new features and protocols can get deployed faster ๐.
This architecture can also support apps by offering racing mechanisms, which try multiple IP addresses, protocols, or network paths in parallel. Otherwise, every app would need to build that stuff on its own (see Section 4.2.2). Racing selects one or more candidates. Each candidate has an equivalent Protocol Stack, and racing is used to find an optimal combination of a transport protocol instance (like TCP, UDP, or another transport), plus the configuration of its parameters and interfaces ๐ฏ. A Connection is an object that, once established, can be used to send and receive Messages. A Connection can also be cloned from another Connection, and then it becomes part of a Connection Group whose Connections share Properties ๐ซถ.
This document was developed alongside the Transport Services API specification [RFC9622] and the implementation guidelines [RFC9623]. Following the Transport Services Architecture doesn't require every API and implementation to be identical. But a common minimal set of features, represented in a consistent way, means apps can be ported easily from one Transport Services System implementation to another ๐.
1.1. Background ๐
The architecture of the Transport Services System is based on a survey of the services provided by IETF transport protocols and congestion control mechanisms [RFC8095], plus the distilled minimal set of features that transport protocols offer [RFC8923]. Those documents identified common features and patterns across all the transport protocols developed so far in the IETF ๐ .
Transport security is becoming more and more relevant when you use transport protocols on the Internet. So this document also looks at how transport security protocols affect the feature set exposed by Transport Services [RFC8922] ๐.
One of the big insights from identifying the minimal set of features that transport protocols provide [RFC8923] was that features fall into two groups. Either they (1) need application interaction and guidance (that document calls them Functional or Optimizing Features), or they (2) can be handled automatically by an implementation of the Transport Services System (called Automatable Features). Some of the Functional and Optimizing Features are common across all or nearly all transport protocols. Others would only be useful with a subset of protocols, but wouldn't hurt the others if specified. For example, some protocols can deliver messages faster for apps that don't need messages to arrive in the order they were sent. That functionality has to be explicitly allowed by the application, because reordering messages would be undesirable in many cases ๐.
1.2. Overview ๐บ๏ธ
Here's the rundown on the Transport Services System sections:
- Section 2 describes how the Transport Services API model is different from socket-based APIs. Specifically, it offers asynchronous, event-driven interaction, the use of Messages for data transfer, and the flexibility to use different transport protocols and paths without needing major changes to the application ๐.
- Section 3 explains the fundamental requirements for a Transport Services System. These principles are meant to make sure transport protocols can keep getting enhanced and evolving without significant changes from application developers ๐.
- Section 4 presents the Transport Services Implementation and defines the concepts used by the API [RFC9622] and described in the implementation guidelines [RFC9623]. It also introduces the Preconnection, which lets applications configure Connection Properties โจ.
1.3. Specification of Requirements ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.
1.4. Glossary of Key Terms ๐โจ
okay bestie, this part is the glossary ๐ซถ it gives you a quick, short description of the key terms that show up later in the doc, so you're never lost when they pop up ๐
- Application: an entity that uses the transport layer for end-to-end delivery of data across the network [RFC8095] ๐
- Cached State: the state and history that the Transport Services Implementation keeps for each set of the associated Endpoints that have been used before ๐๏ธ
- Candidate Path: one path that is available to an application and follows the Selection Properties and System Policy during racing ๐ฃ๏ธ
- Candidate Protocol Stack: one Protocol Stack that an application can use for a Connection during racing ๐ฅ
- Client: the peer that's responsible for starting a Connection ๐โโ๏ธ
- Clone: a Connection that was made from another Connection and is part of a Connection Group ๐
- Connection: shared state of two or more Endpoints that sticks around across the Messages sent and received between them [RFC8303]. when this doc and other Transport Services docs use the capitalized "Connection" term, they mean a Connection object that the Transport Services System is offering, not the more generic vibe of the word "connection" ๐
- Connection Context: a set of stored Properties across Connections, like cached protocol state, cached path state, and heuristics, which can include one or more Connection Groups ๐ง
- Connection Group: a set of Connections that share Properties and caches ๐ซ
- Connection Property: a Transport Property that controls per-Connection behavior of a Transport Services Implementation ๐๏ธ
- Endpoint: an entity that communicates with one or more other Endpoints using a transport protocol ๐ก
- Endpoint Identifier: an identifier that specifies one side of a Connection (local or remote), such as a hostname or URL ๐ชช
- Equivalent Protocol Stacks: Protocol Stacks that can be safely swapped or raced in parallel while a Connection is being established ๐
- Event: a primitive that an Endpoint invokes [RFC8303] ๐
- Framer: a data translation layer that can be added to a Connection to define how application-layer Messages get sent over a Protocol Stack ๐งต
- Local Endpoint: the local Endpoint ๐
- Local Endpoint Identifier: a representation of the application's identifier for itself, which it uses for a Connection ๐ช
- Message: a unit of data that can be transferred between two Endpoints over a Connection ๐
- Message Property: a property that can be used to specify details about Message transmission, or to get details about the transmission after a Message is received ๐
- Parameter: a value passed between an application and a transport protocol by a primitive [RFC8303] ๐
- Path: a representation of an available set of Properties that a Local Endpoint can use to communicate with a Remote Endpoint ๐บ๏ธ
- Peer: an Endpoint application party to a Connection ๐ฏ
- Preconnection: an object that represents a Connection that hasn't been established yet ๐ฑ
- Preference: a preference for prohibiting, avoiding, ignoring, preferring, or requiring a specific transport feature ๐ฆ
- Primitive: a function call used to communicate locally between an application and an Endpoint, related to one or more transport features [RFC8303] ๐
- Protocol Instance: a single instance of one protocol, including any state needed to establish connectivity or to send and receive Messages ๐งฉ
- Protocol Stack: a set of protocol instances that are used together to establish connectivity or to send and receive Messages ๐ฅโจ
- Racing: the attempt to select between multiple Protocol Stacks, based on the Selection and Connection Properties the application communicates, along with any Security Parameters ๐
- Remote Endpoint: the peer that a Local Endpoint can communicate with once a Connection is established ๐
- Remote Endpoint Identifier: a representation of the application's identifier for a peer that can take part in establishing a Connection ๐
- Rendezvous: the action of establishing a peer-to-peer Connection with a Remote Endpoint ๐ค
- Security Parameters: parameters that define an application's requirements for authentication and encryption on a Connection ๐
- Selection Property: a Transport Property that can be set to influence the selection of paths between the Local and Remote Endpoints ๐ฏ
- Server: the peer that's responsible for responding to a Connection initiation ๐๏ธ
- Socket: the combination of a destination IP address and a destination port number [RFC8303] ๐
- System Policy: input from an operating system or other global preferences that can constrain or influence how an implementation gathers Candidate Paths and Candidate Protocol Stacks and races the candidates while a Connection is being established ๐๏ธ
- Transport Feature: a specific end-to-end feature that the transport layer provides to an application โจ
- Transport Property: a property of a transport protocol and the services it provides [RFC8095] ๐
- Transport Service: a set of transport features, not tied to any given framing protocol, that gives an application a complete service ๐
- Transport Services API: the abstract interface [RFC9622] to a Transport Services Implementation [RFC9623] ๐ช
- Transport Services Implementation: all the objects and protocol instances used internally by a system or library to provide the functionality needed for a transport service across a network, as the abstract interface requires ๐ ๏ธ
- Transport Services System: the Transport Services Implementation and the Transport Services API together ๐
2. API Model ๐ง ๐
okay so the model of using sockets looks like this (see Figure 1) ๐
- Applications create connections and transfer data using the Socket API ๐ฒ
- The Socket API gives you the interface to the implementations of TCP and UDP (usually living in the system's kernel) ๐งฑ
- TCP and UDP in the kernel send and receive data over the available network-layer interfaces ๐ค
- Sockets are bound directly to transport-layer and network-layer addresses, which you get through a separate resolution step, usually handled by a system-provided DNS stub resolver ๐งญ
+-----------------------------------------------------+
| Application |
+-----------------------------------------------------+
| | |
+------------+ +------------+ +--------------+
| DNS Stub | | Stream API | | Datagram API |
| Resolver | +------------+ +--------------+
+------------+ | |
+---------------------------------+
| TCP UDP |
| Kernel Networking Stack |
+---------------------------------+
|
+-----------------------------------------------------+
| Network-Layer Interface |
+-----------------------------------------------------+
Figure 1: Socket API Model
the Transport Services System is basically an upgraded version of that model ๐ it modernizes the API that the transport layer shows to applications, and it levels up the capabilities of the Transport Services Implementation under that API ๐
the Transport Services API [RFC9622] is the interface an application uses to create Connections and transfer data ๐ช it mashes together interfaces for multiple interaction patterns into one unified whole (see Figure 2) ๐ซถ this gives generic functions and also protocol-specific mappings for TCP, UDP, UDP-Lite, and other protocol layers ๐ those mappings are extensible, so future documents could define similar mappings for new layers and for other transport protocols, like QUIC [RFC9000] ๐
+-----------------------------------------------------+
| Application |
+-----------------------------------------------------+
|
+-----------------------------------------------------+
| Transport Services API |
+-----------------------------------------------------+
|
+-----------------------------------------------------+
| Transport Services Implementation |
| (Using DNS, UDP, TCP, SCTP, DCCP, TLS, QUIC, etc.) |
+-----------------------------------------------------+
|
+-----------------------------------------------------+
| Network-Layer Interface |
+-----------------------------------------------------+
Figure 2: Transport Services API Model
by combining name resolution with Connection establishment and data transfer in one single API, it lets more flexible implementations provide path and transport protocol agility on the application's behalf ๐ฆ
the Transport Services Implementation [RFC9623] is the part of the Transport Services System that implements the transport-layer protocols and the other functions needed to send and receive data ๐ ๏ธ it's responsible for mapping the API to a specific available transport Protocol Stack, and for managing the available network interfaces and paths ๐ฃ๏ธ
there are key differences between the architecture of the Transport Services System and the architecture of the Socket API ๐ the API of the Transport Services System:
- is asynchronous and event-driven โก
- uses Messages for representing data transfer to applications ๐
- describes how a Transport Services Implementation can resolve Endpoint Identifiers to use multiple IP addresses, multiple protocols, and multiple paths, and to provide multiple application streams ๐โจ
2.1. Event-Driven API โจ
okay so, back in the day the Socket API was blocking, which means it made you sit there waiting for connections and data to show up ๐ญ. But most modern apps talk to the network asynchronously, so that was a total mismatch. The workaround people used was a try-and-fail model. If the app wants to read but the peer hasn't sent anything yet, the read just fails. Then the app waits and tries again later. Not iconic ๐.
The Transport Services API is different. All interactions are expected to be asynchronous ๐ . It's built around an event-driven model (see Section 4.1.6) that handles this async vibe. Other forms of async communication could also be available to apps, depending on the platform implementing the interface.
For example, when a Transport Services app wants to receive data, it issues an async call to receive new data from the Connection. When the data arrives, it gets delivered to the app through async events that contain the data. Error handling is async too, so errors show up as async error events.
The API also delivers events about the lifetime of a connection and changes in the available network links. The Socket API never made those explicit ๐.
Async events make connecting and transferring data feel much more natural. Events over time match how networks actually behave, instead of treating network resources like file system objects that might be temporarily unavailable ๐ฆ.
Callbacks are also provided for async interactions that aren't directly tied to events on the network or network interfaces ๐.
2.2. Data Transfer Using Messages
The Socket API gives you a message interface for datagram protocols like UDP, but for TCP it's just an unstructured stream ๐ญ. TCP can send and receive data as a byte-stream, but most apps need to figure out the structure inside that stream. For example, HTTP/1.1 uses character delimiters to segment messages over a byte-stream [RFC9112]. TLS record headers carry a version, content type, and length [RFC8446]. HTTP/2 uses frames to segment its headers and bodies [RFC9113].
Transport Services represents data as Messages, so it matches the way apps actually use the network ๐ง. A Message-based abstraction comes with lots of perks, such as:
- providing additional information to the Protocol Stack;
- the ability to associate deadlines with Messages, for apps that care about timing;
- the ability to control reliability, which Messages to retransmit when there is packet loss, and how best to make use of the data that arrived;
- the ability to automatically assign Messages and connections to underlying transport connections to utilize multistreaming and create Pooled Connections.
Letting apps interact with Messages is backward-compatible with existing protocols and APIs, because it doesn't change the wire format of any protocol ๐ซถ. Instead, it gives the Protocol Stack extra info so it can make better use of modern transport protocols, while making the app's parsing job simpler. For protocols that naturally use a streaming abstraction, Framers (Section 4.1.5) bridge the gap between the two ๐.
2.3. Flexible Implementation
The Socket API for protocols like TCP is usually limited to connecting to a single address over a single interface (IP source address) ๐. It also presents a single stream to the app. Software built on top of that often inherits this single-address, single-stream thinking. The Transport Services Architecture is designed to:
- handle multiple candidate endpoints, protocols, and paths;
- support candidate protocol racing to select the most optimal stack in each situation;
- support multipath and multistreaming protocols;
- provide state caching and application control over it.
A Transport Services Implementation is meant to be flexible at Connection establishment time. It considers many different options and tries to pick the most optimal combinations by racing them and measuring the results (see Sections 4.2.1 and 4.2.2). This requires apps to specify identifiers for the Local and Remote Endpoint that sit at a higher level than IP addresses, such as a hostname or URL. The Transport Services Implementation uses these identifiers for resolution, path selection, and racing. An implementation can also add fallback mechanisms if connection establishment for one protocol fails or performance is judged unsatisfactory.
Information used during Connection establishment (for example, cryptographic resumption tokens, information about whether certain protocols are usable on the path, and results of racing in previous connections) is cached in the Transport Services Implementation. Apps get to control whether that information is used for a specific establishment, which lets them make trade-offs between efficiency and linkability ๐.
Flexibility after Connection establishment matters too. Transport protocols that can migrate between multiple network-layer interfaces need to be able to process and react to interface changes. Protocols that support multiple application-layer streams need to support initiating and receiving new streams using existing connections ๐ฅ.
2.4. Coexistence
Transport Services is designed as an enhanced replacement for the Socket API, but it doesn't need to replace it entirely on a system or platform ๐. Coexistence has been recommended for incremental deployability [RFC8170]. So the architecture is designed to run alongside (or, indeed, on top of) an existing Socket API implementation. Only apps built on the Transport Services API are managed by the system's Transport Services Implementation.
3. API and Implementation Requirements โจ
One goal of the architecture is to redefine the interface between apps and transports in a way that lets the transport layer evolve and improve without fundamentally changing the contract with the app. That means carefully thinking about how to expose the capabilities of protocols. The architecture also covers system policies that can influence and inform how transport protocols use a network path or interface.
There are several ways the Transport Services System can offer flexibility to an app. It can:
- provide access to transport protocols and protocol features;
- use these protocols across multiple paths that could have different performance and functional characteristics;
- communicate with different remote systems to optimize performance, robustness to failure, or some other metric.
Beyond these, if the Transport Services API stays the same over time, new protocols and features can be added to the Transport Services Implementation without requiring app changes to adopt them ๐ฆ. Similarly, this can provide a common basis for utilizing information about a network path or interface, enabling evolution below the transport layer.
The normative requirements in this section allow Transport Services APIs and Transport Services Implementations to provide this functionality without causing incompatibility or introducing security vulnerabilities ๐ก๏ธ.
3.1. Provide Common APIs for Common Features
Any functionality that is common across multiple transport protocols SHOULD be made accessible through a unified set of calls using the Transport Services API. As a baseline, any Transport Services API SHOULD allow access to the minimal set of features offered by transport protocols [RFC8923]. If that minimal set is updated or expanded in the future, the Transport Services API ought to be extended to match โจ.
An app can specify constraints and preferences for the protocols, features, and network interfaces it will use via Properties. Properties let an app declare its preferences for how the transport service should operate at each stage in the lifetime of a connection. Transport Properties are subdivided into the following:
- Selection Properties, which specify which paths and Protocol Stacks can be used and are preferred by the app;
- Connection Properties, which inform decisions made during Connection establishment and fine-tune the established connection; and
- Message Properties, which can be set on individual Messages.
It is RECOMMENDED that the Transport Services API offer Properties that are common to multiple transport protocols ๐ซถ. This lets a Transport Services System appropriately select between protocols that offer equivalent features. Similarly, it is RECOMMENDED that the Properties offered by the Transport Services API be applicable to a variety of network-layer interfaces and paths, so different network paths can be raced without affecting the apps using the API. Each is expected to have a default value.
It is RECOMMENDED that default values for Properties be selected to ensure correctness for the widest set of apps, while providing the widest set of options for selection. For example, since both apps that require reliability and those that do not can function correctly when a protocol provides reliability, reliability ought to be enabled by default. As another example, the default value for a Property regarding the selection of network interfaces ought to permit as many interfaces as possible ๐ธ.
Apps using the Transport Services API need to be designed to be robust to the automated selection provided by the Transport Services System. This automated selection is constrained by the preferences the app expresses, and it requires apps to explicitly set Properties that define any necessary constraints on protocol, path, and interface selection ๐ .
3.2. Allow Access to Specialized Features โจ
Okay so some apps need to get into the nitty-gritty of transport protocols to tune how they behave and stay compatible with the remote system ๐ง. So it is RECOMMENDED that the Transport Services API and the Transport Services Implementation let apps use more specialized protocol features ๐ .
Some specialized features only matter for one specific protocol and not the others ๐ฆ. For example, if an app is using TCP, it might need control over the User Timeout Option for TCP [RFC5482]. That feature wouldn't do anything for other transport protocols. So in that case, the API ought to expose the feature so it takes effect when that protocol is selected, without implying that only that protocol could ever be used ๐ง. Like, if the API lets an app say it prefers the User Timeout Option, the communication would not fail just because a protocol like UDP got selected instead.
Other specialized features can also be strictly required by an app, and those further constrain which protocols are allowed ๐. For example, if an app requires automatic handover or failover for a connection, only Protocol Stacks that provide this feature are eligible, like stacks that include a multipath protocol or a protocol that supports connection migration ๐ฃ๏ธ. So a Transport Services API needs to let apps define requirements like that and limit the options the Transport Services Implementation can use. Since these options aren't part of the core/common features, it's generally simple for an app to change its set of constraints and adjust which protocol features are allowed, all without changing the core implementation ๐.
To control these specialized features, the app declares its preference: whether a specific feature is prohibited, should be avoided, can be ignored, is preferred, or is required in the preestablishment phase ๐ซถ. The implementation honors that preference and lets the app check the availability of each specialized feature after the connection is successfully established ๐.
3.3. Select Between Equivalent Protocol Stacks ๐งฉ
A Transport Services Implementation can attempt to use, and select between, multiple Protocol Stacks based on the Selection and Connection Properties the app communicated, along with any Security Parameters ๐. It can only attempt to use multiple Protocol Stacks when they are "equivalent", which means the stacks can provide the same Transport Properties and interface expectations the app asked for. Equivalent Protocol Stacks can be safely swapped or raced in parallel (see Section 4.2.2) during Connection establishment ๐.
Here are two examples of stacks that are not equivalent ๐ :
- If the app requires preservation of Message boundaries, a Protocol Stack that runs UDP as the top-level interface to the app is not equivalent to a Protocol Stack that runs TCP as the top-level interface. A UDP stack lets the app read out Message boundaries based on the datagrams sent from the remote system, whereas TCP doesn't preserve Message boundaries on its own and needs a framing protocol on top to determine them.
- If the app specifies that it requires reliable transmission of data, a Protocol Stack using UDP without any reliability layer on top isn't allowed to replace a Protocol Stack using TCP.
And here's an equivalent one ๐:
- If the app does not require reliable transmission of data, a Protocol Stack that adds reliability could be regarded as an equivalent Protocol Stack, as long as providing this wouldn't conflict with any other application-requested Properties.
A Transport Services Implementation can race different security protocols, e.g., if the System Policy is explicitly configured to consider them equivalent ๐. A Transport Services Implementation SHOULD only race Protocol Stacks where the transport security protocols within the stacks are identical. To make sure security protocols aren't swapped by accident, a Transport Services Implementation MUST only select Protocol Stacks that meet application requirements [RFC8922]. A Transport Services Implementation MUST NOT automatically fall back from secure protocols to insecure protocols, or fall back to weaker versions of secure protocols. A Transport Services Implementation MAY allow applications to explicitly specify which versions of a protocol ought to be permitted, e.g., to allow a minimum version of TLS 1.2 if TLS 1.3 is not available.
Security is not a vibe to gamble with ๐. Keep the rules above in mind, because they're the guardrails that stop your data from sneaking onto a weaker protocol without you noticing.
A Transport Services Implementation MAY specify security Properties relating to how the system operates, like requirements, prohibitions, and preferences for using DNS Security Extensions (DNSSEC) or DNS over HTTPS (DoH) ๐.
3.4. Maintain Interoperability ๐ค
Quick heads up ๐: neither the Transport Services API [RFC9622] nor the guidelines for implementation of the Transport Services System [RFC9623] define new protocols or protocol capabilities that affect what gets communicated across the network. A Transport Services System MUST NOT require that a peer on the other side of a connection use the same API or implementation. A Transport Services Implementation acting as a connection initiator can talk to any existing Endpoint that implements the transport protocol(s) and all the required Properties selected. Similarly, a Transport Services Implementation acting as a Listener can receive connections for any protocol that's supported from an existing initiator that implements the protocol, whether or not that initiator uses the Transport Services System.
A Transport Services Implementation is the one making decisions about which protocols and interfaces get selected ๐ง . In normal use, a given version of a Transport Services System SHOULD result in consistent protocol and interface selection decisions for the same network conditions, given the same set of Properties. That's intended to give the app predictable outcomes ๐ฎ.
3.5. Support Monitoring ๐
The Transport Services API adds a layer of abstraction for apps and enables more automation below the API ๐ค. But that abstraction comes at the cost of extra complexity when app programmers, users, or system administrators try to figure out why issues and failures are happening ๐ญ. So a Transport Services System should offer monitoring functions that provide relevant debug and diagnostic information ๐ ๏ธ. For example, these functions could indicate the protocol(s) in use, the number of open connections per protocol, and any statistics those protocols may offer.
4. Transport Services Architecture and Concepts ๐๏ธ
This section describes the architecture non-normatively, meaning it explains things rather than laying down rules, and explains how a Transport Services Implementation works ๐. The concepts defined in this document are mainly meant for the documents and specs that describe the Transport Services System. That includes the architecture, the Transport Services API, and the associated Transport Services Implementation. The specific terminology can show up in some implementations, but it's expected that running code will keep using a bunch of other terms too ๐ป.
The architecture divides the concepts for the Transport Services System into two categories ๐๏ธ:
- API concepts, which are meant to be exposed to applications; and
- System-implementation concepts, which are meant to be used internally by a Transport Services Implementation.
Here's the top-level picture of how the concepts in a Transport Services System relate to one another ๐ผ๏ธ:
+-----------------------------------------------------+
| Application |
+-+----------------+------^-------+--------^----------+
| | | | |
pre- | data | events
establishment | transfer | |
| establishment | termination |
| | | | |
| +--v------v-------v+ |
+-v-------------+ Connection(s) +-------+----------+
| Transport +--------+---------+ |
| Services | |
| API | +-------------+ |
+------------------------+--+ Framer(s) |-----------+
| +-------------+
+------------------------|----------------------------+
| Transport | |
| System | +-----------------+ |
| Implementation | | Cached | |
| | | State | |
| (Candidate Gathering) | +-----------------+ |
| | |
| (Candidate Racing) | +-----------------+ |
| | | System | |
| | | Policy | |
| +----------v-----+ +-----------------+ |
| | Protocol | |
+-------------+ Stack(s) +----------------------+
+-------+--------+
V
+-----------------------------------------------------+
| Network-Layer Interface |
+-----------------------------------------------------+
Figure 3: Concepts and Relationships in the Architecture of the
Transport Services System
The Transport Services Implementation includes the Cached State and System Policy ๐งฑ.
The System Policy provides input from an operating system or other global preferences. It can constrain or influence how an implementation gathers Candidate Paths and Protocol Stacks, and how it races those candidates when establishing a Connection โ๏ธ. The details of System Policy configuration and enforcement are largely dependent on the platform and implementation, and they don't affect application-level interoperability. That's why the Transport Services API [RFC9622] does not specify an interface for reading or writing System Policy ๐ .
The Cached State is the state and history that the Transport Services Implementation keeps for each set of associated Endpoints that have previously been used ๐๏ธ. An application ought to explicitly request any required or preferred Properties via the Transport Services API ๐ซถ.
4.1. Transport Services API Concepts ๐
Okay so, the big picture: a Transport Services API needs to give you Connection objects (Section 4.1.2) so your app can set up a conversation and then send and receive data ๐จ. Depending on your programming language, these might show up as handles or referenced objects. Either way, bestie, you're holding the connection ๐ซถ
Beyond Connection objects, every Transport Services API has to offer a few big groups of actions:
- Preestablishment (Section 4.1.3) is where your app describes what it wants from the network: its goals, the stuff it needs, the stuff it refuses to accept, and what it'd prefer. These Properties work across several transport protocols unless we say otherwise. They're a huge deal, because they shape how the connection gets set up, what you can expect when sending data, and which events you'll get to hear about ๐
- Establishment (Section 4.1.4) is all about the things your app does to a Connection object to get it ready for data transfer ๐
- Data transfer (Section 4.1.5) covers how your app represents the data going out and coming in, the functions used to send and receive it, and how your app finds out how the transfer is going ๐ฆ
- Event handling (Section 4.1.6) lists the kinds of notifications your app can get while a Connection is alive. Events are also your chance to poke at the underlying transport, like checking its state or tweaking its maintenance options ๐
- Termination (Section 4.1.7) is the exit plan: how data stops flowing and how the connection state gets torn down ๐
The diagram below is the lifetime of a Connection object at a glance ๐ฆ Some actions are alternatives (you either start a connection or listen for incoming ones, not both at once), some are optional (like setting Connection and Message Properties during preestablishment), and a few got left out to keep things simple.
Preestablishment : Established : Termination
----------------- : ----------- : -----------
: :
+-- Local Endpoint : Message :
+-- Remote Endpoint : Receive() | :
+-- Transport Properties : Send() | :
+-- Security Parameters : | :
| : | :
| InitiateWithSend() | Close() :
| +---------------+ Initiate() +-----+------+ Abort() :
+---+ Preconnection |------------->| Connection |-----------> Closed
+---------------+ Rendezvous() +------------+ :
Listen() | : | | :
| : | v :
v : | Connection :
+----------+ : | Ready :
| Listener |----------------------+ :
+----------+ Connection Received :
: :
Figure 4: The Lifetime of a Connection Object
So here's the vibe of the whole lifecycle โจ It's split into three phases: preestablishment, the Established state, and termination. In preestablishment you're working with a Preconnection object, which holds sub-objects describing the Properties and parameters of the connections you want (Local and Remote Endpoints, Transport Properties, and Security Parameters) ๐ง From a Preconnection you can either start listening for inbound connections, which creates a Listener object, or make a new connection straight away with Initiate (for outbound connections) or Rendezvous (for peer-to-peer connections).
Once a Connection is Established, your app can send and receive Message objects and keep up with state updates ๐ And whether you close or abort it, locally or because the peer did, a Connection can be terminated ๐
4.1.1. Endpoint Objects
An Endpoint Identifier describes one side of a transport connection ๐ Endpoints come in two flavors, Local Endpoints and Remote Endpoints, and each Endpoint Identifier stands for the identity your app uses as the source or destination of a connection. You can specify an Endpoint Identifier at different levels of abstraction. A high-level one, like a hostname, can get resolved into more concrete identities, like IP addresses ๐ A Remote Endpoint Identifier can even stand for a multicast group or an anycast address. If it's multicast, a multicast transport is the one that gets selected for the communication ๐
Remote Endpoint Identifier: This is your app's identifier for a peer that can take part in a transport connection. For example, it could be a DNS name for the peer paired with a service name or port ๐
Local Endpoint Identifier: This is your app's identifier for itself, the one it uses for transport connections. For example, a local IP address and port ๐
4.1.2. Connections and Related Objects
Connection: A Connection object stands for one or more active transport protocol instances that can send and/or receive Messages between Local and Remote Endpoints. It's an abstraction of the communication itself, and it holds the state for the underlying transport protocol instances and any ongoing data transfers ๐ง For example, an active Connection can be a connection-oriented protocol like TCP. It can also be a fully specified 5-tuple for a connectionless protocol like UDP, where the Connection is still just an abstraction at the endpoints. It can even be a pool of transport protocol instances, like a set of TCP and QUIC connections to equivalent endpoints, or one stream of a multistreaming transport protocol instance ๐ Connections can be created from a Preconnection or by a Listener.
Preconnection: A Preconnection object is a Connection that hasn't been established yet ๐ฑ It stores the parameters of that Connection: the Local Endpoint Identifier it'll be established from, the Remote Endpoint Identifier it'll connect to, and the Transport Properties that influence which paths and protocols the Connection uses. A Preconnection can be fully specified, which means it describes one single possible Connection, or partially specified, which means it describes a whole family of possible Connections ๐ฆ A Local Endpoint (Section 4.1.3) is required for a Preconnection used to Listen for incoming Connections, but it's optional if the Preconnection is used to Initiate a Connection. The Remote Endpoint Identifier is required for a Preconnection used to Initiate a Connection, but optional if it's used to Listen. And if a peer-to-peer Rendezvous is going to happen based on the Preconnection, then both the Local Endpoint Identifier and the Remote Endpoint Identifier are required ๐ซถ
Transport Properties: Transport Properties are how your app expresses its requirements, prohibitions, and preferences, and how it configures a Transport Services Implementation ๐๏ธ There are three kinds:
- Selection Properties (Section 4.1.3): these can only be set on a Preconnection ๐
- Connection Properties (Section 4.1.3): these can be set on a Preconnection and changed later on the Connection ๐ง
- Message Properties (Section 4.1.5): these can be set as defaults on a Preconnection or a Connection, and they can also be set during data transfer to affect specific Messages ๐ฌ
Listener: A Listener object accepts incoming transport protocol connections from Remote Endpoints and makes the matching Connection objects for them ๐ It's created from a Preconnection object that describes the type of incoming Connections it's going to accept.
4.1.3. Preestablishment
Selection Properties: Selection Properties are the Properties your app sets to influence which paths get picked between the Local and Remote Endpoints, which transport protocols get picked, or how the generic transport protocol features behave ๐ฃ๏ธ They can be requirements, prohibitions, or preferences. Some examples that affect path selection are the interface type (like a Wi-Fi connection or a Cellular LTE connection), requirements around the largest Message that can be sent, or preferences for throughput and latency ๐ Examples that affect protocol selection and the configuration of transport protocol features include reliability, multipath support, and support for TCP Fast Open โก
Connection Properties: Connection Properties configure protocol-specific options and control how each connection behaves in a Transport Services Implementation ๐งฉ For instance, a protocol-specific Connection Property can say that if TCP gets used, the implementation ought to use the User Timeout Option. Having that Property doesn't force any particular protocol to be used, though, so no drama there ๐ In general, these Properties don't directly decide which paths or protocols get selected, but an implementation can use them during Connection establishment. They get set on a Preconnection before the Connection is established, and you can still modify them on the Connection afterwards. Changes made after establishment take effect on a best-effort basis ๐
Security Parameters: Security Parameters define your app's requirements for authentication and encryption on a Connection ๐ Transport security protocols, like the ones described in [RFC8922], use them to set up secure Connections. Some parameters you can set are local identities, private keys, supported cryptographic algorithms, and requirements for validating trust in remote identities ๐๏ธ Security Parameters are mostly tied to a Preconnection object, but Properties about identities can be attached directly to Endpoints ๐ซง
4.1.4. Establishment Actions โจ
Initiate: okay so this is the main move an app makes to create a Connection to a Remote Endpoint ๐ It also sets up whatever local or remote state is needed so Messages can actually be sent. For some protocols it kicks off a client-to-server-style handshake ๐ค. For others, like connectionless UDP, it just sets up local state ๐ฆ Figuring out how to connect, like resolving the Remote Endpoint Identifier, happens right after you call Initiate ๐ง
Listen: this one enables a Listener to accept incoming connections ๐ The Listener then makes Connection objects as incoming connections get accepted (Section 4.1.6). By default, Listeners register on multiple paths, protocols, and Local Endpoints ๐ The only time that changes is if Selection Properties and/or the Local Endpoint Identifier(s) you specify put limits on it. Connections can be accepted on any of the available paths or endpoints, so it's giving main character energy ๐
Rendezvous: this is how you set up a peer-to-peer connection with a Remote Endpoint ๐ซถ It tries to initiate a connection to the Remote Endpoint and listens for an incoming one from that same Endpoint at the same time ๐ฅ Figuring out your options, like resolving the Remote Endpoint Identifier(s), happens once you call Rendezvous. Just like Listeners, the set of local paths and endpoints is limited by Selection Properties ๐ If it works, calling Rendezvous makes a Connection object and hands it back asynchronously to represent the peer-to-peer connection ๐ How it actually connects depends on the Local and Remote Endpoints you set on the Preconnection. For example, if both are TCP host candidates, a TCP simultaneous open [RFC9293] might be performed ๐ง But if the Local Endpoints include server-reflexive candidates, like the ones STUN (Session Traversal Utilities for NAT) [RFC8489] provides, then Rendezvous races candidates in the style of the ICE (Interactive Connectivity Establishment) algorithm [RFC8445]. That's how it does NAT binding discovery and starts the peer-to-peer connection ๐ธ
4.1.5. Data Transfer Objects and Actions ๐
Message: a Message object is a unit of data that can be represented as bytes and transferred between two endpoints over a transport connection ๐ฆ The bytes inside a Message are assumed to be ordered. If an application doesn't care what order its peer gets two distinct spans of bytes in, those spans count as independent Messages โจ Messages get sent in the payload of IP packets. One packet can carry one or more Messages, or parts of a Message ๐
Message Properties: these are how you specify details about how a Message gets sent ๐ You can set them directly on individual Messages, or as defaults on a Preconnection or Connection. They might only affect how the Message is sent, like how the transport handles prioritization and reliability, but they can also include Properties that specific protocols encode and send to the Remote Endpoint ๐ง When receiving, Message Properties can hold info about the received Message, like metadata generated at the receiver and information the Remote Endpoint signaled ๐ฆ For example, a Message can be marked with a Message Property saying it's the final Message on a Connection. Iconic, right? ๐
Send: the Send action transmits a Message over a Connection to the Remote Endpoint ๐ The Send interface can accept Message Properties that control how that specific Message content is sent. The status of the Send action gets delivered back to the sending app in an event (Section 4.1.6) ๐
Receive: the Receive action tells the system the app is ready to asynchronously accept a Message over a Connection from a Remote Endpoint ๐โโ๏ธ The Message content itself shows up later in an event (Section 4.1.6). The Receive interface can include Message Properties that are specific to the Message being delivered to the app ๐ท
Framer: a Framer is a data translation layer you can add to a Connection ๐งฉ Framers let you extend a Connection's Protocol Stack so it knows how to encapsulate or encode outbound Messages and how to decapsulate or decode inbound data back into Messages. That's how Message boundaries can stay intact on a Connection object, even when the protocol underneath is just an unstructured stream, like TCP ๐ซถ This exists because so many application protocols grew up on TCP, which doesn't preserve Message boundaries ๐ญ Lots of those protocols need boundaries to work, so each one ended up defining its own framing. For example, when an HTTP application sends and receives HTTP Messages over a byte-stream transport, it has to parse the boundaries of those HTTP Messages out of the stream of bytes ๐
4.1.6. Event Handling ๐
The following categories of events can be delivered to an application ๐
Connection Ready: this signals to an app that a Connection is ready to send and/or receive Messages ๐ฆ If the Connection relies on handshakes to set up state between peers, it's assumed those steps have already happened ๐ค
Connection Closed: this signals to an app that a Connection can no longer be used to send or receive Messages ๐ฅ The event delivers a reason or error that describes how the termination happened ๐
Connection Received: this signals to an app that a Listener has received a Connection ๐ฌ
Message Received: this delivers received Message content to the app, based on a Receive action ๐ฅ To let an app limit how often these events happen, each call to Receive gets paired with a single Receive event ๐ฏ This can include an error if the Receive action can't be satisfied, e.g., because the Connection got closed ๐
Message Sent: this notifies the app about the status of its Send action ๐จ It might indicate a failure if the Message can't be sent, or it might indicate that the Message has been processed by the Transport Services System โ
Path Properties Changed: this notifies the app that a Property of the Connection has changed in a way that might affect how and where data is sent and/or received ๐ฃ๏ธ Plot twist, the network moved, bestie ๐ช๏ธ
4.1.7. Termination Actions ๐
Close: this is the action an app takes on a Connection to say it no longer intends to send data, or is no longer willing to receive it ๐ซก The protocol should signal this state to the Remote Endpoint if the transport protocol allows it ๐ก (Note that this is different from "half-closing" a bidirectional connection, like when a FIN is sent in one direction of a TCP connection [RFC9293] ๐ The end of a stream can also be indicated using Message Properties when sending ๐)
Abort: this is the action an app takes on a Connection to tell the Transport Services System not to try delivering any outstanding data, and to close and drop the connection right away ๐ It's meant for immediate termination, usually when something went wrong ๐ฌ Not me ending it like this, but okay ๐
4.1.8. Connection Groups ๐ฏโโ๏ธ
A Connection Group is a set of Connections that shares Connection Properties and Cached State generated by protocols ๐ง A Connection Group handles state for managing Connections inside a single application, and it doesn't need end-to-end protocol signaling ๐ซง For transport protocols that support multiplexing, only Connections in the same Connection Group are allowed to be multiplexed together ๐
The API lets you create a Connection from another Connection ๐ช That new Connection gets added to the Connection Group. If you change one of the Connection Properties on any Connection in the group, it automatically changes for all the others ๐ซ All Connections in a Connection Group share the same set of Connection Properties except for Connection Priority. Those shared Properties are said to be entangled ๐งถ
Passive Connections can also be added to a Connection Group ๐ฟ For example, that happens when a Listener receives a new Connection that's just a new stream of a multistreaming protocol instance that's already active ๐
Connection Groups are managed by the Transport Services Implementation, but an app can define different Connection Contexts for different Connection Groups to explicitly control caching boundaries, as discussed in Section 4.2.3 ๐โจ
4.2. Transport Services Implementation ๐ฅ
okay so this section is the inside story ๐ It lays out the key architectural concepts for the Transport Services Implementation, which lives inside the Transport Services System โจ
The Transport Services System has two parts: the Transport Services Implementation and the Transport Services API ๐ The Implementation is basically every object and protocol instance a system or library uses internally to deliver a transport service across a network, as the abstract interface needs ๐ง
Path: a set of Properties a Local Endpoint can use to talk to a Remote Endpoint ๐ฃ๏ธ Think routes, addresses, and physical and virtual network interfaces ๐ธ
Protocol Instance: one single instance of one protocol, including any state it needs to set up connectivity or send and receive Messages ๐ฆ
Protocol Stack: a set of protocol instances (application, security, transport, or Internet protocols) that work together to set up connectivity or send and receive Messages ๐ A stack can be simple, like one application stream carried over TCP running over IP, or complex, like multiple application streams carried over a multipath transport protocol using multiple subflows over IP (e.g., ๐คฏ)
Candidate Path: one path that's available to an application and conforms to the Selection Properties and System Policy. There can be several of these. Candidate Paths get identified during the gathering phase (Section 4.2.1) and can be used during the racing phase (Section 4.2.2) โจ
Candidate Protocol Stack: one Protocol Stack an application can use for a connection, and again, there can be several candidates. These get identified during gathering (Section 4.2.1) and started during racing (Section 4.2.2) ๐
System Policy: the input from an operating system or other global preferences that can constrain or influence how an implementation gathers Candidate Paths and Candidate Protocol Stacks (Section 4.2.1) and races the candidates during establishment (Section 4.2.2) ๐ Some aspects apply to all Connections, and others only to certain ones, depending on the runtime context and the Properties of the Connection ๐ง
Cached State: the state and history an implementation keeps for each set of associated Endpoints that have been used before ๐๏ธ This can include DNS results, TLS session state, previous success and quality of transport protocols over certain paths, and other info. Caching doesn't mean the same decisions are necessarily made for later connections. It just means Cached State helps a Transport Services Implementation with things like choosing which candidates to race and selecting appropriate transport parameters, etc. An application SHOULD NOT rely on specific caching behavior ๐ Instead, it ought to explicitly request any required or preferred Properties through the Transport Services API ๐
4.2.1. Candidate Gathering ๐งบ
Candidate Path Selection: the act of choosing one or more paths that are available to use, based on the Selection Properties and any available Local and Remote Endpoint Identifiers the application provided, plus the policies and heuristics of a Transport Services Implementation ๐บ๏ธ
Candidate Protocol Selection: the act of choosing one or more sets of Protocol Stacks that are available to use, based on the Transport Properties the application provided, and the heuristics or policies within the Transport Services Implementation ๐งฉ
4.2.2. Candidate Racing ๐๏ธ
Connection establishment attempts for a set of candidates may be performed simultaneously, synchronously, serially, or using some combo of all of these. We call this racing, borrowing the terminology from Happy Eyeballs [RFC8305] ๐
Protocol Option Racing: the act of attempting to establish, or scheduling attempts to establish, multiple Protocol Stacks that differ based on the composition of protocols or the options used for protocols ๐ฏ
Path Racing: the act of attempting to establish, or scheduling attempts to establish, multiple Protocol Stacks that differ based on a selection from the available paths. Since different paths have distinct configurations (see [RFC7556]) for local addresses and DNS servers, attempts across different paths perform separate DNS resolution steps, which can lead to further racing of the resolved Remote Endpoint Identifiers ๐ค๏ธ
Remote Endpoint Racing: the act of attempting to establish, or scheduling attempts to establish, multiple Protocol Stacks that differ based on the specific representation of the Remote Endpoint Identifier, like a particular IP address that was resolved from a DNS hostname ๐
4.2.3. Separating Connection Contexts ๐ซง
A Transport Services Implementation can, by default, share stored Properties across Connections within an application, like cached protocol state, cached path state, and heuristics. This gives efficiency and convenience to the application, since the Transport Services System can automatically optimize behavior โจ
The Transport Services API can let applications explicitly define Connection Contexts that force separation of Cached State and Protocol Stacks. For example, a web browser application could use Connection Contexts with separate caches when implementing different tabs ๐ Possible reasons to isolate Connections using separate Connection Contexts include privacy concerns about:
- reusing cached protocol state, since this can lead to linkability. Sensitive state could include TLS session state [RFC8446] and HTTP cookies [RFC6265]. These concerns could be addressed using Connection Contexts with separate caches, such as for different browser tabs ๐ช
- allowing Connections to multiplex together, which can tell a Remote Endpoint that all of the Connections are coming from the same application. Using Connection Contexts avoids the Connections being multiplexed in an HTTP/2 or QUIC stream ๐ โโ๏ธ
5. IANA Considerations ๐
This document has no IANA actions. Nothing to see here for IANA, bestie ๐ โโ๏ธ
6. Security and Privacy Considerations ๐
Okay, this part is seriously important, so listen up ๐จ The Transport Services System doesn't recommend any specific security protocols or algorithms. Its whole goal is ease of use for existing protocols, by giving a generic security-related interface. Each interface it provides translates to an existing protocol-specific interface from the supported security protocols. For example, trust verification callbacks are common parts of TLS APIs, and a Transport Services API exposes similar functionality [RFC8922] ๐ง
As described above in Section 3.3, if a Transport Services Implementation races between two different Protocol Stacks, both need to use the same security protocols and options. However, a Transport Services Implementation can race different security protocols, e.g., if the application explicitly specifies that it considers them equivalent ๐
The application controls whether information from previous racing attempts, or other information about past communications that was cached by the Transport Services System, is used during establishment. This lets applications make trade-offs between efficiency (through racing) and privacy (via information that might leak from the cache toward an on-path observer). Some apps have features (e.g., "incognito mode") that line up with this functionality ๐ถ๏ธ
Applications need to make sure they use security APIs appropriately ๐ When applications use an interface to provide sensitive keying material, e.g., access to private keys or copies of pre-shared keys (PSKs), key use needs to be validated and scoped to the intended protocols and roles. For example, if an application provides a certificate that's only to be used as client authentication for outbound TLS and QUIC connections, the Transport Services System MUST NOT use this automatically in other contexts (such as server authentication for inbound connections, or in other security protocol handshakes that aren't equivalent to TLS) ๐ซ
A Transport Services System MUST NOT automatically fall back from secure protocols to insecure protocols, or fall back to weaker versions of secure protocols (see Section 3.3). For example, if an application requests a specific version of TLS but the desired version isn't available, its connection will fail ๐ญ As described in Section 3.3, the Transport Services API can let applications specify minimum versions that are allowed to be used by the Transport Services System ๐
7. References ๐
7.1. Normative References ๐ซถ
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
7.2. Informative References ๐โจ
Okay bestie, here's the reading list for the extra-credit corner ๐ค๐. These aren't required to build the thing, but they're where all the good background lives.
[POSIX] "IEEE/Open Group Standard for Information Technology - Portable Operating System Interface (POSIX(TM)) Base Specifications, Issue 8", IEEE Std 1003.1-2024, DOI 10.1109/IEEESTD.2024.10555529, 2024, <https://ieeexplore.ieee.org/document/10555529>.
[RFC5482] Eggert, L. and F. Gont, "TCP User Timeout Option", RFC 5482, DOI 10.17487/RFC5482, March 2009, <https://www.rfc-editor.org/info/rfc5482>.
[RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, DOI 10.17487/RFC6265, April 2011, <https://www.rfc-editor.org/info/rfc6265>.
[RFC7556] Anipko, D., Ed., "Multiple Provisioning Domain Architecture", RFC 7556, DOI 10.17487/RFC7556, June 2015, <https://www.rfc-editor.org/info/rfc7556>.
[RFC8095] Fairhurst, G., Ed., Trammell, B., Ed., and M. Kuehlewind, Ed., "Services Provided by IETF Transport Protocols and Congestion Control Mechanisms", RFC 8095, DOI 10.17487/RFC8095, March 2017, <https://www.rfc-editor.org/info/rfc8095>.
[RFC8170] Thaler, D., Ed., "Planning for Protocol Adoption and Subsequent Transitions", RFC 8170, DOI 10.17487/RFC8170, May 2017, <https://www.rfc-editor.org/info/rfc8170>.
[RFC8303] Welzl, M., Tuexen, M., and N. Khademi, "On the Usage of Transport Features Provided by IETF Transport Protocols", RFC 8303, DOI 10.17487/RFC8303, February 2018, <https://www.rfc-editor.org/info/rfc8303>.
[RFC8305] Schinazi, D. and T. Pauly, "Happy Eyeballs Version 2: Better Connectivity Using Concurrency", RFC 8305, DOI 10.17487/RFC8305, December 2017, <https://www.rfc-editor.org/info/rfc8305>.
[RFC8445] Keranen, A., Holmberg, C., and J. Rosenberg, "Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal", RFC 8445, DOI 10.17487/RFC8445, July 2018, <https://www.rfc-editor.org/info/rfc8445>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.
[RFC8489] Petit-Huguenin, M., Salgueiro, G., Rosenberg, J., Wing, D., Mahy, R., and P. Matthews, "Session Traversal Utilities for NAT (STUN)", RFC 8489, DOI 10.17487/RFC8489, February 2020, <https://www.rfc-editor.org/info/rfc8489>.
[RFC8922] Enghardt, T., Pauly, T., Perkins, C., Rose, K., and C. Wood, "A Survey of the Interaction between Security Protocols and Transport Services", RFC 8922, DOI 10.17487/RFC8922, October 2020, <https://www.rfc-editor.org/info/rfc8922>.
[RFC8923] Welzl, M. and S. Gjessing, "A Minimal Set of Transport Services for End Systems", RFC 8923, DOI 10.17487/RFC8923, October 2020, <https://www.rfc-editor.org/info/rfc8923>.
[RFC9000] Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, DOI 10.17487/RFC9000, May 2021, <https://www.rfc-editor.org/info/rfc9000>.
[RFC9112] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP/1.1", STD 99, RFC 9112, DOI 10.17487/RFC9112, June 2022, <https://www.rfc-editor.org/info/rfc9112>.
[RFC9113] Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, DOI 10.17487/RFC9113, June 2022, <https://www.rfc-editor.org/info/rfc9113>.
[RFC9293] Eddy, W., Ed., "Transmission Control Protocol (TCP)", STD 7, RFC 9293, DOI 10.17487/RFC9293, August 2022, <https://www.rfc-editor.org/info/rfc9293>.
[RFC9622] Trammell, B., Ed., Welzl, M., Ed., Enghardt, R., Fairhurst, G., Kรผhlewind, M., Perkins, C. S., Tiesel, P.S., and T. Pauly, "An Abstract Application Programming Interface (API) for Transport Services", RFC 9622, DOI 10.17487/RFC9622, January 2025, <https://www.rfc-editor.org/info/rfc9622>.
[RFC9623] Brunstrom, A., Ed., Pauly, T., Ed., Enghardt, R., Tiesel, P.S., and M. Welzl, "Implementing Interfaces to Transport Services", RFC 9623, DOI 10.17487/RFC9623, January 2025, <https://www.rfc-editor.org/info/rfc9623>.
Acknowledgements ๐๐ซถ
Big thank-yous to everyone who made this happen ๐ฅฐ. This work got funding from the European Union's Horizon 2020 research and innovation programme under grant agreements No. 644334 (NEAT), No. 688421 (MAMI), and No. 815178 (5GENESIS) ๐ช๐บโจ.
It was also supported by:
- Leibniz Prize project funds from the DFG - German Research Foundation: Gottfried Wilhelm Leibniz-Preis 2011 (FKZ FE 570/4-1). ๐
- the UK Engineering and Physical Sciences Research Council under grant EP/R04144X/1. ๐ฌ๐ง
Huge thanks to Reese Enghardt, Max Franke, Mirja Kรผhlewind, Jonathan Lennox, and Michael Welzl for the discussions and feedback that helped shape the architecture of the system described here ๐ง ๐ . Special shout-out to Philipp S. Tiesel and Christopher A. Wood, who were both coauthors of this specification as it progressed through the Transport Services (TAPS) Working Group ๐. Thanks as well to Stuart Cheshire, Josh Graessley, David Schinazi, and Eric Kinnear for their implementation and design efforts, including Happy Eyeballs, which heavily influenced this work ๐โญ.
Authors' Addresses ๐ฆ
Here's where to find the people behind the pages ๐.
Tommy Pauly (editor)
Apple Inc.
One Apple Park Way
Cupertino, CA 95014
United States of America
Email: tpauly@apple.com
Brian Trammell (editor)
Google Switzerland GmbH
Gustav-Gull-Platz 1
CH-8004 Zurich
Switzerland
Email: ietf@trammell.ch
Anna Brunstrom
Karlstad University
Universitetsgatan 2
651 88 Karlstad
Sweden
Email: anna.brunstrom@kau.se
Godred Fairhurst
University of Aberdeen
Fraser Noble Building
Aberdeen, AB24 3UE
United Kingdom
Email: gorry@erg.abdn.ac.uk
URI: https://erg.abdn.ac.uk/
Colin S. Perkins
University of Glasgow
School of Computing Science
Glasgow G12 8QQ
United Kingdom
Email: csp@csperkins.org
That's the whole spec, bestie! ๐๐ You made it through all 8 parts ๐ญ๐
๐ฆ where this page comes from
- ietf: rfc9621 2025-01
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms