RFC 4336
Problem Statement for the Datagram Congestion Control Protocol (DCCP)
RFC 4336 ๐ Part 1 of 5
okay bestie, this one is Problem Statement for the Datagram Congestion Control Protocol (DCCP) ๐ It was written by S. Floyd (ICIR), M. Handley (UCL), and E. Kohler (UCLA). It's Informational, dated March 2006, and the header doesn't list anything it obsoletes or updates โจ
Status of This Memo ๐
this memo is info for the Internet community. it does not specify an Internet standard of any kind ๐ โโ๏ธ distribution is unlimited, so go wild ๐ฆ
Copyright Notice ยฉ๏ธ
Copyright (C) The Internet Society (2006) ๐
Abstract ๐ธ
this doc records, for the historical record, the reasoning behind DCCP, the Datagram Congestion Control Protocol ๐ง DCCP is an unreliable transport protocol with end-to-end congestion control built in. it gives you a congestion-controlled, unreliable flow of datagrams, which is perfect for things like streaming media and online games ๐ฎ
Table of Contents ๐
1. Introduction ....................................................2
2. Problem Space ...................................................3
2.1. Congestion Control for Unreliable Transfer .................4
2.2. Overhead ...................................................6
2.3. Firewall Traversal .........................................6
2.4. Parameter Negotiation ......................................7
3. Solution Space for Congestion Control of Unreliable Flows .......7
3.1. Providing Congestion Control Above UDP .....................8
3.1.1. The Burden on the Application Designer ..............8
3.1.2. Difficulties with ECN ...............................8
3.1.3. The Evasion of Congestion Control ..................10
3.2. Providing Congestion Control Below UDP ....................10
3.2.1. Case 1: Congestion Feedback at the Application .....11
3.2.2. Case 2: Congestion Feedback at a Layer Below UDP ...11
3.3. Providing Congestion Control at the Transport Layer .......12
3.3.1. Modifying TCP? .....................................12
3.3.2. Unreliable Variants of SCTP? .......................13
3.3.3. Modifying RTP? .....................................14
3.3.4. Designing a New Transport Protocol .................14
4. Selling Congestion Control to Reluctant Applications ...........15
5. Additional Design Considerations ...............................15
6. Transport Requirements of Request/Response Applications ........16
7. Summary of Recommendations .....................................17
8. Security Considerations ........................................18
9. Acknowledgements ...............................................18
Informative References ............................................19
1. Introduction ๐
okay so historically, most of the Internet's unicast traffic was congestion-controlled TCP, with UDP making up most of what was left ๐ UDP was mostly for short request-response stuff, like DNS and SNMP, where people wanted to skip TCP's three-way handshake, retransmission, and/or stateful connections ๐ UDP also skips TCP's built-in end-to-end congestion control, and UDP apps usually didn't build their own. but UDP traffic was tiny next to congestion-controlled TCP flows, so the network didn't collapse ๐ซถ
then recently, a bunch of apps started using UDP in a totally new way ๐ฅ think streaming audio, Internet telephony, and multiplayer and massively multiplayer online games. they all care more about timeliness than reliability โฑ๏ธ TCP can add arbitrary delay because of its reliability and in-order delivery rules, so these apps go with UDP instead ๐ this growth of long-lived traffic with no congestion control, compared to the congestion-controlled stuff, is a real threat to the overall health of the Internet [RFC2914, RFC3714] ๐ญ
apps could build their own congestion control, one case at a time, with the IETF cheering them on, and some already do ๐ but experience shows congestion control is hard to get right, and most app writers would rather not reinvent this particular wheel ๐ so we believe a new protocol is needed, one that combines unreliable datagram delivery with built-in congestion control โจ this protocol is an enabling technology, so existing and new apps can easily use it to move timely data without destabilizing the Internet ๐ฆ
this document is the problem statement for that protocol ๐ we list the properties the protocol should have, then explain why each one is necessary. we also explain why a new protocol is the best answer to the bigger problem of bringing congestion control to unreliable flows of unicast datagrams ๐ and we briefly cover the side requirements: mobility, defense against Denial of Service (DoS) attacks and spoofing, interoperation with RTP, and interactions with Network Address Translators (NATs) and firewalls ๐ง
one design preference we bring to all this is a preference for a clean, understandable, low-overhead, and minimal protocol ๐ as you'll see later, this means reliability or Forward Error Correction (FEC) gets layered on top instead of being built into the transport protocol itself ๐
this document started in 2002 as a formalization of the goals of DCCP, the Datagram Congestion Control Protocol [RFC4340] ๐ธ we meant DCCP to satisfy this problem statement, so the original reasoning behind lots of DCCP's design choices lives right here ๐ but we believed, and still believe, that the problem should be solved whether or not DCCP ends up being the chosen solution ๐
2. Problem Space ๐
we see a bunch of problems with using unreliable data flows on the Internet ๐ the big ones are:
- the potential for non-congestion-controlled datagram flows to cause congestion collapse of the network. (See Section 5 of [RFC2914] and Section 2 of [RFC3714].) ๐
- the difficulty of correctly implementing effective congestion control mechanisms for unreliable datagram flows ๐ค
- the lack of a standard solution for reliably transmitting congestion feedback for an unreliable data flow ๐ญ
- the lack of a standard solution for negotiating Explicit Congestion Notification (ECN) [RFC3168] usage for unreliable flows ๐ฉ๏ธ
- the lack of a choice of TCP-friendly congestion control mechanisms ๐ฅฒ
we assume most app writers would use congestion control for long-lived unreliable flows if it came in a standard, easy-to-use form ๐ซถ obviously they would, bestie ๐
there are also some smaller issues:
- the difficulty of deploying applications using UDP-based flows in the presence of firewalls ๐งฑ
- the desire to have a single way to negotiate congestion control parameters for unreliable flows, independent of whichever signalling protocol is used to set up the flow ๐ค
- the desire for low per-packet byte overhead ๐ชถ
the subsections below dig into these problems in more detail: providing congestion control, traversing firewalls, and negotiating parameters โจ a separate subsection also covers the problem of minimizing packet header overhead ๐
2.1. Congestion Control for Unreliable Transfer
okay bestie, the big goal here is bringing easy-to-use congestion control to apps that send large or long-lived streams of unreliable datagrams ๐, like RealAudio ๐ง, Internet telephony ๐, and multiplayer games ๐ฎ. The whole point is to avoid congestion collapse ๐. (Short flows from request-response apps like DNS and SNMP don't really cause congestion in practice ๐, and any congestion control would kick in between flows, not inside one single end-to-end transfer of info.) BUT before we design anything for these apps, we have to understand why they use unreliable datagrams in the first place, or we could totally wreck the very properties they need ๐ญ.
There are a few reasons protocols currently pick UDP over TCP, like:
- Startup Delay: they want to skip the delay of a three-way handshake before data starts flowing โจ.
- Statelessness: they want to avoid holding connection state, plus the potential state-holding attacks that come with it ๐ก๏ธ.
- Trading of Reliability against Timing: the data is timely, meaning if it isn't delivered by some deadline (usually a small number of RTTs), it won't be useful at the receiver โฐ.
Of these, apps making large or long-lived datagram flows, like media transfer and games, mostly care about balancing timing against reliability. They use UDP because they want to send the most appropriate data in each datagram ๐. If a datagram gets lost, they might or might not resend the same data, depending on whether it'll still be useful at the receiver. Data can stop being useful for lots of reasons:
- In a telephony or streaming video session, the data in a packet is a timeslice of a continuous stream. Once a timeslice has been played out, the next one is needed right away. If the data for that timeslice shows up later, it's no longer useful ๐. These apps can mask missing packets to some extent, so when the sender transmits its next packet, it's important that it only sends data with a good chance of arriving in time for playout ๐ฌ.
- In an interactive game or virtual-reality session, position info is transient ๐น๏ธ. If a datagram with position info is lost, resending the old position usually doesn't make sense -- instead, every position datagram should carry the latest position info ๐.
In a congestion-controlled flow, the allowed sending rate depends on measured network congestion. So some control gets handed over to the congestion control mechanism, which decides exactly when packets can go out. Still, apps can decide at transmission time which info goes into a packet. TCP doesn't allow that control, and these apps really demand it ๐ .
Often these apps (especially games and telephony) work on very short playout timescales. While they can usually adjust their transmission rate based on congestion feedback, there are constraints on how that adaptation can happen so the impact on session quality stays minimal. So they tend to need some say over the short-term dynamics of the congestion control algorithm, while still being fair to other traffic over medium timescales ๐ค. That control includes, but isn't limited to, some influence over which congestion control algorithm gets used -- for example, TCP-Friendly Rate Control (TFRC) [RFC3448] instead of strict TCP-like congestion control. (TFRC was standardized in the IETF as a congestion control mechanism that changes its sending rate more smoothly than TCP does, while still keeping long-term fair bandwidth sharing with TCP [RFC3448].) ๐ฆ
2.2. Overhead
The apps we care about often send compressed data or lots of small packets ๐ฆ. For example, when Internet telephony or streaming media run over low-bandwidth modem links, squishing the payload data is essential ๐๏ธ. For telephony and games, the requirement is low delay, so small packets go out frequently โก.
For example, a telephony app sending a 5.6 Kbps stream but wanting moderately low delay might send a packet every 20 ms, with only 14 data bytes in each one. On top of that, 20 bytes goes to the IP header, plus extra bytes for transport and/or application headers. Honestly, it's very desirable for an app like this to have a low-overhead transport protocol header ๐.
In some cases the right fix would be link-based packet header compression to squish the packet headers, though we can't guarantee that such compression is available on any particular link ๐คท.
Delaying data until a handshake completes is also potentially unnecessary overhead ๐. So a new protocol might let senders include some data on their initial datagrams ๐.
2.3. Firewall Traversal
Apps needing a flow of unreliable datagrams currently tend to use signalling protocols like RTSP [RFC2326], SIP [RFC3261], and H.323 alongside UDP for the data flow ๐. The initial setup request uses a signalling protocol to find the right remote end-system for the flow, sometimes after being redirected or relayed to other machines ๐.
Since UDP flows have no explicit setup and teardown, it's hard for firewalls to handle them properly ๐งฑ. Typically, the firewall has to parse RTSP, SIP, and H.323 to grab the info it needs to open a hole in the firewall ๐ณ๏ธ. Although, for bi-directional flows, the firewall can open a bi-directional hole if it gets a UDP packet from inside the firewall -- but then it can't easily tell when to close the hole again ๐ฌ.
We don't consider these major problems, but they're still issues app designers have to deal with ๐ซ . Right now, streaming media players try UDP first, then switch to TCP if UDP doesn't work out. Streaming over TCP is undesirable and can make the receiver temporarily stop playout while it "rebuffers" data โธ๏ธ. Telephony apps don't even have that option ๐ญ.
2.4. Parameter Negotiation
Different apps have different congestion control requirements, which may map to different congestion feedback ๐๏ธ. Examples include ECN capability and desired congestion control dynamics (the choice of algorithm and, therefore, the form of feedback info required). These parameters need to be reliably negotiated before congestion control can work correctly ๐.
Negotiation could be done with signalling protocols like SIP, RTSP, and H.323, but it would be nice to have one standard way of negotiating these transport parameters ๐. This matters a lot with ECN, because sending ECN-marked packets to a non-ECN-capable receiver can cause serious congestion problems for other flows ๐จ. We'll dig into the ECN issue more below ๐.
3. Solution Space for Congestion Control of Unreliable Flows โจ
So we want congestion control for unreliable flows, providing both ECN and a choice of congestion control forms, while keeping overhead reasonable in terms of packet size, state, and CPU processing ๐ง . There are a few options for end-to-end congestion control for the unicast traffic that currently uses UDP, depending on which layer provides the mechanism:
- Congestion control above UDP.
- Congestion control below UDP.
- Congestion control at the transport layer in an alternative to UDP.
We explore these below. The concerns raised in those discussions convinced us that the best way to provide congestion control for unreliable flows is at the transport layer, as an alternative to the use of UDP and TCP ๐.
3.1. Providing Congestion Control Above UDP
One possibility is providing congestion control at the application layer, or at some other layer above UDP. This would let the mechanism be tightly integrated with the app itself ๐งฉ.
3.1.1. The Burden on the Application Designer
A big downside of congestion control above UDP is that it puts an unnecessary burden on the application designer, who might be perfectly happy using congestion control from a lower layer ๐ฉ. If the app can rely on a lower layer that offers a choice between TCP-like or TFRC-like congestion control, and that offers ECN, many app designers would probably be super happy ๐ฅฐ.
The long history of debugging TCP implementations [RFC2525, PF01] makes the difficulties of implementing end-to-end congestion control abundantly clear ๐. It's clearly more robust for a lower layer to provide congestion control for the app. In rare cases there might be compelling reasons for the mechanism to live in the app itself, but we don't expect that to be the general case ๐ . For example, apps that use RTP over UDP might be just as happy if RTP itself implemented end-to-end congestion control. (See Section 3.3.3 for more discussion of RTP.) ๐
In addition to congestion control issues, there are also the firewall traversal and parameter negotiation problems discussed in Sections 2.3 and 2.4. Building on top of UDP means the app designer has to address those too ๐ซถ.
3.1.2. Difficulties with ECN ๐
Okay so there's a second problem with building congestion control on top of UDP ๐ฉ. You'd either have to give up ECN entirely, or let the app directly control the ECN field in the IP header ๐. Giving up ECN is a big no, bestie, because ECN is especially useful for unreliable flows, where the data sender won't retransmit a dropped packet ๐.
Here's the plot twist ๐: ECN can be useful even when the network doesn't support it. The ECN nonce makes that possible โจ. The data sender uses the nonce, plus feedback from the data receiver, to check that the receiver is correctly reporting all lost packets. This is super handy for unreliable delivery, where the receiver might otherwise have very little reason to report lost packets ๐ฅบ.
To let a layer above UDP use ECN, the UDP socket would need to let the application control the ECN field in the IP header ๐. Specifically, the application would need to decide whether the ECN-Capable Transport (ECT) codepoints get set in that field ๐ฆ.
The ECN deal is that senders who set the ECT codepoint MUST... wait, sorry, must (lowercase, because we're not doing BCP 14 drama here ๐) respond to Congestion Experienced (CE) codepoints by slowing down their sending rates ๐ข. So the ECT codepoint can only be safely set in a UDP packet's header if both of these things are guaranteed ๐ซถ:
- if a router sets the CE codepoint, the receiving IP layer passes that CE status up to the UDP layer, which passes it up to the receiving application at the data receiver; and
- when a packet with the CE codepoint set arrives, the receiving application takes the right congestion control action, like telling the data sender.
BUT (and this is giving major suspense ๐ญ), the UDP implementation at the data sender has no way of knowing whether the UDP implementation at the data receiver has been upgraded to pass CE status up to the application. It also can't know whether the application will actually use the conformant end-to-end congestion control that comes with using ECN ๐.
Without widespread deployment of mechanisms in routers that detect flows not using conformant congestion control, letting applications freely control the ECT codepoints for UDP packets would seem like an unnecessary opening for applications to use ECN while dodging end-to-end congestion control ๐ โโ๏ธ. So we've got a classic "chicken-and-egg" problem ๐๐ฅ: do we deploy policing mechanisms in routers first, or enable ECN for UDP flows first? Without those router policing mechanisms, we would not advise adding ECN-capability to UDP sockets at this time ๐ซ.
If there's no finer-grained way to handle a stretch of sustained congestion, one option is for routers to stop using ECN with UDP packets during the congested period and only use ECN with TCP or DCCP packets ๐ธ. That's a reasonable move if TCP or DCCP flows turn out to be more likely to be using conformant end-to-end congestion control than UDP flows are ๐ง. If routers did this, DCCP flows would be more likely to get the benefits of ECN during congestion than UDP flows would ๐.
3.1.3. The Evasion of Congestion Control ๐
Third problem, and it's a bit of a tea spill โ: relying on congestion control at the application level makes it somewhat easier for some users to dodge end-to-end congestion control ๐ค. We're not claiming a transport protocol like DCCP would always be implemented in the kernel, and we're not trying to measure how hard it is to modify kernel code versus code outside the kernel ๐คทโโ๏ธ. Still, we think putting congestion control at the transport level instead of the application level makes it just slightly less likely that users will bother modifying the code to avoid end-to-end congestion control ๐ก๏ธ.
3.2. Providing Congestion Control Below UDP ๐งฑ
Instead of building congestion control above UDP, there's another option: provide congestion control for unreliable applications at a layer below UDP, with the applications still using UDP as their transport protocol ๐. Since UDP doesn't provide sequence numbers or congestion feedback by itself, there are two possible forms for that feedback โจ:
- Feedback at the application: The application above UDP could provide sequence numbers and feedback to the sender, which would then pass loss information to the congestion control mechanism. This is the approach currently standardized by the Congestion Manager (CM) [RFC3124] ๐.
- Feedback at the layer below UDP: The application could use UDP, and a protocol could be implemented with a shim header between IP and UDP to provide sequence number information for data packets and return feedback to the data sender ๐ง. The original proposal for the Congestion Manager [BRS99] suggested providing this layer for applications that didn't have their own feedback about dropped packets ๐.
We'll talk through these two cases separately below ๐.
3.2.1. Case 1: Congestion Feedback at the Application ๐ฆ
In this case, the application provides sequence numbers and congestion feedback above UDP, but sends that feedback to a congestion manager below UDP, which decides when packets are allowed to go out ๐ฆ. This approach suffers from most of the problems described in Section 3.1 ๐ฉ. Namely, the application designer has to reinvent the wheel every time for packet formats and parameter negotiation, and there are problems with ECN usage, firewalls, and evasion ๐.
It would spare the application writer from implementing the control part of the congestion control mechanism ๐. But it's unclear how easily multiple congestion control algorithms (like receiver-based TFRC) could be supported, since the form of congestion feedback usually needs to be tightly coupled to the congestion control algorithm in use ๐ค. So this design limits which congestion control mechanisms applications can choose from, while also burdening applications with implementing congestion feedback ๐ญ.
3.2.2. Case 2: Congestion Feedback at a Layer Below UDP ๐๏ธ
Providing feedback at a layer below UDP would need an extra packet header below UDP to carry sequence numbers, on top of the 8-byte header UDP already has ๐. Unless this header were an IP option (which is likely to cause problems for many IPv4 routers), its presence would need to be signaled with a different IP protocol value than UDP's ๐ฉ. So the packets would no longer look like UDP on the wire, and the modified protocol would face deployment challenges similar to those of an entirely new protocol ๐ซ .
To use congestion feedback below UDP most effectively, the semantics of the UDP socket Application Programming Interface (API) would also need to change ๐ง. That's so the application can make a late decision about what to send, and so it can access sequence numbers (meaning the application wouldn't need to duplicate them for its own purposes) ๐ฏ. So the socket API would no longer look like UDP to end hosts, and this would effectively be a new transport protocol ๐ .
Given all these complications, it seems cleaner to actually design a new transport protocol ๐ฆ. That also lets us tackle firewall traversal, flow setup, and parameter negotiation in one go โจ. We should note that any new transport protocol could also use a Congestion Manager approach to share congestion state between flows using the same congestion control algorithm, if that turns out to be desirable ๐ซถ.
3.3. Providing Congestion Control at the Transport Layer ๐
The concerns from the discussion above have convinced us that the best way to give congestion control to applications that currently use UDP is to provide it at the transport layer, in a transport protocol used as an alternative to UDP ๐. One big advantage of putting end-to-end congestion control in an unreliable transport protocol is that a wide range of applications currently using UDP could use it easily, with minimal changes to the application itself ๐ท. The application wouldn't have to implement the congestion control mechanism, or even the feedback from the data receiver to the data sender about lost or marked packets ๐.
That raises the question of whether to adapt TCP for use by unreliable applications, use an unreliable variant of the Stream Control Transmission Protocol (SCTP) or a version of RTP with built-in congestion control, or design a new transport protocol altogether ๐ค.
As we'll argue below, the desire for minimal overhead leads us to a transport protocol with only the minimal necessary functionality ๐. Other functionality, like reliability, semi-reliability, or Forward Error Correction (FEC), gets layered on top instead ๐ง.
3.3.1. Modifying TCP? ๐คจ
One alternative might be to create an unreliable variant of TCP, with reliability layered on top for applications that want reliable delivery ๐ญ. But our requirement isn't simply "TCP minus in-order reliable delivery." We also need applications to be able to choose their congestion control algorithms ๐๏ธ. TCP's feedback mechanism works well for TCP-like congestion control, but it's inappropriate (or at the very least, inefficient) for TFRC ๐ฌ. On top of that, TCP sequence numbers count bytes, not datagrams ๐. That would complicate both congestion feedback and any attempt to let the application decide, at transmission time, what information goes into a packet ๐.
Then there's the question of whether a modified TCP would need a new IP protocol number too. A significantly modified TCP using the same IP protocol number could have unwanted interactions with some of the middleboxes already deployed in the network ๐ง.
So it seems best to leave TCP as it is, and to create a new congestion control protocol for unreliable transfer ๐. This is especially true because any change to TCP, no matter how small, takes an inordinate amount of time to standardize and deploy ๐. That's given TCP's importance in today's Internet and the historical difficulty of getting TCP implementations right ๐ซฃ.
3.3.2. Unreliable Variants of SCTP? ๐ฆ
okay so SCTP, the Stream Control Transmission Protocol [RFC2960], was kind of built to juggle multiple streams inside one end-to-end connection ๐ง It also loosened TCP's whole reliable, in-order thing so it could deliver stuff out of order. But here's the tea: a fully unreliable transport like DCCP already delivers out of order by definition, so it doesn't need explicit multi-stream support on a single flow at the transport layer ๐ And since an unreliable transport doesn't need streams, apps shouldn't have to pay the header-size penalty that comes with streams in SCTP. bestie that's just wasteful ๐ญ
The basic shape of an SCTP packet (a common SCTP header, then chunks for data, SACK info, and so on) comes from SCTP's whole multi-stream mission ๐ The catch is that chunks have to line up on 32-bit boundaries, so every chunk needs a fixed-size 4-byte chunk header, and the packets get bigger as a result. For example, a connection using ECN gets separate control chunks for the Explicit Congestion Notification Echo (ECNE) and Congestion Window Reduced (CWR) functions, and each of those chunks is 8 bytes ๐ Another example: the common header carries a 4-byte verification tag to validate the sender. Little bytes add up fast, honestly.
Second problem, and this one's kinda big: SCTP as it's currently specified uses TCP-like congestion control. It doesn't support alternative congestion control algorithms like TFRC, even though some of the apps that currently run over UDP would find that way more attractive โจ So the current version of SCTP wouldn't meet the requirements for getting a choice between forms of end-to-end congestion control. no thanks ๐ โโ๏ธ
Last one: the SCTP Partial Reliability extension [RFC3758] lets a sender selectively abandon outstanding messages. That stops retransmissions and lets the receiver deliver whatever is queued on the affected streams ๐ธ This is a really good model for some apps, but it gives the application somewhat less flexibility than UDP's fully unreliable service does. It's not the same vibe at all.
Now, someone could totally suggest adding alternative congestion control as an option to SCTP, plus a fully unreliable variant that skips the multi-stream stuff. We would argue against this ๐ โโ๏ธ SCTP is a great fit for apps that want limited retransmission with multistream or multihoming support, and piling on fully unreliable variants, multiple congestion control profiles, and reduced single-stream headers would risk unforeseen interactions and make future changes even harder to make. Instead, we chose to build a minimal protocol designed for fully unreliable datagram service, one that provides only end-to-end congestion control plus any other mechanisms that can't be provided in a higher layer ๐ฆ minimal and iconic.
3.3.3. Modifying RTP? ๐
Several of our target apps already use RTP layered above UDP to move their data. So why not just modify RTP to give us end-to-end congestion control? ๐ค
When RTP lives above UDP, modifying it to support congestion control could bring along some of the problems from Section 3.1 ๐ Specifically, user-level RTP implementations would want access to the ECN bits in UDP datagrams. Giving that access to RTP but not to other user-level programs might be difficult, or just undesirable, and nobody wants that drama ๐
Kernel implementations of RTP wouldn't have this problem ๐ง But in the end, the argument against modifying RTP is the same one we made against modifying SCTP. Some applications, like exporting flow information from routers, need congestion control but don't need much of RTP's functionality. From their point of view, RTP would add unnecessary overhead. So again, we'd argue for a clean, minimal protocol focused on end-to-end congestion control ๐
That said, RTP would commonly sit on top of any new transport protocol anyway ๐ซถ So the design of that new transport should take this into account. Either it avoids duplicating info that's already in the RTP header, or it suggests changes to RTP, like a reduced RTP header that drops any fields redundant with the new protocol's headers. Team work makes the dream work โจ
3.3.4. Designing a New Transport Protocol ๐
In the first half of this document, we argued for providing congestion control at the transport layer as an alternative to UDP, rather than relying on congestion control supplied only above or below UDP ๐ In this section, we looked at the options: modifying SCTP, modifying TCP, and designing a new transport protocol. Mostly because of the need for unreliable transport, and because we want to accommodate TFRC as well as TCP-like congestion control, we concluded that modifying SCTP or TCP isn't the best answer ๐ โโ๏ธ So a new transport protocol is needed.
That new protocol should offer unreliable delivery, accommodate TFRC as well as TCP-like congestion control, accommodate the use of ECN, and require minimal overhead in packet size, and in the state and CPU processing needed at the data receiver. literally the whole dream, no cap ๐
4. Selling Congestion Control to Reluctant Applications ๐
The goal of this work is to provide general congestion control mechanisms that will actually get used by many of the apps that currently run on UDP ๐ธ That includes apps that are perfectly happy without end-to-end congestion control, which is the tricky part. Several of our design requirements come from wanting to design and deploy a congestion-controlled protocol that's actually attractive to these "reluctant" apps ๐ฅบ Those requirements include a choice between different forms of congestion control, moderate overhead in the size of the packet header, and the use of Explicit Congestion Notification (ECN) and the ECN nonce [RFC3540], which give the application itself a positive benefit. the app gets something out of it, which is the whole point โจ
There will always be a few flows that resist end-to-end congestion control. They prefer an environment where everyone else uses it, but they don't want to use it themselves ๐ There's been substantial agreement [RFC2309, FF99] that, to keep end-to-end congestion control working, router mechanisms are needed to detect and penalize uncontrolled high-bandwidth flows during times of high congestion. These router mechanisms are colloquially known as "penalty boxes" ๐ฆ However, before anyone makes a concerted push to deploy penalty boxes in the Internet, it seems reasonable, and more effective, to first make a concerted effort to make end-to-end congestion control easily available to applications currently using UDP ๐ Fix the vibe before you bring out the punishments, periodt.
5. Additional Design Considerations ๐ง
This section covers some additional design considerations that should be thought about when designing a new transport protocol ๐
- Mobility: Mechanisms for multihoming and mobility are one area of extra functionality that can't necessarily be layered cleanly and effectively on top of a transport protocol ๐ฆ So one open design decision for any new transport protocol is whether to build multihoming and mobility mechanisms into the protocol itself. The current version of DCCP [RFC4340] includes no multihoming or mobility support.
- Defense against DoS attacks and spoofing: A reliable handshake for connection setup and teardown offers protection against DoS and spoofing attacks ๐ก๏ธ Mechanisms that let a server avoid holding any state for unacknowledged connection attempts or already-finished connections offer additional protection against DoS attacks ๐ญ So when designing a new transport protocol, even one meant to provide minimal functionality, the requirements for defending against DoS attacks and spoofing need to be considered. not optional, bestie ๐
- Interoperation with RTP: As Section 3.3.3 describes, attention should be paid to any necessary or desirable changes to RTP when it's used over the new protocol, such as reduced RTP headers ๐
- API: Some functionality required by the protocol, or useful for applications using it, may need new API mechanisms to be defined โจ Examples include letting applications decide what information goes into a packet at transmission time, and giving applications some information about packet sequence numbers ๐ง
- Interactions with NATs and firewalls: NATs and firewalls don't play nicely with UDP ๐ UDP has no explicit flow setup and teardown, and in practice many UDP applications don't have well-known ports. Some of these issues are application specific, and others should be addressed by the transport protocol itself ๐
- Consider general experiences with unicast transport: A Requirements for Unicast Transport/Sessions (RUTS) BOF was held at the IETF meeting in December 1998, with the goal of understanding the requirements of applications whose needs weren't met by TCP [RUTS] ๐ Not all of those unmet needs are relevant to, or appropriate for, a unicast, congestion-controlled, unreliable flow of datagrams designed for long-lived transfers. Some are, though, and any new protocol should address those needs along with other requirements derived from the community's experience ๐ We believe this document addresses the requirements relevant to our problem area that were brought up at the RUTS BOF โจ
6. Transport Requirements of Request/Response Applications โจ
okay so up until now, this doc has been all about apps that send long-lived, big streams of unreliable datagrams ๐. This section is a quick look at a different crowd: request/response apps ๐. Their replies can be just a few packets, and they want reliable delivery plus as little state kept at each end as possible. Reliability could happen by having the receiver re-ask when a packet from the reply goes missing. ngl, neither UDP nor TCP really fits these apps ๐.
Short-lived reliable flows like these definitely need a transport protocol, but we don't think DCCP should try to cover them. The overlap is basically nonexistent, so DCCP should not be designed to meet the needs of these request/response apps ๐ โโ๏ธ. Here's where they clash:
- Reliability: DCCP apps don't need reliability, and long-lived apps that do need it are better off on TCP or SCTP ๐ . Request/response apps, on the other hand, do need reliability, maybe even client-driven reliability where they ask for the missing pieces of a reply ๐.
- Connection setup and teardown: DCCP is built for flows whose length is often unknown up front, so it handles NATs and firewalls with explicit handshakes for setup and teardown ๐ค. Short-lived request/response apps know the transfer length ahead of time, but they can't afford the extra delay of a handshake just to set up a flow ๐ค. So the ways of dealing with NATs and firewalls will probably be totally different for these two groups ๐งฑ.
- Congestion control mechanisms: The style of congestion control and how its features get negotiated depend heavily on how long a flow lasts ๐. On top of that, request/response apps want a stateless server, and that really shapes which congestion control choices make sense ๐ง . So DCCP and these short-lived apps end up with pretty different needs, both for congestion control mechanisms and for negotiation procedures ๐.
7. Summary of Recommendations ๐
Our problem statement talked about the need to add congestion control for unreliable flows ๐ฆ. There are other problems too: keeping overhead low, getting through firewalls, and negotiating parameters reliably ๐. After thinking it all through, here are our general recommendations ๐:
- A unicast transport protocol for unreliable datagrams should be developed, with mandatory built-in congestion control, explicit connection setup and teardown, reliable feature negotiation, and reliable congestion feedback ๐.
- The protocol must provide a set of congestion control mechanisms that the application can pick from. These should include, at minimum, TCP-like congestion control and a more slowly-responding congestion control such as TFRC ๐ข.
- Important features of the connection, like which congestion control mechanism is in use, should be reliably negotiated by both endpoints ๐ค.
- Support for ECN should be included. (Applications could still choose not to use ECN for a particular session ๐.)
- The overhead must be low, both in packet size and in protocol complexity ๐ชถ.
- Some DoS protection for servers must be included. In particular, servers can make themselves resistant to spoofed connection attacks ("SYN floods") ๐ก๏ธ.
- Connection setup and teardown must use explicit handshakes, which makes it easier to get through stateful firewalls ๐ง.
In 2002, the community agreed that a new unicast transport protocol for unreliable datagrams was needed ๐. The next step was to look at the more detailed architectural issues ๐.
8. Security Considerations ๐
ok so this one is serious bestie ๐ญ. This document has no security considerations of its own ๐. It does talk through a bunch of security issues while analyzing the problem, like DoS resistance and firewall traversal, and it's giving high stakes ๐. The security considerations for DCCP are covered separately in [RFC4340] ๐ฆ.
9. Acknowledgements ๐ซถ
We want to thank Spencer Dawkins, Jiten Goel, Jeff Hammond, Lars-Erik Jonsson, John Loughney, Michael Mealling, and Rik Wade for their feedback on earlier versions of this document ๐. We also want to thank everyone in the Transport Area Working Group and the DCCP Working Group for talking through these issues with us ๐ธ.
Informative References ๐
[BRS99] Balakrishnan, H., Rahul, H., and S. Seshan, "An
Integrated Congestion Management Architecture for
Internet Hosts", SIGCOMM, Sept. 1999.
[FF99] Floyd, S. and K. Fall, "Promoting the Use of End-to-
End Congestion Control in the Internet", IEEE/ACM
Transactions on Networking, August 1999.
[PF01] Padhye, J. and S. Floyd, "Identifying the TCP Behavior
of Web Servers", SIGCOMM 2001.
[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.
[RFC2326] Schulzrinne, H., Rao, A., and R. Lanphier, "Real Time
Streaming Protocol (RTSP)", RFC 2326, April 1998.
[RFC2525] Paxson, V., Allman, M., Dawson, S., Fenner, W.,
Griner, J., Heavens, I., Lahey, K., Semke, J., and B.
Volz, "Known TCP Implementation Problems", RFC 2525,
March 1999.
[RFC2914] Floyd, S., "Congestion Control Principles", BCP 41,
RFC 2914, September 2000.
[RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C.,
Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M.,
Zhang, L., and V. Paxson, "Stream Control Transmission
Protocol", RFC 2960, October 2000.
[RFC3124] Balakrishnan, H. and S. Seshan, "The Congestion
Manager", RFC 3124, June 2001.
[RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The
Addition of Explicit Congestion Notification (ECN) to
IP", RFC 3168, September 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.
[RFC3448] Handley, M., Floyd, S., Padhye, J., and J. Widmer,
"TCP Friendly Rate Control (TFRC): Protocol
Specification", RFC 3448, January 2003.
[RFC3540] Spring, N., Wetherall, D., and D. Ely, "Robust
Explicit Congestion Notification (ECN) Signaling with
Nonces", RFC 3540, June 2003.
[RFC3714] Floyd, S. and J. Kempf, "IAB Concerns Regarding
Congestion Control for Voice Traffic in the Internet",
RFC 3714, March 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.
[RFC4340] Kohler, E., Handley, M., and S. Floyd, "Datagram
Congestion Control Protocol (DCCP)", RFC 4340, March
2006.
[RUTS] Requirements for Unicast Transport/Sessions (RUTS)
BOF, Dec. 7, 1998. URL
"http://www.ietf.org/proceedings/98dec/43rd-ietf-
98dec-142.html".
Authors' Addresses ๐บ๏ธ
Sally Floyd
ICSI Center for Internet Research (ICIR),
International Computer Science Institute,
1947 Center Street, Suite 600
Berkeley, CA 94704
USA
EMail: floyd@icir.org
Mark Handley
Department of Computer Science
University College London
Gower Street
London WC1E 6BT
UK
EMail: M.Handley@cs.ucl.ac.uk
Eddie Kohler
4531C Boelter Hall
UCLA Computer Science Department
Los Angeles, CA 90095
USA
EMail: kohler@cs.ucla.edu
Full Copyright Statement โ๏ธ
The legal text below stays complete and word for word ๐:
Copyright (C) The Internet Society (2006).
This document is subject to the rights, licenses and restrictions
contained in BCP 78, and except as set forth therein, the authors
retain all their rights.
This document and the information contained herein are provided on an
"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Intellectual Property ๐งพ
The full IPR text stays verbatim too ๐:
The IETF takes no position regarding the validity or scope of any
Intellectual Property Rights or other rights that might be claimed to
pertain to the implementation or use of the technology described in
this document or the extent to which any license under such rights
might or might not be available; nor does it represent that it has
made any independent effort to identify any such rights. Information
on the procedures with respect to rights in RFC documents can be
found in BCP 78 and BCP 79.
Copies of IPR disclosures made to the IETF Secretariat and any
assurances of licenses to be made available, or the result of an
attempt made to obtain a general license or permission for the use of
such proprietary rights by implementers or users of this
specification can be obtained from the IETF on-line IPR repository at
http://www.ietf.org/ipr.
The IETF invites any interested party to bring to its attention any
copyrights, patents or patent applications, or other proprietary
rights that may cover technology that may be required to implement
this standard. Please address the information to the IETF at ietf-
ipr@ietf.org.
Acknowledgement ๐
Funding for the RFC Editor function is provided by the IETF
Administrative Support Activity (IASA).
That's the whole thing, bestie ๐โจ we made it to the end ๐ ๐
๐ฆ where this page comes from
- ietf: rfc4336 2006-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms