RFC 9868
Transport Options for UDP
Transport Options for UDP ๐
RFC 9868 โจ (October 2025)
- Authors: J. Touch (Independent Consultant) and C. Heard, Ed. (Unaffiliated) ๐
- Category: Standards Track ๐ฅ
- Stream: Internet Engineering Task Force (IETF) ๐ธ
- ISSN: 2070-1721
- Updates: RFC 768 (UDP) ๐ฆ
Abstract
okay so the big idea here is that transport protocols get extended with transport header options ๐ง this doc updates RFC 768 (UDP) by saying where UDP options live, what they look like, and what they mean. the spot is the surplus area after the end of the UDP user data but before the end of the IP datagram ๐
Status of This Memo
this is an Internet Standards Track document ๐ซถ
it's a product of the Internet Engineering Task Force (IETF) and it represents the consensus of the IETF community. it got public review and was approved for publication by the Internet Engineering Steering Group (IESG). if you want more on Internet Standards, check Section 2 of RFC 7841 ๐
for the current status, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc9868 ๐
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. please actually read those, bestie, because they describe your rights and restrictions for this doc ๐ also, Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Revised BSD License โ๏ธ
Table of Contents
1. Introduction
2. Conventions Used in This Document
3. Terminology
4. Background
5. UDP Option Intended Uses
6. UDP Option Design Principles
7. The UDP Option Area
8. The UDP Surplus Area Structure
9. The Option Checksum (OCS)
10. UDP Options
11. SAFE UDP Options
11.1. End of Options List (EOL)
11.2. No Operation (NOP)
11.3. Additional Payload Checksum (APC)
11.4. Fragmentation (FRAG)
11.5. Maximum Datagram Size (MDS)
11.6. Maximum Reassembled Datagram Size (MRDS)
11.7. Echo Request (REQ) and Echo Response (RES)
11.8. Timestamp (TIME)
11.9. Authentication (AUTH), RESERVED Only
11.10. Experimental (EXP)
12. UNSAFE Options
12.1. UNSAFE Compression (UCMP)
12.2. UNSAFE Encryption (UENC)
12.3. UNSAFE Experimental (UEXP)
13. Rules for Designing New Options
14. Option Inclusion and Processing
15. UDP API Extensions
16. UDP Options Are for Transport, Not Transit
17. UDP Options vs. UDP-Lite
18. Interactions with Legacy Devices
19. Options in a Stateless, Unreliable Transport Protocol
20. UDP Option State Caching
21. Updates to RFC 768
22. Interactions with Other RFCs
23. Multicast and Broadcast Considerations
24. Network Management Considerations
25. Security Considerations
25.1. General Considerations Regarding the Use of Options
25.2. Considerations Regarding On-Path Attacks
25.3. Considerations Regarding Option Processing
25.4. Considerations for Fragmentation
25.5. Considerations for Providing UDP Security
25.6. Considerations Regarding Middleboxes
26. IANA Considerations
27. References
27.1. Normative References
27.2. Informative References
Appendix A. Implementation Information
Acknowledgments
Authors' Addresses
1. Introduction โจ
transport protocols use options to level up their capabilities ๐ TCP [RFC9293], the Stream Control Transmission Protocol (SCTP) [RFC9260], and the Datagram Congestion Control Protocol (DCCP) [RFC4340] all have room for these options, but UDP [RFC0768] doesn't, and it's kind of the odd one out ๐ this document updates RFC 768 with an extension that gives UDP space for transport options. it covers their generic syntax and how they're used in UDP's stateless, unreliable message protocol ๐ฆ the details of what this does to RFC 768 are in Section 21. and this extension does not apply to UDP-Lite, which Section 17 explains more ๐ง
2. Conventions Used in This Document ๐
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 ๐ซถ so the caps are doing the heavy lifting, periodt ๐
also, the characters >> at the beginning of a paragraph mean that paragraph is making a statement with one of those key words ๐ it's there so reviewers can spot the important parts fast, which is honestly iconic of them ๐ธ
3. Terminology ๐
here's the vocab we're using ๐
- IP datagram [RFC0791] [RFC8200]: an IP packet made of the IP header (including any IPv4 options) and an IP payload area (including any IPv6 extension headers or other shim headers) ๐ฆ
- Must-support options: UDP Options that all implementations are required to support. their use in individual UDP packets is optional ๐
- SAFE Options: UDP Options that are designed to be safe to ignore for a receiver that doesn't understand them. they don't alter the UDP user data or signal a change in what its contents represent ๐ซง
- Socket pair: a pair of sockets defining a UDP exchange, made of a remote socket and a local socket, each one an IP address plus a UDP port number (most widely known from TCP [RFC0793], which has been obsoleted by [RFC9293]) ๐
- Surplus area: the area of an IP payload that follows a UDP packet. this area is used for UDP Options in this document โจ
- UDP packet: the more contemporary term used here to refer to a user datagram [RFC0768] ๐ฆ
- UDP fragment: one or more components of a UDP packet and its UDP Options that enable transmission over multiple IP payloads, larger than the maximum size of a single IP packet allows. each UDP fragment is itself transmitted as a UDP packet with its own options ๐งฉ
- (UDP) User data: the user data field of a UDP packet [RFC0768] ๐
- UDP Length: the length field of a UDP header [RFC0768] ๐
- UNSAFE Options: UDP Options that are not designed to be safely ignored by a receiver that doesn't understand them. they could alter the UDP user data or signal a change in what its contents represent, but there are restrictions on how they can be transmitted. those restrictions are noted in Sections 10 and 12 โ ๏ธ
- User: the upper layer application, protocol, or service that produces and consumes the content UDP transfers ๐งโ๐ป
- User datagram: a UDP packet made of a UDP header and UDP payload. as discussed here, the UDP payload doesn't have to reach the end of the IP datagram. this document redefines the original idea that a UDP datagram matches the user portion of a single IP datagram, because a UDP datagram can now span more than one IP datagram through UDP fragmentation ๐
4. Background ๐ธ
lots of protocols come with a default, invariant header and an area for header options that changes from packet to packet ๐ those options let a protocol get extended for particular environments, or in ways the original designers never saw coming ๐ง examples include TCP's Maximum Segment Size (MSS), Window Scale, Timestamp, and Authentication Options [RFC9293] [RFC5925] [RFC7323] ๐
header options show up in both stateful (connection-oriented, e.g., TCP [RFC9293], SCTP [RFC9260], and DCCP [RFC4340]) and stateless (connectionless, e.g., IPv4 [RFC0791] and IPv6 [RFC8200]) protocols ๐ in stateful protocols, they can help extend how state gets managed. in stateless protocols, their effect is usually limited to individual packets, but they can add up to an aggregate effect across a sequence of packets too ๐ฆ
UDP is one of the most popular protocols that has no space for header options [RFC0768] ๐ญ its header was meant to be a minimal addition to IP, giving only port numbers and a checksum for error detection ๐ this document extends UDP with a trailer area for those options, sitting after the UDP user data ๐ซถ
UDP Options are possible because UDP has its own length field, separate from the IP header's. other transport protocols infer their transport payload length from the IP datagram length (TCP, DCCP, and SCTP) ๐ historians have floated a few reasons why UDP has this field, like supporting multiple UDP packets within the same IP datagram, or marking the length of the UDP user data apart from zero padding that some systems needed because they couldn't write an arbitrary number of bytes ๐ค those ideas don't line up with earlier versions of UDP or with the concurrent design of multi-segment, multiplexing protocols, though, so the real reason is still unknown ๐ either way, this field gives us a chance to tell the UDP user data apart from the implied transport payload length, and this document uses that to support a trailer options field ๐
there are other ways to add header fields or options to protocols that otherwise can't be extended. in particular, in-band encoding can tell transport payload apart from extra fields, like what was proposed in [Hi15] ๐งฉ that approach can cause complications with legacy devices, so this document doesn't consider it further ๐ซ
IPv6 Teredo extensions [RFC4380] [RFC6081] use a similar mismatch between UDP and IPv6 packet lengths to support trailers โจ but here the values differ between the UDP header and an IPv6 length carried as the payload of the UDP user data. that allows IPv6 trailers in the UDP user data, and it has nothing to do with the surplus area this document talks about ๐ฆ so, as a result, Teredo extensions are compatible with UDP Options ๐
5. UDP Option Intended Uses โจ
UDP Options give UDP a soft control plane ๐ง Bestie, that's the whole vibe. They bring back capabilities that other transport protocols already have, like fragmentation and reassembly. That means UDP frames bigger than the IP MTU can get through devices that look at transport ports, such as Network Address Translations (NATs), with no extra mechanisms or state needed ๐ It's giving efficiency.
They also add features that could someday protect transport integrity and validate source identity (authentication). Some could even encrypt the user payload while the UDP transport header stays protected, which is not something Datagram Transport Layer Security (DTLS) [RFC9147] does ๐ Then there's PLPMTUD over UDP, known as Datagram Packetization Layer Path Maximum Transmission Unit Discovery (DPLPMTUD) [RFC9869]. It gives a way to validate probe packets without touching the user data plane, and it provides an explicit indication of the receiver transport reassembly size. Iconic. ๐ญ
UDP originally assumed that the user or a layer above UDP [RFC0768] would provide these capabilities. But enough protocols now use UDP directly that an intermediate layer would be hard to deploy for legacy applications ๐ So UDP Options use that surplus area to enable these extensions inside the UDP transport layer itself โจ One use case that could benefit is request-response protocols, like DNS over UDP [He24] ๐ซถ
6. UDP Option Design Principles ๐ธ
UDP Options are built on the following core principles. Each one is either an observation about how UDP [RFC0768] already behaves without these extensions, which this document does not intend to change, or a lesson learned from other protocol designs. Main character energy, honestly ๐
- UDP is stateless; UDP Options do not change that fact.
The state required or maintained by the endpoints is intended to be managed either by the application or by a layer or library acting on the application's behalf. Reassembly of fragments is the only limited exception where this document introduces a notion of state to UDP. ๐ง
- UDP is unidirectional; UDP Options do not change that fact.
Responses to options are initiated by the application or by a layer or library acting on the application's behalf. A mechanism that requires bidirectionality needs to be defined in a separate document ๐ฆ
- UDP Options have no length limit separate from that of the UDP packet itself.
Past experience with other protocols confirms that static length limits will always need to be exceeded. TCP options and IPv4 addresses are a good example of that ๐ญ Each implementation can limit how long or how many options there are, but a specification is more robust when it does not introduce such a limit. โจ
- UDP Options are not intended to replace or replicate other protocols.
This includes NTP, ICMP (notably echo), and so on. UDP Options are meant to introduce features that are useful for applications. They are not meant to replace these other protocols, and they are not meant to instrument UDP so that it replaces the need for network testing devices ๐
- UDP Options are a framework, not a protocol.
Options can be defined in this initial document even when the details are not enough to specify a complete protocol. Uses of those options can then be described or supplemented in other documents. Examples here include REQ/RES and TIME. In both cases the option format is defined. The protocol that uses REQ/RES is specified elsewhere (for DPLPMTUD [RFC9869]), while the protocol that uses TIME is left undefined ๐ง
- The UDP Option mechanism and UDP Options themselves are intended to default to the same behavior experienced by a legacy receiver.
By default, even when option checksums (OCS, APC), authentication, or decryption fail, all received packets are passed to the user application, possibly with an empty data payload. The exception is UDP fragments, which are not passed. Options that do not modify user data are intended to result in the user data also being passed by default, even if option checksums or authentication fail, for example. It is always the user's or application's obligation to override this default behavior explicitly ๐ฅ
These principles are meant to enable the design and use of UDP Options with minimal impact on legacy UDP endpoints, ideally none at all. UDP is, and remains, a minimal transport protocol. Any extra capability is explicitly activated by user applications or by libraries acting on their behalf ๐
Last thing, and this one is important ๐ UDP Options do not try to match the number of zero-length UDP datagrams that legacy and option-aware receivers get from a source using UDP fragmentation (see Section 11.4). Legacy receivers interpret every UDP fragment as a zero-length packet, because they do not perform reassembly. Option-aware receivers, however, would reassemble the packet as a non-zero-length packet. Zero-length UDP packets have been used as "liveness" indicators (see Section 5 of [RFC8085]), but that use is dangerous because they lack unique identifiers. The IPv6 base header has none, and the IPv4 ID field is deprecated for such use [RFC6864]. Not it ๐ โโ๏ธ
7. The UDP Option Area ๐
The UDP transport header includes demultiplexing and service identification (port numbers), an error detection checksum, and a field that indicates the UDP datagram length, including the UDP header. The UDP Length field is typically redundant with the size of the maximum space available as a transport protocol payload, which is determined by the IP header (see details in Section 18). The UDP Option area is created when the UDP Length indicates a smaller transport payload than the IP header implies ๐ฆ
For IPv4, the IP Total Length field indicates the total IP datagram length, including the IP header. The size of the IP options is indicated in the IP header, in 4-byte words, as the "Internet Header Length" (IHL) [RFC0791], as shown in Figure 1. In exceptional cases the Protocol field in IPv4 might not indicate UDP (that is, 17). This can happen when intervening shim headers are present, such as IP Security (IPsec) [RFC4301] or IP Payload Compression (IPComp) [RFC3173] ๐
The upper bound for UDP Length when Protocol = 17 is given by:
UDP_Length <= IPv4_Total_Length - IPv4_IHL * 4
If shim headers are present, this upper bound must be reduced by the sum of the lengths of the shim headers that precede the UDP header.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL | DSCP |ECN| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Proto=17 (UDP)| Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... zero or more IP options (using space as indicated by IHL) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... zero or more shim headers (each indicating size) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UDP Source Port | UDP Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UDP Length | UDP Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 1: IPv4 Datagram with UDP Header
For IPv6, the IP Payload Length field indicates the transport payload after the base IPv6 header. That payload includes the IPv6 extension headers and the space available for the transport protocol, as shown in Figure 2 [RFC8200]. The Next Header field in IPv6 might not indicate UDP (that is, 17), for example when intervening IP extension headers are present. For IPv6, the lengths of any additional IP extensions are indicated within each extension [RFC8200], so the upper bound for UDP Length is given by:
UDP_Length <= IPv6_Payload_Length - sum(extension header lengths)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class | Flow Label |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Next Header | Hop Limit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...
| Source Address (128 bits) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
...
| Destination Address (128 bits) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... zero or more IP Extension headers (each indicating size) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UDP Source Port | UDP Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| UDP Length | UDP Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Figure 2: IPv6 Datagram with UDP Header
In both cases, IP indicates the space available for the UDP packet, either directly in the base header or by adding information in the shim headers or extensions. Either way, this document refers to that available space as the "IP transport payload" ๐ง
Because of this redundancy, the UDP Length field can be used to split the IP transport payload into two areas. One is the UDP user data. The other is an additional "surplus area" (as shown in Figure 3) ๐
IP transport payload
<------------------------------------------------->
+--------+---------+----------------------+------------------+
| IP Hdr | UDP Hdr | UDP user data | surplus area |
+--------+---------+----------------------+------------------+
<------------------------------>
UDP Length
Figure 3: IP Transport Payload vs. UDP Length
In most cases, the IP transport payload and UDP Length point to the same location, which means there is no surplus area. That is not a requirement of UDP [RFC0768], and Section 18 has more on it. This document uses the surplus area for UDP Options ๐ซถ
The surplus area can start at any valid byte offset. It does not need to be 16-bit or 32-bit aligned. In effect, this document redefines the UDP Length field as a "trailer options offset" ๐
8. The UDP Surplus Area Structure ๐
Okay so UDP Options take over the entire surplus area ๐ฆ, which is everything in the IP payload after the last byte of the UDP payload ๐ . They kick off with a 2-byte Option Checksum (OCS) field, lined up on the first 2-byte boundary of that area (counting from the start of the IP datagram). You add zeroes right before the OCS if you need padding to get there โจ. The UDP Option area works with any UDP payload length, even zero (so a UDP Length of 8 is totally valid, bestie ๐), as long as there's room for the aligned OCS plus whatever options you're using ๐.
Here's the tea: UDP Options MAY begin at any UDP Length offset ๐ธ.
Any option area bytes used for alignment before the OCS MUST be zero ๐ง. If that's not the case, all options MUST be ignored and the surplus area silently discarded ๐.
Those alignment bytes, plus the OCS computed over the rest of the surplus area, make sure the one's complement sum of the whole surplus area comes out to zero ๐ฅ. The OCS sits on a half-word (2-byte) boundary so implementers don't have to byte-swap it in their code ๐.
The OCS holds an optional one's complement sum that catches errors in the surplus area. The UDP checksum doesn't cover that area, so this is the extra safety net, as detailed in Section 9 ๐.
The rest of the surplus area is made of options. All of them except two use TLV (type, length, and optional value) syntax, kinda like TCP [RFC9293], as detailed in Section 10. The No Operation (NOP) and End of Options List (EOL) types are the two exceptions, since they have an implicit length of one byte ๐. The options keep going until the end of the surplus area, or you can stop early with an EOL Option followed by zeroes (more on that in Section 10) โญ.
9. The Option Checksum (OCS) ๐
The Option Checksum (OCS) Option is a conventional Internet checksum [RFC0791] that detects errors in the surplus area ๐. It holds a 16-bit checksum that's lined up on the first 2-byte boundary, with zero padding in front if it's needed. Check out Figure 4 ๐
+--------+--------+--------+--------+
| UDP data | 0 |
+--------+--------+--------+--------+
| OCS | UDP Options... |
+--------+--------+--------+--------+
Figure 4: UDP OCS Format, Here Using One Zero Byte for Alignment
The OCS is a 16-bit Internet checksum [RFC1071], computed over the surplus area and including the length of the surplus area as an unsigned 16-bit value. It protects the surplus area from errors in pretty much the same way the UDP checksum protects the UDP user data (when that checksum isn't zero) ๐ซถ.
The main job of the OCS is to catch existing nonstandard (aka non-option) uses of that area, plus accidental errors ๐ญ. It is not intended to detect attacks, as discussed further in Section 25 ๐. OCS isn't meant to stop future nonstandard uses of the surplus area, and it doesn't allow sharing that area with mechanisms that don't comply with UDP Options ๐ .
This design lets packets get through errant middleboxes that wrongly compute the UDP checksum over the entire IP payload [Fa18] [Zu20], instead of only the UDP header and UDP payload (based on the UDP header length) ๐ฆ. Because the OCS is computed over the surplus area and its length, and then inverted, it cancels out the effect the surplus has on the UDP checksum when it's wrongly included. So when the OCS is non-zero, the UDP checksum comes out the same either way โจ.
The OCS MUST be non-zero when the UDP checksum is non-zero ๐ฅ.
When the UDP checksum is zero, the OCS MAY be unused, and it's then indicated by a zero OCS value ๐ธ.
UDP Option implementations MUST default to using the OCS (i.e., as a non-zero value). Users who override that default take the risk of not detecting nonstandard uses of the option area, of which there are none currently known ๐.
Like the UDP checksum, the OCS is optional in certain situations, and it holds zero when it's not used ๐. UDP checksums can be zero for IPv4 [RFC0791] and for IPv6 [RFC8200] when the UDP payload is already covered by another checksum, as might happen with tunnels [RFC6935]. The same exceptions apply to the OCS when it's used to detect bit errors. There's an extra exception for its use in the UDP datagram prior to fragmentation or after reassembly (see Section 11.4) ๐ง.
The benefits are similar to letting UDP checksums be zero, but the risks are different ๐. The OCS is extra important for making sure packets with UDP Options can traverse errant middleboxes [Zu20]. When computing an OCS costs basically nothing, it's better to use the OCS to ensure that traversal โญ. In cases where those traversal risks can safely be ignored, like in controlled environments, over paths where traversal has been validated, or where upper layer protocols (applications, libraries, etc.) can adapt by enabling the OCS when packet exchange fails, the OCS can be disabled. The same goes for when bit errors at the UDP layer would be detected by other layers (as with the UDP checksum). You might disable it to conserve energy or processing resources, or when performance can be improved ๐. This is why zeroing the OCS is only safe when the UDP checksum is also zero, and why the OCS might still be used in that case ๐ .
The OCS covers the surplus area as formatted for transmission, and it's processed immediately upon reception ๐.
If the receiver's validation of the OCS fails, all options MUST be ignored and the surplus area silently discarded ๐.
UDP user data that's validated by a correct UDP checksum MUST by default be delivered to the application layer, even if the OCS fails, unless the endpoints have negotiated otherwise for this UDP packet's socket pair ๐ซถ.
When it's not used (i.e., it contains zero), the OCS is assumed to be "correct" for the purpose of accepting UDP datagrams at a receiver (see Section 14) โจ.
10. UDP Options ๐
okay bestie, so every UDP Option is at least two bytes long ๐ซถ the only exceptions are the one-byte ones, No Operation (NOP) and End of Options List (EOL), which I'll explain below ๐
+--------+--------+------------~~------------+
| Kind | Length | (remainder of option...) |
+--------+--------+------------~~------------+
Figure 5: UDP Option Default Format
The Kind field is always one byte, and it's named after the matching TCP field. Other protocols just call it "Type" ๐ฆ The Length field counts the whole option in bytes, including the Kind and Length bytes themselves. For any length below 255, it's just one byte. If the length is exactly 255, that's the signal to switch to the extended format in Figure 6 โจ In that case, the Extended Length field is 16 bits, sent in network standard byte order. Whichever field applies, that's the one the option's length is measured by ๐
+--------+--------+--------+--------+
| Kind | 255 | Extended Length |
+--------+--------+--------+--------+
| (remainder of option...) |
+--------+--------+--------+--------+
Figure 6: UDP Option Extended Format
The UDP Length MUST be at least as big as the UDP header (8) and no bigger than the IP transport payload. If a datagram's length falls outside that range, it MUST be silently dropped as invalid, and it MUST be logged ๐
All logging SHOULD be rate limited ๐ if there's a flood of log events, you can bundle them up and report a count, or quietly drop them if you need to protect your resources ๐
If an option's Length (or Extended Length, where that applies) is smaller than the minimum for its Kind, that's an error, and it MUST be treated that way. Those errors make the rest of the surplus area sus ๐ so all UDP Options MUST be silently discarded as a result ๐ญ
Any UDP Option other than NOP or EOL whose length is 254 or less MUST use the default format from Figure 5. NOP and EOL never use either length format, so they're the odd ones out ๐ง
Any UDP Option whose length is larger than 254 MUST use the extended format from Figure 6 ๐
For compactness, UDP Options SHOULD use the smallest format they can ๐
UDP Options MUST be interpreted in the order they show up in the surplus area. If they're part of UDP fragments, the order is the one they appear in within the UDP fragment option area instead (see Section 11.4) ๐ฅ
These are the UDP Options that are currently defined, so check the table, bestie โจ
+=========+==========+==========================================+
| Kind | Length | Meaning |
+=========+==========+==========================================+
| 0* | - | End of Options List (EOL) |
+---------+----------+------------------------------------------+
| 1* | - | No Operation (NOP) |
+---------+----------+------------------------------------------+
| 2* | 6 | Additional Payload Checksum (APC) |
+---------+----------+------------------------------------------+
| 3* | 10/12 | Fragmentation (FRAG) |
+---------+----------+------------------------------------------+
| 4* | 4 | Maximum Datagram Size (MDS) |
+---------+----------+------------------------------------------+
| 5* | 5 | Maximum Reassembled Datagram Size (MRDS) |
+---------+----------+------------------------------------------+
| 6* | 6 | Request (REQ) |
+---------+----------+------------------------------------------+
| 7* | 6 | Response (RES) |
+---------+----------+------------------------------------------+
| 8 | 10 | Timestamp (TIME) |
+---------+----------+------------------------------------------+
| 9 | (varies) | RESERVED for Authentication (AUTH) |
+---------+----------+------------------------------------------+
| 10-126 | (varies) | Unassigned (assignable by IANA) |
+---------+----------+------------------------------------------+
| 127 | (varies) | RFC3692-style experiments (EXP) |
+---------+----------+------------------------------------------+
| 128-191 | | Reserved |
+---------+----------+------------------------------------------+
| 192 | (varies) | Reserved for UNSAFE Compression (UCMP) |
+---------+----------+------------------------------------------+
| 193 | (varies) | Reserved for UNSAFE Encryption (UENC) |
+---------+----------+------------------------------------------+
| 194-253 | | Unassigned-UNSAFE (assignable by IANA) |
+---------+----------+------------------------------------------+
| 254 | (varies) | RFC3692-style UNSAFE experiments (UEXP) |
+---------+----------+------------------------------------------+
| 255 | | Reserved-UNSAFE |
+---------+----------+------------------------------------------+
Table 1
Kinds 0 through 191 are called SAFE Options, because they don't get in the way of legacy endpoints using the UDP user data, even when an option isn't supported ๐ฆ Kinds 192 through 255 are UNSAFE Options, because they could mess with legacy receiving endpoints, like an option that changes the UDP data payload ๐ฌ
UNSAFE Option nicknames are supposed to start with a capital "U", so SAFE Option nicknames have to avoid that letter (see Section 26) ๐ RESERVED and RESERVED-UNSAFE aren't assignable by IANA, and they aren't defined yet either ๐ AUTH, UCMP, and UENC are held for future options covering authentication, compression, and encryption, and they stay reserved until they're assigned to those jobs โจ
Okay, so FRAG technically changes the original UDP payload, which makes it UNSAFE in theory ๐ but it only ever shows up on later fragments that carry zero-length UDP user data, so in actual use it's SAFE. More on that in Section 11.4 ๐
These options get their own subsections below. Options 0 and 1 use the same values as they do for TCP ๐ธ
An endpoint that supports UDP Options MUST support every option marked with an "" above: EOL, NOP, APC, FRAG, MDS, MRDS, REQ, and RES. That means it has to be able to recognize them *and generate them when it's set up to do so. These are the "must-support" options ๐
The must-support set is fixed in this document. New options can't be added to it ๐
Every other SAFE Option (the ones without an "*") MAY be implemented. Whether they get used SHOULD be decided out-of-band or negotiated, especially if you need to figure out when a legacy receiver is silently ignoring them ๐ง
Receivers that support UDP Options MUST silently ignore unknown or malformed SAFE Options, the same way a legacy receiver would ignore every UDP Option ๐ซ An option counts as malformed when its length doesn't match one of the values in that option's spec. The FRAG Option is the exception to this, because a malformed FRAG Option SHALL be treated as an unsupported UNSAFE Option ๐ฅ
Options with an inherently invalid Length, meaning they either underrun themselves or overrun the surplus area by pointing past the end of the IP payload, MUST be treated as a sign that the surplus area is malformed. When that happens, all options MUST be silently discarded ๐
Receivers can't really treat unexpected Option Lengths as invalid in general, because that would box in future revisions of options. For example, someone might define a new APC with a different length ๐
When UNSAFE Options are present, the UDP user data MUST be empty, and any transport payload MUST be carried inside a FRAG Option (see Section 11.4) ๐ Remember, these options can change the transport payload or signal that its contents mean something different. Following this rule keeps them safe in environments that might have legacy receivers (see Section 12), since the transport payload sits inside the FRAG Option area and legacy receivers just throw it away ๐ซถ
Receivers that support UDP Options and get an unsupported option in the UNSAFE range MUST stop all option processing, and they MUST silently drop every UDP Option in that datagram. Section 12 has more on UNSAFE Options ๐
Apart from FRAG, NOP, EXP, and UEXP, each option SHOULD NOT show up more than once in a single UDP datagram ๐ โโ๏ธ If any option outside those four repeats, the receiver MUST only interpret the first instance and MUST ignore the later ones. Section 25 has extra advice on Denial of Service (DoS) issues that come from big numbers of options, whether they're valid, unknown, or repeated ๐ก๏ธ
NOP MAY appear multiple times, either back to back or in between other options, to keep things aligned ๐ธ Section 11.2 lists any extra repetition rules.
If FRAG shows up more than once, the options area MUST be treated as malformed and MUST NOT be processed ๐ซ
EXP and UEXP MAY appear more than once, but they SHOULD NOT repeat using the same Experimental ID (ExID) (see Sections 11.10 and 12.3) ๐งช
Options other than OCS, AUTH, and UENC MUST NOT include fields whose values depend on what's in the surplus area ๐ โโ๏ธ
AUTH and UENC are always computed as if their hash and the OCS are zero. The OCS is always computed as if its own contents are zero, and it's done after the AUTH or UENC hash has been computed ๐งฎ
Future options MUST NOT be defined so that an option field depends on the content or presence of other options, or on the rest of the surplus area (meaning the area after the last option, which is presumably EOL) ๐ซ
If future options depended on other options, the values, the OCS, and the AUTH and UENC Options could start interacting in unpredictable ways ๐ตโ๐ซ That doesn't rule out options that modify later options (in the order they appear in a packet), which is what compression (UCMP) would typically do ๐๏ธ
There's no need to save space after the last UDP Option for future use, since any future need can be handled by defining a new UDP Option over that area instead ๐งฉ Using an option for this is also safer than treating that region as an exception, because you can verify its use from the option's Kind and Length ๐
AUTH and UENC MUST NOT be used at the same time ๐ โโ๏ธ
They never go together anyway, because UENC would cover both jobs ๐
Must-support options other than NOP and EOL MUST be placed by the transmitter before any other SAFE UDP Options. If that ordering isn't honored, a receiver MAY drop all UDP Options. When that happens, the event MAY be logged for diagnostics ๐
The reason must-support options go first is so endpoints can add DoS protection, which Section 25 covers in more detail ๐ก๏ธ๐
11. SAFE UDP Options ๐
Okay bestie, SAFE UDP Options are the chill ones ๐ซถ Legacy receivers can silently ignore them without changing what the UDP user data means. They're the total opposite of UNSAFE Options, which change the user data in ways that make it unusable for legacy receivers (see Section 12) ๐ The subsections below cover the SAFE Options defined in this document โจ
11.1. End of Options List (EOL) ๐
The End of Options List (EOL, Kind=0) Option says "that's all, folks" ๐ฌ It marks the end of the options list, so you don't have to pad the rest of the option space with NOP Options (more on those in the next section) ๐ โโ๏ธ
Figure 7: UDP EOL Option Format
+--------+
| Kind=0 |
+--------+
Okay, rules time ๐ When the UDP Options don't eat up the whole surplus area or the options area of a UDP fragment, the last non-NOP Option MUST be EOL. No skipping this one ๐
NOPs SHOULD NOT be used as padding before the EOL Option. EOL is only one byte, so it doesn't need any other alignment ๐ง
All bytes after EOL in the surplus area or the options area of a UDP fragment MUST be set to zero when you send them ๐
Bytes after EOL in the surplus area or the options area of a UDP fragment MAY be checked to be zero when you receive them. But they MUST NOT be processed in any other way (the OCS calculation is the one exception, since zeros wouldn't change it anyway) and they MUST NOT be passed to the user ๐
If a receiver decides to check the bytes after EOL and finds that they aren't all zero, it MUST silently discard the options area. In that case the UDP user data MUST be delivered to the application layer, unless the socket was explicitly configured to do something different, either by the upper layer or by agreement with the other endpoint ๐ธ
Why all the zero drama? Requiring the post-option surplus area to be zero blocks side-channel sneakiness ๐ต๏ธโโ๏ธ It means any real use of the surplus area has to be UDP Options that both endpoints actually support. Zero padding is also handy for growing the UDP datagram length without changing the UDP user data length, for example during UDP DPLPMTUD (Section 4.4 of [RFC9869]) โจ
11.2. No Operation (NOP) ๐
The No Operation (NOP, Kind=1) Option is a one-byte placeholder ๐งธ It's meant for padding, like lining up multi-byte options on 16-bit, 32-bit, or 64-bit boundaries ๐
Figure 8: UDP NOP Option Format
+--------+
| Kind=1 |
+--------+
UDP packets SHOULD NOT use more than seven consecutive NOPs. That's enough to line things up to 8-byte boundaries, and anything more is overkill ๐ UDP packets also SHOULD NOT use NOPs at the end of the options area as a stand-in for EOL followed by zero-fill. NOPs are for alignment only, not for random padding or filler ๐
Receivers that keep seeing packets with more than seven consecutive NOPs SHOULD log those events, at least now and then, since it could be a potential DoS indicator ๐จ
NOPs are never reported to the user, whether they're used per-datagram or per-fragment (as defined in Section 11.4) ๐ซฅ
This issue gets more attention in Section 25 ๐
11.3. Additional Payload Checksum (APC) ๐
The Additional Payload Checksum (APC, Kind=2) Option is like a stronger backup for the checksum in the UDP header ๐ช It uses a 32-bit Cyclic Redundancy Check (CRC) that only covers the usual UDP user data payload. It skips the IP pseudoheader, the UDP header, and the surplus area. APC is not a replacement for the UDP checksum, because it doesn't cover the IP pseudoheader or the UDP header. It also isn't a supplement to the OCS, since the OCS only covers the surplus area. Its whole job is catching user data errors the UDP checksum might miss โจ
CRC32c was picked because it's everywhere already, including Internet Small Computer System Interface (iSCSI) [RFC3385] and SCTP ๐ The option carries the CRC32c in network standard byte order, the same way iSCSI does ๐ง
Figure 9: UDP APC Option Format
+--------+--------+--------+--------+
| Kind=2 | Len=6 | CRC32c... |
+--------+--------+--------+--------+
| CRC32c (cont.) |
+--------+--------+
When APC is present, it always holds a valid CRC checksum. There are no reserved values, and that includes zero. A CRC value of zero is a perfectly valid checksum ๐ So a zero does NOT mean "APC isn't being used." If you don't want APC, you just leave the option out entirely ๐ซถ
APC doesn't protect the UDP pseudoheader. Only the current UDP checksum does that (when it's in use) ๐ก๏ธ APC can't do this job because it would have to be recalculated every time the UDP pseudoheader changed, like during NAT address and port translation (see [RFC1141]) ๐
UDP packets with incorrect APC Option checksum fields SHOULD be passed to the application with an indication of an APC Option checksum failure. That's the default behavior for APC ๐
Like all SAFE UDP Options, APC MUST be silently ignored when it fails, unless the receiver has been explicitly configured to do otherwise ๐คซ
Okay so here's the reasoning ๐ง Every UDP Option aware endpoint supports APC, since it's in the required set. But silently ignoring it on failure means option-aware receivers act exactly like legacy receivers, unless someone overrides that. There's another reason too: the APC check can fail even when the user data is totally fine, like when a middlebox intentionally rewrites embedded port numbers or IP addresses. Those rewrites might be deliberate and not widely known. Defaulting to silent ignore means option-aware endpoints don't change how users or apps behave unless they're explicitly told to ๐ธ
UDP packets with unrecognized APC lengths MUST get the same treatment as UDP packets with incorrect APC Option checksum fields ๐
Treating unrecognized APC lengths as incorrect checksums means future versions of APC can be handled the same way, which is honestly iconic of them ๐
APC is reported to the user, and it's only useful per-datagram, since fragments don't have any UDP user data ๐ฆ
11.4. Fragmentation (FRAG) ๐งฉ
The Fragmentation (FRAG, Kind=3) Option handles UDP fragmentation and reassembly. That's how you send UDP messages bigger than the IP Effective MTU for Receiving (EMTU_R) allows [RFC1122] ๐ FRAG puts a copy of the same UDP transport ports in each fragment. That lets fragments get through stateless Network Address (and port) Translation (NAT) devices, which regular IP fragments can't do [RFC4787] ๐ฆ FRAG is usually paired with the UDP MDS and MRDS Options to make large messages more efficient at both the UDP and IP layers โจ The design is similar to the IPv6 Fragmentation Header [RFC8200], with one difference: the UDP version uses a 16-bit Offset measured in bytes, while IPv6 uses a 13-bit Fragment Offset measured in 8-byte units. This UDP variant also avoids creating reserved fields ๐งผ
FRAG also lets you use options that change the UDP payload, like encryption (UENC, see Section 12.2) ๐ Just like FRAG, those options wouldn't be safe on UDP payloads by themselves, since legacy receivers would misread them. FRAG allows them to be used either on fragments or on a whole, unfragmented message. That second case is an "atomic" fragment at the UDP layer, similar to atomic IP datagrams [RFC6864]. It's safe because FRAG hides the payload from legacy receivers by tucking it inside the surplus area ๐ซฃ
When FRAG is present, it SHOULD come as early as possible in the UDP Options list ๐ฅ
Putting FRAG first makes life easier for some implementations, especially hardware-accelerated ones that expect FRAG to sit in a fixed spot ๐๏ธ But sometimes FRAG just can't go first. For example, when it's combined with per-fragment UENC or UCMP. In those cases, encryption or compression (or both) comes before FRAG if they also encrypt or compress the fragment option itself. Recoding could be another case, like supporting Forward Error Correction (FEC) across a group of fragments. If FRAG isn't first, software ("slow path") option processing might happen, or a small set of known cases might be handled another way ๐ข
When FRAG is present, the UDP user data MUST be empty. If the user data isn't empty, all UDP Options MUST be silently ignored and the user data received MUST be sent to the user. Plot twist, but it's still a rule ๐ญ
Legacy receivers read FRAG messages as zero-length user data UDP packets (the UDP Length field is 8, which is just the UDP header). That doesn't bother the receiver unless the mere presence of the UDP packet is a signal (see Section 5 of [RFC8085]) ๐ So FRAG also helps hide UNSAFE Options, which makes them safer to use around legacy receivers ๐
The FRAG Option comes in two formats. Non-terminal fragments use the shorter one (Figure 10), and terminal fragments use the longer one (Figure 11). The longer format also covers stand-alone fragments, where data is inside the FRAG Option but no reassembly is needed โจ
Figure 10: UDP Non-Terminal FRAG Option Format
+--------+--------+--------+--------+
| Kind=3 | Len=10 | Frag. Start |
+--------+--------+--------+--------+
| Identification |
+--------+--------+--------+--------+
| Frag. Offset |
+--------+--------+
Most fields are shared by both FRAG formats. The option's Len field tells you whether more fragments are coming (Len=10) or whether this is the last one (Len=12) ๐
The Frag. Start field points to where the fragment data begins, measured from the start of this fragment's UDP header. The fragment data comes after the rest of the UDP Options and runs to the end of the IP datagram (which is the end of the surplus area) ๐ Any options before or after FRAG are applied to this UDP fragment ๐ง
The Frag. Offset field shows where this fragment sits relative to the original UDP datagram (before fragmentation or after reassembly). It's measured from the start of the original UDP datagram's header ๐
The Identification field is a 32-bit value. Together with the IP source address, UDP source port, IP destination address, and UDP destination port, it uniquely identifies the original UDP datagram ๐ชช
Figure 11: UDP Non-Terminal FRAG Option Format
+--------+--------+--------+--------+
| Kind=3 | Len=12 | Frag. Start |
+--------+--------+--------+--------+
| Identification |
+--------+--------+--------+--------+
| Frag. Offset |Reass DgOpt Start|
+--------+--------+--------+--------+
Okay bestie, the terminal FRAG Option ๐ gets a Reassembled Datagram Option Start (RDOS) pointer โจ. It's measured from the start of the original UDP datagram header, and it marks where the reassembled data ends and the surplus area begins. UDP Options that apply to the reassembled datagram live in that reassembled surplus area, and RDOS tells you where it starts. UDP Options sitting inside a fragment get processed on that fragment. So you can do pre-reassembly or post-reassembly stuff, like using UENC on every fragment while also using TIME on the reassembled datagram for round-trip latency measurements ๐ง.
Figure 12 shows how the fragments map onto the original datagram ๐ฆ. In this example the trailer with the per-datagram options sits entirely inside the terminal fragment, but that doesn't have to be true every time ๐ธ.
Constituent UDP Fragments Original UDP Datagram
+-------------+------------+
| Src Port | Dst Port |
+-------------+------------+
| UDP Len (8) | UDP Chksum |
+-------------+------------+
| OCS | K=3 L=10 | +-------------+------------+
+-------------+------------+ | Src Port | Dst Port |
,--| Frag. Start | Identifi- ~ +-------------+------------+
| +-------------+------------+ | UDP L.(RDOS)| UDP Chksum |
| ~ cation | Frag. Off. |----->+-------------+------------+
| +-------------+------------+ | Frag Data from 1st Frag. |
| ~ Per-Fragment Options ~ | . |
'->+-------------+------------+ ~ . ~
~ Fragment Data ~ | . |
+-------------+------------+ ,-->+-------------+------------+
| | Frag Data from 2nd Frag. |
+-------------+------------+ | | . |
| Src Port | Dst Port | | ~ . ~
+-------------+------------+ | | . |
| UDP Len (8) | UDP Chksum | | ,>+-------------+------------+
+-------------+------------+ | | | OCS | UDP Options|
| OCS | K=3 L=12 | | | +-------------+ +
+-------------+------------+ | | ~ . ~
,--| Frag. Start | Identifi- ~ | | +-------------+------------+
| +-------------+------------+ | |
| ~ cation | Frag. Off. |--' |
| +-------------+------------+ |
| | RDOS | Frag.Opts. | |
'->+--|----------+------------+ |
~ | Fragment Data ~ |
+--|----------+------------+ |
| |
'----------------------------'
Figure 12: UDP Fragments and Original UDP Datagram
The FRAG Option doesn't need a "more fragments" bit (the kind IP fragmentation uses) ๐ , because the longer 12-byte variant, shown in Figure 11, already tells the receiver the same thing.
The FRAG Option MAY be used on a single fragment ๐ซถ. In that case the Frag. Offset is zero and the option uses the 12-byte format.
Endpoints supporting UDP Options MUST be capable of fragmenting and reassembling at least two fragments, and each one has to fit within the standard Ethernet MTU of 1,500 bytes โจ. For more details, check out Section 11.6.
Using the single-fragment variant can be really helpful when you want UNSAFE Options without causing trouble for receivers that don't support UDP Options or those specific UNSAFE Options ๐.
During fragmentation, the UDP header checksum of each fragment stays constant ๐. It doesn't depend on the fragment data (which lives in the surplus area), because every fragment has a zero-length user data field.
The Identification field is a 32-bit value that MUST be unique over the expected fragment reassembly timeout ๐. It SHOULD be generated in a way that's similar to the IPv6 Fragment ID [RFC8200] ๐.
UDP fragments MUST NOT overlap ๐ซ.
Just like IPv6 reassembly [RFC8200], if any fragments being reassembled overlap with other fragments for the same UDP packet, the reassembly of that UDP packet MUST be abandoned. All the fragments received for that UDP packet MUST be discarded, and no ICMP error messages are to be sent in this case. This stops a potential DoS attack from turning into an ICMP storm in the reverse direction ๐.
Fragments can be duplicated in the network, so note that ๐. Instead of treating exact duplicate fragments as overlapping fragments, an implementation MAY choose to detect them and drop the exact duplicates while keeping the other fragments that belong to the same UDP packet.
UDP fragmentation relies on a fragment expiration timer. It can be preset, or it can use a value computed from the UDP Timestamp Option โฐ.
The default UDP reassembly expiration timeout SHOULD be no more than 2 minutes โณ.
UDP reassembly expiration MUST NOT generate an ICMP error. These events aren't IP errors, and the user/application layer can deal with them if it wants to ๐ซง.
UDP reassembly space SHOULD be limited, so DoS attacks have less impact on resource use ๐ก๏ธ.
UDP reassembly space limits SHOULD NOT be computed as a shared resource across multiple sockets, so that cross-socket pair DoS attacks are avoided ๐ง.
Individual UDP fragments MUST NOT be forwarded to the user ๐ โโ๏ธ. The reassembled datagram only gets delivered after complete reassembly, checksum validation, and continued processing of the remaining UDP Options.
Per-fragment UDP Options, if used alongside FRAG, occur before the fragment data ๐. They typically come after the FRAG Option, except when they modify the FRAG Option itself (for example, UENC or UCMP). Per-fragment options are processed before the fragment is added to the reassembled datagram. They're handy for protecting the reassembly process itself, like keeping the reassembly cache from getting polluted (using AUTH or UENC) ๐ก๏ธ.
Fragments of a single datagram MAY use different sets of options ๐. Checking that every fragment matches would be computationally expensive, and there could be legit reasons to put options on some fragments but not others (like MDS and MRDS).
If an option is used per-fragment but is defined as not usable per-fragment, it gets treated like any other unknown option ๐คทโโ๏ธ.
Per-datagram UDP Options, if used, live in the surplus area of the original UDP datagram. They get processed after reassembly is complete, which makes it safe to use UNSAFE Options. Those are required to get the entire UDP datagram discarded if the receiver doesn't know them or they otherwise fail (see Section 12) ๐.
In general, UDP packets get fragmented like this:
- Create a UDP packet with data and UDP Options. This is the original UDP datagram, which we'll call "D" ๐ฐ. The UDP Options follow the UDP user data and sit in the surplus area, just like in an unfragmented UDP datagram with UDP Options.
The UDP Options for the original packet MUST be fully prepared before you do the rest of the fragmentation steps below ๐ .
The UDP checksum of the original packet SHOULD be set to zero, because it's never transmitted. You still get equivalent protection if each fragment has a non-zero OCS value, which will be the case if each fragment's UDP checksum is non-zero. Similarly, the OCS value of the original packet SHOULD be zero if each fragment will have a non-zero OCS value, which again happens when each fragment's UDP checksum is non-zero โจ.
- Pick the desired fragment size, which we'll call "S" ๐. This value takes the path MTU into account (if it's known) and leaves room for per-fragment options.
- Split "D" into chunks no larger than "S"-12 each (10 for the non-terminal FRAG Option and 2 for OCS), with one final chunk no larger than "S"-14 (12 for the terminal FRAG Option and 2 for OCS). The per-datagram options from step 1 don't all need to sit in the terminal fragment, though. The RDOS pointer can mark the start of the original surplus area anywhere in the reassembled datagram ๐งฉ.
- For each chunk of "D" from step 3, create a UDP packet with no user data (UDP Length=8). Follow it with the word-aligned OCS, the FRAG Option, any extra per-fragment UDP Options, and then the FRAG data chunk ๐ฆ.
- Finish the processing that goes with creating those extra per-fragment UDP Options for each fragment ๐.
Receivers basically run that sequence in reverse ๐. They process all the options in each fragment. When they hit the FRAG Option, the FRAG data gets used in reassembly. Once every fragment has arrived, the whole UDP packet is processed, with any trailing UDP Options applying to the reassembled user data.
Reassembly failures at the receiver mean any per-fragment options and fragment contents get silently discarded ๐คซ. Those failures SHOULD NOT generate zero-length frames to the user.
Last but not least, fragmentation processing can get expensive ๐ธ, so the FRAG Option SHOULD be avoided unless the original datagram needs fragmentation or the FRAG Option is needed for "safe" use of UNSAFE Options.
The FRAG Option MAY also give limited support for UDP Options in systems that can only see the initial portion of the data in incoming or outgoing packets ๐, since those systems could potentially access per-fragment options. Of course, legacy receivers that don't support UDP Options will just silently ignore those packets ๐ซ .
The presence of the FRAG Option is not reported to the user ๐.
11.5. Maximum Datagram Size (MDS) ๐ฆ
okay so the Maximum Datagram Size (MDS, Kind=4) Option is a 16-bit hint about the biggest UDP packet or UDP fragment an endpoint thinks it can receive without IP fragmentation ๐. It helps UDP apps keep their packets small enough to avoid UDP fragmentation, and it helps UDP fragmentation pick the biggest fragment to send. Both are about dodging IP fragmentation ๐ .
It's giving the same energy as the TCP Maximum Segment Size (MSS) Option [RFC9293]. The number is the IP layer MTU minus only the fixed IP and UDP headers [RFC9293]. The sender has to adjust for the space that IP and UDP Options take up when it uses the value ๐ง. The number that gets sent is based on EMTU_R, the biggest IP datagram that can be received (aka reassembled at the receiver) [RFC1122]. BUT, just like TCP, it's only a hint of what the receiver thinks, especially when it's used with PLPMTUD at the UDP layer, which we'll get to later in this section ๐ซถ.
MDS does not indicate a known path MTU and thus MUST NOT be used to limit transmissions. ๐ญ not me reading that and still wanting to use it anyway ๐
+--------+--------+--------+--------+
| Kind=4 | Len=4 | MDS size |
+--------+--------+--------+--------+
Figure 13: UDP MDS Option Format
The UDP MDS Option MAY be used as a hint for path MTU discovery [RFC1191] [RFC8201], but this could be difficult because of known issues with ICMP blocking [RFC2923] and the fact that UDP doesn't have automatic retransmission. ๐ธ
MDS is more likely to be useful when it's paired with IP source fragmentation or UDP fragmentation to limit the largest reassembled UDP message, as indicated by MRDS (see Section 11.6). This is especially true when EMTU_R is larger than the required minimums (576 for IPv4 [RFC0791] and 1500 for IPv6 [RFC8200]) โจ.
MDS can be used with DPLPMTUD [RFC8899] to give a hint to the Packetization Layer Path MTU (PLPMTU) value, though it MUST NOT prohibit transmission of larger UDP packets used as DPLPMTUD probes. ๐ฆ
MDS is reported to the user, whether it's used per-datagram or per-fragment (as defined in Section 11.4). When it's used per-fragment, the reported value is the minimum of the MDS values received per-fragment ๐.
11.6. Maximum Reassembled Datagram Size (MRDS) ๐งฉ
The Maximum Reassembled Datagram Size (MRDS, Kind=5) Option is a 16-bit indicator of the largest reassembled UDP datagram that can be received, including the UDP header and any per-datagram UDP Options. It comes with an 8-bit indication of how many UDP fragments can be reassembled ๐. The MRDS size field is the UDP version of IP's EMTU_R, but the two aren't related [RFC1122]. With the FRAG Option (Section 11.4), UDP packets can be sent as transport fragments, each in its own (presumably not fragmented) IP datagram, and then reassembled at the UDP layer. MRDS segs is the number of UDP fragments that can be reassembled ๐.
+--------+--------+--------+--------+---------+
| Kind=5 | Len=5 | MRDS size |MRDS segs|
+--------+--------+--------+--------+---------+
Figure 14: UDP MRDS Option Format
Endpoints supporting UDP Options MUST support a local MRDS size of at least 2,926 bytes for IPv4 and 2,886 bytes for IPv6. Support for larger values is encouraged ๐.
Endpoints supporting UDP Options MUST support a local MRDS segs value of at least 2. Support for larger values is encouraged ๐ซถ.
These parameters, plus the Path MTU (PMTU), let a sender figure out the size of the largest pre-fragmentation UDP packet that a receiver will guarantee to accept ๐งฎ. MMS_S is defined as the PMTU minus the size of the IP header and the UDP header. In other words, it's the maximum UDP message size that can be successfully sent in a single UDP datagram if there are no IP options or extension headers and no UDP per-fragment options. With those size definitions in place, the size of the largest pre-fragmentation UDP packet that the receiver will guarantee to accept is the smaller of the MRDS size and the following:
(MMS_S - 12) * (MRDS segs) - 2 - (Total Per-Frag IP/UDP Options) + 8
In the expression above, Total Per-Frag IP/UDP Options includes the size of all IP options and extension headers, plus all per-fragment UDP Options (except for OCS and FRAG) that are in the sequence of UDP fragments ๐ง .
If no MRDS Option has been received, a sender MUST assume that MRDS size is 2,926 bytes for IPv4 and 2,886 bytes for IPv6, and that MRDS segs is 2. Those are the minimum values allowed ๐.
MRDS is reported to the user, whether it's used per-datagram or per-fragment (as defined in Section 11.4). When it's used per-fragment, the reported value is the minimum of the MRDS values received per-fragment ๐.
11.7. Echo Request (REQ) and Echo Response (RES) ๐
The echo Request (REQ, Kind=6) and echo Response (RES, Kind=7) Options give you UDP packet-level acknowledgments as a capability for upper layer protocols to use, like user applications, libraries, operating systems, and so on ๐ . Both REQ and RES are controlled by these upper layers. In other words, UDP Option support described in this document never automatically responds to a REQ with a RES. Instead, the REQ gets delivered to the upper layer, and that layer decides whether and when to send a RES ๐.
One such use is described as part of DPLPMTUD [RFC9869]. This use case is described as part of UDP Options, but it's logically considered a capability of an upper layer that uses UDP Options ๐ฆ. Both options have the format shown in Figure 15, where the token has no internal structure or meaning.
+--------+--------+-----------------+
| Kind | Len=6 | token |
+--------+--------+-----------------+
1 byte 1 byte 4 bytes
Figure 15: UDP REQ and RES Options Format
As advice for upper layer protocol and library designers: when you support REQ/RES and respond with a RES, the upper layer SHOULD respond with the most recently received REQ token. Think of it as the main character move ๐.
If the implementation includes a layer or library that produces and consumes REQ/RES on behalf of the user or application, then that layer MUST be disabled by default. In that case, REQ/RES are simply sent when the user or application asks for them, and passed up to it when received, just like most other UDP Options ๐.
For example, an application needs to explicitly enable the generation of a RES Option by DPLPMTUD when using UDP Options [RFC9869] ๐ฅ.
The token transmitted in a RES Option MUST be a token received in a REQ Option by the transmitter. This makes sure the response is to a request that was actually received ๐ซถ.
REQ and RES Option kinds each appear at most once in each UDP packet, just like most other options. A single packet can include both options, though they'd otherwise be unrelated to each other. Also, the FRAG Option is not used when sending DPLPMTUD probes to determine a PLPMTU [RFC9869] โจ.
REQ and RES are reported to the user, whether they're used per-datagram or per-fragment (as defined in Section 11.4). When they're used per-fragment, the reported value indicates the most recently received token ๐.
11.8. Timestamp (TIME) โฐ
Timestamps are provided as a capability for applications and other upper layer protocols to use ๐ธ. They're based on a notion of time as a monotonically non-decreasing unsigned integer, with wraparound. They're defined the same way as TCP Protection Against Wrapped Sequence (PAWS) numbers, meaning "without any connection to [real-world, classical physics wall-clock] time" [RFC7323]. They're pretty similar to relativistic time or the individual scalars of Lamport clocks [La78]. Still, if you want, they can correspond to real-world time, for example for round-trip time (RTT) estimation. This option makes no assertions about which is the case. The decision is up to the application layer using this option ๐ง.
The Timestamp (TIME, Kind=8) Option exchanges two four-byte unsigned timestamp fields. It serves a similar purpose to TCP's Timestamp (TS) Option [RFC7323], letting UDP estimate the RTT between hosts. For UDP, this RTT can be useful for setting UDP fragment reassembly timeouts or transport-layer rate limiting [RFC8085] ๐.
+--------+--------+------------------+------------------+
| Kind=8 | Len=10 | TSval | TSecr |
+--------+--------+------------------+------------------+
1 byte 1 byte 4 bytes 4 bytes
Figure 16: UDP TIME Option Format
TS Value (TSval) and TS Echo Reply (TSecr) are used in a similar way to the TCP TS Option [RFC7323]. On transmitted UDP packets that use the option, TSval is always set based on the local "time" value. Received TSval and TSecr field contents are passed to the application, which can pass the received TSval along to be used as TSecr in UDP messages sent back (in other words, to echo the received TSval). A received TSecr of zero means the TSval wasn't echoed by the transmitter, i.e., from a previously received UDP packet ๐.
TIME MAY use an RTT estimate based on non-zero Timestamp values as a hint for fragmentation reassembly, rate limiting, or other mechanisms that benefit from that kind of estimate ๐.
An application MAY use TIME to compute this RTT estimate for further use by the user ๐ .
UDP timestamps are modeled after TCP timestamps and have similar expectations. Specifically, they're supposed to follow these guidelines:
- Values are monotonic and non-decreasing, except for anticipated number-space rollover events.
- Values "increase" (allowing for rollover, i.e., modulo the field size except zero) according to a typical 'tick' time.
- A request is defined as TSval being non-zero, and a reply is defined as TSecr being non-zero.
- A receiver always responds to a request with the highest TSval received (allowing for rollover), which is not necessarily the most recently received.
Rollover can be handled as a special case, or more completely using sequence number extension [RFC9187]. Either way, zero values need to be avoided explicitly ๐ฆ.
TIME values MUST NOT use zeros as valid time values, because zeros are used as indicators of requests and responses. โ ๏ธ
TIME is reported to the user, whether it's used per-datagram or per-fragment (as defined in Section 11.4). When it's used per-fragment, the reported value is the minimum and maximum of each of the timestamp values received per-fragment ๐.
Use of TIME per-fragment is NOT RECOMMENDED. The exceptions are supporting diagnostics on the reassembly process itself, which could be more appropriate to handle within the UDP Option processing implementation ๐.
11.9. Authentication (AUTH), RESERVED Only ๐
Okay so the Authentication (AUTH, Kind=9) Option is basically reserved for all UDP authentication mechanisms [To24]. ๐ฆ AUTH is expected to cover the UDP user data and UDP Options, with possible extra coverage of the IP pseudoheader and UDP header, and potentially even support for NAT traversal. That NAT traversal would work by zeroing the remote socket (the source IP address and UDP port) before computing the check, kind of like how the TCP Authentication Option (TCP-AO) NAT traversal does it [RFC6978]. ๐ธ
Like APC, AUTH is a SAFE Option because it doesn't modify the UDP user data. ๐ Still, AUTH could fail even when the user data hasn't been corrupted, like when its contents have been overwritten. Those overwrites could be intentional and not widely known, so the default is silent ignore. That way option-aware endpoints don't change how users or applications operate unless they're explicitly told to. ๐
When a socket pair relies on AUTH (for example, after a security policy gets configured), this default is expected to be overridden. Incoming packets without AUTH, or with a failed AUTH check, would then be silently dropped, so only authenticated packets would reach the user. โจ This lets the AUTH security checks happen above UDP, in a separate shim layer or application library. ๐
A specification for using AUTH is expected to define how the AUTH security parameters get coordinated, and how the socket pair gets configured when those parameters are installed. ๐ That specification is expected to address the rules for when AUTH is required on transmission, and when the presence and correct validation of AUTH is required on reception. ๐ซถ
11.10. Experimental (EXP) ๐งช
The Experimental (EXP, Kind=127) Option is allocated for experiments [RFC3692]. Only one value is allocated, because experiments are expected to use an Experimental ID (ExID) to tell apart concurrent use for different purposes. Those UDP ExIDs get registered with IANA, following the approach developed for TCP experimental options [RFC6994]. ๐
+----------+----------+----------+----------+
| Kind=127 | Len | UDP ExID |
+----------+----------+----------+----------+
| (option contents, as defined)... |
+----------+----------+----------+----------+
Figure 17: UDP EXP Option Format
The length of the Experimental Option MUST be at least 4 to account for the Kind, Len, and 16-bit UDP ExID (similar to TCP ExIDs [RFC6994]). ๐
The UDP EXP Option uses only 16-bit ExIDs, unlike TCP ExIDs. ๐ In TCP, the first 16 bits of the ExID are unique, and the additional 16 bits, where present, are used to decrease the chance of the entire ExID occurring in legacy use of the TCP EXP Option. This extended variant gives UDP EXP no similar use, because ExIDs are required. ๐
The UDP EXP Option also has an Extended Length format, where the option Len is 255, followed by two bytes of Extended Length. ๐
+----------+----------+----------+----------+
| Kind=127 | 255 | Extended Length |
+----------+----------+----------+----------+
| UDP ExID |(option contents...) |
+----------+----------+----------+----------+
Figure 18: UDP EXP Extended Option Format
UDP Experimental IDs (ExIDs) are assigned from a combined TCP/UDP ExID registry managed by IANA (see Section 26). ๐๏ธ Assigned ExIDs can be used in either the EXP or UEXP Options (see Section 12.3 for the latter). ๐
12. UNSAFE Options โ ๏ธ
UNSAFE Options are not safe to ignore, and they can be used unidirectionally or without soft-state confirmation of UDP Option capability. ๐ฅ They are only ever used when the user data occurs inside a reassembled set of one or more UDP fragments. That way, if UDP fragmentation isn't supported, the enclosed UDP user data would be silently dropped anyway. ๐ซ
Applications using UNSAFE Options SHOULD NOT also use zero-length UDP packets as signals, because they will arrive when UNSAFE Options fail. Those that choose to allow such packets MUST account for such events. ๐
UNSAFE Options MUST be used only as part of UDP fragments, used either per-fragment or after reassembly. ๐งฉ
Receivers supporting UDP Options MUST silently drop the UDP user data of the reassembled datagram if any fragment or the entire datagram includes an UNSAFE Option whose Kind is not supported, or if an UNSAFE Option appears outside the context of a fragment or reassembled fragments. ๐ซ
12.1. UNSAFE Compression (UCMP) ๐๏ธ
The UNSAFE Compression (UCMP, Kind=192) Option is reserved for all UDP compression mechanisms. ๐ UCMP is expected to cover the UDP user data and some (e.g., later, in sequence) UDP Options. ๐ธ
12.2. UNSAFE Encryption (UENC) ๐
The UNSAFE Encryption (UENC, Kind=193) Option is reserved for all UDP encryption mechanisms. ๐ฆ UENC is expected to provide all of the services of the AUTH Option (Section 11.9), and in addition to encrypt the UDP user data and some (e.g., later or in sequence) UDP Options, in a similar manner as the TCP Authentication Option Extension for Payload Encryption (TCP-AO-ENC) [To18]. ๐
12.3. UNSAFE Experimental (UEXP) ๐งช
The UNSAFE Experimental (UEXP, Kind=254) Option is reserved for experiments [RFC3692]. Just like EXP, only one such UEXP value is reserved, because experiments are expected to use an Experimental ID (ExIDs) to tell apart concurrent use for different purposes. Those UDP ExIDs are registered with IANA, following the approach developed for TCP experimental options [RFC6994]. โจ
Assigned ExIDs can be used with either the UEXP or EXP Options. ๐
13. Rules for Designing New Options ๐
The UDP Option Kind space allows for the definition of new options. ๐ฑ However, the currently defined options (including AUTH, UENC, and UCMP) do not allow for arbitrary new options. Here's a summary of the rules for new options and their rationales, bestie. ๐ซถ
New options MUST NOT be defined as "must-implement", i.e., they are not eligible for the asterisk ("*") designation used in Section 10. ๐ซ
This document defines the minimum set of "must-implement" UDP Options. ๐ All new options are included at the discretion of a given implementation. ๐
New options MUST NOT modify the content of options that precede them (in order of appearance and thus processing). ๐ โโ๏ธ
The fields of new options MUST NOT depend on the content of other options. ๐ง
UNSAFE Options can both depend on and vary user data content, because they are contained only inside UDP fragments and thus are processed only by receivers capable of handling UDP Options. ๐ฅ
New options MUST NOT declare their order relative to other options, whether new or old, even as a preference. ๐ซ
At the sender, new options MUST NOT modify UDP packet content anywhere outside their option field, excepting only UNSAFE Options. Areas that need to remain unmodified include the IP header, IP options, UDP user data, and surplus area (i.e., other options). ๐ก๏ธ
Options MUST NOT be modified in transit. This includes those already defined as well as new options. ๐ง
New options MUST NOT require or allow that any UDP Options (including themselves) or the remaining surplus area be modified in transit. ๐
All options MUST indicate whether they can be used per-fragment and, if so, MUST also indicate how their success or failure is reported to the user. It is RECOMMENDED that new options be designed to support per-fragment use. It is also RECOMMENDED that options used per-fragment be reported to the user as a finite aggregate (e.g., a sum, a flag, etc.) rather than individually. ๐
With one exception, UNSAFE Options are used when UDP user data needs to be modified: ๐ฆ
The FRAG Option modifies UDP user data, splitting it across multiple IP packets. UNSAFE Options MAY modify the UDP user data, e.g., by encryption, compression, or other transformations. All other (SAFE) options MUST NOT modify the UDP user data. ๐
14. Option Inclusion and Processing โจ
okay bestie, this section is all about who gets to decide what ๐ senders pick which options get added, and receivers pick which ones they actually handle. it's giving teamwork ๐ซถ
Senders MAY add any option, as configured by the API.
All "must-support" options MUST be processed by receivers, if present (presuming UDP Options are supported at that receiver).
Options that are not "must-support" options MAY, if present, be ignored by receivers, based, e.g., on API settings.
All options MUST be processed by receivers in the order encountered in the options area.
Unless configuration settings direct otherwise, all options except UNSAFE Options MUST result in the UDP user data being passed to the upper layer protocol or application, regardless of whether all options are processed, are supported, or succeed.
The basic premise is that, for options-aware endpoints, the sender decides what options to add and the receiver decides what options to handle. ngl this is so fair ๐ฆ simply adding an option doesn't force any work onto a receiver, except for the "must-support" options.
Upon receipt, the receiver checks various properties of the UDP packet and its options to decide whether to accept or drop the UDP packet, and whether to accept or ignore some of its options. It goes in this order:
if the UDP checksum fails then
silently drop the entire UDP packet (per RFC 1122)
if the UDP checksum passes or is zero then
if (OCS != 0 and OCS fails) or
(OCS == 0 and UDP CS != 0) then
deliver the UDP user data but ignore other options
(this is required to emulate legacy behavior)
if (OCS != 0 and OCS passes) or
(OCS == 0 and UDP CS == 0) then
deliver the UDP user data after parsing
and processing the rest of the options,
regardless of whether each is supported or succeeds
(again, this is required to emulate legacy behavior)
The design of the UNSAFE Options makes sure the resulting UDP data gets silently dropped in both legacy receivers and options-aware receivers that don't recognize those options. Again, note that this still results in the delivery of a zero-length UDP packet ๐
Options-aware receivers can drop UDP packets with option processing errors, either through an override of the default UDP processing or at the application layer.
Put another way, every option gets treated the same way: the transmitter can add each option as desired, and the receiver has the choice to require a given option or not. Only if a receiver marks a particular option as mandatory (e.g., through API configuration) does it need to confirm that the option is present and correct.
Here's the summary for all options:
- if the option is not required by the receiver, then UDP packets missing the option are accepted.
- if the option is required (e.g., by override of the default behavior at the receiver) and missing or incorrectly formed, silently drop the UDP packet.
- if the UDP packet is accepted (either because the option is not required or because it was required and correct), then pass the option with the UDP packet via the API. Note that FRAG, NOP, and EOL are not passed to the user (see Section 15).
Any options whose length exceeds that of the UDP packet (i.e., intending to use data that would have been beyond the surplus area) SHOULD be silently ignored (again to model legacy behavior) ๐
15. UDP API Extensions
UDP currently specifies an Application Programming Interface (API), summarized as follows (with a Unix-style command as an example) [RFC0768]:
- Method to create new receive ports
- e.g.,
bind(handle, recvaddr(optional), recvport)
- e.g.,
- Receive, which returns data octets, source port, and source address
- e.g.,
recvfrom(handle, srcaddr, srcport, data)
- e.g.,
- Send, which specifies data, source and destination addresses, and source and destination ports
- e.g.,
sendto(handle, destaddr, destport, data)
- e.g.,
This API gets extended to support options, like so โจ
- Extend the method to create receive ports to include per-packet and per-fragment receive options that are required or omitted as indicated by the application.
Datagrams not containing these required options MUST be silently dropped and SHOULD be logged.
- Extend the method to create receive ports to have a means to indicate that all packets containing UDP Options that are received on a particular socket pair are to be discarded.
The default value for the setting to drop all packets containing UDP Options MUST be to process packets containing UDP Options normally (i.e., not to discard them).
- Extend the receive function to indicate the per-packet options and their parameters as received with the corresponding received datagram. Note that per-fragment options are handled within the processing of each fragment.
Options and their processing status (success/fail) MUST be available to the user (i.e., application layer or upper layer protocol/service), both for the packet and for the fragment set, except for FRAG, NOP, and EOL. Those three options are handled within UDP Option processing only. As a reminder (from Section 14), all options except UNSAFE Options MUST result in the UDP user data being passed to the application layer (unless overridden in the API), regardless of whether all options are processed, supported, or succeed.
- For fragments, success for an option is reported only when all fragments succeed for that option.
Per-fragment option status reporting SHOULD default as needed (e.g., not computed and/or not passed up to the upper layers) to minimize overhead, unless actively requested (e.g., by the user or application layer).
SAFE Options associated with fragments are accumulated when associated with the reassembled packet. Values MAY be coalesced, e.g., to indicate that only an AUTH failure of a fragment occurred, rather than not indicating the AUTH status of each fragment.
- Extend the send function to indicate the options to be added to the corresponding sent datagram. This includes indicating which options apply to individual fragments versus which apply to the UDP packet prior to fragmentation, if fragmentation is enabled. It also includes a minimum datagram length, such that the options list ends in EOL and additional space is zero-filled as needed. Finally, it includes a maximum fragment size, e.g., as discovered by DPLPMTUD, whether implemented at the application layer per [RFC8899] or in conjunction with other UDP Options [RFC9869].
Examples of API instances for Linux and FreeBSD are provided in Appendix A to encourage uniform cross-platform implementations ๐
APIs are not intended to provide user control over option order, especially on a per-packet basis, as this could create a covert channel (see Section 25). Similarly, APIs are not intended to provide user or application control over UDP fragment boundaries on a per-packet basis. They are, however, expected to allow control over which options, including fragmentation, are enabled (or disabled) on a per-packet basis. Such control over fragmentation is critical to DPLPMTUD ๐
16. UDP Options Are for Transport, Not Transit
UDP Options are indicated in the surplus area of the IP payload that is not used by UDP. That area is really part of the IP payload, not the UDP payload, so it might be tempting to wonder whether this is a generally useful approach for extending IP ๐ค
Unfortunately, the surplus area only exists for transports that include their own transport layer payload length indicator. TCP and SCTP include header length fields that already provide space for transport options, by indicating the total length of the header area, so the entire remaining area indicated in the network layer (IP) is the transport payload. UDP-Lite already uses the UDP Length field to indicate the boundary between data covered by the transport checksum and data not covered, so there is no remaining area where the length of the UDP-Lite payload as a whole can be indicated [RFC3828]. no room, no surplus ๐ญ
UDP Options are transport options. They are no more (or less) appropriate to be modified in transit than any other portion of the transport datagram.
Generally, transport headers, options, and data are not intended to be modified in transit. UDP Options are no exception, and are specified here as "MUST NOT be altered in transit".
However, note that the UDP Option mechanism provides no specific protection against in-transit modification of the UDP header, UDP payload, or surplus area, except as provided by the OCS or the options selected (e.g., AUTH or UENC).
Unless protected by encryption (e.g., UENC, or via other layers like IPsec), UDP Options remain visible to devices on the network path. The decision not to require mandatory encryption for UDP Options, to prevent that visibility, was made because the key distribution and management infrastructure needed to support such encryption doesn't exist in many of the deployment scenarios of interest. That's especially true for those that use UDP directly as a stateless and connectionless transport protocol (e.g., see [He24]). so yeah, visible by design ๐ง
17. UDP Options vs. UDP-Lite
UDP-Lite provides partial checksum coverage, so UDP packets with errors in some locations can be delivered to the user [RFC3828]. It uses a different transport protocol number (136) than UDP (17), so that it can interpret the UDP Length field as the prefix covered by the UDP checksum.
UDP (protocol 17) already defines the UDP Length field as the limit of the UDP checksum, but by default it also limits the data provided to the application to whatever precedes the UDP Length. A goal of UDP-Lite is to deliver data beyond UDP Length by default, which is why a separate transport protocol number was required ๐ฆ
UDP Options don't use or need a separate transport protocol number, because the data beyond the UDP Length offset (surplus data) isn't provided to the application by default. That data is interpreted exclusively within the UDP transport layer ๐
UDP-Lite cannot support UDP Options, either as proposed here or in any other form, because the entire payload of the UDP packet is already defined as user data, and there's no additional field in which to indicate a surplus area for options. The UDP Length field in UDP-Lite is already used to mark the boundary between user data covered by the checksum and user data not covered. no spare field, no options, periodt ๐
18. Interactions with Legacy Devices ๐
okay so it has always been totally fine for the UDP Length to not match the IP transport payload length [RFC0768]. UDP-Lite actually used that inconsistency with a different transport number [RFC3828] ๐ฆ. There are no known systems using this trick for UDP, ngl. But it's possible it could interact with UDP Options, like a legacy system might send datagrams that look like they have UDP Options ๐. The OCS protects against that way better than a static "magic number" ๐ .
UDP Options have been tested as interoperable with Linux, macOS, and Windows Cygwin, and they worked through NAT devices ๐. These systems only delivered the user data that the UDP Length field indicated, and they quietly discarded the surplus area ๐.
One embedded device was reported to pass the entire IP datagram to the UDP application layer ๐ณ. This could enable application-layer UDP Option processing, but it would require conventional UDP user applications to examine only the UDP user data. It's also inconsistent with the UDP application interface [RFC0768] [RFC1122], so it's a no from me ๐.
It has been noted that Alcatel-Lucent's "Brick" Intrusion Detection System has a default configuration that treats inconsistencies between UDP Length and IP Length as an attack to be reported ๐จ. Other firewall systems, e.g., Check Point, use a default "relaxed UDP Length verification" so they don't falsely flag this inconsistency as an attack ๐ซถ.
There are known uses of UDP exchanges of zero-length UDP user data packets, notably in the TIME protocol [RFC0868] โฐ. The need to support such packets is also noted in the UDP usage guidelines [RFC8085]. Some mechanisms in this document can generate more zero-length UDP packets for a UDP Option aware endpoint than for a legacy endpoint (e.g., based on some error conditions), and some can generate fewer (e.g., fragment reassembly) โจ. Because such packets inherently carry no unique transport header or transport content, endpoints are already expected to be tolerant of their (inadvertent) replication or loss by the network, so such variations are not expected to be problematic ๐ฅฐ.
19. Options in a Stateless, Unreliable Transport Protocol ๐ง
there are two ways to interpret options for a stateless, unreliable protocol. An option is either local to the message, or it's intended to affect a stream of messages in a soft-state manner ๐. Either interpretation is valid for defined UDP Options โ .
It is impossible to know in advance whether an endpoint supports a UDP Option ๐คทโโ๏ธ.
>> All UDP Options other than UNSAFE ones MUST be ignored if not supported or upon failure (e.g., APC).
>> All UDP Options that fail MUST result in the UDP data still being sent to the application layer by default to ensure equivalence with legacy devices.
UDP Options that rely on soft-state exchange need to allow message reordering and loss, in the same way as UDP applications [RFC8085] ๐ซ .
The above requirements prevent using any option that cannot be safely ignored, unless it is hidden inside the FRAG area (i.e., UNSAFE Options) ๐ซ. Legacy systems also always need to be able to interpret the transport fragments as individual UDP packets ๐.
20. UDP Option State Caching ๐
Some TCP connection parameters, stored in the TCP Control Block (TCB), can be usefully shared either among concurrent connections or between connections in sequence. This is known as TCB sharing [RFC9040] ๐. Although UDP is stateless, some of the options proposed herein could have similar benefits in being shared or cached. We call this UCB sharing, or UDP Control Block sharing, by analogy ๐ซง. Just as TCB sharing is not a standard because it is consistent with existing TCP specifications, UCB sharing would be consistent with existing UDP specifications, including this one. Both are implementation issues that are outside the scope of their respective specifications, so UCB sharing is outside the scope of this document ๐ฆ.
21. Updates to RFC 768 ๐
This document updates [RFC0768] as follows:
- This document defines the meaning of the IP payload area beyond the UDP Length but within the IP Length as the surplus area used herein for UDP Options ๐.
- This document extends the UDP API to support the use of UDP Options ๐ .
22. Interactions with Other RFCs ๐ฆ
This document clarifies the interaction between UDP Length and IP Length, which is not explicitly constrained in either UDP or the host requirements [RFC0768] [RFC1122] ๐.
Teredo extensions define use of a similar difference between these lengths for trailers [RFC4380] [RFC6081]. In [RFC6081], Teredo extensions define the length of an IPv6 payload inside UDP as pointing to less than the end of the UDP payload, which enables trailing options for that IPv6 packet ๐:
| ...the IPv6 packet length (i.e., the Payload Length value in the
| IPv6 header plus the IPv6 header size) is less than or equal to
| the UDP payload length (i.e., the Length value in the UDP header
| minus the UDP header size)
UDP Options are not affected by the difference between the UDP user payload end and the payload IPv6 end. Both would end at the UDP user payload, which could end before the enclosing IPv4 or IPv6 header indicates. That allows UDP Options in addition to the trailer options of the IPv6 payload ๐ง. The result, if UDP Options were used, is shown in Figure 19 ๐.
Outer IP Length
<---------------------------------------------------------->
+--------+---------+------------------------------+----------+
| IP Hdr | UDP Hdr | IPv6 packet/len | TE trailer | surplus |
+--------+---------+------------------------------+----------+
<--------------->
Inner IPv6 Length
<-------------------------------------->
UDP Length
Figure 19: TE Trailers and UDP Options Used Concurrently
UDP Options cannot be supported when a UDP packet has no independent UDP Length. One such case is when UDP Length==0 in IPv6, intended for (but not limited to) IPv6 Jumbograms [RFC2675] ๐. Note that although this technique is "Standard", the specification did not "update" UDP [RFC0768]. Another such case arises when UDP is proxied via HTTP [RFC9298], as the UDP header is omitted and only the UDP user data is transported ๐.
This document is consistent with the UDP profile for RObust Header Compression (ROHC) [RFC3095], noted here ๐๏ธ:
| The Length field of the UDP header MUST match the Length field(s)
| of the preceding subheaders, i.e., there must not be any padding
| after the UDP payload that is covered by the IP Length.
ROHC compresses UDP headers only when this match succeeds. It does not prohibit UDP headers where the match fails. In those cases, ROHC default rules (Section 5.10 of [RFC3095]) would cause the UDP header to remain uncompressed. Upon receipt of a compressed UDP header, Appendix A.1.3 of [RFC3095] indicates that the UDP Length is "INFERRED"; in uncompressed packets, it would simply be explicitly provided ๐งฉ.
This issue of handling UDP header compression is more explicitly described in more recent specifications, e.g., Section 10.10 of [RFC8724] ๐.
23. Multicast and Broadcast Considerations ๐ก
UDP Options are primarily intended for unicast use ๐. Using these options over multicast or broadcast IP requires careful consideration. For example, you need to make sure the options used are safe for different endpoints to interpret differently (e.g., either to support or silently ignore), or make sure that all receivers of a multicast or broadcast group confirm support for the options in use ๐ฏ.
24. Network Management Considerations ๐ธ
UDP Options use and configuration may be useful to track and manage remotely ๐ฐ๏ธ. IP Flow Information Export (IPFIX) [RFC7011] Information Elements for UDP Options have been defined in [RFC9870]. Similar to what has been done for TCP [RFC9648], a YANG model [RFC7950] for use by network management protocols (e.g., NETCONF [RFC6241] or RESTCONF [RFC8040]) may be developed. Development of these models is outside the scope of this document ๐งธ.
25. Security Considerations ๐
๐จ Bestie, this is the serious part, so read it carefully! ๐จ
There are a number of security issues raised by the introduction of options to UDP ๐. Some are specific to this variant, but others are associated with any packet processing mechanism. All are discussed further in this section.
25.1. General Considerations Regarding the Use of Options
Note that any user application that considers UDP Options to adversely affect security need not enable them ๐ โโ๏ธ. However, their use does not impact security in a substantially different way than TCP options. Both enable the use of a control channel that has the potential for abuse. Similar to TCP, there are many options that, if unprotected, could be used by an attacker to interfere with communication ๐ค.
UDP Options are not covered by DTLS [RFC9147]. Neither TLS [RFC8446] (Transport Layer Security for TCP) nor DTLS (TLS for UDP) protect the transport layer. Both operate as a shim layer solely on the user data of transport packets, protecting only their contents ๐ก๏ธ.
Just as TLS does not protect the TCP header or its options, DTLS does not protect the UDP header or the new options introduced by this document. Transport security is provided in TCP by the TCP Authentication Option (TCP-AO) [RFC5925] and, when defined, in UDP by the Authentication (AUTH) Option (Section 11.9) and, when defined, the UNSAFE Encryption (UENC) Option (Section 12). Transport headers are also protected as payload when using IP security (IPsec) [RFC4301] ๐.
Some UDP Options are never passed to the receiving application, notably FRAG, NOP, and EOL ๐ซฅ. They are not intended to convey information, either by their presence (FRAG, EOL) or by their number (NOP). It could also be useful to provide the options received in a reference order (e.g., sorted by option number) to avoid the order of options being used as a covert channel ๐ต๏ธโโ๏ธ.
All logging is rate limited to avoid logging itself becoming a resource vulnerability ๐ชต๐ .
25.2. Considerations Regarding On-Path Attacks โจ
okay so UDP Options are like any other options: they can expose option information to on-path attackers ๐, unless the options are encrypted (which might happen with some configurations of UENC, when it gets defined). Application protocol designers are expected to make sure nobody treats information in UDP Options as private unless UENC actually provides that privacy ๐. Designers who use secure payloads (say, via DTLS) need to know that UDP Options add information that sits outside the UDP payload ๐ , so it isn't protected by that same mechanism. Alternate mechanisms (again, maybe some UENC configurations) could be needed too, to guard against information disclosure ๐.
>> Implementations worried about UDP Options being used as a covert channel MAY consider limiting use of some or all options ๐ต๏ธโโ๏ธ. Those implementations SHOULD return options in an order that isn't related to their sequence in the received packet ๐.
Ngl, UDP Options also open up new chances for Distributed DoS (DDoS) attacks ๐ญ, especially through fragmentation ๐ฅ. When they're enabled, UDP Options add extra work at the receiver ๐ฅต. Of the "must-support" options, only REQ (for example, when used with DPLPMTUD [RFC9869]) will make the upper layer start a UDP response when the user hasn't transmitted anything ๐ซข.
>> Implementations concerned about DoS attacks that use large numbers of UDP Options (implemented or unknown), or long runs of repeating valid options (like NOPs), SHOULD detect excessive occurrences and limit the resources they use, for instance through silent packet drops ๐. Such responses SHOULD be logged ๐. The specific thresholds depend on the implementation, so they aren't included here ๐คทโโ๏ธ.
25.3. Considerations Regarding Option Processing ๐งฉ
UDP Options use a TLV syntax that's similar to TCP's ๐. That syntax is known to need serial processing, and it could be a DoS risk. For example, an attacker could add lots of unknown options that have to be parsed in full, which is also the case for IPv6 [RFC8504] ๐ค.
Using UDP packets with inconsistent IP and UDP Length fields can trigger a buffer overflow if it isn't handled properly ๐จ. That happens if space is allocated based on the smaller field but copying is based on the larger one. There have been no reports of this vulnerability though ๐, and it would depend on inconsistent use of the two fields for memory allocation and copying.
Required options come first and appear at most once each ๐. The exception is NOPs, which never need to come in runs of more than seven in a row โจ. That's why their DoS impact is limited ๐ . TLV formats for options do need serial processing, but any format that allows future options (whether they're ignored or not) could bring a similar DoS vulnerability ๐ฅบ.
>> Implementations concerned that UDP Options could introduce a vulnerability MAY implement only the required UDP Options, and SHOULD also limit TLV processing by number of non-padding options, total length, or both ๐ง. The number of non-zero TLVs allowed in that case MUST be at least as many as the number of concurrent options supported, plus a few extra to handle unexpected unknown options ๐งฎ. It SHOULD also consider being adaptive and based on the implementation, so the limit isn't locked in globally ๐.
For example, if a system supports 10 different option types that could be used at the same time, it's expected to allow up to around 13-14 different options in the same packet ๐. This document doesn't specify a fixed minimum ๐ โโ๏ธ, but it does recognize that a given system might not expect more than a few unknown option types per packet ๐.
25.4. Considerations for Fragmentation ๐งต
UDP fragmentation brings its own set of security concerns ๐ฌ. They can be handled in a way similar to IP reassembly or TCP segment reordering [CERT18] ๐ ๏ธ. In particular, the number of UDP packets pending reassembly, and the effort used for reassembly, is typically limited ๐. It could also be useful to assume a reasonable minimum fragment size, for example that non-terminal fragments are never smaller than 500 bytes ๐.
>> Implementations concerned that UDP fragmentation could introduce a vulnerability SHOULD implement limits on the number of pending fragments ๐ฆ.
25.5. Considerations for Providing UDP Security ๐
UDP security is not meant to rely only on transport layer processing of options ๐ญ. UNSAFE Options are the only type that share fate with the UDP data ๐ซฑ๐ซฒ, because the data is hidden in the surplus area until those options are processed ๐. All other options default to being silently ignored at the transport layer ๐คซ. They could still be dropped if that default is overridden (for example, by configuration) or discarded at the application layer (for example, using information about the processed options that is passed along with the UDP packet) ๐๏ธ.
Options that provide UDP security, like AUTH and UENC, need endpoint key and security parameter coordination ๐. UDP Options are stateless, so they don't facilitate that coordination ๐ต. These parameters include whether and when to override the defaults described here ๐๏ธ. That matters especially at the transmitter, for deciding when emitted packets need to include AUTH ๐ค, and at the receiver, for deciding whether (and when) packets with failed AUTH, or without AUTH (or that fail the AUTH checks), are not forwarded to the user or application ๐ซ.
25.6. Considerations Regarding Middleboxes ๐ฐ
Some middleboxes act as UDP relays ๐. They forward data between a UDP socket and another transport socket by modifying the IP and/or UDP headers, without properly acting as a protocol endpoint (that is, an application layer proxy) ๐ณ. In those cases, a sender might add UDP Options that get stripped by the middlebox before the packet is forwarded to the second socket ๐ช. The remote application won't receive the options ๐ โโ๏ธ. For SAFE Options, the payload data will be received ๐ฌ. For UNSAFE Options, the payload data will not be received ๐. The application then functions as it would when talking to a remote endpoint that doesn't support UDP Options ๐ซ .
Also, [Zu20] reports that packets containing UDP Options don't traverse certain Internet paths ๐บ๏ธ. Most likely, those options were stripped (for example, by resetting the IP Length to match the UDP Length, which truncates the surplus area) or the packets with options were dropped ๐ฅ. UDP Options do not function over those paths ๐ญ.
26. IANA Considerations ๐
IANA has created the "User Datagram Protocol (UDP)" registry group ๐. It consists of the "UDP Option Kind Numbers" registry and a pointer to the unified "TCP/UDP Experimental Option Experiment Identifiers (TCP/UDP ExIDs)" registry ๐งพ. The "TCP experimental IDs (ExIDs)" registry has been renamed to the "TCP/UDP Experimental Option Experiment Identifiers (TCP/UDP ExIDs)" registry, and it's now a unified registry for both TCP and UDP ExIDs ๐ค. IANA has added the following note to the unified TCP/UDP ExID registry:
| 16-bit ExIDs can be used with either TCP or UDP; 32-bit ExIDs can
| be used with TCP or their first 16 bits can be used with UDP. Use
| with each transport (TCP, UDP) is indicated in the protocol
| column, as defined in RFC 9868.
Initial values of the "UDP Option Kind Numbers" registry are as listed in Section 10, including those both assigned and reserved ๐. Additional values in this registry are to be assigned from the Unassigned values in Section 10 by IESG Approval or Standards Action [RFC8126] โ . Those assignments are subject to the conditions set forth in this document, particularly (but not limited to) those in Section 13 ๐.
>> Although option nicknames are not used in-band, new UNSAFE Option names MUST commence with the capital letter "U", and new SAFE Options MUST NOT commence with either uppercase or lowercase "U" ๐ค.
IANA has added the following note to the "UDP Option Kind Numbers" registry, indicating that entries are mandatory to implement when UDP Options are supported ๐. No new options may be created that are mandatory to implement in all UDP Options implementations ๐ซ.
| Codepoints 0-7 MUST be supported on any implementation supporting
| UDP Options. All others are supported at the discretion of each
| implementation.
UDP Experimental Option Experiment Identifiers (UDP ExIDs) are meant to be used in a similar way to TCP ExIDs [RFC6994] ๐งช. Both TCP and UDP ExIDs are managed as a single, unified registry ๐๏ธ. That's because such options could be used for both transport protocols, and the option space is large enough that there's no clear need to maintain them separately ๐. This TCP/UDP ExIDs registry has entries for both transports ๐, but each codepoint needs to be explicitly defined for each transport protocol where it's used ๐โโ๏ธ. In other words, defining a codepoint in TCP doesn't imply it has a similar use in UDP ๐ โโ๏ธ. IANA has added a "Protocol" field to the registry and updated the current TCP ExIDs to be indicated as defined for TCP ๐ท๏ธ. New assignments are to indicate the transport they're defined for ๐.
TCP/UDP ExIDs can be used in either or both of the UDP EXP (Section 11.10) or UEXP (Section 12.3) Options ๐. TCP/UDP ExID entries for use in UDP consist of a 16-bit ExID (in network-standard order) and, as with the original TCP ExIDs, will preferably also include a short description and acronym for use in documentation ๐. TCP/UDP ExIDs used for UDP are always 16 bits ๐ข. Their use in EXP and UEXP Options is required, so they don't need a larger codepoint value to decrease the probability of accidental occurrence with non-ExID uses of the experimental options ๐ฒ. That's the case with TCP ExIDs, for example when using 32-bit ExIDs ๐ง. ExIDs defined solely for TCP options could be either 16 or 32 bits ๐. All ExIDs, including UDP ones now, need to be unique in their first 16 bits, as originally described for TCP [RFC6994] ๐.
Values in the TCP/UDP ExID registry are to be assigned by IANA using the First Come First Served (FCFS) policy [RFC8126] ๐. That policy applies to both the ExID value and the acronym ๐ค. UDP Options using these ExIDs are subject to the same conditions as new UDP Options ๐ . In other words, they too are subject to the conditions set forth in this document, particularly (but not limited to) those in Section 13 ๐.
27. References ๐
27.1. Normative References โจ
okay bestie, these are the docs you NEED to have open before you touch the spec ๐๐ they're the foundation, so you can't skip them ๐ซถ
[RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, DOI 10.17487/RFC0768, August 1980, https://www.rfc-editor.org/info/rfc768.
[RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791, DOI 10.17487/RFC0791, September 1981, https://www.rfc-editor.org/info/rfc791.
[RFC1122] Braden, R., Ed., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989, https://www.rfc-editor.org/info/rfc1122.
[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.
[RFC9869] Fairhurst, G. and T. Jones, "Datagram Packetization Layer Path MTU Discovery (DPLPMTUD) for UDP Options", RFC 9869, DOI 10.17487/RFC9869, October 2025, https://www.rfc-editor.org/info/rfc9869.
27.2. Informative References ๐ธ
these ones are the extra-cozy reading list ๐ง the drafts, the old classics, and the wild side quests that give you the full story ๐ they're not required reading, but ngl they're iconic and you'll want them ๐ฅ
[CERT18] CERT Coordination Center, "TCP implementations vulnerable to Denial of Service", Vulnerability Note VU#962459, Software Engineering Institute, CMU, 2018, https://www.kb.cert.org/vuls/id/962459.
[Fa18] Fairhurst, G., Jones, T., and R. Zullo, "Checksum Compensation Options for UDP Options", Work in Progress, Internet-Draft, draft-fairhurst-udp-options-cco-00, 19 October 2018, https://datatracker.ietf.org/doc/html/draft-fairhurst-udp-options-cco-00.
[He24] Heard, C. M., "Use of UDP Options for Transmission of Large DNS Responses", Work in Progress, Internet-Draft, draft-heard-dnsop-udp-opt-large-dns-responses-00, 28 April 2024, https://datatracker.ietf.org/doc/html/draft-heard-dnsop-udp-opt-large-dns-responses-00.
[Hi15] Hildebrand, J. and B. Trammell, "Substrate Protocol for User Datagrams (SPUD) Prototype", Work in Progress, Internet-Draft, draft-hildebrand-spud-prototype-03, 9 March 2015, https://datatracker.ietf.org/doc/html/draft-hildebrand-spud-prototype-03.
[La78] Lamport, L., "Time, clocks, and the ordering of events in a distributed system", Communications of the ACM, vol. 21, no. 7, pp. 558-565, DOI 10.1145/359545.359563, July 1978, https://doi.org/10.1145/359545.359563.
[RFC0793] Postel, J., "Transmission Control Protocol", RFC 793, DOI 10.17487/RFC0793, September 1981, https://www.rfc-editor.org/info/rfc793.
[RFC0868] Postel, J. and K. Harrenstien, "Time Protocol", STD 26, RFC 868, DOI 10.17487/RFC0868, May 1983, https://www.rfc-editor.org/info/rfc868.
[RFC1071] Braden, R., Borman, D., and C. Partridge, "Computing the Internet checksum", RFC 1071, DOI 10.17487/RFC1071, September 1988, https://www.rfc-editor.org/info/rfc1071.
[RFC1141] Mallory, T. and A. Kullberg, "Incremental updating of the Internet checksum", RFC 1141, DOI 10.17487/RFC1141, January 1990, https://www.rfc-editor.org/info/rfc1141.
[RFC1191] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191, DOI 10.17487/RFC1191, November 1990, https://www.rfc-editor.org/info/rfc1191.
[RFC2675] Borman, D., Deering, S., and R. Hinden, "IPv6 Jumbograms", RFC 2675, DOI 10.17487/RFC2675, August 1999, https://www.rfc-editor.org/info/rfc2675.
[RFC2923] Lahey, K., "TCP Problems with Path MTU Discovery", RFC 2923, DOI 10.17487/RFC2923, September 2000, https://www.rfc-editor.org/info/rfc2923.
[RFC3095] Bormann, C., Burmeister, C., Degermark, M., Fukushima, H., Hannu, H., Jonsson, L., Hakenberg, R., Koren, T., Le, K., Liu, Z., Martensson, A., Miyazaki, A., Svanbro, K., Wiebke, T., Yoshimura, T., and H. Zheng, "RObust Header Compression (ROHC): Framework and four profiles: RTP, UDP, ESP, and uncompressed", RFC 3095, DOI 10.17487/RFC3095, July 2001, https://www.rfc-editor.org/info/rfc3095.
[RFC3173] Shacham, A., Monsour, B., Pereira, R., and M. Thomas, "IP Payload Compression Protocol (IPComp)", RFC 3173, DOI 10.17487/RFC3173, September 2001, https://www.rfc-editor.org/info/rfc3173.
[RFC3385] Sheinwald, D., Satran, J., Thaler, P., and V. Cavanna, "Internet Protocol Small Computer System Interface (iSCSI) Cyclic Redundancy Check (CRC)/Checksum Considerations", RFC 3385, DOI 10.17487/RFC3385, September 2002, https://www.rfc-editor.org/info/rfc3385.
[RFC3692] Narten, T., "Assigning Experimental and Testing Numbers Considered Useful", BCP 82, RFC 3692, DOI 10.17487/RFC3692, January 2004, https://www.rfc-editor.org/info/rfc3692.
[RFC3828] Larzon, L., Degermark, M., Pink, S., Jonsson, L., Ed., and G. Fairhurst, Ed., "The Lightweight User Datagram Protocol (UDP-Lite)", RFC 3828, DOI 10.17487/RFC3828, July 2004, https://www.rfc-editor.org/info/rfc3828.
[RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, DOI 10.17487/RFC4301, December 2005, https://www.rfc-editor.org/info/rfc4301.
[RFC4340] Kohler, E., Handley, M., and S. Floyd, "Datagram Congestion Control Protocol (DCCP)", RFC 4340, DOI 10.17487/RFC4340, March 2006, https://www.rfc-editor.org/info/rfc4340.
[RFC4380] Huitema, C., "Teredo: Tunneling IPv6 over UDP through Network Address Translations (NATs)", RFC 4380, DOI 10.17487/RFC4380, February 2006, https://www.rfc-editor.org/info/rfc4380.
[RFC4787] Audet, F., Ed. and C. Jennings, "Network Address Translation (NAT) Behavioral Requirements for Unicast UDP", BCP 127, RFC 4787, DOI 10.17487/RFC4787, January 2007, https://www.rfc-editor.org/info/rfc4787.
[RFC5925] Touch, J., Mankin, A., and R. Bonica, "The TCP Authentication Option", RFC 5925, DOI 10.17487/RFC5925, June 2010, https://www.rfc-editor.org/info/rfc5925.
[RFC6081] Thaler, D., "Teredo Extensions", RFC 6081, DOI 10.17487/RFC6081, January 2011, https://www.rfc-editor.org/info/rfc6081.
[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., "Network Configuration Protocol (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011, https://www.rfc-editor.org/info/rfc6241.
[RFC6864] Touch, J., "Updated Specification of the IPv4 ID Field", RFC 6864, DOI 10.17487/RFC6864, February 2013, https://www.rfc-editor.org/info/rfc6864.
[RFC6935] Eubanks, M., Chimento, P., and M. Westerlund, "IPv6 and UDP Checksums for Tunneled Packets", RFC 6935, DOI 10.17487/RFC6935, April 2013, https://www.rfc-editor.org/info/rfc6935.
[RFC6978] Touch, J., "A TCP Authentication Option Extension for NAT Traversal", RFC 6978, DOI 10.17487/RFC6978, July 2013, https://www.rfc-editor.org/info/rfc6978.
[RFC6994] Touch, J., "Shared Use of Experimental TCP Options", RFC 6994, DOI 10.17487/RFC6994, August 2013, https://www.rfc-editor.org/info/rfc6994.
[RFC7011] Claise, B., Ed., Trammell, B., Ed., and P. Aitken, "Specification of the IP Flow Information Export (IPFIX) Protocol for the Exchange of Flow Information", STD 77, RFC 7011, DOI 10.17487/RFC7011, September 2013, https://www.rfc-editor.org/info/rfc7011.
[RFC7323] Borman, D., Braden, B., Jacobson, V., and R. Scheffenegger, Ed., "TCP Extensions for High Performance", RFC 7323, DOI 10.17487/RFC7323, September 2014, https://www.rfc-editor.org/info/rfc7323.
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language", RFC 7950, DOI 10.17487/RFC7950, August 2016, https://www.rfc-editor.org/info/rfc7950.
[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017, https://www.rfc-editor.org/info/rfc8040.
[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, "UDP Usage Guidelines", BCP 145, RFC 8085, DOI 10.17487/RFC8085, March 2017, https://www.rfc-editor.org/info/rfc8085.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, https://www.rfc-editor.org/info/rfc8126.
[RFC8200] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", STD 86, RFC 8200, DOI 10.17487/RFC8200, July 2017, https://www.rfc-editor.org/info/rfc8200.
[RFC8201] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed., "Path MTU Discovery for IP version 6", STD 87, RFC 8201, DOI 10.17487/RFC8201, July 2017, https://www.rfc-editor.org/info/rfc8201.
[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.
[RFC8504] Chown, T., Loughney, J., and T. Winters, "IPv6 Node Requirements", BCP 220, RFC 8504, DOI 10.17487/RFC8504, January 2019, https://www.rfc-editor.org/info/rfc8504.
[RFC8724] Minaburo, A., Toutain, L., Gomez, C., Barthel, D., and JC. Zuniga, "SCHC: Generic Framework for Static Context Header Compression and Fragmentation", RFC 8724, DOI 10.17487/RFC8724, April 2020, https://www.rfc-editor.org/info/rfc8724.
[RFC8899] Fairhurst, G., Jones, T., Tรผxen, M., Rรผngeler, I., and T. Vรถlker, "Packetization Layer Path MTU Discovery for Datagram Transports", RFC 8899, DOI 10.17487/RFC8899, September 2020, https://www.rfc-editor.org/info/rfc8899.
[RFC9040] Touch, J., Welzl, M., and S. Islam, "TCP Control Block Interdependence", RFC 9040, DOI 10.17487/RFC9040, July 2021, https://www.rfc-editor.org/info/rfc9040.
[RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", RFC 9147, DOI 10.17487/RFC9147, April 2022, https://www.rfc-editor.org/info/rfc9147.
[RFC9187] Touch, J., "Sequence Number Extension for Windowed Protocols", RFC 9187, DOI 10.17487/RFC9187, January 2022, https://www.rfc-editor.org/info/rfc9187.
[RFC9260] Stewart, R., Tรผxen, M., and K. Nielsen, "Stream Control Transmission Protocol", RFC 9260, DOI 10.17487/RFC9260, June 2022, https://www.rfc-editor.org/info/rfc9260.
27.2. Informative References (continued) ๐ฆ
[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. Okay, this is the TCP spec, the OG that basically runs the internet's reliable-delivery vibes ๐
[RFC9298] Schinazi, D., "Proxying UDP in HTTP", RFC 9298, DOI 10.17487/RFC9298, August 2022, https://www.rfc-editor.org/info/rfc9298. This one is about tunneling UDP through HTTP, which is such a glow-up for UDP ๐
[RFC9648] Scharf, M., Jethanandani, M., and V. Murgai, "YANG Data Model for TCP", RFC 9648, DOI 10.17487/RFC9648, October 2024, https://www.rfc-editor.org/info/rfc9648. A YANG data model for TCP, so yes, it's giving structured config ๐
[RFC9870] Boucadair, M. and T. Reddy.K, "Export of UDP Options Information in IP Flow Information Export (IPFIX)", RFC 9870, DOI 10.17487/RFC9870, October 2025, https://www.rfc-editor.org/info/rfc9870. This is the one that lets you export UDP Options info over IPFIX, very useful and very on-brand for this whole doc ๐ซถ
[To18] Touch, J. D., "A TCP Authentication Option Extension for Payload Encryption", Work in Progress, Internet-Draft, draft-touch-tcp-ao-encrypt-09, 19 July 2018, https://datatracker.ietf.org/doc/html/draft-touch-tcp-ao-encrypt-09. A draft (so, still cooking) about encrypting the payload with the TCP Authentication Option ๐ฅ
[To24] Touch, J. D., "The UDP Authentication Option", Work in Progress, Internet-Draft, draft-touch-tsvwg-udp-auth-opt-00, 3 March 2024, https://datatracker.ietf.org/doc/html/draft-touch-tsvwg-udp-auth-opt-00. Same author, but for UDP auth, and it's also a work in progress ๐
[Zu20] Zullo, R., Jones, T., and G. Fairhurst, "Overcoming the Sorrows of the Young UDP Options", 4th Network Traffic Measurement and Analysis Conference (TMA), 2020, https://dl.ifip.org/db/conf/tma/tma2020/tma2020-camera-paper70.pdf. The title alone is iconic ๐ญ It's a conference paper about the challenges UDP Options run into.
Appendix A. Implementation Information โจ
Okay, this is the part for implementers who want their API names to match up ๐ The following info is here to encourage consistent naming across API implementations, so everyone's on the same page.
System-level variables (sysctl) are listed in Table 2 below:
+=======================+=========+=======================+
| Name | Default | Meaning |
+=======================+=========+=======================+
| net.ipv4.udp_opt | 0 | UDP Options available |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_ocs | 1 | Use OCS |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_apc | 0 | Include APC |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_frag | 0 | Fragment |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_mds | 0 | Include MDS |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_mrds | 0 | Include MRDS |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_req | 0 | Include REQ |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_resp | 0 | Include RES |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_time | 0 | Include TIME |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_auth | 0 | Include AUTH |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_exp | 0 | Include EXP |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_ucmp | 0 | Include UCMP |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_uenc | 0 | Include UENC |
+-----------------------+---------+-----------------------+
| net.ipv4.udp_opt_uexp | 0 | Include UEXP |
+-----------------------+---------+-----------------------+
Table 2
Next up are the socket options (sockopt), which are cached for outgoing datagrams. That's Table 3 ๐ธ
+==============+=============================+
| Name | Meaning |
+==============+=============================+
| UDP_OPT | Enable UDP Options (at all) |
+--------------+-----------------------------+
| UDP_OPT_OCS | Use UDP OCS |
+--------------+-----------------------------+
| UDP_OPT_APC | Enable UDP APC Option |
+--------------+-----------------------------+
| UDP_OPT_FRAG | Enable UDP fragmentation |
+--------------+-----------------------------+
| UDP OPT MDS | Enable UDP MDS Option |
+--------------+-----------------------------+
| UDP OPT MRDS | Enable UDP MRDS Option |
+--------------+-----------------------------+
| UDP OPT REQ | Enable UDP REQ Option |
+--------------+-----------------------------+
| UDP OPT RES | Enable UDP RES Option |
+--------------+-----------------------------+
| UDP_OPT_TIME | Enable UDP TIME Option |
+--------------+-----------------------------+
| UDP OPT AUTH | Enable UDP AUTH Option |
+--------------+-----------------------------+
| UDP OPT EXP | Enable UDP EXP Option |
+--------------+-----------------------------+
| UDP_OPT_UCMP | Enable UDP UCMP Option |
+--------------+-----------------------------+
| UDP_OPT_UENC | Enable UDP UENC Option |
+--------------+-----------------------------+
| UDP OPT UEXP | Enable UDP UEXP Option |
+--------------+-----------------------------+
Table 3
For send/sendto parameters, it's the same as the sysctl stuff, just with different prefixes:
- (Same as sysctl, with different prefixes)
Connection parameters (per-socket pair cached state, part UCB) are in Table 4 ๐
+==============+======================+
| Name | Initial Value |
+==============+======================+
| opts_enabled | net.ipv4.udp_opt |
+--------------+----------------------+
| ocs_enabled | net.ipv4.udp_opt_ocs |
+--------------+----------------------+
Table 4
NB: The JUNK Option is included for debugging purposes and is not intended to be enabled otherwise. So, bestie, this is a debugging-only vibe. Please don't turn it on in prod ๐
The JUNK system variable is set like this:
System variables:
net.ipv4.udp_opt_junk 0
The JUNK sysctl table is Table 5:
+=======================+=========+=====================+
| Name | Default | Meaning |
+=======================+=========+=====================+
| net.ipv4.udp_opt_junk | 0 | Default use of junk |
+-----------------------+---------+---------------------+
Table 5
The JUNK socket options are Table 6 ๐ง
+==============+=========+=================================+
| Name | Params | Meaning |
+==============+=========+=================================+
| UDP_JUNK | - | Enable UDP junk option |
+--------------+---------+---------------------------------+
| UDP_JUNK_VAL | fillval | Value to use as junk fill |
+--------------+---------+---------------------------------+
| UDP_JUNK_LEN | length | Length of junk payload in bytes |
+--------------+---------+---------------------------------+
Table 6
And the connection parameters for JUNK are Table 7:
+==============+=======================+
| Name | Initial Value |
+==============+=======================+
| junk_enabled | net.ipv4.udp_opt_junk |
+--------------+-----------------------+
| junk_value | 0xABCD |
+--------------+-----------------------+
| junk_len | 4 |
+--------------+-----------------------+
Table 7
Acknowledgments ๐ซถ
This work got so much help from Erik Auerswald, Bob Briscoe, Ken Calvert, Ted Faber, and Gorry Fairhurst (who contributed OCS for errant middlebox traversal). C. M. Heard, the editor of this doc, also gets a huge shoutout ๐ They did the work of combining the previous FRAG and LITE Options into the new FRAG, plus Figure 12. Tom Herbert, Tom Jones, Mark Smith, Carl Williams, and Raffaele Zullo were also a massive help, and so were the discussions on the IETF TSVWG and SPUD email lists. Literally so many brilliant people ๐ญ
This work was partly supported by USC/ISI's Postel Center. Thank you, Postel Center ๐
Authors' Addresses ๐
Joe Touch Independent Consultant Manhattan Beach, CA 90266 United States of America Phone: +1 (310) 560-0334 Email: touch@strayalpha.com
C. M. (Mike) Heard (editor) Unaffiliated PO Box 2667 Redwood City, CA 94064-2667 United States of America Phone: +1 (408) 499-7257 Email: heard@pobox.com
๐ฆ where this page comes from
- ietf: rfc9868 2025-10
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms