RFC 4341
Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 2: TCP-like Congestion Control
๐ RFC 4341: Profile for DCCP Congestion Control ID 2, TCP-Like Congestion Control ๐
Okay bestie, paperwork first ๐ . This is RFC 4341, filed under the Network Working Group. S. Floyd (ICIR) and E. Kohler (UCLA) wrote it, it's a Standards Track doc, and it's dated March 2006 ๐๏ธ. It's all about Congestion Control ID 2 (CCID 2), TCP-like congestion control for the Datagram Congestion Control Protocol (DCCP) ๐ฆ. The title block doesn't list anything it obsoletes or updates, so it's a clean, standalone spec โจ.
Status of This Memo โจ
This is an Internet standards track protocol for the whole Internet community, and it's literally asking everyone to chat about it and send suggestions ๐ฌ. For the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1) ๐. Distribution of this memo is unlimited, so share away ๐.
Copyright Notice
Copyright (C) The Internet Society (2006). ๐ฉท
Abstract
Okay so this doc holds the profile for CCID 2, TCP-like Congestion Control, inside DCCP ๐ซถ. CCID 2 should be used by senders who want to grab the available bandwidth in an environment with rapidly changing conditions, and who can handle the abrupt changes in the congestion window that come with TCP's Additive Increase Multiplicative Decrease (AIMD) congestion control ๐ฅ. It's giving "bold but make it adaptable" energy ๐ .
Table of Contents
1. Introduction ....................................................2
2. Conventions and Notation ........................................2
3. Usage ...........................................................3
3.1. Relationship with TCP ......................................3
3.2. Half-Connection Example ....................................4
4. Connection Establishment ........................................5
5. Congestion Control on Data Packets ..............................5
5.1. Response to Idle and Application-Limited Periods ...........8
5.2. Response to Data Dropped and Slow Receiver .................8
5.3. Packet Size ................................................8
6. Acknowledgements ................................................9
6.1. Congestion Control on Acknowledgements .....................9
6.1.1. Detecting Lost and Marked Acknowledgements .........10
6.1.2. Changing Ack Ratio .................................10
6.2. Acknowledgements of Acknowledgements ......................11
6.2.1. Determining Quiescence .............................12
7. Explicit Congestion Notification ...............................12
8. Options and Features ...........................................12
9. Security Considerations ........................................13
10. IANA Considerations ...........................................13
10.1. Reset Codes ..............................................13
10.2. Option Types .............................................13
10.3. Feature Numbers ..........................................14
11. Thanks ........................................................14
A. Appendix: Derivation of Ack Ratio Decrease ....................15
B. Appendix: Cost of Loss Inference Mistakes to Ack Ratio ........15
Normative References ..............................................17
Informative References ............................................18
1. Introduction โจ
Alright, this section is the intro to the CCID 2 profile for DCCP [RFC4340] ๐ฆ. DCCP uses Congestion Control Identifiers, or CCIDs, to say which congestion control mechanism is running on a half-connection ๐.
The TCP-like Congestion Control CCID sends data using a close variant of TCP's congestion control mechanisms, and it brings in a variant of selective acknowledgements (SACK) [RFC2018, RFC3517] ๐ธ. CCID 2 is a good fit for senders who can adapt to the abrupt changes in congestion window that come with TCP's Additive Increase Multiplicative Decrease (AIMD) congestion control ๐. It's especially useful for senders who want to grab available bandwidth in an environment with rapidly changing conditions ๐. Check out Section 3 for more on application requirements ๐.
2. Conventions and Notation ๐
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 [RFC2119] โญ.
So a DCCP half-connection is the application data one endpoint sends, plus the acknowledgements the other endpoint sends back ๐. The terms "HC-Sender" and "HC-Receiver" mean the endpoints sending application data and acknowledgements, respectively ๐. Since CCIDs apply at the half-connection level, this doc just shortens HC-Sender to "sender" and HC-Receiver to "receiver" ๐ซถ. For more on this, see [RFC4340] ๐.
For simplicity, we say senders send DCCP-Data packets and receivers send DCCP-Ack packets ๐. Both of those categories are meant to include DCCP-DataAck packets too ๐ง.
The phrases "ECN-marked" and "marked" mean packets marked ECN Congestion Experienced, unless it says otherwise ๐.
3. Usage ๐
CCID 2, TCP-like Congestion Control, is the right pick for DCCP flows that want as much bandwidth as possible over the long term, as long as they stay consistent with end-to-end congestion control ๐. CCID 2 flows also have to tolerate the big sending rate swings that come with AIMD congestion control, including halving the congestion window when a congestion event happens ๐ญ.
If an app just needs to move as much data as possible in as short a time as possible, CCID 2 is the move ๐๏ธ. Now, the contrast: CCID 3, TCP-Friendly Rate Control (TFRC) [RFC4342], is for flows that would rather minimize abrupt changes in sending rate ๐ฆ. For example, CCID 2 is recommended over CCID 3 for streaming media apps that buffer a lot of data at the application receiver before playback time, since that buffer shields the app somewhat from sudden sending rate changes ๐ฌ. Those apps could easily pick DCCP's CCID 2 over TCP itself, possibly adding some form of selective reliability at the application layer ๐ . CCID 2 is also recommended over CCID 3 for apps where halving the sending rate in response to congestion isn't likely to hurt app-level performance ๐ธ.
Another perk of CCID 2 is that its TCP-like congestion control mechanisms are pretty well understood, with traffic dynamics that look a lot like TCP's ๐ง . The network research community is still learning about TCP's dynamics after 15 years as the dominant transport protocol on the Internet, and some apps might prefer the well-known dynamics of TCP-like congestion control over newer mechanisms that haven't yet been tested by widespread Internet deployment ๐ค.
3.1. Relationship with TCP ๐ฉท
The congestion control mechanisms here closely follow mechanisms the IETF standardized for SACK-based TCP, and we partially rely on existing TCP docs, like [RFC793], [RFC2581], [RFC3465], and [RFC3517] ๐. TCP congestion control keeps evolving, but CCID 2 implementations SHOULD wait for explicit updates to CCID 2 rather than track TCP's evolution directly ๐.
Here's how CCID 2 differs from straight TCP congestion control ๐:
- CCID 2 applies congestion control to acknowledgements, a mechanism not currently standardized for use in TCP ๐ซง.
- DCCP is a datagram protocol, so several parameters whose units are bytes in TCP, such as the congestion window cwnd, have units of packets in DCCP ๐ฆ.
- As an unreliable protocol, DCCP never retransmits a packet, so congestion control mechanisms that distinguish retransmissions from new packets have been redesigned for the DCCP context ๐.
3.2. Half-Connection Example ๐ฆ
This example shows the typical progress of a half-connection using CCID 2's TCP-like Congestion Control, leaving out connection initiation and termination โจ. It's informative, not normative, so think of it as a walkthrough rather than a rulebook ๐.
- The sender sends
DCCP-Datapackets, and how many it sends is governed by a congestion window, cwnd, just like in TCP ๐. EachDCCP-Datapacket uses a sequence number ๐ข. The sender also sends an Ack Ratio feature option that specifies how many data packets eachAckpacket from the receiver should cover, and Ack Ratio defaults to two ๐. TheCCValfield in the DCCP header is set to zero 0๏ธโฃ.
If the half-connection is Explicit Congestion Notification (ECN) capable (the ECN Incapable feature is zero, which is the default), each DCCP-Data packet is sent as ECN Capable with either the ECT(0) or the ECT(1) codepoint set, as described in [RFC3540] ๐.
- The receiver sends a
DCCP-Ackpacket acknowledging the data packets, once for every Ack Ratio data packets the sender transmits ๐ฌ. EachDCCP-Ackpacket uses a sequence number and contains an Ack Vector ๐งพ. The sequence number acknowledged in aDCCP-Ackpacket is the one from the received packet with the highest sequence number. It is not a TCP-like cumulative acknowledgement, so no cumulative vibes here ๐ โโ๏ธ.
The receiver returns the sum of received ECN Nonces via Ack Vector options, which lets the sender probabilistically verify that the receiver isn't misbehaving ๐ต๏ธโโ๏ธ. DCCP-Ack packets from the receiver are also sent as ECN Capable, since the sender controls the acknowledgement rate in a roughly TCP-friendly way using the Ack Ratio feature ๐ซถ. The receiver doesn't really need to verify the nonces of its own DCCP-Ack packets, since the sender can't get much benefit from misreporting the ack mark rate ๐.
- The sender keeps sending
DCCP-Datapackets as controlled by the congestion window โฏ๏ธ. WhenDCCP-Ackpackets come in, the sender checks their Ack Vectors to learn about marked or dropped data packets, and adjusts its congestion window accordingly ๐. Because this is unreliable transfer, the sender does not retransmit dropped packets ๐ซ . - Because
DCCP-Ackpackets use sequence numbers, the sender has some info about lost or markedDCCP-Ackpackets ๐ต๏ธ. The sender responds to lost or markedDCCP-Ackpackets by modifying the Ack Ratio it sends to the receiver ๐ง. - The sender acknowledges the receiver's acknowledgements at least once per congestion window ๐. If both half-connections are active, the sender's acknowledgement of the receiver's acknowledgements is included in the sender's acknowledgement of the receiver's data packets ๐ค. If the reverse-path half-connection is quiescent, the sender sends at least one
DCCP-DataAckpacket per congestion window ๐. - The sender estimates round-trip times, either by keeping track of acknowledgement round-trip times the way TCP does, or through explicit Timestamp options โฑ๏ธ. From that, it calculates a TimeOut (TO) value, much like how the RTO (Retransmit Timeout) is calculated in TCP ๐งฎ. The TO decides when a new
DCCP-Datapacket can be transmitted, for when the sender has been limited by the congestion window and no feedback has come back from the receiver ๐ซง.
To be continued in part 2 ๐โจ
4. Connection Establishment โจ
okay so Ack Vector is mandatory on CCID 2 half-connections ๐
which means the sender MUST send a Change R(Send Ack Vector, 1) option to the receiver as part of setting up the connection ๐. ngl it's the vibe check before the vibe. The sender SHOULD NOT send data until it gets the matching Confirm L(Send Ack Vector, 1) back from the receiver, except it MAY send data on DCCP-Request packets ๐ฆ
5. Congestion Control on Data Packets ๐ธ
CCID 2's congestion control is based on SACK-based TCP's [RFC3517] stuff, and that makes sense bc the Ack Vector carries basically all the info that SACK options could carry ๐ซถ
A CCID 2 data sender tracks three integer parameters, all counted in packets ๐ง
- The congestion window
cwnd, which is the max number of data packets allowed in the network at any time. ("Data packet" means any DCCP packet that has user data: DCCP-Data, DCCP-DataAck, and occasionally DCCP-Request and DCCP-Response.) - The slow-start threshold
ssthresh, which controls howcwndgets adjusted. - The pipe value
pipe, which is the sender's best guess at how many data packets are still out there in the network.
These get changed, and their starting values get set, following SACK-based TCP's behavior, except they're counted in packets instead of bytes. The rest of this section gets more specific ๐
The sender MAY send a data packet when pipe < cwnd, but MUST NOT send a data packet when pipe >= cwnd. Every data packet sent bumps pipe up by 1 ๐ฅ
The sender lowers pipe as it figures out that data packets have left the network, either because they got received or because they got dropped ๐ญ specifically:
- Acked data packets. The sender reduces
pipeby 1 for each data packet newly acknowledged as received (Ack Vector State 0 or State 1) by some DCCP-Ack. - Dropped data packets. The sender reduces
pipeby 1 for each data packet it can infer as lost because of the DCCP version of TCP's "duplicate acknowledgements" ๐ This depends on the NUMDUPACK parameter, which is the number of duplicate acknowledgements needed to infer a loss. NUMDUPACK is set to three, same as TCP does right now. A packet P is inferred to be lost, rather than just delayed, when at least NUMDUPACK packets sent after P have been acknowledged as received (Ack Vector State 0 or State 1) by the receiver. Note that the acknowledged packets after the hole might be DCCP-Acks or other non-data packets. - Transmit timeouts. The sender also needs transmit timeouts, handled like TCP's retransmission timeouts, in case a whole window of packets gets lost ๐ฑ The sender estimates the round-trip time at most once per window of data, and uses TCP's algorithms for keeping the average round-trip time, mean deviation, and timeout value [RFC2988]. (If you measured more than once per round-trip time, the averagers' weights would have to be adjusted so the average round-trip time still comes from measurements across multiple round-trip times.) Because DCCP doesn't retransmit data, DCCP doesn't need TCP's recommended minimum timeout of one second. The exponential backoff of the timer is exactly the same as TCP. When a transmit timeout happens, the sender sets
pipeto zero. The adjustments tocwndandssthreshare described below.
The sender MUST NOT decrement pipe more than once per data packet. True duplicate acknowledgements, for example, MUST NOT affect pipe. The sender also MUST NOT decrement pipe again when it gets an acknowledgement for a packet that was previously inferred as lost. Furthermore, the sender MUST NOT decrement pipe for non-data packets, like DCCP-Acks, even though the Ack Vector will contain info about them ๐
Congestion events make CCID 2 shrink its congestion window. A congestion event has at least one lost or marked packet. Just like TCP, two losses or marks count as part of a single congestion event when the second packet was sent before the loss or mark of the first packet was detected ๐ As an approximation, a sender can treat two losses or marks as part of one congestion event when the packets were sent within one RTT estimate of each other, using the RTT estimate that was current when the packets were sent. For each congestion event, whether it's shown explicitly as an Ack Vector State 1 (ECN-marked) acknowledgement or inferred from "duplicate acknowledgements", cwnd is halved, and then ssthresh is set to the new cwnd. Cwnd never drops below one packet. After a timeout, ssthresh is set to cwnd/2, and then cwnd is set to one packet. When it's halved, cwnd and ssthresh get rounded down, except cwnd is never less than one and ssthresh is never less than two ๐
When cwnd < ssthresh, meaning the sender is in slow-start, the congestion window goes up by one packet for every two newly acknowledged data packets with Ack Vector State 0 (not ECN-marked), up to a maximum of Ack Ratio/2 packets per acknowledgement. This is a modified form of Appropriate Byte Counting [RFC3465] that's consistent with TCP's current standard (which doesn't include byte counting), but it lets CCID 2 grow as aggressively as TCP when CCID 2's Ack Ratio is bigger than the default value of two ๐ When cwnd >= ssthresh, the congestion window goes up by one packet for every window of data acknowledged without lost or marked packets. The cwnd parameter starts at most four packets for new connections, following the rules from [RFC3390]. The ssthresh parameter starts at an arbitrarily high value ๐ง
Senders MAY use a form of rate-based pacing when they send multiple data packets freed up by a single ack packet, instead of blasting all the freed-up data packets in one burst ๐
5.1. Response to Idle and Application-Limited Periods
CCID 2 is designed to follow TCP's congestion control mechanisms as much as possible, but TCP doesn't have complete standardization for its congestion control response to idle periods (when no data packets are sent) or to application-limited periods (when the sending rate is less than what cwnd allows) ๐ฅฑ This section is a quick guide to the TCP standards in this area.
For idle periods, [RFC2581] recommends that the TCP sender SHOULD slow-start after an idle period, where an idle period is defined as a period exceeding the timeout interval. [RFC2861], currently Experimental, suggests a slightly more chill mechanism where the congestion window is halved for every round-trip time that the sender has been idle ๐
There are currently no standards governing TCP's use of the congestion window during an application-limited period. Like, it's possible for TCP's congestion window to get pretty huge during a long uncongested period when the sender is application limited and sending at a low rate ๐ณ [RFC2861] basically suggests that TCP's congestion window should not be increased during application-limited periods when the congestion window isn't being fully used.
5.2. Response to Data Dropped and Slow Receiver
DCCP's Data Dropped option lets a receiver say a packet was dropped at the end host before it got delivered to the application, for instance because of corruption or receive buffer overflow ๐ DCCP's Slow Receiver option lets a receiver say it's having trouble keeping up with the sender's packets, even though nothing has been dropped yet. CCID 2 senders respond to these options as described in [RFC4340], with the following extra clarifications โจ
- Drop Code 2 ("receive buffer drop"). The congestion window
cwndis reduced by one for each packet newly acknowledged as Drop Code 2, except it's never reduced below one. - Exiting slow start. The sender MUST exit slow start whenever it receives a relevant Data Dropped or Slow Receiver option ๐จ
5.3. Packet Size
CCID 2 is optimized for applications that generally use a fixed packet size and vary their sending rate in packets per second in response to congestion ๐ฆ CCID 2 is not a good fit for applications that need a fixed interval of time between packets and instead vary their packet size rather than their packet rate in response to congestion.
CCID 2 maintains a congestion window in packets, and it does not increase the congestion window in response to a decrease in packet size. However, some attention might be needed for CCID 2 applications that vary their packet size not because of congestion, but because of other application-level requirements ๐ค
CCID 2 implementations MAY check for applications that appear to be manipulating packet size inappropriately. For example, an application might send small packets for a while to build up a fast rate, then switch to large packets to take advantage of that fast rate ๐ (Preliminary simulations indicate that applications may not be able to increase their overall transfer rates this way, so it's not clear this manipulation will happen in practice [V03].)
6. Acknowledgements ๐ซง
CCID 2 acknowledgements are generally paced by the sender's data packets. Each required acknowledgement MUST contain Ack Vector options that declare exactly which packets arrived and whether those packets were ECN-marked. Acknowledgement data in the Ack Vector options SHOULD generally cover the receiver's entire Acknowledgement Window; see [RFC4340], Section 11.4.2. Any Data Dropped options SHOULD likewise cover the receiver's entire Acknowledgement Window ๐
CCID 2 senders use DCCP's Ack Ratio feature to influence how often receivers generate DCCP-Ack packets, which controls reverse-path congestion ๐ This is different from TCP, which currently has no congestion control for pure acknowledgement traffic. CCID 2's reverse-path congestion control doesn't try to be TCP friendly. It just tries to avoid congestion collapse, and to do somewhat better than TCP when there's a high packet loss or mark rate on the reverse path ๐ The default Ack Ratio is two, and CCID 2 with this Ack Ratio behaves like TCP with delayed acks. [RFC4340], Section 11.3, describes the Ack Ratio in more detail, including how it relates to acknowledgement pacing and DCCP-DataAck packets. This document's Section 6.1.1 describes how a CCID 2 sender detects lost or marked acknowledgements, and Section 6.1.2 describes how it changes the Ack Ratio ๐ง
6.1. Congestion Control on Acknowledgements
When Ack Ratio is R, the receiver sends one DCCP-Ack packet per R data packets, more or less ๐ Since the sender sends cwnd data packets per round-trip time, the acknowledgement rate equals cwnd/R DCCP-Acks per round-trip time. The sender keeps the acknowledgement rate roughly TCP friendly by watching the acknowledgement stream for lost and marked DCCP-Ack packets and adjusting R to match ๐ For every RTT that contains a DCCP-Ack congestion event (that is, a lost or marked DCCP-Ack), the sender halves the acknowledgement rate by doubling Ack Ratio. For every RTT that contains no DCCP-Ack congestion event, it additively increases the acknowledgement rate through gradual decreases in Ack Ratio ๐ฆ
6.1.1. Detecting Lost and Marked Acknowledgements ๐ฆ
okay so the sender can totally tell when the receiver's packets get lost or marked, because every packet from the receiver carries a sequence number ๐ขโจ. It figures out receiver packet loss the same way it figures out loss of its own data packets: a packet from the receiver counts as lost once at least NUMDUPACK packets with greater sequence numbers have arrived ๐
.
Now the tea ๐ต: DCCP-Ack packets are usually tiny, so they hit congested links way less hard than DCCP-Data and DCCP-DataAck packets do ๐ซถ. That's why Ack Ratio depends on losses and marks on the receiver's non-data packets, not on the total losses and marks across all of the receiver's packets ๐ธ. The non-data crew is every packet type that can't carry application data: DCCP-Ack, DCCP-Close, DCCP-CloseReq, DCCP-Reset, DCCP-Sync, and DCCP-SyncAck.
The sender can easily tell non-data marks apart from other marks, which is so convenient ๐. Losses are trickier, though, because the sender can't always know whether a lost packet was carrying data ๐. So unless it has better information, the sender SHOULD assume, for the purpose of Ack Ratio calculation, that every lost packet was a non-data packet. If it needs better information, DCCP's NDP Count option has got it ๐ง. (Appendix B talks about the costs of mistaking data packet loss for non-data packet loss, so go check that out ๐.)
A receiver with its own acknowledgement congestion control, independent of Ack Ratio, SHOULD NOT cut its DCCP-Ack rate just because of losses or marks on its data packets ๐ โโ๏ธ.
6.1.2. Changing Ack Ratio ๐
Ack Ratio always meets three constraints, no exceptions ๐
: (1) Ack Ratio is an integer. (2) Ack Ratio does not exceed cwnd/2, rounded up, except that Ack Ratio 2 is always acceptable. (3) Ack Ratio is two or more for a congestion window of four or more packets.
So the sender adjusts Ack Ratio inside those rules like this ๐. For each congestion window of data with lost or marked DCCP-Ack packets, Ack Ratio gets doubled ๐ฅ. For each cwnd/(R^2 - R) consecutive congestion windows of data with no lost or marked DCCP-Ack packets, Ack Ratio drops by 1 ๐ฑ. (See Appendix A for the math, it's giving derivation ๐ค.) Any changes get signalled through feature negotiation, so see [RFC4340], Section 11.3 ๐จ.
With a constant congestion window, this gives an Ack sending rate that's roughly TCP friendly ๐ฆ. Of course cwnd usually changes over time, so the dynamics get pretty complex, but still roughly TCP friendly โจ. We recommend that the sender use the most recent value of cwnd when deciding whether to drop Ack Ratio by 1.
The sender doesn't need Ack Ratio perfectly up to date, bestie ๐ซถ. For instance, it MAY rate-limit Ack Ratio renegotiations to once every four or five round-trip times, or to once every second or two. The sender SHOULD NOT try to renegotiate Ack Ratio more than once per round-trip time ๐ โโ๏ธ. Also, it MAY enforce a minimum Ack Ratio of two, or it MAY set Ack Ratio to one for half-connections with persistent congestion windows of 1 or 2 packets ๐ง.
Putting it all together ๐: the receiver always sends at least one acknowledgement per window of data when cwnd = 1, and at least two acknowledgements per window of data otherwise. So the receiver could be sending two ack packets per window of data even when the reverse path is absolutely jammed ๐ญ. BUT, if congestion is heavy enough that all the ack packets get dropped, the sender falls back on an exponentially backed-off timeout, same as TCP ๐. So if the reverse path is badly congested, the sender cuts its sending rate on the forward path, and that lowers the rate on the reverse path too ๐. It's self-correcting, periodt ๐ .
6.2. Acknowledgements of Acknowledgements ๐ซถ
An active sender DCCP A MUST occasionally acknowledge its peer DCCP B's acknowledgements, so that DCCP B can free up Ack Vector state ๐งน. When both half-connections are active, A's acknowledgements of B's acknowledgements get automatically tucked inside A's acknowledgements of B's data ๐. If the B-to-A half-connection is quiescent, though, DCCP A must occasionally send acknowledgements proactively, like by sending a "DCCP-DataAck" packet that includes an Acknowledgement Number in the header ๐ฌ.
An active sender SHOULD acknowledge the receiver's acknowledgements at least once per congestion window ๐ธ. Of course, the sender's application might go silent, and that's totally fine โจ. When neither side is sending data, a sender can wait arbitrarily long before sending an ack ๐ด.
6.2.1. Determining Quiescence ๐
This section explains how a CCID 2 receiver figures out that the corresponding sender isn't sending any data, and therefore has gone quiescent ๐คซ. For general info on quiescence, see [RFC4340], Section 11.1 ๐.
Let T equal the greater of 0.2 seconds and two round-trip times โฑ๏ธ. (The receiver might know the round-trip time from its role as the sender for the other half-connection. If it doesn't, it should use a default RTT of 0.2 seconds, as described in [RFC4340], Section 3.4 ๐ง .) Once the sender acknowledges the receiver's Ack Vectors, and the sender hasn't sent more data for at least T seconds, the receiver can infer that the sender is quiescent ๐ซง. To be more precise ๐
: the receiver infers that the sender has gone quiescent when at least T seconds have passed without receiving any data from the sender, and when the sender has acknowledged receiver Ack Vectors covering all data packets received at the receiver ๐ฏ.
7. Explicit Congestion Notification ๐ฆ
CCID 2 supports Explicit Congestion Notification (ECN) [RFC3168] ๐ฅ. The sender uses the ECN Nonce for data packets, and the receiver echoes those nonces in its Ack Vectors, as specified in [RFC4340], Section 12.2 ๐. Info about marked packets also comes back in the Ack Vector. Because the info in the Ack Vector is reliably transferred, DCCP doesn't need the TCP flags of ECN-Echo and Congestion Window Reduced ๐.
For unmarked data packets, the receiver computes the ECN Nonce Echo as in [RFC3540] and returns it as part of its Ack Vector options ๐งฎ. The sender SHOULD check these ECN Nonce Echoes against the expected values, which protects against the accidental or malicious concealment of marked packets ๐ก๏ธ.
Because CCID 2 acknowledgements are congestion controlled, ECN may also be used for its acknowledgements ๐. In this case we don't use the ECN Nonce, and the reasons are honestly iconic ๐: it wouldn't be easy to protect against the sender concealing marked ack packets, and the sender doesn't have much motivation to lie about the mark rate on acknowledgements ๐คทโโ๏ธ.
8. Options and Features ๐
DCCP's Ack Vector option, plus its ECN Capable, Ack Ratio, and Send Ack Vector features, are relevant for CCID 2 ๐.
9. Security Considerations ๐
โ ๏ธ Serious bestie moment: take this section seriously, no cap.
Security considerations for DCCP have been discussed in [RFC4340], and security considerations for TCP have been discussed in [RFC2581] ๐.
[RFC2581] discusses ways an attacker could hurt the performance of a TCP connection by dropping packets, or by forging extra duplicate acknowledgements or acknowledgements for new data ๐ฑ. We aren't aware of any new security considerations created by this document in its use of TCP-like congestion control ๐ง.
10. IANA Considerations ๐
This specification defines the value 2 in the DCCP CCID namespace managed by IANA ๐ข. This assignment is also mentioned in [RFC4340]. CCID 2 also introduces three sets of numbers whose values should be allocated by IANA: CCID 2-specific Reset Codes, option types, and feature numbers ๐๏ธ. These ranges keep future CCID 2-specific allocations from polluting DCCP's corresponding global namespaces, see [RFC4340], Section 10.3 ๐งน. This document doesn't make any particular allocations from those ranges, except for experimental and testing use [RFC3692] ๐งช. We refer to the Standards Action policy outlined in [RFC2434] ๐.
10.1. Reset Codes ๐
Each entry in the DCCP CCID 2 Reset Code registry has a CCID 2-specific Reset Code (a number in the range 128-255), a short description of the Reset Code, and a reference to the RFC defining the Reset Code ๐๏ธ. Reset Codes 184-190 and 248-254 are permanently reserved for experimental and testing use ๐งช. The remaining Reset Codes -- 128-183, 191-247, and 255 -- are currently reserved and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication ๐๏ธ.
10.2. Option Types ๐งฉ
Each entry in the DCCP CCID 2 option type registry has a CCID 2-specific option type (a number in the range 128-255), the name of the option, and a reference to the RFC defining the option type ๐. Option types 184-190 and 248-254 are permanently reserved for experimental and testing use ๐งช. The remaining option types -- 128-183, 191-247, and 255 -- are currently reserved and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication ๐๏ธ.
10.3. Feature Numbers ๐๏ธ
Each entry in the DCCP CCID 2 feature number registry has a CCID 2-specific feature number (a number in the range 128-255), the name of the feature, and a reference to the RFC defining the feature number ๐. Feature numbers 184-190 and 248-254 are permanently reserved for experimental and testing use ๐งช. The remaining feature numbers -- 128-183, 191-247, and 255 -- are currently reserved and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication ๐๏ธ.
11. Thanks ๐
We thank Mark Handley and Jitendra Padhye for their help in defining CCID 2 ๐. We also thank Mark Allman, Aaron Falk, Nils-Erik Mattsson, Greg Minshall, Arun Venkataramani, Magnus Westerlund, and members of the DCCP Working Group for feedback on this document ๐ซถโจ.
A. Appendix: Derivation of Ack Ratio Decrease ๐งฎโจ
okay so this bit is the math receipts for the Ack Ratio algorithm from Section 6.1.2 ๐ it's giving "trust me, I did the homework" energy
TCP's congestion avoidance halves the cwnd for every window with congestion. CCID 2 does the same kind of move with Ack Ratio: it doubles the Ack Ratio for every window with congestion on the return path, which roughly halves the DCCP-Ack sending rate ๐
TCP's congestion avoidance also bumps cwnd up by one MSS for every congestion-free window. If you apply that same vibe to acknowledgement traffic, it means adding one more DCCP-Ack packet per window after each congestion-free window of DCCP-Ack packets ๐ธ the catch is that Ack Ratio is an integer, so we can't do that exactly. Instead, we have to drop Ack Ratio by one after K windows go by without a congestion event on the reverse path. K gets picked so the long-term number of DCCP-Ack packets per congestion window is roughly TCP friendly, following AIMD congestion control ๐ฆ
for CCID 2, you get rough TCP-friendliness for the ack traffic by setting K to cwnd/(R^2 - R), where R is the current Ack Ratio ๐
here's how that got calculated, bestie ๐ค
R = Ack Ratio = # data packets / ack packets, and
W = Congestion Window = # data packets / window, so
W/R = # ack packets / window.
The requirement is to increase W/R by 1 per congestion-free window. Since R can only go down in steps of one, we look for the K where, after K congestion-free windows, W/R + K ends up equal to W/(R-1) ๐ง
(W/R) + K = W/(R-1), so
K = W/(R-1) - W/R = W/(R^2 - R).
ta-da ๐ the derivation is complete ๐
B. Appendix: Cost of Loss Inference Mistakes to Ack Ratio ๐ต๏ธโโ๏ธ๐
so back in Section 6.1.1, we already learned that the sender often can't tell whether lost packets were carrying data ๐ that makes it tricky to separate non-data loss events from everything else. With no better info, the sender just assumes, for Ack Ratio purposes, that every lost packet was a non-data packet. This might overestimate the non-data loss event rate, which can push Ack Ratio too high, and then acks go out too slowly ๐ข
the good news is that all acknowledgement information still gets through, because DCCP acknowledgements are reliable ๐ซถ the bad news is that the acks show up in a burstier way. Unless you're doing some kind of rate-based pacing, that can make the sender's data traffic burstier too ๐ฌ
there are a bunch of situations where the too-high Ack Ratio problem, and the burstiness that comes with it, just won't happen ๐ so let's call the receiver DCCP B and the sender DCCP A:
- the problem won't show up unless DCCP B is sending a real chunk of data itself. When the B-to-A half-connection is quiet or low rate, most of what DCCP B sends is pure acknowledgements, so DCCP A's estimate of the DCCP-Ack loss rate is pretty accurate ๐ธ
- the problem won't show up if DCCP B keeps piggybacking acknowledgement info on its data packets. Piggybacked acks aren't limited by Ack Ratio, so they can arrive often enough to stop the bursts ๐
- the problem won't show up if DCCP A's sending rate is low, since burstiness isn't much of a problem at low rates ๐ง
- the problem won't show up if DCCP B's sending rate is high compared to DCCP A's sending rate. That's because the B-to-A loss rate has to be low to support DCCP B's sending rate, which keeps Ack Ratio at reasonable values even when DCCP A labels every loss as a DCCP-Ack loss ๐
- the problem won't show up if DCCP B sends NDP Count options when it's appropriate (the Send NDP Count/B feature is true). Then the sender can use the receiver's NDP Count options to figure out, in most cases, whether lost packets were data packets or DCCP-Acks โจ
- finally, the problem won't show up if DCCP A rate-paces its data packets ๐ซง
that leaves one spicy case: DCCP B is sending roughly the same number of data packets and non-data packets, without NDP Count options, and with all of its acknowledgement information in DCCP-Ack packets ๐ญ so now we need to quantify the potential cost, in terms of a too-large Ack Ratio, from the sender misclassifying data packet losses as DCCP-Ack losses. To keep things simple, we assume a big statistically multiplexed environment where the packet drop rate doesn't depend on the sending rate of any one connection ๐
say that when DCCP A correctly counts non-data losses, Ack Ratio is set so that the B-to-A data and acknowledgement traffic both sit at a sending rate of D packets per second. Then, when DCCP A incorrectly counts data losses as non-data losses, the B-to-A data traffic still goes at D pps, but the acknowledgement traffic drops to f*D pps, with f < 1 ๐ call the packet loss rate p. The sender then estimates the non-data loss rate as (pD+pfD)/fD, which is the same as p(1 + 1/f) ๐งฎ
the congestion control for acknowledgement traffic is roughly TCP friendly, so the non-data sending rate and the data sending rate both grow as 1/sqrt(x), where x is the packet drop rate. That gives us:
fD/D = sqrt(p)/sqrt(p(1 + 1/f)),
so
f^2 = 1/(1 + 1/f).
solving that, we get f = 0.62 ๐ฏ so if the sender wrongly counts lost data packets as non-data in this scenario, the acknowledgement rate drops by a factor of 0.62. That leads to a moderate increase in burstiness for the A-to-B data traffic, which can be softened by sending NDP Count options or piggybacked acknowledgements, or by rate-pacing the data out ๐
Normative References ๐
heads up, these are the must-read references, babe ๐ฉท
[RFC793] Postel, J., "Transmission Control Protocol", STD 7,
RFC 793, September 1981.
[RFC2018] Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow,
"TCP Selective Acknowledgement Options", RFC 2018,
October 1996.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing
an IANA Considerations Section in RFCs", BCP 26, RFC
2434, October 1998.
[RFC2581] Allman, M., Paxson, V., and W. Stevens, "TCP
Congestion Control", RFC 2581, April 1999.
[RFC2988] Paxson, V. and M. Allman, "Computing TCP's
Retransmission Timer", RFC 2988, November 2000.
[RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The
Addition of Explicit Congestion Notification (ECN) to
IP", RFC 3168, September 2001.
[RFC3390] Allman, M., Floyd, S., and C. Partridge, "Increasing
TCP's Initial Window", RFC 3390, October 2002.
[RFC3517] Blanton, E., Allman, M., Fall, K., and L. Wang, "A
Conservative Selective Acknowledgment (SACK)-based
Loss Recovery Algorithm for TCP", RFC 3517, April
2003.
[RFC3692] Narten, T., "Assigning Experimental and Testing
Numbers Considered Useful", BCP 82, RFC 3692, January
2004.
[RFC4340] Kohler, E., Handley, M., and S. Floyd, "Datagram
Congestion Control Protocol (DCCP)", RFC 4340, March
2006.
Informative References ๐ท
these ones are extra reading if you're curious ๐ค
[RFC2861] Handley, M., Padhye, J., and S. Floyd, "TCP Congestion
Window Validation", RFC 2861, June 2000.
[RFC3465] Allman, M., "TCP Congestion Control with Appropriate
Byte Counting (ABC)", RFC 3465, February 2003.
[RFC3540] Spring, N., Wetherall, D., and D. Ely, "Robust
Explicit Congestion Notification (ECN) Signaling with
Nonces", RFC 3540, June 2003.
[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.
[V03] Arun Venkataramani, August 2003. Citation for
acknowledgement purposes only.
Authors' Addresses ๐ซถ
meet the brilliant minds behind this doc โจ
Sally Floyd
ICSI Center for Internet Research
1947 Center Street, Suite 600
Berkeley, CA 94704
USA
EMail: floyd@icir.org
Eddie Kohler
4531C Boelter Hall
UCLA Computer Science Department
Los Angeles, CA 90095
USA
EMail: kohler@cs.ucla.edu
Full Copyright Statement โ๏ธ
this is the legal stuff, so I'm keeping it exact ๐
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 IETF takes no position on 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 on whether any license under such rights might or might not be available. It also doesn't claim to have made any independent effort to identify any such rights. Info on the procedures for 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). ๐ฉท๐
๐ฆ where this page comes from
- ietf: rfc4341 2006-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms