RFC 4654

TCP-Friendly Multicast Congestion Control (TFMCC): Protocol Specification

๐Ÿ“… published August 2006, from ietf

Status of This Memo โœจ

This memo defines an Experimental Protocol for the Internet community. It does not specify an Internet standard of any kind. Discussion and suggestions for improvement are requested. Distribution of this memo is unlimited.

Copyright (C) The Internet Society (2006).

Abstract ๐ŸŒธ

This document specifies TCP-Friendly Multicast Congestion Control (TFMCC). TFMCC is a congestion control mechanism for multicast transmissions in a best-effort Internet environment. It is a single-rate congestion control scheme, where the sending rate is adapted to the receiver experiencing the worst network conditions. TFMCC is reasonably fair when competing for bandwidth with TCP flows and has a relatively low variation of throughput over time, making it suitable for applications where a relatively smooth sending rate is of importance, such as streaming media.

Table of Contents ๐Ÿ“‹

   1. Introduction ....................................................3
      1.1. Related Documents ..........................................4
      1.2. Environmental Requirements and Considerations ..............4
   2. Protocol Overview ...............................................5
      2.1. TCP Throughput Equation ....................................6
      2.2. Packet Contents ............................................7
           2.2.1. Sender Packets ......................................8
           2.2.2. Feedback Packets ....................................9
   3. Data Sender Protocol ...........................................10
      3.1. Sender Initialization .....................................10
      3.2. Determining the Maximum RTT ...............................10
      3.3. Adjusting the Sending Rate ................................11
      3.4. Controlling Receiver Feedback .............................12
      3.5. Assisting Receiver-Side RTT Measurements ..................14
      3.6. Slowstart .................................................15
      3.7. Scheduling of Packet Transmissions ........................15
   4. Data Receiver Protocol .........................................16
      4.1. Receiver Initialization ...................................17
      4.2. Receiver Leave ............................................17
      4.3. Measurement of the Network Conditions .....................17
           4.3.1. Updating the Loss Event Rate .......................17
           4.3.2. Basic Round-Trip Time Measurement ..................17
           4.3.3. One-Way Delay Adjustments ..........................18
           4.3.4. Receive Rate Measurements ..........................19
      4.4. Setting the Desired Rate ..................................19
      4.5. Feedback and Feedback Suppression .........................20
   5. Calculation of the Loss Event Rate .............................22
      5.1. Detection of Lost or Marked Packets .......................22
      5.2. Translation from Loss History to Loss Events ..............23
      5.3. Inter-Loss Event Interval .................................24
      5.4. Average Loss Interval .....................................24
      5.5. History Discounting .......................................25
      5.6. Initializing the Loss History after the First Loss Event ..27
   6. Security Considerations ........................................28
   7. Acknowledgments ................................................29
   8. References .....................................................29
      8.1. Normative References ......................................29
      8.2. Informative References ....................................29

1. Introduction โœจ

This document specifies TCP-Friendly Multicast Congestion Control (TFMCC) [3]. TFMCC is a source-based, single-rate congestion control scheme that builds upon the unicast TCP-Friendly Rate Control mechanism (TFRC) [4]. TFMCC is stable and responsive under a wide range of network conditions and scales to receiver sets on the order of several thousand receivers. To support scalability, as much congestion control functionality as possible is located at the receivers. Each receiver continuously determines a desired receive rate that is TCP-friendly for the path from the sender to this receiver. Selected receivers then report the rate to the sender in feedback packets. ๐Ÿ’–

TFMCC is a building block as defined in RFC 3048 [1]. Instead of specifying a complete protocol, this document simply specifies a congestion control mechanism that could be used in a transport protocol such as RTP [11], in an application incorporating end-to-end congestion control at the application level. This document does not discuss packet formats, reliability, or implementation-related issues. ๐Ÿงฉ

TFMCC is designed to be reasonably fair when competing for bandwidth with TCP flows. A multicast flow is "reasonably fair" if its sending rate is generally within a factor of two of the sending rate of a TCP flow from the sender to the slowest receiver of the multicast group under the same network conditions. โš–๏ธ

In general, TFMCC has a low variation of throughput, which makes it suitable for applications where a relatively smooth sending rate is of importance, such as streaming media. The penalty of having smooth throughput while competing fairly for bandwidth is a reduced responsiveness to changes in available bandwidth. Thus TFMCC should be used when the application has a requirement for smooth throughput, in particular, avoiding halving of the sending rate in response to a single packet drop. For applications that simply need to multicast as much data as possible in as short a time as possible, PGMCC [10] may be more suitable. Smooth vibes only, bestie ๐ŸŒŠ

This memo contains part of the definitions necessary to fully specify a Reliable Multicast Transport protocol in accordance with RFC 2357. As per RFC 2357, the use of any reliable multicast protocol in the Internet requires an adequate congestion control scheme. This document specifies an experimental congestion control scheme. While waiting for initial deployment and experience to show this scheme to be effective and scalable, the IETF publishes this scheme in the "Experimental" category. ๐Ÿงช

It is the intent of the Reliable Multicast Transport (RMT) Working Group to re-submit the specification as an IETF Proposed Standard as soon as the scheme is deemed adequate. Glow-up incoming ๐Ÿฆ‹

As described in RFC 3048 [1], TFMCC is a building block that is intended to be used, in conjunction with other building blocks, to help specify a protocol instantiation. It follows the general guidelines provided in RFC 3269 [2]. In particular, TFMCC is a suitable congestion control building block for NACK-Oriented Reliable Multicast (NORM) [5].

1.2. Environmental Requirements and Considerations ๐ŸŒˆ

TFMCC is intended to be a congestion control scheme that can be used in a complete protocol instantiation that delivers objects and streams (both reliable content delivery and streaming of multimedia information).

TFMCC is most applicable for sessions that deliver a substantial amount of data (i.e., in length from hundreds of kilobytes to many gigabytes) and whose duration is on the order of tens of seconds or more.

TFMCC is intended for multicast delivery. There are currently two models of multicast delivery: the Any-Source Multicast (ASM) model as defined in [6] and the Source-Specific Multicast (SSM) model as defined in [7]. TFMCC works with both multicast models, but in a slightly different way. When ASM is used, feedback from the receivers is multicast to the sender, as well as to all other receivers. Feedback can be either multicast on the same group address used for sending data or on a separate multicast feedback group address. For SSM, the receivers must unicast the feedback directly to the sender. Hence, feedback from a receiver will not be received by other receivers. ๐Ÿ‘€

TFMCC inherently works with all types of networks that allow bi-directional communication, including LANs, WANs, Intranets, the Internet, asymmetric networks, wireless networks, and satellite networks. However, in some network environments varying the sending rate to the receivers may not be advantageous (e.g., for a satellite or wireless network, there may be no mechanism for receivers to effectively reduce their reception rate since there may be a fixed transmission rate allocated to the session). ๐Ÿ›ฐ๏ธ

The difference in responsiveness of TFMCC and TCP may result in significant throughput differences in case of a very low bitrate. TFMCC requires an estimate of the loss event rate to calculate a fair sending rate. This estimate may be inaccurate in case TFMCC receives only very few packets per RTT. TFMCC should not be used together with TCP if the capacity of the bottleneck link is less than 30KBit/s (e.g., a very slow modem connection). TFMCC may also achieve a rate that is very different from the average TCP rate in case buffer space at the bottleneck is severely underprovisioned. In particular, TFMCC is less susceptible to small buffer sizes since TFMCC spaces out packets in time, whereas TCP sends them back to back. Thus TCP is much more likely to see a packet loss if buffer space is scarce. Not the vibe for a dial-up connection ๐Ÿ’€

TFMCC is designed for applications that use a fixed packet size and vary their sending rate in packets per second in response to congestion. Some applications (e.g., those using audio) require a fixed interval of time between packets and vary their packet size instead of their packet rate in response to congestion. The congestion control mechanism in this document cannot be used by those applications. ๐ŸŽ€


2. Protocol Overview โœจ

Okay so TFMCC is basically TFRC's glow-up for multicast ๐Ÿฆ‹. It takes the basic TFRC moves and brings them into multicast land ๐ŸŒธ. To stay fair with TCP, every TFMCC receiver checks the network conditions it's seeing and works out a rate that's TCP-friendly on the path between the sender and itself ๐Ÿ’…. That rate comes from a TCP throughput equation, which roughly tells you TCP's sending rate based on the loss event rate, round-trip time (RTT), and packet size. A loss event is one or more lost or marked packets among the packets received during one RTT, and a marked packet is a congestion signal from Explicit Congestion Notification (ECN) [9]. The multicast sender adjusts its rate to match the receiver having the worst network conditions ๐Ÿซถ.

Basically, TFMCC's congestion control works like this:

  • Each receiver measures the loss event rate and its RTT to the sender.
  • Each receiver then uses that info, plus the TCP throughput equation, to work out a TCP-friendly sending rate.
  • Through a distributed feedback suppression mechanism, only some receivers are allowed to send feedback, so the sender doesn't get a feedback implosion ๐Ÿ™ˆ. The mechanism makes sure receivers reporting a low desired transmission rate have a high probability of sending feedback.
  • Receivers whose feedback isn't suppressed send the calculated transmission rate back to the sender in receiver reports. Those reports do two jobs: they tell the sender what rate to use, and they let receivers measure their RTT.
  • The sender picks the receiver reporting the lowest rate as the current limiting receiver (CLR). Whenever feedback with an even lower rate reaches the sender, that receiver becomes CLR and the sending rate drops to match its calculated rate. The sending rate goes up when the CLR reports a calculated rate higher than the current sending rate.

The dynamics of TFMCC are sensitive to how the measurements are performed and applied, and to which feedback suppression mechanism gets picked. We recommend specific mechanisms below for doing and applying these measurements. Other mechanisms are possible, but it's important to understand how they interact and affect TFMCC's dynamics ๐ŸŽ€.

2.1. TCP Throughput Equation

Any realistic equation that gives TCP throughput as a function of loss event rate and RTT should be suitable for TFMCC. However, the TCP throughput equation used must reflect TCP's retransmit timeout behavior, since that dominates TCP throughput at higher loss rates ๐Ÿ“‰. Also, the assumptions the throughput equation makes about the loss event rate parameter have to be a reasonable match for how the loss rate or loss event rate is actually measured. That match isn't perfect for the throughput equation and loss rate measurement mechanisms given below, but in practice the assumptions turn out close enough ๐Ÿคž.

The throughput equation we currently recommend for TFMCC is a slightly simplified version of the Reno TCP throughput equation from [8]:

                              8 s
X =  ---------------------------------------------------------   (1)
     R * (sqrt(2*p/3) + (12*sqrt(3*p/8) * p * (1+32*p^2)))

where

  • X is the transmit rate in bits/second.
  • s is the packet size in bytes.
  • R is the round-trip time in seconds.
  • p is the loss event rate, between 0.0 and 1.0, of the number of loss events as a fraction of the number of packets transmitted.

In the future, different TCP equations may be substituted for this one. The requirement is that the throughput equation be a reasonable approximation of the sending rate of TCP for conformant TCP congestion control ๐Ÿ’–.

The parameters s, p and R need to be measured or calculated by a TFMCC implementation. R is measured as specified in Section 4.3.2, and p is measured as specified in Section 5. The parameter s is normally known to an application. That may not be the case in two situations:

  • The packet size naturally varies depending on the data. Here the size varies, but that variation isn't coupled to the transmit rate. It should normally be safe to use an estimate of the mean packet size for s.
  • The application needs to change the packet size rather than the number of packets per second to do congestion control. This would normally be the case with packet audio applications, where each packet has to represent a fixed interval of time. Such applications need a different way of measuring parameters.

Currently, TFMCC cannot be used for the second class of applications ๐Ÿ˜ญ.

2.2. Packet Contents

Before we spec the sender and receiver functionality, let's look at the congestion control info in packets from the sender and the feedback packets from receivers ๐Ÿงš. Info from the sender can either go in separate congestion control messages or be piggybacked onto data packets. If separate congestion control messages are sent at time intervals longer than the interval between data packets (for example, once per feedback round), it's necessary to include timestamp info for more than one receiver, so enough receivers can measure their RTT.

As TFMCC gets used along with a transport protocol, we don't specify packet formats, since those depend on the details of the transport protocol used. The recommended representation of the header fields is given below. Alternatively, if the computational overhead of a floating point representation is prohibitive, fixed point arithmetic can be used at the expense of larger packet headers. Senders and receivers of a specific TFMCC instance need to agree on a common encoding for the header fields ๐Ÿค.

2.2.1. Sender Packets

Each packet sent by the data sender contains the following information:

  • A sequence number i. This number is incremented by one for each data packet transmitted. The field must be sufficiently large that it does not wrap, causing two different packets with the same sequence number to be in the receiver's recent packet history at the same time. In most cases, the sequence number will be supplied by the transport protocol used along with TFMCC.
  • A suppression rate X_supp in bits/s. Only receivers with a calculated rate lower than the suppression rate are eligible to give feedback, unless their RTT is higher than the maximum RTT described below, in which case they are also eligible to give feedback. The suppression rate should be represented as a 12-bit floating point value with 5 bits for the unsigned exponent and 7 bits for the unsigned mantissa (to represent rates from 100 bit/s to 400 Gbit/s with an error of less than 1%) ๐Ÿ”ฅ.
  • A timestamp ts_i indicating when the packet is sent. The resolution of the timestamp should typically be milliseconds, and the timestamp should be an unsigned integer value no less than 16 bits wide.
  • A receiver ID r and a copy of the timestamp tr_r' = tr_r of that receiver's last report, which allows the receiver to measure its RTT. If there is a delay ts_d between receiving the report from receiver r and sending the data packet, then tr_r' = tr_r + ts_d is included in the packet instead. The receiver ID is described in the next section. The resolution of the timestamp echo should be milliseconds, and the timestamp should be an unsigned integer value no less than 16 bits wide. If separate congestion control messages are used instead of piggybacked ones, the packet needs to contain a list of receiver IDs with corresponding timestamps, so enough receivers can simultaneously measure their RTT. For the default values used for the feedback process, this corresponds to a list size on the order of 10 to 20 entries.
  • A flag is_CLR indicating whether the receiver with ID r is the CLR ๐Ÿ‘‘.
  • A feedback round counter fb_nr. This counter is incremented by the sender at the beginning of a new feedback round to notify receivers that all feedback for older rounds should be suppressed. The feedback round counter should be at least 4 bits wide.
  • A maximum RTT value R_max, representing the maximum of the RTTs of all receivers. The RTT should be measured in milliseconds. An 8-bit floating point value with 4 bits for the unsigned exponent and 4 bits for the unsigned mantissa (to represent RTTs from 1 millisecond to 64 seconds with an error of ca. 6%) should be used for the representation.

