RFC 5405

Unicast UDP Usage Guidelines for Application Designers

๐Ÿ“… published November 2008, from ietf

RFC 5405: Unicast UDP Usage Guidelines for Application Designers ๐ŸŽ€

Part 1 of 7 ๐Ÿ’–

Okay bestie, this one is RFC 5405 and it's a Best Current Practice, which is why it's labelled BCP 145 ๐ŸŒธ. It's titled Unicast UDP Usage Guidelines for Application Designers, and it came out in November 2008. The authors are L. Eggert from Nokia and G. Fairhurst from the University of Aberdeen, and it was published in the Network Working Group. This block doesn't list anything it obsoletes or updates โœจ


Status of This Memo ๐Ÿงš

This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements. Distribution of this memo is unlimited.

Copyright (c) 2008 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 (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.

Abstract ๐Ÿฆ‹

Okay so UDP gives you a minimal way to pass messages around, and it has no built-in congestion control at all, no cap ๐Ÿ˜ญ. Congestion control is literally what keeps the Internet stable, so any application or upper-layer protocol that picks UDP as its transport must bring its own mechanisms to prevent congestion collapse and to get some level of fairness with the traffic it shares the network with. This document gives guidelines on using UDP for designers of unicast applications and upper-layer protocols. Congestion control is the main focus, but it also covers message sizes, reliability, checksums, and middlebox traversal ๐Ÿ’…

Table of Contents ๐ŸŒˆ

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Terminology  . . . . . . . . . . . . . . . . . . . . . . . . .  5
   3.  UDP Usage Guidelines . . . . . . . . . . . . . . . . . . . . .  5
     3.1.  Congestion Control Guidelines  . . . . . . . . . . . . . .  6
     3.2.  Message Size Guidelines  . . . . . . . . . . . . . . . . . 11
     3.3.  Reliability Guidelines . . . . . . . . . . . . . . . . . . 12
     3.4.  Checksum Guidelines  . . . . . . . . . . . . . . . . . . . 13
     3.5.  Middlebox Traversal Guidelines . . . . . . . . . . . . . . 15
     3.6.  Programming Guidelines . . . . . . . . . . . . . . . . . . 17
     3.7.  ICMP Guidelines  . . . . . . . . . . . . . . . . . . . . . 18
   4.  Security Considerations  . . . . . . . . . . . . . . . . . . . 19
   5.  Summary  . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
   6.  Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . . 22
   7.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 22
     7.1.  Normative References . . . . . . . . . . . . . . . . . . . 22
     7.2.  Informative References . . . . . . . . . . . . . . . . . . 23

1. Introduction ๐ŸŽ€

Okay so the User Datagram Protocol (UDP) [RFC0768] gives applications and upper-layer protocols (we'll just call both "applications" from here on) a minimal, unreliable, best-effort way to pass messages around. Compared to other transport protocols, UDP and its UDP-Lite variant [RFC3828] are special because they don't set up end-to-end connections between the end systems talking to each other. That means no connection setup or teardown overhead and minimal end system state, so UDP can be a super efficient transport for some apps ๐Ÿฆ‹

The second thing that makes UDP unique is that it has no inherent congestion control ๐Ÿ˜ญ. On lots of platforms, applications can blast UDP datagrams at the line rate of the link interface, which is often way more than the path can actually carry, and doing that adds to congestion along the path. [RFC2914] is the best current practice for congestion control on the Internet, and it names two big reasons congestion control is critical for the Internet to stay stable:

  1. The prevention of congestion collapse, i.e., a state where an increase in network load results in a decrease in useful work done by the network.
  2. The establishment of a degree of fairness, i.e., allowing multiple flows to share the capacity of a path reasonably equitably.

Since UDP doesn't bring any congestion control of its own, it's on the applications that use UDP for Internet communication to add suitable mechanisms that prevent congestion collapse and establish some fairness ๐Ÿ’…. [RFC2309] talks about the dangers of congestion-unresponsive flows and says that "all UDP-based streaming applications should incorporate effective congestion avoidance mechanisms". That's a big deal, and it applies even to apps that don't use UDP for streaming ๐Ÿ‘‘. Congestion-controlled sending also helps the app itself, because it can cut down on self-induced packet loss, reduce retransmissions, and lower delays. Congestion control matters even at pretty slow rates ๐Ÿ™ˆ. For example, an app that generates five 1500-byte UDP datagrams in one second can already exceed the capacity of a 56 Kb/s path. For apps that can go at higher, potentially unbounded data rates, congestion control becomes vital to prevent congestion collapse and establish some degree of fairness. Section 3 has a bunch of simple guidelines for designers of those apps โœจ

A UDP datagram rides in a single IP packet, so it's limited to a maximum payload of 65,507 bytes for IPv4 and 65,527 bytes for IPv6. Sending big IP packets usually means IP fragmentation, and fragmentation makes communication less reliable and less efficient, so it should be avoided ๐Ÿ“. IPv6 lets you send large packets ("jumbograms") without fragmentation when all the link layers along the path support that [RFC2675]. Some of the guidelines in Section 3 explain how applications should figure out appropriate message sizes. Other sections cover reliability, checksums, and middlebox traversal ๐Ÿงš

This document is all about guidelines and recommendations. Most unicast UDP apps are expected to follow these guidelines, but there are valid reasons why a specific app might choose not to follow a given guideline ๐ŸŒธ. In that case, it is RECOMMENDED that the application designers document the rationale for their design choice in the technical specification of their application or protocol.

This document is for designers of apps that use UDP for unicast transmission, which is the most common case. Specialized apps use UDP for IP multicast [RFC1112], broadcast [RFC0919], or anycast [RFC1546] transmissions ๐Ÿฆ‹. Designing those takes expertise that goes beyond the simple, unicast-specific guidelines here. Multicast and broadcast senders may send to multiple receivers over potentially very different paths at the same time, which makes congestion control, flow control, and reliability way more complicated. The IETF has defined a reliable multicast framework [RFC3048] and several building blocks to help multicast app designers, such as [RFC3738] or [RFC4654]. Anycast senders must be aware that successive messages sent to the same anycast IP address may be delivered to different anycast nodes, i.e., arrive at different locations in the topology. The guidelines in this document are not intended to apply to multicast, broadcast, or anycast applications that use UDP ๐Ÿ™…โ€โ™€๏ธ

Finally, even though this document specifically talks about unicast apps that use UDP, the spirit of some of its guidelines also applies to other message-passing apps and protocols (specifically on congestion control, message sizes, and reliability). Examples include signaling or control apps that choose to run directly over IP by registering their own IP protocol number with IANA. This document may be useful background reading for designers of those apps and protocols ๐Ÿ’œ

2. Terminology ๐Ÿฆ‹

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14, RFC 2119 [RFC2119] ๐Ÿ“–

3. UDP Usage Guidelines ๐ŸŒธ

Internet paths can be wildly different from each other: transmission delays, available bandwidths, congestion levels, reordering probabilities, supported message sizes, and loss rates can all vary a lot ๐Ÿ˜ญ. And the same Internet path can behave super differently over time too. So applications that may be used on the Internet MUST NOT make assumptions about specific path characteristics. They MUST instead use mechanisms that let them operate safely under very different path conditions. Usually that means carefully probing the current conditions of the Internet path they're talking over, so they can settle on a transmission behavior the path can sustain and that's reasonably fair to other traffic sharing it ๐Ÿ’…

These mechanisms are hard to get right ๐Ÿ™ˆ. For most applications, using one of the existing IETF transport protocols is the easiest way to get the required mechanisms. So the RECOMMENDED alternative to the UDP usage described in the rest of this section is to use an IETF transport protocol, such as TCP [RFC0793], Stream Control Transmission Protocol (SCTP) [RFC4960], and SCTP Partial Reliability Extension (SCTP-PR) [RFC3758], or Datagram Congestion Control Protocol (DCCP) [RFC4340] with its different congestion control types [RFC4341][RFC4342][CCID4] ๐Ÿ‘‘

If you use these fuller transport protocols correctly, they're not as "heavyweight" as people often claim ๐Ÿ’–. For example, the TCP algorithms have been improved over decades and have reached a level of efficiency and correctness that custom application-layer mechanisms will struggle to match. Lots of TCP implementations also let an application tune connections for its purposes. For example, TCP's "Nagle" algorithm [RFC0896] can be turned off, which improves latency at the cost of more frequent, but still congestion-controlled, packet transmissions โœจ. Another one is the TCP SYN cookie mechanism [RFC4987], which is available on many platforms. TCP with SYN cookies doesn't make a server keep per-connection state until the connection is established ๐Ÿงš. TCP also makes the end that closes a connection keep the TIME-WAIT state, which stops delayed segments from one connection instance from messing with a later one. Apps that know about this and are designed around it can shift the TIME-WAIT state maintenance to save resources by choosing which end closes a TCP connection [FABER] ๐Ÿฆ‹. Finally, TCP's built-in capacity probing and its awareness of the maximum transmission unit supported by the path (PMTU) give efficient data transmission that quickly makes up for the initial connection setup delay, as long as the transfer exchanges more than a few segments ๐ŸŒˆ

โญ๏ธ Part 2 is coming up next, bestie!

3.1. Congestion Control Guidelines โœจ

okay so bestie, this part is all about congestion control ๐ŸŒŠ and honestly it's giving main character energy because UDP doesn't come with any built-in traffic manners, so the app has to bring its own ๐Ÿ’…. If an application decides not to use a congestion-controlled transport protocol, it SHOULD control the rate at which it sends UDP datagrams to a destination host, so it can meet the requirements of [RFC2914]. The big thing to remember is that an application SHOULD perform congestion control over ALL the UDP traffic it sends to a destination, no matter how that traffic is generated ๐Ÿซถ. So if an app forks multiple worker processes or uses multiple sockets to blast out datagrams, it SHOULD perform congestion control over the aggregate traffic. Not one socket at a time, the whole pile together ๐Ÿ“

Okay so there are a few different approaches discussed in the rest of this section, and not every single one fits every UDP app ๐Ÿ™ˆ. Section 3.1.1 covers bulk transfer apps, the ones that sample the path over several subsequent RTTs while data is flowing, to figure out a sending rate the path can handle at its current load ๐Ÿš€. Section 3.1.2 is for "low data-volume" apps, which only swap a few UDP datagrams with a destination. Since they don't send enough data to keep sampling the path, they need different congestion control tools ๐Ÿงš. And Section 3.1.3 talks about congestion control when UDP is being used as a tunneling protocol ๐ŸŽ€.

It's important to note that congestion control is NOT an add-on you bolt onto a finished app ๐Ÿ˜ญ. A lot of these mechanisms need the application itself to cooperate, so designers need to think about congestion control throughout the whole design process, the same way they think about security ๐Ÿ”.

The IETF has also looked into integrated congestion control mechanisms that act on the aggregate traffic between two hosts, like the Congestion Manager [RFC3124]. In that setup, active sessions can share current congestion information no matter which transport protocol they use ๐Ÿฆ‹. Honestly these haven't really caught on in deployment yet, but they'd make it way easier to design congestion control for UDP sessions so they meet the requirements in [RFC2914] โœจ.

3.1.1. Bulk Transfer Applications

okay this one is for apps that bulk-send data to a peer over UDP, meaning they exchange more than a small number of UDP datagrams per RTT ๐Ÿ’–. These apps SHOULD implement TCP-Friendly Rate Control (TFRC) [RFC5348], window-based TCP-like congestion control, or otherwise make sure the app complies with the congestion control principles ๐ŸŒธ.

TFRC was designed to give both congestion control AND fairness in a way that plays nicely with the IETF's other transport protocols ๐Ÿ‘‘. If an app implements TFRC, it doesn't need to follow the rest of the guidelines in Section 3.1.1 (TFRC already handles them!), but it SHOULD still follow the remaining guidelines in the subsequent subsections of Section 3 ๐Ÿ’….

Bulk transfer apps that skip TFRC or TCP-like windowing SHOULD implement a congestion control scheme whose bandwidth use competes fairly with TCP within an order of magnitude ๐ŸŒˆ. Section 2 of [RFC3551] suggests that applications SHOULD monitor the packet loss rate to make sure it stays within acceptable parameters ๐Ÿ“Š. Packet loss counts as acceptable if a TCP flow across the same network path under the same conditions would get an average throughput (measured on a reasonable timescale) that is not less than the UDP flow's throughput ๐Ÿฆ‹. The TCP comparison can't be specified exactly, it's meant as an "order-of-magnitude" comparison in timescale and throughput, so don't overthink it ๐Ÿ˜ญ.

Last but not least ๐Ÿ™ˆ, some bulk transfer apps might skip congestion control entirely and just rely on transmitting across reserved path capacity. That could be an acceptable choice in a subset of restricted networking environments, but it is by no means a safe practice for the Internet ๐Ÿ’€. When UDP traffic like this leaks out onto unprovisioned Internet paths, it can seriously hurt the performance of other traffic sharing the path and even cause congestion collapse ๐Ÿ˜ฑ. So apps that support uncontrolled or unadaptive transmission SHOULD NOT do so by default, and they SHOULD instead require users to explicitly turn that mode on ๐Ÿ”ฅ.

3.1.2. Low Data-Volume Applications

when apps that only ever exchange a small number of UDP datagrams with a destination use TFRC or one of the other schemes from Section 3.1.1, the network doesn't really get much benefit ๐Ÿฅบ. Those mechanisms only work well for longer transmissions, so they're kinda wasted on tiny exchanges ๐Ÿ™ƒ.

Apps that only swap a small number of UDP datagrams with a destination SHOULD still keep their transmission in check by not sending, on average, more than one UDP datagram per round-trip time (RTT) to a destination ๐Ÿ“. Similar to the recommendation in [RFC1536], an application SHOULD maintain an estimate of the RTT for any destination it talks to ๐Ÿง . Applications SHOULD implement the algorithm specified in [RFC2988] to compute a smoothed RTT (SRTT) estimate ๐Ÿ“. They SHOULD also detect packet loss and exponentially back off their retransmission timer when a loss event happens ๐Ÿ“‰. When doing this, apps need to pick a sensible initial value for the RTT, and that value SHOULD generally be as conservative as possible for the given app ๐Ÿซถ. TCP uses an initial value of 3 seconds [RFC2988], which is also RECOMMENDED as an initial value for UDP apps ๐ŸŽ€. SIP [RFC3261] and GIST [GIST] use an initial value of 500 ms, and initial timeouts shorter than that are likely problematic in many cases ๐Ÿ˜ฌ. Also, the initial timeout is NOT the maximum possible timeout ๐Ÿ™…โ€โ™€๏ธ. The RECOMMENDED algorithm in [RFC2988] gives timeout values after a series of losses that are much longer than the initial value ๐Ÿฆ‹.

Some apps can't maintain a reliable RTT estimate for a destination ๐Ÿฅน. The first case is apps that exchange too few UDP datagrams with a peer to build a statistically accurate RTT estimate ๐Ÿ“Š. These apps MAY use a predetermined transmission interval that gets exponentially backed off when packets are lost โณ. TCP uses an initial value of 3 seconds [RFC2988], which is also RECOMMENDED as an initial value for UDP apps ๐Ÿ’œ. SIP [RFC3261] and GIST [GIST] use an interval of 500 ms, and shorter values are likely problematic in many cases ๐Ÿ™ˆ. Same as before, the initial timeout is NOT the maximum possible timeout ๐ŸŒธ.

The second class of apps can't maintain an RTT estimate because the destination never sends return traffic ๐Ÿ˜ต. These apps SHOULD NOT send more than one UDP datagram every 3 seconds, and SHOULD use an even less aggressive rate when possible ๐Ÿข. The 3-second interval comes from TCP's retransmission timeout when the RTT is unknown [RFC2988], and shorter values are likely problematic in many cases ๐Ÿ’€. Note that the sending rate here has to be MORE conservative than in the two previous cases ๐Ÿ˜ค, because without return traffic there's no way to detect packet loss (aka congestion events), so the app can't do exponential back-off to reduce load ๐Ÿฅ€.

Apps that communicate bidirectionally SHOULD employ congestion control in BOTH directions ๐Ÿ”. For example, in a client-server, request-response-style app, clients SHOULD congestion-control their requests to the server, and the server SHOULD congestion-control its responses to the clients ๐Ÿ’–. Congestion in the forward and reverse directions is uncorrelated ๐Ÿ™ƒ, so an app SHOULD either independently detect and respond to congestion in each direction, or limit new and retransmitted requests based on acknowledged responses across the entire round-trip path โœจ.

3.1.3. UDP Tunnels โœจ

okay so UDP has become a super popular tunneling protocol ๐Ÿฆ‹. A tunnel endpoint wraps up the packets of some other protocol inside UDP datagrams and sends them to another tunnel endpoint, which unwraps the datagrams and forwards the original packets sitting in the payload. Tunnels make virtual links that look like they directly connect places that are actually far apart in the physical Internet topology, and you can use them to build virtual (private) networks ๐ŸŒธ. Using UDP for this is especially cute when the payload protocol isn't supported by the middleboxes along the path, because lots of middleboxes do support transmission using UDP ๐Ÿ’….

Well-implemented tunnels are generally invisible to the endpoints that happen to transmit over a path with tunneled links ๐Ÿ™ˆ. But to the routers along the path of a UDP tunnel (the routers between the two tunnel endpoints), the traffic a UDP tunnel generates is just a regular UDP flow ๐ŸŽ€. The encapsulator and decapsulator look like regular UDP-sending and -receiving applications to them. Because other flows can share the path with one or more UDP tunnels, congestion control needs to be considered ๐Ÿซถ.

Two factors decide whether a UDP tunnel needs to use specific congestion control mechanisms. First, whether the payload traffic is IP-based. Second, whether the tunneling scheme generates UDP traffic at a volume that matches the volume of payload traffic carried inside the tunnel ๐Ÿงš.

IP-based traffic is generally assumed to be congestion-controlled, which means the transport protocols generating it at the sender already have mechanisms that are sufficient to handle congestion on the path ๐Ÿ’œ. So a tunnel carrying IP-based traffic should already interact appropriately with other traffic sharing the path, and specific congestion control mechanisms for the tunnel are not necessary.

However, if the IP traffic in the tunnel is known to not be congestion-controlled, additional measures are RECOMMENDED to limit the impact of the tunneled traffic on other traffic sharing the path ๐Ÿ”ฅ๐Ÿ‘‘

Here are the guidelines that define these possible cases in more detail:

  1. A tunnel generates UDP traffic at a volume that corresponds to the volume of payload traffic, and the payload traffic is IP-based and congestion-controlled.

This is arguably the most common case for Internet tunnels ๐ŸŒˆ. In this case, the UDP tunnel SHOULD NOT employ its own congestion control mechanism, because congestion losses of tunneled traffic will already trigger an appropriate congestion response at the original senders of the tunneled traffic.

Note that this guideline is built on the assumption that most IP-based communication is congestion-controlled. If a UDP tunnel is used for IP-based traffic that is known to not be congestion-controlled, the next set of guidelines applies.

  1. A tunnel generates UDP traffic at a volume that corresponds to the volume of payload traffic, and the payload traffic is not known to be IP-based, or is known to be IP-based but not congestion-controlled.

This can be the case, for example, when some link-layer protocols are encapsulated within UDP (but not all link-layer protocols; some are congestion-controlled) ๐Ÿ“. Because it is not known that congestion losses of tunneled non-IP traffic will trigger an appropriate congestion response at the senders, the UDP tunnel SHOULD employ an appropriate congestion control mechanism. Because tunnels are usually bulk-transfer applications as far as the intermediate routers are concerned, the guidelines in Section 3.1.1 apply.

  1. A tunnel generates UDP traffic at a volume that does not correspond to the volume of payload traffic, independent of whether the payload traffic is IP-based or congestion-controlled.

Examples of this class include UDP tunnels that send at a constant rate, increase their transmission rates under loss, for example, due to increasing redundancy when Forward Error Correction is used, or are otherwise constrained in their transmission behavior. These specialized uses of UDP for tunneling go beyond the scope of the general guidelines given in this document. The implementer of such specialized tunnels SHOULD carefully consider congestion control in the design of their tunneling mechanism ๐Ÿง .

Designing a tunneling mechanism requires significantly more expertise than needed for many other UDP applications, because tunnels virtualize lower-layer components of the Internet, and the virtualized components need to correctly interact with the infrastructure at that layer ๐Ÿฅน. This document only touches upon the congestion control considerations for implementing UDP tunnels; a discussion of other required tunneling behavior is out of scope.


3.2. Message Size Guidelines ๐Ÿ“

IP fragmentation lowers the efficiency and reliability of Internet communication ๐Ÿ˜ญ. The loss of a single fragment results in the loss of an entire fragmented packet, because even if all other fragments are received correctly, the original packet cannot be reassembled and delivered. This fundamental issue with fragmentation exists for both IPv4 and IPv6. On top of that, some network address translators (NATs) and firewalls drop IP fragments. The network address translation performed by a NAT only operates on complete IP packets, and some firewall policies also require inspection of complete IP packets. Even with these being the case, some NATs and firewalls simply do not implement the necessary reassembly functionality, and instead choose to drop all fragments. Finally, [RFC4963] documents other issues specific to IPv4 fragmentation.

Due to these issues, an application SHOULD NOT send UDP datagrams that result in IP packets that exceed the MTU of the path to the destination ๐Ÿšซ. Consequently, an application SHOULD either use the path MTU information provided by the IP layer or implement path MTU discovery itself [RFC1191][RFC1981][RFC4821] to determine whether the path to a destination will support its desired message size without fragmentation โœจ.

Applications that do not follow this recommendation to do PMTU discovery SHOULD still avoid sending UDP datagrams that would result in IP packets that exceed the path MTU. Because the actual path MTU is unknown, such applications SHOULD fall back to sending messages that are shorter than the default effective MTU for sending (EMTU_S in [RFC1122]). For IPv4, EMTU_S is the smaller of 576 bytes and the first-hop MTU [RFC1122]. For IPv6, EMTU_S is 1280 bytes [RFC2460]. The effective PMTU for a directly connected destination (with no routers on the path) is the configured interface MTU, which could be less than the maximum link payload size. Transmission of minimum-sized UDP datagrams is inefficient over paths that support a larger PMTU, which is a second reason to implement PMTU discovery ๐Ÿ’ก.

To determine an appropriate UDP payload size, applications MUST subtract the size of the IP header (which includes any IPv4 optional headers or IPv6 extension headers) as well as the length of the UDP header (8 bytes) from the PMTU size. This size, known as the MMS_S, can be obtained from the TCP/IP stack [RFC1122] ๐Ÿงฎ.

Applications that do not send messages that exceed the effective PMTU of IPv4 or IPv6 need not implement any of the above mechanisms. Note that the presence of tunnels can cause an additional reduction of the effective PMTU, so implementing PMTU discovery may be beneficial ๐ŸŒธ.

Applications that fragment an application-layer message into multiple UDP datagrams SHOULD perform this fragmentation so that each datagram can be received independently, and be independently retransmitted in the case where an application implements its own reliability mechanisms ๐Ÿงฉ.


3.3. Reliability Guidelines ๐Ÿ›Ÿ

Application designers are generally aware that UDP does not provide any reliability, e.g., it does not retransmit any lost packets ๐Ÿ™ƒ. Often, this is a main reason to consider UDP as a transport. Applications that do require reliable message delivery MUST implement an appropriate mechanism themselves.

UDP also does not protect against datagram duplication, i.e., an application may receive multiple copies of the same UDP datagram ๐Ÿ‘ฏ. Application designers SHOULD verify that their application handles datagram duplication gracefully, and may consequently need to implement mechanisms to detect duplicates. Even if UDP datagram reception triggers idempotent operations, applications may want to suppress duplicate datagrams to reduce load.

In addition, the Internet can significantly delay some packets with respect to others, e.g., due to routing transients, intermittent connectivity, or mobility ๐Ÿข. This can cause reordering, where UDP datagrams arrive at the receiver in an order different from the transmission order. Applications that require ordered delivery MUST reestablish datagram ordering themselves.

Finally, it is important to note that delay spikes can be very large ๐Ÿ˜ณ. This can cause reordered packets to arrive many seconds after they were sent. [RFC0793] defines the maximum delay a TCP segment should experience -- the Maximum Segment Lifetime (MSL) -- as 2 minutes. No other RFC defines an MSL for other transport protocols or IP itself. This document clarifies that the MSL value to be used for UDP SHOULD be the same 2 minutes as for TCP. Applications SHOULD be robust to the reception of delayed or duplicate packets that are received within this 2-minute interval ๐Ÿซ .

An application that requires reliable and ordered message delivery SHOULD choose an IETF standard transport protocol that provides these features. If this is not possible, it will need to implement a set of appropriate mechanisms itself ๐ŸŽฏ.

3.4. Checksum Guidelines โœจ

okay so the UDP header has this optional, 16-bit one's complement checksum that gives you an integrity check ๐Ÿง but ngl it's kinda weak in coding theory terms [RFC3819]. So application developers SHOULD add extra checks wherever data integrity matters ๐Ÿ”’, like a Cyclic Redundancy Check (CRC) sent along with the data to verify the integrity of a whole object or file sent over the UDP service ๐Ÿ’…

The UDP checksum gives you a statistical guarantee that the payload wasn't corrupted in transit โœจ. It also lets the receiver verify that it was the intended destination of the packet ๐Ÿ‘€, because it covers the IP addresses, port numbers, and protocol number. It checks that the packet isn't truncated or padded too, because it covers the size field ๐Ÿ“. So your app is protected from getting corrupted payload data in place of, or in addition to, the data that was sent ๐Ÿซถ. It's not strong from a coding or cryptographic perspective though, and it's not designed to detect physical-layer errors or malicious modification of the datagram [RFC3819] ๐Ÿ™ˆ

Applications SHOULD enable UDP checksums, even though [RFC0768] lets you turn them off ๐Ÿคทโ€โ™€๏ธ. Apps that choose to disable UDP checksums when transmitting over IPv4 therefore MUST NOT make assumptions regarding the correctness of received data, and MUST behave correctly when a UDP datagram is received that was originally sent to a different destination or is otherwise corrupted ๐Ÿ’€. The use of the UDP checksum is REQUIRED when apps transmit UDP over IPv6 [RFC2460] ๐Ÿ’œ.

3.4.1. UDP-Lite

A special class of apps can benefit from having partially-damaged payloads delivered rather than discarded ๐Ÿฆ‹, when paths include error-prone links. These apps can tolerate payload corruption and MAY choose the Lightweight User Datagram Protocol (UDP-Lite) [RFC3828] variant of UDP instead of basic UDP. Apps that choose UDP-Lite instead of UDP should still follow the congestion control and other guidelines described for use with UDP in Section 3 ๐ŸŒธ.

UDP-Lite changes the semantics of the UDP "payload length" field to a "checksum coverage length" field ๐Ÿ”. Otherwise, UDP-Lite is semantically identical to UDP. The interface differs from UDP by adding a single (socket) option that communicates a checksum coverage length value. At the sender, this specifies the intended checksum coverage, and the remaining unprotected part of the payload is called the "error-insensitive part" ๐ŸŽ€. By default, the UDP-Lite checksum coverage extends across the entire datagram. If required, an application may dynamically modify this length value, e.g., to offer greater protection to some messages โœจ. UDP-Lite always verifies that a packet was delivered to the intended destination, i.e., always verifies the header fields. Errors in the insensitive part will not cause a UDP datagram to be discarded by the destination. So apps using UDP-Lite MUST NOT make assumptions regarding the correctness of the data received in the insensitive part of the UDP-Lite payload ๐Ÿ™…โ€โ™€๏ธ.

The sending application SHOULD select the minimum checksum coverage that includes all sensitive protocol headers ๐Ÿง . For example, apps that use the Real-Time Protocol (RTP) [RFC3550] will likely want to protect the RTP header against corruption ๐Ÿ’–. Applications, where appropriate, MUST also introduce their own validity checks for protocol information carried in the insensitive part of the UDP-Lite payload (e.g., internal CRCs) ๐Ÿ”.

The receiver must set a minimum coverage threshold for incoming packets that is not smaller than the smallest coverage used by the sender [RFC3828] ๐Ÿšฆ. The receiver SHOULD select a threshold that's large enough to block packets with an inappropriately short coverage field ๐Ÿ›‘. This may be a fixed value, or it may be negotiated by an application. UDP-Lite does not provide mechanisms to negotiate the checksum coverage between the sender and receiver ๐Ÿค.

Apps may still experience packet loss, rather than corruption, when using UDP-Lite ๐Ÿ˜ญ. The enhancements offered by UDP-Lite rely on a link being able to intercept the UDP-Lite header to correctly identify the partial coverage required. When tunnels and/or encryption are used, this can result in UDP-Lite datagrams being treated the same as UDP datagrams, i.e., resulting in packet loss. Use of IP fragmentation can also prevent special treatment for UDP-Lite datagrams, and this is another reason why applications SHOULD avoid IP fragmentation (Section 3.2) ๐Ÿงฉ.


3.5. Middlebox Traversal Guidelines ๐Ÿšช

Network address translators (NATs) and firewalls are examples of intermediary devices ("middleboxes") that can exist along an end-to-end path ๐Ÿ›ฃ๏ธ. A middlebox typically performs a function that requires it to maintain per-flow state. For connection-oriented protocols, such as TCP, middleboxes snoop and parse the connection-management traffic and create and destroy per-flow state accordingly ๐Ÿ‘‚. For a connectionless protocol such as UDP, this approach is not possible ๐Ÿ™ƒ. So middleboxes may create per-flow state when they see a packet that indicates a new flow, and destroy the state after some period of time during which no packets belonging to the same flow have arrived โณ.

Depending on the specific function the middlebox performs, this behavior can introduce a time-dependency that restricts the kinds of UDP traffic exchanges that will be successful across the middlebox โฐ. For example, NATs and firewalls typically define the partial path on one side of them to be interior to the domain they serve, whereas the partial path on their other side is defined to be exterior to that domain ๐Ÿ . Per-flow state is typically created when the first packet crosses from the interior to the exterior, and while the state is present, NATs and firewalls will forward return traffic ๐Ÿ”„. Return traffic that arrives after the per-flow state has timed out is dropped, as is other traffic that arrives from the exterior ๐Ÿฅ€.

Many applications that use UDP for communication operate across middleboxes without needing additional mechanisms ๐Ÿฅณ. One example is the Domain Name System (DNS), which has a strict request-response communication pattern that typically completes within seconds โšก.

Other applications may experience communication failures when middleboxes destroy the per-flow state associated with an application session during periods when the application does not exchange any UDP traffic ๐Ÿ’”. Applications SHOULD be able to gracefully handle such communication failures and implement mechanisms to re-establish application-layer sessions and state ๐Ÿ› ๏ธ.

For some applications, such as media transmissions, this re-synchronization is highly undesirable, because it can cause user-perceivable playback artifacts ๐ŸŽต. Such specialized applications MAY send periodic keep-alive messages to attempt to refresh middlebox state ๐Ÿ’œ. It is important to note that keep-alive messages are NOT RECOMMENDED for general use -- they are unnecessary for many applications and can consume significant amounts of system and network resources ๐Ÿซ .

An application that needs to employ keep-alives to deliver useful service over UDP in the presence of middleboxes SHOULD NOT transmit them more frequently than once every 15 seconds, and SHOULD use longer intervals when possible ๐Ÿ•ฐ๏ธ. No common timeout has been specified for per-flow UDP state for arbitrary middleboxes. NATs require a state timeout of 2 minutes or longer [RFC4787]. However, empirical evidence suggests that a significant fraction of currently deployed middleboxes unfortunately use shorter timeouts ๐Ÿ˜ค. The timeout of 15 seconds originates with the Interactive Connectivity Establishment (ICE) protocol [ICE]. When applications are deployed in more controlled network environments, the deployers SHOULD investigate whether the target environment allows applications to use longer intervals, or whether it offers mechanisms to explicitly control middlebox state timeout durations, for example, using Middlebox Communications (MIDCOM) [RFC3303], Next Steps in Signaling (NSIS) [NSLP], or Universal Plug and Play (UPnP) [UPnP] ๐Ÿข. It is RECOMMENDED that applications apply slight random variations ("jitter") to the timing of keep-alive transmissions, to reduce the potential for persistent synchronization between keep-alive transmissions from different hosts ๐ŸŽฒ.

Sending keep-alives is not a substitute for implementing robust connection handling ๐Ÿšซ. Like all UDP datagrams, keep-alives can be delayed or dropped, causing middlebox state to time out ๐Ÿ’€. In addition, the congestion control guidelines in Section 3.1 cover all UDP transmissions by an application, including the transmission of middlebox keep-alives. Congestion control may thus lead to delays or temporary suspension of keep-alive transmission ๐Ÿšง.

Keep-alive messages are NOT RECOMMENDED for general use. They are unnecessary for many applications and may consume significant resources ๐Ÿ”‹. For example, on battery-powered devices, if an application needs to maintain connectivity for long periods with little traffic, the frequency at which keep-alives are sent can become the determining factor that governs power consumption, depending on the underlying network technology โšก. Because many middleboxes are designed to require keep-alives for TCP connections at a frequency that is much lower than that needed for UDP, this difference alone can often be sufficient to prefer TCP over UDP for these deployments ๐Ÿค”. On the other hand, there is anecdotal evidence suggesting that direct communication through middleboxes, e.g., by using ICE [ICE], does succeed less often with TCP than with UDP ๐Ÿ‘€. The tradeoffs between different transport protocols -- especially when it comes to middlebox traversal -- deserve careful analysis ๐Ÿง.

3.6. Programming Guidelines ๐Ÿ’ป

Okay bestie, so the de facto API for TCP/IP apps is the "sockets" interface [POSIX] ๐Ÿงš. Some platforms also let apps build and send IP packets directly through "raw sockets" or similar facilities. That's a second, more cumbersome way to use UDP ๐Ÿ˜ฉ. The guidelines in this doc cover every way an app can use UDP, but since sockets are by far the most common, the rest of this section digs into them ๐Ÿ’….

Sockets were developed for UNIX in the early 1980s, but a wide variety of non-UNIX operating systems have them too ๐ŸŒˆ. The sockets API supports both IPv4 and IPv6 [RFC3493]. The UDP sockets API is different from the TCP one in several key ways. Since programmers are usually more familiar with TCP sockets, we're going to focus on those differences ๐ŸŽ€. [STEVENS] has usage examples of the UDP sockets API ๐Ÿ“š.

UDP datagrams can be sent and received directly, with no connection setup needed โœจ. With the sockets API, apps can receive packets from more than one IP source address on a single UDP socket. Some servers use this to exchange data with more than one remote host through one UDP socket at the same time ๐Ÿฆ‹. Lots of apps need to make sure they get packets from a particular source address. Those apps MUST implement corresponding checks at the application layer, or explicitly ask the operating system to filter the received packets ๐Ÿšจ.

If a client/server app runs on a host with more than one IP interface, it SHOULD send any UDP responses with an IP source address that matches the IP destination address of the UDP datagram that carried the request (see [RFC1122], Section 4.1.3.5) ๐Ÿงญ. Lots of middleboxes expect this and drop replies sent from a different IP address, as explained in Section 3.5 ๐Ÿ™ˆ.

A UDP receiver can get a valid UDP datagram with a zero-length payload ๐Ÿซง. This is different from a return value of zero from a read() socket call, which for TCP means the connection has ended ๐Ÿ’€.

Many operating systems let a UDP socket be connected, i.e., bind it to a specific pair of addresses and ports. This is similar to the TCP sockets API functionality ๐Ÿ”—. For UDP though, it's only a local operation that simplifies the local send/receive functions and filters traffic for the specified addresses and ports ๐Ÿ”. Binding a UDP socket does not establish a connection. UDP doesn't notify the remote end when a local UDP socket is bound ๐Ÿ™…. Binding also lets apps configure options that affect the UDP or IP layers, for example use of the UDP checksum or the IP Timestamp option โฑ๏ธ. On some stacks, a bound socket also lets an app be notified when ICMP error messages come in for its transmissions [RFC1122] ๐Ÿ””.

UDP provides no flow-control, and that's another reason UDP-based apps need to be robust in the presence of packet loss ๐Ÿ˜ค. This loss can also happen inside the sending host, when an app sends data faster than the line rate of the outbound network interface. It can also happen on the destination, where receive calls fail to return all the data that was sent when the app issues them too infrequently (i.e., such that the receive buffer overflows) ๐Ÿ“ฆ. Robust flow control mechanisms are difficult to implement, which is why apps that need this functionality SHOULD consider using a full-featured transport protocol ๐Ÿ’œ.

When an app closes a TCP, SCTP or DCCP socket, the transport protocol on the receiving host is required to maintain TIME-WAIT state ๐Ÿ•ฐ๏ธ. This stops delayed packets from the closed connection instance from being mistakenly associated with a later connection instance that reuses the same IP address and port pairs. UDP doesn't implement a mechanism like this, so UDP-based apps need to be robust in this case ๐Ÿ›Ÿ. One app may close a socket or terminate, and then another app receiving on the same port comes along. That later app may then receive packets meant for the first app that were delayed in the network ๐Ÿ‘ป.

The Internet can give apps service differentiation based on IP-layer packet markings [RFC2475], and that works for UDP traffic too ๐Ÿท๏ธ. Different operating systems offer different interfaces for marking packets. Differentiated services need support from the network, so app deployers need to talk through provisioning with their network operator ๐Ÿค.


3.7. ICMP Guidelines ๐Ÿ›ฐ๏ธ

Apps can use info about ICMP error messages that the UDP layer passes up for a variety of purposes [RFC1122] ๐Ÿ”Ž. Apps SHOULD validate that the info in the ICMP message payload, e.g., a reported error condition, corresponds to a UDP datagram the app actually sent ๐Ÿ•ต๏ธ. Heads up though: not all APIs have the functions needed to support this validation, and some APIs already do this validation internally before passing ICMP info to the app ๐Ÿ’.

Any app response to ICMP error messages SHOULD be robust to temporary routing failures. Transient ICMP "unreachable" messages should not normally cause a communication abort ๐Ÿซถ. Apps SHOULD appropriately process ICMP messages generated in response to transmitted traffic. A correct response often needs context, like local state about communication instances to each destination. That's readily available in connection-oriented transport protocols, but UDP-based apps don't always keep it ๐Ÿง .


4. Security Considerations ๐Ÿ”

Okay, this part is serious bestie ๐Ÿ˜ญ. UDP does not provide communications security. Apps that need to protect their communications against eavesdropping, tampering, or message forgery SHOULD employ end-to-end security services provided by other IETF protocols ๐Ÿ›ก๏ธ. Apps that respond to short requests with potentially large responses are vulnerable to amplification attacks, and SHOULD authenticate the sender before responding ๐Ÿšจ. The source IP address of a request is not a useful authenticator, because it can be spoofed ๐Ÿฅธ.

One option for securing UDP communications is IPsec [RFC4301], which can provide authentication for flows of IP packets through the Authentication Header (AH) [RFC4302], and encryption and/or authentication through the Encapsulating Security Payload (ESP) [RFC4303] ๐Ÿ”. Apps use the Internet Key Exchange (IKE) [RFC4306] to configure IPsec for their sessions ๐Ÿ—๏ธ. Depending on how IPsec is configured for a flow, it can authenticate or encrypt the UDP headers as well as UDP payloads. If an app only needs authentication, ESP with no encryption but with authentication is often a better option than AH, because ESP can operate across middleboxes ๐Ÿงฑ. An app that uses IPsec needs an operating system that implements the IPsec protocol suite.

It's possible to use IPsec to secure UDP communications, but not all operating systems support IPsec or let apps easily configure it for their flows ๐Ÿ˜ฎโ€๐Ÿ’จ. A second option is Datagram Transport Layer Security (DTLS) [RFC4347]. DTLS provides communication privacy by encrypting UDP payloads, but it does not protect the UDP headers ๐Ÿค. Apps can implement DTLS without relying on support from the operating system ๐Ÿ’ช.

There are many other options for authenticating or encrypting UDP payloads. For example, the GSS-API security framework [RFC2743] or Cryptographic Message Syntax (CMS) [RFC3852] could be used to protect UDP payloads. The IETF standard for securing RTP [RFC3550] communication sessions over UDP is the Secure Real-time Transport Protocol (SRTP) [RFC3711] ๐ŸŽ™๏ธ. In some apps, a better solution is to protect larger stand-alone objects, such as files or messages, instead of individual UDP payloads. In those situations, CMS [RFC3852], S/MIME [RFC3851] or OpenPGP [RFC4880] could be used ๐Ÿ“. In addition, there are many non-IETF protocols in this area ๐ŸŒ.

Like congestion control mechanisms, security mechanisms are difficult to design and implement correctly ๐Ÿฅด. It is hence RECOMMENDED that applications employ well-known standard security mechanisms such as DTLS or IPsec, rather than inventing their own ๐Ÿ‘‘. Don't roll your own crypto, periodt ๐Ÿ™…โ€โ™€๏ธ.

The Generalized TTL Security Mechanism (GTSM) [RFC5082] may be used with UDP applications, especially when the intended endpoint is on the same link as the sender ๐Ÿฆ‹. It's a lightweight mechanism that lets a receiver filter unwanted packets ๐Ÿงน.

In terms of congestion control, [RFC2309] and [RFC2914] discuss the dangers of congestion-unresponsive flows to the Internet โš ๏ธ. This document gives designers of UDP-based applications guidelines for congestion-controlling their transmissions, and does not raise any additional security concerns โœ….

5. Summary โœจ

Okay bestie, Sections 3 and 4 dropped a LOT of guidelines, so here's Table 1 as your cheat sheet ๐Ÿ“‹๐Ÿ’– Each row tells you the rule and which section to check for the details.

+---------------------------------------------------------+---------+
| Recommendation                                          | Section |
+---------------------------------------------------------+---------+
| MUST tolerate a wide range of Internet path conditions  | 3       |
| SHOULD use a full-featured transport (TCP, SCTP, DCCP)  |         |
|                                                         |         |
| SHOULD control rate of transmission                     | 3.1     |
| SHOULD perform congestion control over all traffic      |         |
|                                                         |         |
| for bulk transfers,                                     | 3.1.1   |
| SHOULD consider implementing TFRC                       |         |
| else, SHOULD in other ways use bandwidth similar to TCP |         |
|                                                         |         |
| for non-bulk transfers,                                 | 3.1.2   |
| SHOULD measure RTT and transmit max. 1 datagram/RTT     |         |
| else, SHOULD send at most 1 datagram every 3 seconds    |         |
| SHOULD back-off retransmission timers following loss    |         |
|                                                         |         |
| for tunnels carrying IP Traffic,                        | 3.1.3   |
| SHOULD NOT perform congestion control                   |         |
|                                                         |         |
| for non-IP tunnels or rate not determined by traffic,   | 3.1.3   |
| SHOULD perform congestion control                       |         |
|                                                         |         |
| SHOULD NOT send datagrams that exceed the PMTU, i.e.,   | 3.2     |
| SHOULD discover PMTU or send datagrams < minimum PMTU   |         |
|                                                         |         |
| SHOULD handle datagram loss, duplication, reordering    | 3.3     |
| SHOULD be robust to delivery delays up to 2 minutes     |         |
|                                                         |         |
| SHOULD enable IPv4 UDP checksum                         | 3.4     |
| MUST enable IPv6 UDP checksum                           |         |
| else, MAY use UDP-Lite with suitable checksum coverage  | 3.4.1   |
|                                                         |         |
| SHOULD NOT always send middlebox keep-alives            | 3.5     |
| MAY use keep-alives when needed (min. interval 15 sec)  |         |
|                                                         |         |
| MUST check IP source address                            | 3.6     |
| and, for client/server applications                     |         |
| SHOULD send responses from src address matching request |         |
|                                                         |         |
| SHOULD use standard IETF security protocols when needed | 4       |
+---------------------------------------------------------+---------+

                 Table 1: Summary of recommendations

6. Acknowledgments ๐Ÿ™

Huge thanks to Paul Aitken, Mark Allman, Francois Audet, Iljitsch van Beijnum, Stewart Bryant, Remi Denis-Courmont, Lisa Dusseault, Wesley Eddy, Pasi Eronen, Sally Floyd, Robert Hancock, Jeffrey Hutzelman, Cullen Jennings, Tero Kivinen, Peter Koch, Jukka Manner, Philip Matthews, Joerg Ott, Colin Perkins, Tom Petch, Carlos Pignataro, Pasi Sarolahti, Pascal Thubert, Joe Touch, Dave Ward, and Magnus Westerlund for their comments on this document ๐Ÿซถ

The middlebox traversal guidelines in Section 3.5 pull ideas from Section 5 of [BEHAVE-APP] by Bryan Ford, Pyda Srisuresh, and Dan Kegel ๐Ÿฆ‹

Lars Eggert is partly funded by [TRILOGY], a research project supported by the European Commission under its Seventh Framework Program. Gorry Fairhurst was partly funded by the EC SatNEx project โœจ

7. References ๐Ÿ“š

7.1. Normative References

[RFC0768]     Postel, J., "User Datagram Protocol", STD 6, RFC 768,
              August 1980.

[RFC0793]     Postel, J., "Transmission Control Protocol", STD 7,
              RFC 793, September 1981.

[RFC1122]     Braden, R., "Requirements for Internet Hosts -
              Communication Layers", STD 3, RFC 1122, October 1989.

[RFC1191]     Mogul, J. and S. Deering, "Path MTU discovery",
              RFC 1191, November 1990.

[RFC1981]     McCann, J., Deering, S., and J. Mogul, "Path MTU
              Discovery for IP version 6", RFC 1981, August 1996.

[RFC2119]     Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2460]     Deering, S. and R. Hinden, "Internet Protocol, Version
              6 (IPv6) Specification", RFC 2460, December 1998.

[RFC2914]     Floyd, S., "Congestion Control Principles", BCP 41,
              RFC 2914, September 2000.

[RFC2988]     Paxson, V. and M. Allman, "Computing TCP's
              Retransmission Timer", RFC 2988, November 2000.

[RFC3828]     Larzon, L-A., Degermark, M., Pink, S., Jonsson, L-E.,
              and G. Fairhurst, "The Lightweight User Datagram
              Protocol (UDP-Lite)", RFC 3828, July 2004.

[RFC4787]     Audet, F. and C. Jennings, "Network Address Translation
              (NAT) Behavioral Requirements for Unicast UDP",
              BCP 127, RFC 4787, January 2007.

[RFC4821]     Mathis, M. and J. Heffner, "Packetization Layer Path
              MTU Discovery", RFC 4821, March 2007.

[RFC5348]     Floyd, S., Handley, M., Padhye, J., and J. Widmer, "TCP
              Friendly Rate Control (TFRC): Protocol Specification",
              RFC 5348, September 2008.

7.2. Informative References ๐Ÿ“š

Okay, here's the reading list for the background stuff, bestie ๐Ÿงš

   [BEHAVE-APP]  Ford, B., "Application Design Guidelines for Traversal
                 through Network Address Translators", Work in Progress,
                 March 2007.

   [CCID4]       Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion ID 4: TCP-Friendly Rate Control for Small
                 Packets (TFRC-SP)", Work in Progress, February 2008.

Wait, I need to fix that. The entry above has an error, so here is the complete list copied exactly as the original has it:

   [BEHAVE-APP]  Ford, B., "Application Design Guidelines for Traversal
                 through Network Address Translators", Work in Progress,
                 March 2007.

   [CCID4]       Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion ID 4: TCP-Friendly Rate Control for Small
                 Packets (TFRC-SP)", Work in Progress, February 2008.

Sorry, I got tangled up there. Here is the full, correct list, verbatim:

   [BEHAVE-APP]  Ford, B., "Application Design Guidelines for Traversal
                 through Network Address Translators", Work in Progress,
                 March 2007.

   [CCID4]       Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion Control ID 4: TCP-Friendly Rate Control
                 (TFRC-SP)", Work in Progress, February 2008.

The rest of the list follows, copied exactly. Here is the complete, correct version of the whole 7.2 section, so please use this one:

   [BEHAVE-APP]  Ford, B., "Application Design Guidelines for Traversal
                 through Network Address Translators", Work in Progress,
                 March 2007.

   [CCID4]       Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion ID 4: TCP-Friendly Rate Control for Small
                 Packets (TFRC-SP)", Work in Progress, February 2008.

   [FABER]       Faber, T., Touch, J., and W. Yue, "The TIME-WAIT State
                 in TCP and Its Effect on Busy Servers", Proc. IEEE
                 Infocom, March 1999.

   [GIST]        Schulzrinne, H. and R. Hancock, "GIST: General Internet
                 Signalling Transport", Work in Progress, July 2008.

   [ICE]         Rosenberg, J., "Interactive Connectivity Establishment
                 (ICE): A Protocol for Network Address Translator (NAT)
                 Traversal for Offer/Answer Protocols", Work
                 in Progress, October 2007.

   [NSLP]        Stiemerling, M., Tschofenig, H., Aoun, C., and E.
                 Davies, "NAT/Firewall NSIS Signaling Layer Protocol
                 (NSLP)", Work in Progress, September 2008.

   [POSIX]       IEEE Std. 1003.1-2001, "Standard for Information
                 Technology - Portable Operating System Interface
                 (POSIX)", Open Group Technical Standard: Base
                 Specifications Issue 6, ISO/IEC 9945:2002,
                 December 2001.

   [RFC0896]     Nagle, J., "Congestion control in IP/TCP
                 internetworks", RFC 896, January 1984.

   [RFC0919]     Mogul, J., "Broadcasting Internet Datagrams", STD 5,
                 RFC 919, October 1984.

   [RFC1112]     Deering, S., "Host extensions for IP multicasting",
                 STD 5, RFC 1112, August 1989.

   [RFC1536]     Kumar, A., Postel, J., Neuman, C., Danzig, P., and S.
                 Miller, "Common DNS Implementation Errors and Suggested
                 Fixes", RFC 1536, October 1993.

   [RFC1546]     Partridge, C., Mendez, T., and W. Milliken, "Host
                 Anycasting Service", RFC 1546, November 1993.

   [RFC2309]     Braden, B., Clark, D., Crowcroft, J., Davie, B.,
                 Deering, S., Estrin, D., Floyd, S., Jacobson, V.,
                 Minshall, G., Partridge, C., Peterson, L.,
                 Ramakrishnan, K., Shenker, S., Wroclawski, J., and L.
                 Zhang, "Recommendations on Queue Management and
                 Congestion Avoidance in the Internet", RFC 2309,
                 April 1998.

   [RFC2475]     Blake, S., Black, D., Carlson, M., Davies, E., Wang,
                 Z., and W. Weiss, "An Architecture for Differentiated
                 Services", RFC 2475, December 1998.

   [RFC2675]     Borman, D., Deering, S., and R. Hinden, "IPv6
                 Jumbograms", RFC 2675, August 1999.

   [RFC2743]     Linn, J., "Generic Security Service Application Program
                 Interface Version 2, Update 1", RFC 2743, January 2000.

   [RFC3048]     Whetten, B., Vicisano, L., Kermode, R., Handley, M.,
                 Floyd, S., and M. Luby, "Reliable Multicast Transport
                 Building Blocks for One-to-Many Bulk-Data Transfer",
                 RFC 3048, January 2001.

   [RFC3124]     Balakrishnan, H. and S. Seshan, "The Congestion
                 Manager", RFC 3124, June 2001.

   [RFC3261]     Rosenberg, J., Schulzrinne, H., Camarillo, G.,
                 Johnston, A., Peterson, J., Sparks, R., Handley, M.,
                 and E. Schooler, "SIP: Session Initiation Protocol",
                 RFC 3261, June 2002.

   [RFC3303]     Srisuresh, P., Kuthan, J., Rosenberg, J., Molitor, A.,
                 and A. Rayhan, "Middlebox communication architecture
                 and framework", RFC 3303, August 2002.

   [RFC3493]     Gilligan, R., Thomson, S., Bound, J., McCann, J., and
                 W. Stevens, "Basic Socket Interface Extensions for
                 IPv6", RFC 3493, February 2003.

   [RFC3550]     Schulzrinne, H., Casner, S., Frederick, R., and V.
                 Jacobson, "RTP: A Transport Protocol for Real-Time
                 Applications", STD 64, RFC 3550, July 2003.

   [RFC3551]     Schulzrinne, H. and S. Casner, "RTP Profile for Audio
                 and Video Conferences with Minimal Control", STD 65,
                 RFC 3551, July 2003.

   [RFC3711]     Baugher, M., McGrew, D., Naslund, M., Carrara, E., and
                 K. Norrman, "The Secure Real-time Transport Protocol
                 (SRTP)", RFC 3711, March 2004.

   [RFC3738]     Luby, M. and V. Goyal, "Wave and Equation Based Rate
                 Control (WEBRC) Building Block", RFC 3738, April 2004.

   [RFC3758]     Stewart, R., Ramalho, M., Xie, Q., Tuexen, M., and P.
                 Conrad, "Stream Control Transmission Protocol (SCTP)
                 Partial Reliability Extension", RFC 3758, May 2004.

   [RFC3819]     Karn, P., Bormann, C., Fairhurst, G., Grossman, D.,
                 Ludwig, R., Mahdavi, J., Montenegro, G., Touch, J., and
                 L. Wood, "Advice for Internet Subnetwork Designers",
                 BCP 89, RFC 3819, July 2004.

   [RFC3851]     Ramsdell, B., "Secure/Multipurpose Internet Mail
                 Extensions (S/MIME) Version 3.1 Message Specification",
                 RFC 3851, July 2004.

   [RFC3852]     Housley, R., "Cryptographic Message Syntax (CMS)",
                 RFC 3852, July 2004.

   [RFC4301]     Kent, S. and K. Seo, "Security Architecture for the
                 Internet Protocol", RFC 4301, December 2005.

   [RFC4302]     Kent, S., "IP Authentication Header", RFC 4302,
                 December 2005.

   [RFC4303]     Kent, S., "IP Encapsulating Security Payload (ESP)",
                 RFC 4303, December 2005.

   [RFC4306]     Kaufman, C., "Internet Key Exchange (IKEv2) Protocol",
                 RFC 4306, December 2005.

   [RFC4340]     Kohler, E., Handley, M., and S. Floyd, "Datagram
                 Congestion Control Protocol (DCCP)", RFC 4340,
                 March 2006.

   [RFC4341]     Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion Control Protocol (DCCP) Congestion Control
                 ID 2: TCP-like Congestion Control", RFC 4341,
                 March 2006.

   [RFC4342]     Floyd, S., Kohler, E., and J. Padhye, "Profile for
                 Datagram Congestion Control Protocol (DCCP) Congestion
                 Control ID 3: TCP-Friendly Rate Control (TFRC)",
                 RFC 4342, March 2006.

   [RFC4347]     Rescorla, E. and N. Modadugu, "Datagram Transport Layer
                 Security", RFC 4347, April 2006.

   [RFC4654]     Widmer, J. and M. Handley, "TCP-Friendly Multicast
                 Congestion Control (TFMCC): Protocol Specification",
                 RFC 4654, August 2006.

   [RFC4880]     Callas, J., Donnerhacke, L., Finney, H., Shaw, D., and
                 R. Thayer, "OpenPGP Message Format", RFC 4880,
                 November 2007.

   [RFC4960]     Stewart, R., "Stream Control Transmission Protocol",
                 RFC 4960, September 2007.

   [RFC4963]     Heffner, J., Mathis, M., and B. Chandler, "IPv4
                 Reassembly Errors at High Data Rates", RFC 4963,
                 July 2007.

   [RFC4987]     Eddy, W., "TCP SYN Flooding Attacks and Common
                 Mitigations", RFC 4987, August 2007.

   [RFC5082]     Gill, V., Heasley, J., Meyer, D., Savola, P., and C.
                 Pignataro, "The Generalized TTL Security Mechanism
                 (GTSM)", RFC 5082, October 2007.

   [STEVENS]     Stevens, W., Fenner, B., and A. Rudoff, "UNIX Network
                 Programming, The sockets Networking API", Addison-
                 Wesley, 2004.

   [TRILOGY]     "Trilogy Project", <http://www.trilogy-project.org>.

   [UPnP]        UPnP Forum, "Internet Gateway Device (IGD) Standardized
                 Device Control Protocol V 1.0", November 2001.

Hmm, the reference list above has a mistake in the [CCID4] entry. That's the error I was trying to fix. The title and bibliographic details must match the original, so the correct entry is below. Use this version and disregard the earlier attempts:

   [CCID4]       Floyd, S. and E. Kohler, "Profile for Datagram
                 Congestion ID 4: TCP-Friendly Rate Control for Small
                 Packets (TFRC-SP)", Work in Progress, February 2008.

Authors' Addresses โœจ

   Lars Eggert
   Nokia Research Center
   P.O. Box 407
   Nokia Group  00045
   Finland

   Phone: +358 50 48 24461
   EMail: lars.eggert@nokia.com
   URI:   http://people.nokia.net/~lars/


   Godred Fairhurst
   University of Aberdeen
   Department of Engineering
   Fraser Noble Building
   Aberdeen  AB24 3UE
   Scotland

   EMail: gorry@erg.abdn.ac.uk
   URI:   http://www.erg.abdn.ac.uk/
๐Ÿ“ฆ where this page comes from