2.2.2. Feedback Packets

Each feedback packet sent by a data receiver contains the following information:

  • A unique receiver ID r. In most cases, the receiver ID will be supplied by the transport protocol, but it may simply be the IP address of the receiver.
  • A flag have_RTT indicating whether the receiver has made at least one RTT measurement since it joined the session.
  • A flag have_loss indicating whether the receiver experienced at least one loss event since it joined the session.
  • A flag receiver_leave indicating that the receiver will leave the session (and should therefore not be CLR) ๐Ÿšช.
  • A timestamp tr_r indicating when the feedback packet is sent. The representation of the timestamp should be the same as that of the timestamp echo in the data packets.
  • An echo ts_i' of the timestamp of the last data packet received. If the last packet received at the receiver has sequence number i, then ts_i' = ts_i is included in the feedback. If there is a delay tr_d between receiving that last data packet and sending feedback, then ts_i' = ts_i + tr_d is included in the feedback instead. The representation of the timestamp echo should be the same as that of the timestamp in the data packets.
  • A feedback round echo fb_nr, reflecting the highest feedback round counter value received so far. The representation of the feedback round echo should be the same as the one used for the feedback round counter in the data packets.
  • The desired sending rate X_r. This is the rate calculated by the receiver to be TCP-friendly on the path from the sender to this receiver. The representation of the desired sending rate should be the same as that of the suppression rate in the data packets ๐Ÿ“.

3. Data Sender Protocol ๐ŸŒˆ

The data sender multicasts a stream of data packets to the data receivers at a controlled rate. Whenever feedback is received, the sender checks whether it's necessary to switch CLRs and to readjust the sending rate ๐Ÿ’….

The main tasks that a TFMCC sender has to provide are:

  • adjusting the sending rate,
  • controlling receiver feedback, and
  • assisting receiver-side RTT measurements.

3.1. Sender Initialization

At initialization of the sender, the maximum RTT is set to a value that should be larger than the highest RTT to any of the receivers. It should not be smaller than 500 milliseconds for operation in the public Internet. The sending rate X is initialized to 1 packet per maximum RTT โญ.

3.2. Determining the Maximum RTT ๐Ÿ’–

Okay so every time a feedback packet lands at the sender, it works out the instantaneous RTT to that receiver like this:

R_r = ts_now - ts_i'

where ts_now is the time the feedback packet arrived. Receivers already adjust ts_i' for the gap between receiving the last data packet and sending their report, so that gap doesn't get counted in R_r โœจ. If the actual RTT is smaller than the resolution of the timestamps and ts_now equals ts_i', then R_r is set to the smallest positive RTT value larger than 0 (i.e., 1 millisecond in our case) ๐Ÿซถ. If the instantaneous RTT is bigger than the current maximum RTT, the maximum RTT jumps up to that value:

R_max = R_r

Otherwise, if no feedback with a higher instantaneous RTT than the maximum RTT comes in during a feedback round (see Section 3.4), the maximum RTT drops to:

R_max = MAX(R_max * 0.9, R_peak)

where R_peak is the peak receiver RTT measured during that feedback round.

The maximum RTT is mainly used for feedback suppression among receivers with heterogeneous RTTs ๐Ÿฆ‹. Feedback suppression is closely coupled to the sending of data packets, and that's why the maximum RTT must not decrease below the maximum time interval between consecutive data packets:

R_max = max(R_max, 8s/X + ts_gran)

where ts_gran is the granularity of the sender's system clock (see Section 3.7).

3.3. Adjusting the Sending Rate ๐ŸŽ€

When a feedback packet from receiver r arrives at the sender, the sender has to check whether it needs to adjust the transmission rate and switch to a new CLR. It's giving decision time ๐Ÿ‘‘

How the rate gets adjusted depends on the desired rate X_r in the receiver report. There are four cases:

  1. If no CLR is present, receiver r becomes the current limiting receiver. The sending rate X is directly set to X_r, so long as this would result in a rate increase of less than 8s/R_max bits/s (i.e., 1 packet per R_max). Otherwise X is gradually increased to X_r at an increase rate of no more than 8s/R_max bits/s every R_max seconds.
  2. If receiver r is not the CLR but a CLR is present, then receiver r becomes the current limiting receiver if X_r is less than the current sending rate X and the receiver_leave flag of that receiver's report is not set. Furthermore, the sending rate is reduced to X_r.
  3. If receiver r is not the CLR but a CLR is present and the receiver_leave flag of the CLR's last report was set, then receiver r becomes the current limiting receiver. However, if X_r > X, the sending rate is not increased to X_r for the duration of a feedback round, so that other (lower rate) receivers have time to give feedback and get selected as CLR ๐Ÿงš
  4. If receiver r is the CLR, the sending rate is set to the minimum of X_r and X + 8s/R_max bits/s.

If the receiver hasn't measured its RTT yet but has already experienced packet loss (indicated by the corresponding flags in the receiver report), the receiver report will include a desired rate based on the maximum RTT instead of the actual RTT to that receiver ๐Ÿ™ˆ. In that case, the sender adjusts the desired rate using its measurement of the instantaneous RTT R_r to that receiver:

X_r' = X_r * R_max / R_r

X_r' is then used instead of X_r to detect whether to switch to a new CLR.

If the TFMCC sender gets no reports from the CLR for 4 RTTs, the sending rate is cut in half, unless the CLR was selected less than 10 RTTs ago. Also, if the sender gets no reports from the CLR for at least 10 RTTs, it assumes that the CLR crashed or left the group ๐Ÿ’€. A new CLR is then selected from the feedback that subsequently arrives at the sender, and we increase as in case 3, above.

If no new CLR can be selected (i.e., with no feedback from any of the receivers at all), the sending rate has to be reduced even further. For every 10 consecutive RTTs without feedback, the sending rate is cut in half. The rate is reduced to at most one packet every 8 seconds.

Note that when receivers stop receiving data packets, they stop sending feedback too. This eventually causes the sending rate to be reduced in the case of network failure ๐Ÿ˜ญ. If the network recovers later on, a linear increase to the calculated rate of the CLR occurs at 8s/R_max bits/s every R_max.

An application using TFMCC may have a minimum sending rate requirement, where the application becomes unusable if the sending rate keeps falling below that minimum rate. The application should exclude receivers that report such a low rate from the multicast group. The specific mechanism to do this is application dependent and beyond the scope of this document ๐ŸŒธ.

3.4. Controlling Receiver Feedback ๐Ÿ”ฅ

The receivers that are allowed to send a receiver report get decided in so-called feedback rounds. Feedback rounds have a duration T of six times the maximum RTT. If the multicast model is ASM (i.e., receiver feedback is multicast to the whole group), the duration of a feedback round may be reduced to four times the maximum RTT โญ.

Only receivers that want to report a rate lower than the suppression rate X_supp, or those with a higher RTT than R_max, may send feedback. At the beginning of each feedback round, X_supp is set to the highest possible value that can be represented. As feedback arrives at the sender over the course of a feedback round, X_supp decreases, so more and more feedback gets suppressed towards the end of the round. How receiver feedback is spread out over the feedback round is discussed in Section 4.5.

Whenever non-CLR feedback for the current round arrives at the sender, X_supp is reduced to:

X_supp = (1-g) * X_r

if X_supp > X_r. Feedback that causes the corresponding receiver to be selected as CLR, but that came from a non-CLR receiver at the time of sending, also contributes to the feedback suppression. Note that X_r must not be adjusted by the sender to reflect the receiver's real RTT when X_r was calculated using the maximum RTT, as is done for setting the sending rate (Section 3.3); otherwise, a feedback implosion is possible ๐Ÿ’…. The parameter g determines to what extent higher rate feedback can suppress lower rate feedback. This mechanism guarantees that the lowest calculated rate reported lies within a factor of g of the actual lowest calculated rate of the receiver set (see [13]). A value of g of 0.1 is recommended.

To let receivers suppress their feedback, the sender's suppression rate needs to be updated whenever feedback is received. This suppression rate has to be communicated to the receivers in a timely manner, either by including it in the data packet header or, if separate congestion control messages are used, by sending a message with the suppression rate whenever the rate changes significantly (i.e., when it is reduced to less than (1-g) times the previously advertised suppression rate) ๐Ÿ“.

After a time span of T, the feedback round ends if non-CLR feedback was received during that time. Otherwise, the feedback round ends as soon as the first non-CLR feedback message arrives at the sender, but at most after 2T. The feedback round counter is incremented by one, and the suppression rate X_supp is reset to the highest representable value. The feedback round counter restarts with round 0 after a wrap-around โœจ.

3.5. Assisting Receiver-Side RTT Measurements ๐Ÿฆ‹

Receivers measure their RTT by sending a timestamp with a receiver report, which the sender echoes back. If congestion control information is piggybacked onto data packets, usually only one receiver ID and timestamp can be included. If multiple feedback messages from different receivers arrive at the sender during the time between two data packets, the sender has to decide which receiver gets to measure the RTT ๐Ÿค”. The same goes if separate congestion control messages can echo multiple receiver timestamps at once, but the number of receivers that gave feedback since the last congestion control message is bigger than the list size.

The sender's timestamp echoes are prioritized in the following order:

  1. a new CLR (after a change of CLR's) or a CLR without any previous RTT measurements
  2. receivers without any previous RTT measurements, in the order of the feedback round echo of the corresponding receiver report (i.e., older feedback first)
  3. non-CLR receivers with previous RTT measurements, again in ascending order of the feedback round echo of the report
  4. the CLR

Ties are broken in favor of the receiver with the lowest reported rate ๐Ÿ‘‘.

It's necessary to account for the time that passes between receiving a report and sending the next data packet. That time needs to be deducted from the RTT, so it has to be added to the receiver's timestamp value ๐Ÿซถ.

Whenever no feedback packets arrive in the interval between two data packets, the CLR's last timestamp, adjusted by the appropriate offset, is echoed. When the number of packets per RTT is so low that all packets carry a non-CLR receiver's timestamp, the CLR's timestamp and ID are included in a data packet at least once per feedback round ๐ŸŒˆ.

3.6. Slowstart ๐Ÿš€

TFMCC uses a slowstart mechanism to quickly approach its fair bandwidth share at the start of a session ๐Ÿ’–. During slowstart, the sending rate increases exponentially. The rate increase is limited to the minimum of the rates included in the receiver reports, and receivers report twice the rate at which they currently receive data. As in normal congestion control mode, the receiver with the smallest reported rate becomes CLR. Since a receiver can never receive data at a rate higher than its link bandwidth, this effectively limits the overshoot to twice that bandwidth ๐Ÿ”ฅ. If the resulting increase over R_max is less than 8s/R_max bits/s, the sender may choose to increase the rate by up to 8s/R_max bits/s every R_max. The current sending rate is gradually adjusted to the target rate reported in the receiver reports over the course of an RTT. Slowstart ends as soon as any one of the receivers experiences its first packet loss. Since that receiver's calculated rate will be lower than the current sending rate, that receiver gets selected as CLR ๐Ÿ“.

During slowstart, the upper bound on the rate increase of 8s/R_max bits/s every RTT does not apply. Only after the TFMCC sender receives the first report with the have_loss flag set is the rate increase limited in this way ๐Ÿ™ˆ.

Slowstart may also be used after the sender has been idle for some time, to quickly get back to the previous sending rate โœจ. When the sender stops sending data packets, it records the current sending rate X' = X. Every 10 RTTs, the allowed sending rate is halved due to lack of receiver feedback, as specified in Section 3.3. This halving may happen multiple times. When the sender resumes, it may perform a slowstart from the current allowed rate up to the recorded rate X'. Slowstart ends after the first packet loss by any of the receivers, or as soon as X' is reached ๐Ÿงš.

To this end, receivers have to clear the have_loss flag after 10 RTTs without data packets, as specified in Section 4.3.1. The have_loss flag is only used during slowstart. Therefore, clearing the flag has no effect if no packets arrived due to network partitioning or packet loss ๐Ÿฆ‹.

3.7. Scheduling of Packet Transmissions

okay so TFMCC is rate-based ๐ŸŒธ, and operating systems literally cannot schedule things precisely (rude ๐Ÿ’€). So the sender has to be opportunistic about sending data packets, which keeps the correct average rate even when the OS scheduling is coarse or irregular ๐Ÿฆ‹. A typical sending loop will work out the right gap between packets, ts_ipi, like this:

ts_ipi = 8s/X

When a sender first starts sending at time t_0, it calculates ts_ipi and then a nominal send time for packet 1: t_1 = t_0 + ts_ipi. โœจ When the application goes idle, it checks the current time, ts_now, and asks to be rescheduled after (ts_ipi - (ts_now - t_0)) seconds. When the application wakes back up, it checks ts_now again. If (ts_now > t_1 - delta), then packet 1 gets sent (more on delta below ๐Ÿ‘€).

Next, a new ts_ipi may be calculated and used for a nominal send time for packet 2, t_2 = t_1 + ts_ipi. ๐Ÿ’… The process then repeats, with each packet's nominal send time calculated from the one before it. Note that the actual send time, ts_i, not the nominal send time, is what goes into the timestamp in the packet header ๐ŸŽ€.

Sometimes, when the nominal send time t_i of the next packet is worked out, it's already true that ts_now > t_i - delta ๐Ÿ˜ญ. In that case, the packet should be sent immediately. So if the OS timer granularity is coarse and the transmit rate is high, TFMCC may send short bursts of several packets, separated by intervals of the OS timer granularity. Iconic chaos, but intentional ๐Ÿ“.

The parameter delta gives a little wiggle room in when a packet gets sent ๐Ÿงš. If the OS has a scheduling timer granularity of ts_gran seconds, then delta would typically be set to:

delta = min(ts_ipi/2, ts_gran/2)

ts_gran is 10 milliseconds on many Unix systems. If ts_gran is not known, a value of 10 milliseconds can be safely assumed ๐ŸŒˆ.


4. Data Receiver Protocol โœจ

Receivers measure the current network conditions (namely, RTT and loss event rate) and use that info to calculate a rate that's fair to competing traffic ๐Ÿ‘‘. The rate then gets communicated to the sender in receiver reports. Because there can be a potentially large number of receivers, it's undesirable for all of them to send reports, especially not at the same time ๐Ÿ˜ญ.

For the receiver side, we'll first look at how receivers measure the network parameters, and then talk about the feedback process ๐Ÿ’–.

4.1. Receiver Initialization

The receiver gets initialized when it receives the first data packet ๐ŸŒธ. Its RTT is set to the maximum RTT value contained in that data packet. This initial value is used as the receiver's RTT until the first real RTT measurement is made. The loss event rate is initialized to 0. Also, the flags receiver_leave, have_RTT, and have_loss get cleared ๐Ÿงน.

4.2. Receiver Leave

A receiver that sends feedback but wants to leave the TFMCC session within the next feedback round can give a heads up by setting the receiver_leave flag in its report ๐Ÿ‘‹. If the leaving receiver is the CLR, the receiver_leave flag should be set for all the reports within the feedback round before the leave takes effect ๐Ÿซถ.

4.3. Measurement of the Network Conditions

Receivers have to update their estimate of the network parameters with every new data packet they receive ๐Ÿ”ฅ.

4.3.1. Updating the Loss Event Rate

When a data packet is received, the receiver adds it to the packet history. Then it recalculates the new value of the loss event rate p. The loss event rate measurement mechanism is described separately in Section 5 ๐Ÿ’….

When a loss event is detected, the flag have_loss is set. In case no data packets are received for 10 consecutive RTTs, the flag gets cleared so the sender can slowstart ๐Ÿข. It gets set again when new data packets arrive and a loss event is detected ๐Ÿฆ‹.

4.3.2. Basic Round-Trip Time Measurement

When a receiver gets a data packet that carries the receiver's own ID in the r field, the receiver updates its RTT estimate ๐Ÿ’œ.

  1. The current RTT is calculated as:
R_sample = tr_now - tr_r'

where tr_now is the time the data packet arrives at the receiver, and tr_r' is the receiver report timestamp echoed in the data packet. If the actual RTT is smaller than the resolution of the timestamps and tr_now equals tr_r', then R_sample is set to the smallest positive RTT value larger than 0 (i.e., 1 millisecond in our case) ๐Ÿค.

  1. The smoothed RTT estimate R is updated:
If no feedback has been received before
    R = R_sample

Else
    R = q*R + (1-q)*R_sample

A filter parameter q of 0.5 is recommended for non-CLR receivers. The CLR performs RTT measurements way more often, so it should use a higher filter value. We recommend using q=0.9. Note that TFMCC is not sensitive to the precise value for the filter constant ๐ŸŒˆ.

Optionally, sender-based RTT measurements can be used instead of receiver-based ones ๐Ÿงš. The sender already determines the RTT to a receiver from the receiver's echo of the sender's own timestamp, for the calculation of the maximum RTT. For sender-based RTT measurements, this RTT measurement needs to be communicated to the receiver. Instead of including an echo of the receiver's timestamp, the sender includes the receiver's RTT in the next data packet, using the prioritization rules described in Section 3.5.

To keep things simple for the sender, smoothing of RTT samples as described above should still be done at the receiver ๐Ÿ’–.

4.3.3. One-Way Delay Adjustments

When an RTT measurement is performed, the receiver also figures out the one-way delay D_r from itself to the sender:

D_r = tr_r' - ts_i

where ts_i and tr_r' are the timestamp and receiver report timestamp echo contained in the data packet. With each new data packet j, the receiver can now calculate an updated RTT estimate as:

R' = max(D_r + tr_now - ts_j, 1 millisecond)

In between RTT measurements, the updated R' is used instead of the smoothed RTT R. Like the RTT samples, R' must be strictly positive ๐Ÿซถ. When a new measurement is made, all interim one-way delay measurements are discarded (i.e., the smoothed RTT is updated according to Section 4.3.2 without taking the interim one-way delay adjustments into account) ๐Ÿ—‘๏ธ.

For the one-way delay measurements, the clocks of the sender and receivers don't need to be synchronized ๐Ÿ•ฐ๏ธ. Clock skew cancels itself out when both one-way measurements get added to form an RTT estimate, as long as clock drift between real RTT measurements is negligible. Main character energy in math form โœจ.

The same one-way delay adjustments should be applied to the RTT supplied by the sender when using sender-based RTT measurements ๐ŸŽ€.

4.3.4. Receive Rate Measurements

When a receiver hasn't experienced any loss events, it can't calculate a TCP-friendly rate to include in the receiver reports ๐Ÿ˜ญ. So instead, the receiver measures the current receive rate and sets the desired rate X_r to twice the receive rate ๐Ÿ”ฅ.

The receive rate in bits/s is measured as the number of bits received over the last k RTTs. This takes into account the IP and transport packet headers, but excludes the link-layer packet headers. A value for k between 2 and 4 is recommended ๐Ÿ“.

4.4. Setting the Desired Rate

When a receiver measures a non-zero loss event rate, it calculates the desired rate using Equation (1) ๐Ÿงฎ. In case no RTT measurement is available yet, the maximum RTT is used instead of the receiver's RTT. The desired rate X_r gets updated whenever the loss event rate or the RTT changes ๐Ÿ’….

A receiver may decide not to report desired rates that are below 1 packet per 8 seconds, since a sender is very slow to recover from such low sending rates ๐ŸŒ. In this case, the receiver reports a desired rate of 1 packet per 8 seconds. However, it must leave the multicast group if, for more than 120 seconds, the calculated rate falls below the reported rate and the current sending rate is higher than the receiver's calculated rate. Not the vibe of a dropped-out receiver, but it's the rule ๐Ÿ™ˆ.

As mentioned above, calculating the desired rate isn't possible before the receiver experiences the first loss event. In that case, twice the rate at which data is received is included in the receiver reports as X_r, so the sender can slowstart as described in Section 3.6. This is also done when the sender resumes sending data packets after the have_loss flag was cleared due to the sender being idle ๐ŸŒธ.

4.5. Feedback and Feedback Suppression ๐Ÿ’Œ

Okay so fb_nr is basically a receiver's bookmark ๐Ÿ”– for the highest feedback round counter value it has received so far. When a new data packet shows up with a higher feedback round counter than fb_nr, a new feedback round begins, fb_nr gets updated, and any outstanding feedback for the old round is canceled ๐Ÿ™…โ€โ™€๏ธ. Now here's the plot twist ๐ŸŒ€: if a feedback number arrives that is more than half the feedback number space lower than fb_nr, the receiver assumes the round counter wrapped around. So it cancels the feedback timer and updates fb_nr too. Wraparound energy, iconic ๐Ÿ’…

The CLR is giving independent vibes ๐Ÿ‘‘. It sends its feedback separately from all the other receivers, once per RTT. Its feedback doesn't suppress anyone else's feedback, and nobody else's feedback can suppress it either. It's untouchable, honestly.

Non-CLR receivers set a feedback timer at the start of a feedback round โฐ. They use an exponentially weighted random timer mechanism, so the timer is set to expire after:

t = max(T * (1 + log(x)/log(N)), 0)

where:

  • x is a random variable uniformly distributed in (0,1]
  • T is the duration of a feedback round (i.e., 6 * R_max)
  • N is an estimated upper bound on the number of receivers

N is a constant specific to the TFMCC protocol ๐Ÿงš. Since TFMCC scales to up to thousands of receivers, setting N to 10,000 for all receivers (and limiting the TFMCC session to at most 10,000 receivers) is recommended. Bestie, keep the squad under 10,000 ๐Ÿ“.

A feedback packet gets sent when the feedback timer expires, unless the timer was canceled first ๐Ÿ“ฌ. When the multicast model is ASM, feedback is multicast to the whole group. Otherwise, it's unicast to the sender. The feedback packet includes the calculated rate that's valid at the time the packet is sent, not the rate from when the timer was set โณ. The copy of the timestamp ts_i from the last data packet received, which goes in the feedback packet, needs to be adjusted by the time interval between receiving that data packet and sending the report. That way the sender can correctly infer the instantaneous RTT. So you add that time interval to the timestamp value. Math-brain moment ๐Ÿง ๐Ÿ’œ

The timer gets canceled if a data packet arrives with a lower suppression rate than the receiver's calculated rate AND a higher or equal maximum RTT than the receiver's RTT ๐Ÿ™ˆ. Likewise, a data packet that signals the beginning of a new feedback round cancels all feedback for older rounds. With ASM, the timer is also canceled if a feedback packet comes in from another non-CLR receiver reporting a lower rate.

Here's the messy part ๐Ÿ˜ญ. The feedback suppression process is complicated because the calculated rates of the receivers change during a feedback round. If the calculated rates drop quickly for everyone, feedback suppression can no longer prevent a feedback implosion, since earlier feedback will always report a higher rate than the current feedback. To make the suppression mechanism robust when rates are changing, we introduce X_fbr, which is the calculated rate of a receiver at the beginning of a feedback round โœจ. A receiver needs to suppress its feedback not only when the suppression rate is less than the receiver's current calculated rate, but also when the suppression rate falls below X_fbr.

When the maximum RTT changes significantly during one feedback round, the feedback timer has to be rescheduled in proportion to that change ๐Ÿ“:

t = t * R_max / R_max'

Here R_max is the new maximum RTT and R_max' is the previous maximum RTT. The same considerations apply when the last data packets were received more than a time interval of R_max ago ๐Ÿ•ฐ๏ธ. In that case, the difference between the inter-packet gap and the maximum RTT gets added to the feedback time, to prevent a feedback implosion (for example, if the sender crashed ๐Ÿ’€):

t = t + max(tr_now - tr_i - R_max, 0)

where tr_i is the time when the last data packet arrived at the receiver.

More details on how the feedback suppression mechanism behaves can be found in [13] and [3] ๐Ÿ“š.


5. Calculation of the Loss Event Rate ๐ŸŒธ

Getting an accurate and stable measurement of the loss event rate is of primary importance for TFMCC, bestie ๐ŸŽ€. Loss rate measurement happens at the receiver, based on spotting lost or marked packets from the sequence numbers of the packets that arrive.

5.1. Detection of Lost or Marked Packets ๐Ÿ•ต๏ธโ€โ™€๏ธ

TFMCC assumes that every packet has a sequence number that goes up by one for each packet sent ๐Ÿ”ข. For this spec, we require that if a lost packet gets retransmitted, the retransmission gets a new sequence number, the latest one in the transmission sequence. It can't reuse the sequence number of the packet that was lost. If a transport protocol requires retransmitting with the original sequence number, then that protocol's designer has to figure out how to tell delayed packets apart from retransmitted ones, and how to detect lost retransmissions ๐Ÿงฉ.

Each receiver maintains a data structure that keeps track of which packets have arrived and which are missing ๐Ÿ“‹. For the purposes of specification, we assume this data structure is a list of packets that have arrived, along with the timestamp of when each one was received. In practice it'll normally be stored in a more compact representation, but that's implementation-specific, so do you ๐Ÿ’….

A packet is detected as lost when at least three packets with a higher sequence number than the lost packet have arrived ๐Ÿ‘€. That three-packet requirement is the same as in TCP, and it's there to make TFMCC more robust when packets get reordered ๐Ÿ”€. Unlike TCP, if a packet shows up late (after 3 subsequent packets have arrived), the late packet can fill the hole in the reception record, and the receiver can recalculate the loss event rate. Future versions of TFMCC might make the three-packet requirement adaptive based on the packet reordering being experienced, but we don't specify such a mechanism here ๐Ÿ”ฎ.

For an ECN-capable connection, a marked packet is detected as a congestion event as soon as it arrives. No waiting around for subsequent packets ๐Ÿšจ.

5.2. Translation from Loss History to Loss Events ๐Ÿฆ‹

TFMCC requires that the loss event rate be robust to several consecutive packets being lost, as long as those packets are part of the same loss event ๐Ÿ’œ. This is similar to TCP, which (typically) only performs one halving of the congestion window during any single RTT. So receivers need to map the packet loss history into a loss event record, where a loss event is one or more packets lost in an RTT.

To decide whether a lost or marked packet should start a new loss event or count as part of an existing one, we need to compare the sequence numbers and timestamps of the packets that arrived at the receiver โฑ๏ธ. For a marked packet S_new, its reception time T_new can be noted directly. For a lost packet, we can interpolate to infer the nominal "arrival time". Let's define the terms ๐Ÿ“–:

  • S_loss is the sequence number of a lost packet.
  • S_before is the sequence number of the last packet to arrive with sequence number before S_loss.
  • S_after is the sequence number of the first packet to arrive with sequence number after S_loss.
  • T_before is the reception time of S_before.
  • T_after is the reception time of S_after.

Note that T_before can be either before or after T_after because of reordering ๐ŸŒช๏ธ.

For a lost packet S_loss, we can interpolate its nominal "arrival time" at the receiver from the arrival times of S_before and S_after. So:

T_loss = T_before + ( (T_after - T_before)
            * (S_loss - S_before)/(S_after - S_before) );

Note that if the sequence space wrapped between S_before and S_after, the sequence numbers have to be modified to account for that before the calculation happens. If the largest possible sequence number is S_max, and S_before > S_after, then modifying each sequence number S by S' = (S + (S_max + 1)/2) mod (S_max + 1) would normally be sufficient ๐Ÿ”„.

If the lost packet S_old was determined to have started the previous loss event, and we've just determined that S_new has been lost, then we interpolate the nominal arrival times of S_old and S_new, called T_old and T_new, respectively โš–๏ธ.

If T_old + R >= T_new, then S_new is part of the existing loss event ๐Ÿซถ. Otherwise, S_new is the first packet of a new loss event ๐ŸŽ‰.

5.3. Inter-Loss Event Interval ๐Ÿ“

If a loss interval, A, is determined to have started with packet sequence number S_A, and the next loss interval, B, started with packet sequence number S_B, then the number of packets in loss interval A is given by (S_B - S_A) โœจ.

5.4. Average Loss Interval ๐Ÿ“Š

To calculate the loss event rate p, we first calculate the average loss interval ๐Ÿ’–. This is done using a filter that weights the n most recent loss event intervals in such a way that the measured loss event rate changes smoothly ๐ŸŒˆ.

Weights w_0 to w_(n-1) are calculated as:

If (i < n/2)
   w_i = 1;
Else
   w_i = 1 - (i - (n/2 - 1))/(n/2 + 1);

So if n=8, the values of w_0 to w_7 are:

1.0, 1.0, 1.0, 1.0, 0.8, 0.6, 0.4, 0.2

The value of n (the number of loss intervals used in calculating the loss event rate) determines how fast TFMCC responds to changes in the level of congestion ๐ŸŽ๏ธ. As currently specified, TFMCC should not be used for values of n significantly greater than 8, for traffic that might compete in the global Internet with TCP. At the very least, safe operation with values of n greater than 8 would require a slight change to TFMCC's mechanisms, to include a more severe response to two or more round-trip times with heavy packet loss ๐Ÿšฉ.

When calculating the average loss interval, we need to decide whether to include the interval since the most recent packet loss event. We only do this if it's large enough to increase the average loss interval ๐Ÿค”.

So, if the most recent loss intervals are I_0 to I_n, with I_0 being the interval since the most recent loss event, then we calculate the average loss interval I_mean as:

I_tot0 = 0;
I_tot1 = 0;
W_tot = 0;
for (i = 0 to n-1) {
  I_tot0 = I_tot0 + (I_i * w_i);
  W_tot = W_tot + w_i;
}
for (i = 1 to n) {
  I_tot1 = I_tot1 + (I_i * w_(i-1));
}
I_tot = max(I_tot0, I_tot1);
I_mean = I_tot/W_tot;

And finally, the loss event rate p is simply:

p = 1 / I_mean;

5.5. History Discounting ๐Ÿ’…

okay so in 5.4 we learned the most recent loss interval only gets 4/(3*n) of the total weight, no matter how big it is ๐Ÿ™ˆ this section is the optional history discounting thing, which lets TFMCC receivers shift the weights so the newest interval gets more of the spotlight. it only kicks in when the most recent interval is more than twice the computed average loss interval. main character moment ๐Ÿ‘‘

to make this work, we attach a discount factor DF_i to each loss interval L_i. these are floating point numbers, and the discount array keeps the cumulative discounting history for every interval. at the start, every DF_i is set to 1:

for (i = 0 to n) {
  DF_i = 1;
}

there's also a general discount factor DF, a floating point number that starts at 1 too ๐ŸŒธ we'll look at how the discount factors get used in the average first, and then later in this section we'll see how they change over time.

as in 5.4, the average loss interval uses the n previous loss intervals I_1, ..., I_n, plus I_0, which is the number of packets received since the last loss event. using the discount factors is a small tweak to the 5.4 procedure, and it looks like this:

I_tot0 = I_0 * w_0
I_tot1 = 0;
W_tot0 = w_0
W_tot1 = 0;
for (i = 1 to n-1) {
  I_tot0 = I_tot0 + (I_i * w_i * DF_i * DF);
  W_tot0 = W_tot0 + w_i * DF_i * DF;
}
for (i = 1 to n) {
  I_tot1 = I_tot1 + (I_i * w_(i-1) * DF_i);
  W_tot1 = W_tot1 + w_(i-1) * DF_i;
}
p = min(W_tot0/I_tot0, W_tot1/I_tot1);

now the general discount factor DF gets updated on every single packet arrival โœจ first, the receiver works out the weighted average I_mean of the loss intervals I_1, ..., I_n:

I_tot = 0;
W_tot = 0;
for (i = 1 to n) {
  W_tot = w_(i-1) * DF_i;
  I_tot = I_tot + (I_i * w_(i-1) * DF_i);
}
I_mean = I_tot / W_tot;

then it compares I_mean to I_0. if I_0 is bigger than twice I_mean, the new interval is way larger than the old ones, so DF gets updated to reduce the relative weight of the older intervals ๐Ÿ”ฅ

if (I_0 > 2 * I_mean) {
  DF = 2 * I_mean/I_0;
  if (DF < THRESHOLD)
    DF = THRESHOLD;
} else
  DF = 1;

the THRESHOLD is what keeps older intervals from an earlier stretch of heavy congestion from getting totally discounted ๐Ÿฅน we recommend a THRESHOLD of 0.5. and fun fact, I_0 keeps growing with every new packet, so DF keeps getting updated too.

when a new loss event happens, the current interval slides from I_0 into I_1, every I_i moves up to I_(i+1), and I_n gets forgotten ๐Ÿ’€ the old DF has to get folded into the discount array, and since DF_i tracks the discount for I_i, the DF_i array needs to shift as well:

for (i = 1 to n) {
  DF_i = DF * DF_i;
}
for (i = n-1 to 0 step -1) {
  DF_(i+1) = DF_i;
}
I_0 = 1;
DF_0 = 1;
DF = 1;

and that's the whole optional history discounting mechanism ๐ŸŽ€ just remember it's optional, and its only job is to help TFMCC react faster when congestion suddenly disappears, which shows up as a long current loss interval.

5.6. Initializing the Loss History after the First Loss Event ๐Ÿฆ‹

the number of packets received before the first loss event usually doesn't match the current loss event rate, so we don't want to trust it ๐Ÿ™…โ€โ™€๏ธ when that first loss event happens, a TFMCC receiver assumes the right data rate is the rate it was getting during the last RTT before the loss. instead of setting the first loss interval to the number of packets sent up to that first loss event, the receiver works backwards to find the loss interval that would produce the receive rate X_recv. it then uses this synthetic loss interval l_0 to seed the loss history mechanism. it's giving reverse engineering ๐Ÿงš

the initial loss interval comes from inverting a simplified version of the TCP Equation (1):

                              8s
  X_recv = sqrt(3/2) * -----------------
                        R * sqrt(1/l_0)

                X_recv * R
  ==> l_0 = (----------------)^2
              sqrt(3/2) * 8s

ngl the resulting initial loss interval is too small at higher loss rates compared to using the more accurate Equation (1). that makes the initial loss event rate more conservative ๐Ÿซถ

if a receiver is still using the initial RTT R_max instead of its real RTT, the initial loss interval ends up too large whenever the initial RTT is higher than the actual RTT ๐Ÿ˜ญ because of that, the receiver calculates a desired rate that's too high when it makes its first RTT measurement R, as long as the initial loss interval is still in the loss history. to fix that, the receiver adjusts l_0 like this:

l_0 = l_0 * (R/R_max)^2

and if the first RTT measurement happens after the initial loss interval has already left the loss history, no action is needed at all โœจ

6. Security Considerations ๐Ÿ”

okay this part is important, bestie ๐Ÿซถ TFMCC isn't a transport protocol on its own. it's a congestion control mechanism meant to be used together with a transport protocol. so security mostly has to be thought about in the context of a specific transport protocol and its authentication mechanisms.

congestion control can be turned into a denial of service attack, and one way that can happen is spoofed feedback ๐Ÿ’€ so any transport protocol using TFMCC should make sure it only accepts feedback from valid receivers of the data. exactly how to do that depends on the transport protocol itself.

congestion control can also get messed with by a greedy receiver that wants more than its fair share of the bandwidth ๐Ÿ‘€ but in TFMCC, a receiver can only influence the sending rate if it's the CLR, which means it has the lowest calculated rate of all the receivers. if it manipulates that calculated rate so it goes above the calculated rate of the second-lowest receiver, it stops being the CLR. a greedy receiver can only really boost the transmission rate significantly if it's the only participant in the session. if that kind of scenario worries you, the usual defense is some form of nonce that the receiver has to feed back to the sender to prove it got the data. but the details of that nonce depend on the transport protocol, and especially on whether the transport protocol is reliable or unreliable.

a receiver could also send feedback claiming it has a super low calculated rate ๐Ÿ™ƒ that would slow down the multicast session and might make it useless, but it obviously can't hurt the network itself.

we expect that protocols combining ECN with TFMCC will also want feedback from the receiver to the sender using the ECN nonce [12] ๐ŸŒˆ the ECN nonce is a modification to ECN that protects the sender from accidental or malicious concealment of marked packets. again, the details of that nonce depend on the transport protocol and aren't covered in this document.

7. Acknowledgments ๐Ÿงก

we'd love to shout out everyone who gave feedback and chatted with us about equation-based congestion control ๐Ÿ“ฃ that includes folks from the Reliable Multicast Research Group, the Reliable Multicast Transport Working Group, and the End-to-End Research Group. a special thank you goes to Brian Adamson, Mark Pullen, Fei Zhao, and Magnus Westerlund for feedback on earlier versions of this document ๐Ÿ’œ

8. References ๐Ÿ“š

8.1. Normative References

[1] 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.

[2] Kermode, R. and L. Vicisano, "Author Guidelines for Reliable Multicast Transport (RMT) Building Blocks and Protocol Instantiation documents", RFC 3269, April 2002.

8.2. Informative References

[3] J. Widmer and M. Handley, "Extending Equation-Based Congestion Control to Multicast Applications", Proc ACM Sigcomm 2001, San Diego, August 2001.

[4] S. Floyd, M. Handley, J. Padhye, and J. Widmer, "Equation-Based Congestion Control for Unicast Applications", Proc ACM SIGCOMM 2000, Stockholm, August 2000.

[5] Adamson, B., Bormann, C., Handley, M., and J. Macker, "Negative-Acknowledgment (NACK)-Oriented Reliable Multicast (NORM) Building Blocks", RFC 3941, November 2004.

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

[7] H. W. Holbrook, "A Channel Model for Multicast," Ph.D. Dissertation, Stanford University, Department of Computer Science, Stanford, California, August 2001.

[8] J. Padhye, V. Firoiu, D. Towsley, and J. Kurose, "Modeling TCP Throughput: A Simple Model and its Empirical Validation", Proc ACM SIGCOMM 1998.

[9] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition of Explicit Congestion Notification (ECN) to IP", RFC 3168, September 2001.

[10] L. Rizzo, "pgmcc: a TCP-friendly single-rate multicast congestion control scheme", Proc ACM Sigcomm 2000, Stockholm, August 2000.

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

[12] Spring, N., Wetherall, D., and D. Ely, "Robust Explicit Congestion Notification (ECN) Signaling with Nonces", RFC 3540, June 2003.

[13] J. Widmer and T. Fuhrmann, "Extremum Feedback for Very Large Multicast Groups", Proc NGC 2001, London, November 2001.

Authors' Addresses ๐Ÿ–Š๏ธ

Joerg Widmer DoCoMo Euro-Labs Landsberger Str. 312, Munich, Germany EMail: widmer@acm.org

Mark Handley UCL (University College London) Gower Street, London WC1E 6BT, UK EMail: m.handley@cs.ucl.ac.uk

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 in it 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 โœจ

okay so the IETF is being super clear here: it takes no position on whether any IP rights could apply to the tech in this doc, or how much of a license for it might or might not be out there ๐Ÿ’… it also hasn't done its own digging to find any of those rights, so don't assume it did ๐Ÿ™ˆ if you want the full rulebook on how rights work for RFC docs, it's all in BCP 78 and BCP 79 ๐Ÿซถ

copies of IPR disclosures sent to the IETF Secretariat are a whole thing too, along with any promises to make licenses available, or the results of anyone trying to get a general license or permission for implementers or users to use those proprietary rights. you can find all of that in the IETF online IPR repository at http://www.ietf.org/ipr ๐Ÿฆ‹

and the IETF straight up invites anyone who's interested to flag any copyrights, patents, patent applications, or other proprietary rights that might cover tech needed to implement this standard. just send that info to ietf-ipr@ietf.org ๐Ÿ’–


Acknowledgement

funding for the RFC Editor function comes from the IETF Administrative Support Activity (IASA) ๐Ÿ‘‘๐ŸŒˆ

๐Ÿ“ฆ where this page comes from