draft-ietf-tsvwg-tfrc-00.txt   draft-ietf-tsvwg-tfrc-01.txt 
Internet Engineering Task Force TSV WG Internet Engineering Task Force TSV WG
INTERNET-DRAFT Mark Handley/ACIRI INTERNET-DRAFT Mark Handley/ACIRI
draft-ietf-tsvwg-tfrc-00.txt Jitendra Padhye/ACIRI draft-ietf-tsvwg-tfrc-01.txt Jitendra Padhye/ACIRI
Sally Floyd/ACIRI Sally Floyd/ACIRI
Joerg Widmer/Univ. Mannheim Joerg Widmer/Univ. Mannheim
17 November 2000 2 March 2001
Expires: May 2001 Expires: September 2001
TCP Friendly Rate Control (TFRC): TCP Friendly Rate Control (TFRC):
Protocol Specification Protocol Specification
Status of this Document Status of this Document
This document is an Internet-Draft and is in full conformance with all This document is an Internet-Draft and is in full conformance with all
provisions of Section 10 of RFC2026. provisions of Section 10 of RFC2026.
Internet-Drafts are working documents of the Internet Engineering Task Internet-Drafts are working documents of the Internet Engineering Task
skipping to change at page 2, line 5 skipping to change at page 2, line 5
This document is a product of the IETF TSV WG. Comments should be This document is a product of the IETF TSV WG. Comments should be
addressed to the authors. addressed to the authors.
Abstract Abstract
This document specifies TCP-Friendly Rate Control (TFRC). This document specifies TCP-Friendly Rate Control (TFRC).
TFRC is a congestion control mechanism for unicast flows TFRC is a congestion control mechanism for unicast flows
operating in a best-effort Internet environment. It is operating in a best-effort Internet environment. It is
reasonably fair when competing for bandwidth with TCP flows, reasonably fair when competing for bandwidth with TCP flows,
but has a much lower variation of throughput over time but has a much lower variation of throughput over time
compared with TCP, which makes it more suitable for compared with TCP, making it more suitable for applications
applications such as telephony or streaming media where a such as telephony or streaming media where a relatively smooth
relatively smooth sending rate is of importance. sending rate is of importance.
Table of Contents Table of Contents
1. Introduction. . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction. . . . . . . . . . . . . . . . . . . . . . 4
2. Terminology . . . . . . . . . . . . . . . . . . . . . . 4 2. Terminology . . . . . . . . . . . . . . . . . . . . . . 5
3. Protocol Mechanism. . . . . . . . . . . . . . . . . . . 4 3. Protocol Mechanism. . . . . . . . . . . . . . . . . . . 5
3.1. TCP Throughput Equation. . . . . . . . . . . . . . . 5 3.1. TCP Throughput Equation. . . . . . . . . . . . . . . 5
3.2. Packet Contents. . . . . . . . . . . . . . . . . . . 6 3.2. Packet Contents. . . . . . . . . . . . . . . . . . . 7
3.2.1. Data Packets. . . . . . . . . . . . . . . . . . . 6 3.2.1. Data Packets. . . . . . . . . . . . . . . . . . . 7
3.2.2. Feedback Packets. . . . . . . . . . . . . . . . . 7 3.2.2. Feedback Packets. . . . . . . . . . . . . . . . . 8
4. Data Sender Protocol. . . . . . . . . . . . . . . . . . 7 4. Data Sender Protocol. . . . . . . . . . . . . . . . . . 8
4.1. Measuring the Packet Size. . . . . . . . . . . . . . 7 4.1. Measuring the Packet Size. . . . . . . . . . . . . . 8
4.2. Sender behavior when a feedback packet is 4.2. Sender behavior when a feedback packet is
received. . . . . . . . . . . . . . . . . . . . . . . . . 8 received. . . . . . . . . . . . . . . . . . . . . . . . . 9
4.3. Expiration of nofeedback timer . . . . . . . . . . . 9 4.3. Expiration of nofeedback timer . . . . . . . . . . . 10
4.4. Sender Initialization. . . . . . . . . . . . . . . . 10 4.4. Sender Initialization. . . . . . . . . . . . . . . . 11
4.5. Preventing Oscillations. . . . . . . . . . . . . . . 10 4.5. Preventing Oscillations. . . . . . . . . . . . . . . 11
4.6. Scheduling of Packet Transmissions . . . . . . . . . 11 4.6. Scheduling of Packet Transmissions . . . . . . . . . 12
5. Calculation of the loss rate (p). . . . . . . . . . . . 11 5. Calculation of the loss event rate (p). . . . . . . . . 13
5.1. Detection of Lost Packets. . . . . . . . . . . . . . 12 5.1. Detection of Lost or Marked Packets. . . . . . . . . 13
5.2. Translation from Loss History to Loss Events . . . . 12 5.2. Translation from Loss History to Loss Events . . . . 14
5.3. Inter-loss Event Interval. . . . . . . . . . . . . . 13 5.3. Inter-loss Event Interval. . . . . . . . . . . . . . 15
5.4. Average Loss Interval. . . . . . . . . . . . . . . . 14 5.4. Average Loss Interval. . . . . . . . . . . . . . . . 15
6. Data Receiver Protocol. . . . . . . . . . . . . . . . . 15 5.5. History Discounting. . . . . . . . . . . . . . . . . 16
6. Data Receiver Protocol. . . . . . . . . . . . . . . . . 18
6.1. Receiver behavior when a data packet is 6.1. Receiver behavior when a data packet is
received. . . . . . . . . . . . . . . . . . . . . . . . . 15 received. . . . . . . . . . . . . . . . . . . . . . . . . 18
6.2. Expiration of feedback timer . . . . . . . . . . . . 16 6.2. Expiration of feedback timer . . . . . . . . . . . . 19
6.3. Receiver initialization. . . . . . . . . . . . . . . 17 6.3. Receiver initialization. . . . . . . . . . . . . . . 20
7. Modifying the Packet Size . . . . . . . . . . . . . . . 17 7. Security Considerations . . . . . . . . . . . . . . . . 20
8. Security Considerations . . . . . . . . . . . . . . . . 17 8. Authors' Addresses. . . . . . . . . . . . . . . . . . . 20
9. Authors' Addresses. . . . . . . . . . . . . . . . . . . 17 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . 21
10. Acknowledgments. . . . . . . . . . . . . . . . . . . . 18 10. References . . . . . . . . . . . . . . . . . . . . . . 21
11. References . . . . . . . . . . . . . . . . . . . . . . 18
1. Introduction 1. Introduction
This document specifies TCP-Friendly Rate Control (TFRC). TFRC is a This document specifies TCP-Friendly Rate Control (TFRC). TFRC is a
congestion control mechanism for unicast flows operating in a best- congestion control mechanism designed for unicast flows operating in a
effort Internet environment. Internet environment and competing with TCP traffic. 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 [5], in an application incorporating end-to-end congestion
control at the application level, or in the context of endpoint
congestion management. This document does not discuss packet formats,
reliability, or implementation-related issues.
TFRC is designed to be reasonably fair when competing for bandwidth with TFRC is designed to be reasonably fair when competing for bandwidth with
TCP flows [1]. However it has a much lower variation of throughput over TCP flows [1]. However it has a much lower variation of throughput over
time compared with TCP, which makes it more suitable for applications time compared with TCP, which makes it more suitable for applications
such as telephony or streaming media where a relatively smooth sending such as telephony or streaming media where a relatively smooth sending
rate is of importance. rate is of importance.
The penalty of having smoother throughput than TCP whilst competing The penalty of having smoother throughput than TCP whilst competing
fairly for bandwidth is that TFRC responds slower than TCP to changes in fairly for bandwidth is that TFRC responds slower than TCP to changes in
available bandwidth. Thus TFRC should only be used when the application available bandwidth. Thus TFRC should only be used when the application
has a strong requirement for smooth and predictable throughput. For has a requirement for smooth throughput, in particular, avoiding TCP's
halving of the sending rate in response to a single packet drop. For
applications that simply require to transfer as much data as possible in applications that simply require to transfer as much data as possible in
as short a time as possible we recommend using TCP, or if reliability is as short a time as possible we recommend using TCP, or if reliability is
not required, using an Additive-Increase, Multiplicative-Decrease (AIMD) not required, using an Additive-Increase, Multiplicative-Decrease (AIMD)
congestion control scheme with similar parameters to those used by TCP. congestion control scheme with similar parameters to those used by TCP.
TFRC is designed for applications that use a fixed packet size, and vary
their sending rate in packets per second in response to congestion.
Some audio applications 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; variants of TFRC for applications that have
a fixed sending rate but vary their packet size in response to
congestion will be addressed in a separate document.
TFRC is a receiver-based mechanism, with the calculation of the
congestion control information (i.e., the loss event rate) in the data
receiver rather in the data sender. This is well-suited to an
application where the sender is a large web server handling many
concurrent connections, and the receiver has more memory and CPU cycles
available for computation. In addition, a receiver-based mechanism is
more suitable as a building block for multicast congestion control.
2. Terminology 2. Terminology
In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" are to be interpreted as described in RFC 2119 and indicate "OPTIONAL" are to be interpreted as described in RFC 2119 and indicate
requirement levels for compliant TFRC implementations. requirement levels for compliant TFRC implementations.
3. Protocol Mechanism 3. Protocol Mechanism
For its congestion control mechanism, TFRC directly uses a throughput For its congestion control mechanism, TFRC directly uses a throughput
equation for the allowed sending rate as a function of the loss event equation for the allowed sending rate as a function of the loss event
rate and round-trip time. In order to compete fairly with TCP, TFRC rate and round-trip time. In order to compete fairly with TCP, TFRC
uses the TCP throughput equation, which roughly describes TCP's sending uses the TCP throughput equation, which roughly describes TCP's sending
rate as a function of the loss event rate and round-trip time. rate as a function of the loss event rate, round-trip time, and packet
size. We define a loss event as one or more lost or marked packets from
a window of data, where a marked packet refers to a mark from Explicit
Congestion Notification (ECN).
Generally speaking, TFRC's congestion control mechanism works as Generally speaking, TFRC's congestion control mechanism works as
follows: follows:
o The receiver measures the loss event rate and feeds this o The receiver measures the loss event rate and feeds this
information back to the sender. information back to the sender.
o The sender also uses these feedback messages to measure the round- o The sender also uses these feedback messages to measure the round-
trip time (RTT). trip time (RTT).
o The loss rate and RTT are then fed into TFRC's throughput equation, o The loss event rate and RTT are then fed into TFRC's throughput
giving the acceptable transmit rate. equation, giving the acceptable transmit rate.
o The sender then adjusts its transmit rate to match the calculated o The sender then adjusts its transmit rate to match the calculated
rate. rate.
The dynamics of TFRC are sensitive to how the measurements are performed The dynamics of TFRC are sensitive to how the measurements are performed
and applied. We recommend specific mechanisms below to perform and and applied. We recommend specific mechanisms below to perform and
apply these measurements. Other mechanisms are possible, but it is apply these measurements. Other mechanisms are possible, but it is
important to understand how the interactions between mechanisms affect important to understand how the interactions between mechanisms affect
the dynamics of TFRC. the dynamics of TFRC.
3.1. TCP Throughput Equation 3.1. TCP Throughput Equation
Any realistic equation of TCP throughput as a function of loss event Any realistic equation of TCP throughput as a function of loss event
rate and RTT should be suitable for use in TFRC. However, we note that rate and RTT should be suitable for use in TFRC. However, we note that
the TCP throughput equation used must reflect TCP's retransmit timeout the TCP throughput equation used must reflect TCP's retransmit timeout
behavior, as this dominates TCP throughput at higher loss rates. We behavior, as this dominates TCP throughput at higher loss rates. We
also note that the assumptions implicit in the throughput equation about also note that the assumptions implicit in the throughput equation about
the loss rate parameter have to be a reasonable match to how the loss the loss event rate parameter have to be a reasonable match to how the
rate is actually measured. Whilst this match is not perfect for the
throughput equation and loss rate measurement mechanisms given below, in loss rate or loss event rate is actually measured. Whilst this match is
practice the assumptions turn out to be close enough. not perfect for the throughput equation and loss rate measurement
mechanisms given below, in practice the assumptions turn out to be close
enough.
The throughput equation we currently recommend for TFRC is a slightly The throughput equation we currently recommend for TFRC is a slightly
simplified version of the throughput equation for Reno TCP from [2]. simplified version of the throughput equation for Reno TCP from [3].
Ideally we'd prefer a throughput equation based on SACK TCP, but the Ideally we'd prefer a throughput equation based on SACK TCP, but no one
differences between the two equations are relatively minor. has yet derived the throughput equation for SACK TCP, and from both
simulations and experiments, the differences between the two equations
are relatively minor.
The throughput equation is: The throughput equation is:
s s
X = ---------------------------------------------------------- X = ----------------------------------------------------------
R*sqrt(2*p/3) + (t_RTO * (3*sqrt(3*p/8) * p * (1+32*p^2))) R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2)))
Where: Where:
X is the transmit rate in bytes/second. X is the transmit rate in bytes/second.
s is the packet size in bytes. s is the packet size in bytes.
R is the round trip time in seconds. R is the round trip time in seconds.
p is the loss event rate, between 0 and 1.0, of the number of loss p is the loss event rate, between 0 and 1.0, of the number of loss
events as a fraction of the number of packets transmitted. events as a fraction of the number of packets transmitted.
t_RTO is the TCP retransmission timeout value in seconds. t_RTO is the TCP retransmission timeout value in seconds.
b is the number of packets acknowledged by a single TCP
acknowledgement.
We further simplify this by setting t_RTO = 4*R. A more accurate We further simplify this by setting t_RTO = 4*R. A more accurate
calculation of t_RTO is possible, but does not appear to be necessary in calculation of t_RTO is possible, but experiments with the current
practice. Another possibility would be to set t_RTO = max(4R, 1 setting have resulted in reasonable fairness with existing TCP
second). implementations [4]. Another possibility would be to set t_RTO = max(4R,
one second), to match the recommended minimum of one second on the RTO
[7].
Many current TCP connections use delayed acknowledgements, sending an
acknowledgement for every two data packets received, and thus have a
sending rate modeled by b = 2. However, TCP is also allowed to send an
acknowledgement for every data packet, and this would be modeled by b =
1. Because many TCP implementations do not use delayed
acknowledgements, we recommend b = 1.
In future, different TCP equations may be substituted for this equation. In future, different TCP equations may be substituted for this equation.
The requirement is that the throughput equation be a reasonable The requirement is that the throughput equation be a reasonable
approximation of the sending rate of TCP for conformant TCP congestion approximation of the sending rate of TCP for conformant TCP congestion
control. control.
The parameters s (packet size), p (loss rate) and R (RTT) need to be The parameters s (packet size), p (loss event rate) and R (RTT) need to
measured or calculated by a TFRC implementation. The measurement of s be measured or calculated by a TFRC implementation. The measurement of
is specified in Section 4.1, measurement of R is specified in Section s is specified in Section 4.1, measurement of R is specified in Section
4.2, and measurement of p is specified in Secion 4.2. 4.2, and measurement of p is specified in Section 4.2. In the rest of
this document, all data rates are measured in bytes/second.
3.2. Packet Contents 3.2. Packet Contents
Before specifying the sender and receiver functionality, we describe the Before specifying the sender and receiver functionality, we describe the
contents of the data packets sent by the sender and feedback packets contents of the data packets sent by the sender and feedback packets
sent by the receiver. As TFRC will be used along with a transport sent by the receiver. As TFRC will be used along with a transport
protocol, we do not specify packet formats, as these depend on the protocol, we do not specify packet formats, as these depend on the
details of the transport protocol used. details of the transport protocol used.
3.2.1. Data Packets 3.2.1. Data Packets
skipping to change at page 8, line 17 skipping to change at page 9, line 17
coupled to the transmit rate. It should normally be safe to use an coupled to the transmit rate. It should normally be safe to use an
estimate of the mean packet size for s. estimate of the mean packet size for s.
o The application needs to change the packet size rather than the o The application needs to change the packet size rather than the
number of packets per second to perform congestion control. This number of packets per second to perform congestion control. This
would normally be the case with packet audio applications where a would normally be the case with packet audio applications where a
fixed interval of time needs to be represented by each packet. fixed interval of time needs to be represented by each packet.
Such applications need to have a completely different way of Such applications need to have a completely different way of
measuring parameters. measuring parameters.
The second class of applications are discussed separately in Section 7. The second class of applications are discussed separately in a separate
For the remainder of this section we assume the sender can estimate the document. For the remainder of this section we assume the sender can
packet size, and that congestion control is performed by adjusting the estimate the packet size, and that congestion control is performed by
number of packets sent per second. adjusting the number of packets sent per second.
4.2. Sender behavior when a feedback packet is received 4.2. Sender behavior when a feedback packet is received
The sender knows its current sending rate, X, and maintains an estimate The sender knows its current sending rate, X, and maintains an estimate
of the current round trip time, R, and an estimate of the timeout of the current round trip time, R, and an estimate of the timeout
interval, t_RTO. interval, t_RTO.
When a feedback packet is received by the sender at time t_now, the When a feedback packet is received by the sender at time t_now, the
following actions should be performed: following actions should be performed:
1) Calculate a new round trip sample. 1) Calculate a new round trip sample.
R_sample = (t_now - t_recvdata) - t_delay. R_sample = (t_now - t_recvdata) - t_delay.
2) Update the round trip time estimate: 2) Update the round trip time estimate:
If no feedback has been received before If no feedback has been received before
R = R_sample R = R_sample;
Else Else
R = q*R + (1-q)*R_sample R = q*R + (1-q)*R_sample;
TFRC is not sensitive to the precise value for the filter constant TFRC is not sensitive to the precise value for the filter constant
q, but we recommend a default value of 0.9. q, but we recommend a default value of 0.9.
3) Update the timeout interval: 3) Update the timeout interval:
t_RTO = 4*R. t_RTO = 4*R.
4) Update the sending rate: 4) Update the sending rate:
First, calculate the allowed transmit rate, X_calc, using the TCP First, calculate the allowed transmit rate, X_calc, using the TCP
equation from Section 3.1. equation from Section 3.1.
Then: Then:
If p > 0 If (p > 0)
X = min(X_calc, 2*X_recv) X = min(X_calc, 2*X_recv, s/64);
Else Else
X = max(min(2*X, 2*X_recv), s/RTT). X = max(min(2*X, 2*X_recv), s/RTT);
Note that if p == 0, then the sender is in slow-start phase, where Note that if p == 0, then the sender is in slow-start phase, where
it approximately doubles the sending rate each round-trip time it approximately doubles the sending rate each round-trip time
until a loss occurs. until a loss occurs. The s/RTT term gives a minimum sending rate
during slow-start of one packet per RTT. When p > 0, the sender
sends at least one packet every 64 seconds.
5) Reset the nofeedback timer to expire after max(2*R, 2*s/X) seconds. 5) Reset the nofeedback timer to expire after max(2*R, 2*s/X) seconds.
4.3. Expiration of nofeedback timer 4.3. Expiration of nofeedback timer
If the nofeedback timer expires, the sender should perform the following If the nofeedback timer expires, the sender should perform the following
actions: actions:
1) Cut the sending rate in half. This is done by modifying the 1) Cut the sending rate in half. This is done by modifying the
sender's cached copy of X_recv (the receive rate) as this will sender's cached copy of X_recv (the receive rate). Because the
trigger the correct slowstart behavior after the problem has been sending rate is limited to at most twice X_recv, modifying X_recv
resolved: limits the current sending rate, but allows the sender to slow-
start, doubling its sending rate each RTT, if feedback messages
resume reporting no losses.
If X_calc > 2*X_recv If (X_calc > 2*X_recv)
X_recv = max(X_recv/2, s/128) X_recv = max(X_recv/2, s/128);
Else Else
X_recv = X_calc/4 X_recv = X_calc/4;
The s/128 term limits the backoff to one packet every 64 seconds in The s/128 term limits the backoff to one packet every 64 seconds in
the case of persistent absense of feedback. the case of persistent absence of feedback.
2) The value of X must then be recalculated as described under point 2) The value of X must then be recalculated as described under point
(4) above. (4) above.
If the nofeedback timer expires when the sender does not yet have
an RTT sample, and has not yet received any feedback from the
sender, then step (1) can be skipped, and the sending rate cut in
half directly:
X = X_calc.
3) Restart the nofeedback timer to expire after max(4*R, 2*s/X) 3) Restart the nofeedback timer to expire after max(4*R, 2*s/X)
seconds. seconds.
Note that when the sender stops sending, the receiver will stop sending Note that when the sender stops sending, the receiver will stop sending
feedback. This will cause the nofeedback timer to start to expire and feedback. This will cause the nofeedback timer to start to expire and
decrease X_recv. If the sender subsequently starts to send again, decrease X_recv. If the sender subsequently starts to send again,
X_recv will limit the transmit rate, and a normal slowstart phase will X_recv will limit the transmit rate, and a normal slowstart phase will
occur until the transmit rate reached X_calc. occur until the transmit rate reached X_calc.
4.4. Sender Initialization 4.4. Sender Initialization
skipping to change at page 10, line 23 skipping to change at page 11, line 34
To prevent oscillatory behavior in environments with a low degree of To prevent oscillatory behavior in environments with a low degree of
statistical multiplexing it is useful to modify sender's transmit rate statistical multiplexing it is useful to modify sender's transmit rate
to provide congestion avoidance behavior by reducing the transmit rate to provide congestion avoidance behavior by reducing the transmit rate
as the queuing delay (and hence RTT) increases. To do this the sender as the queuing delay (and hence RTT) increases. To do this the sender
maintains an estimate of the long-term RTT and modifies its sending rate maintains an estimate of the long-term RTT and modifies its sending rate
depending on how the most recent sample of the RTT differs from this depending on how the most recent sample of the RTT differs from this
value. The long-term sample is R_sqmean, and is set as follows: value. The long-term sample is R_sqmean, and is set as follows:
If no feedback has been received before If no feedback has been received before
R_sqmean = sqrt(R_sample) R_sqmean = sqrt(R_sample);
Else Else
R_sqmean = q2*R_sqmean + (1-q2)*sqrt(R_sample) R_sqmean = q2*R_sqmean + (1-q2)*sqrt(R_sample);
Thus R_sqmean gives the exponentially weighted moving average of the Thus R_sqmean gives the exponentially weighted moving average of the
square root of the RTT samples. The constant q2 should be set similarly square root of the RTT samples. The constant q2 should be set similarly
to q, and we recommend a value of 0.9 as the default. to q, and we recommend a value of 0.9 as the default.
The sender obtains the base tranmit rate, X, from the throughput The sender obtains the base transmit rate, X, from the throughput
function. It then calculates a modified instantaneous transmit rate, function. It then calculates a modified instantaneous transmit rate
X_inst, as follows: X_inst, as follows:
X_inst = X * R_sqmean / sqrt(R_sample) X_inst = X * R_sqmean / sqrt(R_sample);
When sqrt(R_sample) is greater than R_sqmean then the queue is typically When sqrt(R_sample) is greater than R_sqmean then the queue is typically
increasing and so the transmit rate needs to be decreased for stable increasing and so the transmit rate needs to be decreased for stable
operation. operation.
Note: This modification is not always strictly required, especially if Note: This modification is not always strictly required, especially if
the degree of statistical multiplexing in the network is high. However the degree of statistical multiplexing in the network is high. However
we recommend that it is done because it does make TFRC behave better in we recommend that it is done because it does make TFRC behave better in
environments with a low level of statistical multiplexing. If it is not environments with a low level of statistical multiplexing. If it is not
done, we recommend using a very low value of q, such that q is close to done, we recommend using a very low value of q, such that q is close to
skipping to change at page 11, line 14 skipping to change at page 12, line 25
4.6. Scheduling of Packet Transmissions 4.6. Scheduling of Packet Transmissions
As TFRC is rate-based, and as operating systems typically cannot As TFRC is rate-based, and as operating systems typically cannot
schedule events precisely, it is necessary to be opportunistic about schedule events precisely, it is necessary to be opportunistic about
sending data packets so that the correct average rate is maintained sending data packets so that the correct average rate is maintained
despite the course-grain or irregular scheduling of the operating despite the course-grain or irregular scheduling of the operating
system. Thus a typical sending loop will calculate the correct inter- system. Thus a typical sending loop will calculate the correct inter-
packet interval, t_ipi, as follows: packet interval, t_ipi, as follows:
t_ipi = 1/(X_inst * s) t_ipi = s/X_inst;
When a sender first starts sending at time t_0, it calculates t_ipi, and When a sender first starts sending at time t_0, it calculates t_ipi, and
calculates a nominal send time t_1 = t_0 + t_ipi for packet 1. When the calculates a nominal send time t_1 = t_0 + t_ipi for packet 1. When the
application becomes idle, it checks the current time, t_now, and then application becomes idle, it checks the current time, t_now, and then
requests re-scheduling after (t_ipi - (t_now - t_0)) seconds. When the requests re-scheduling after (t_ipi - (t_now - t_0)) seconds. When the
application is re-scheduled, it checks the current time, t_now, again. application is re-scheduled, it checks the current time, t_now, again.
If (t_now > t_1 - delta) then packet 1 is sent. If (t_now > t_1 - delta) then packet 1 is sent.
Now a new t_ipi may be calculated, and used to calculate a nominal send Now a new t_ipi may be calculated, and used to calculate a nominal send
time t_2 for packet 2: t2 = t_1 + t_ipi. The process then repeats, with time t_2 for packet 2: t2 = t_1 + t_ipi. The process then repeats, with
skipping to change at page 11, line 39 skipping to change at page 12, line 50
calculated, it may already be the case that t_now > t_i - delta. In calculated, it may already be the case that t_now > t_i - delta. In
such a case the packet should be sent immediately. Thus if the such a case the packet should be sent immediately. Thus if the
operating system has coarse timer granularity and the transmit rate is operating system has coarse timer granularity and the transmit rate is
high, then TFRC may send short bursts of several packets separated by high, then TFRC may send short bursts of several packets separated by
intervals of the OS timer granularity. intervals of the OS timer granularity.
The parameter delta is to allow a degree of flexibility in the send time The parameter delta is to allow a degree of flexibility in the send time
of a packet. If the operating system has a scheduling timer granularity of a packet. If the operating system has a scheduling timer granularity
of t_gran seconds, then delta would typically be set to: of t_gran seconds, then delta would typically be set to:
delta = min(t_ipi/2, t_gran/2) delta = min(t_ipi/2, t_gran/2);
t_gran is 10ms on many Unix systems. If t_gran is not known, a value of t_gran is 10ms on many Unix systems. If t_gran is not known, a value of
10ms can be safely assumed. 10ms can be safely assumed.
5. Calculation of the loss rate (p) 5. Calculation of the loss event rate (p)
Obtaining a accurate and stable measurement of the loss rate is of Obtaining a accurate and stable measurement of the loss event rate is of
primary importance for TFRC. Loss rate measurement is performed at the primary importance for TFRC. Loss rate measurement is performed at the
receiver, based on the detection of lost packets from the sequence receiver, based on the detection of lost or marked packets from the
numbers of arriving packets. We describe this process before describing sequence numbers of arriving packets. We describe this process before
the rest of the receiver protocol. describing the rest of the receiver protocol.
5.1. Detection of Lost Packets 5.1. Detection of Lost or Marked Packets
TFRC assumes that all packets contain a sequence number that is TFRC assumes that all packets contain a sequence number that is
incremented by one for each packet that is sent. For the purposes of incremented by one for each packet that is sent. For the purposes of
this specification, we require that if a lost packet is retransmitted, this specification, we require that if a lost packet is retransmitted,
the retransmission is given a new sequence number that is the latest in the retransmission is given a new sequence number that is the latest in
the transmission sequence, and not the same sequence number as the the transmission sequence, and not the same sequence number as the
packet that was lost. If a transport protocol has the requirement that packet that was lost. If a transport protocol has the requirement that
it must retransmit with the original sequence number, then the transport it must retransmit with the original sequence number, then the transport
protocol designer must figure out how to distinguish delayed from protocol designer must figure out how to distinguish delayed from
retransmitted packets and how to detect lost retransmissions. retransmitted packets and how to detect lost retransmissions.
skipping to change at page 12, line 36 skipping to change at page 13, line 46
packets with a higher sequence number than the lost packet. The packets with a higher sequence number than the lost packet. The
requirement for three subsequent packets is the same as with TCP, and is requirement for three subsequent packets is the same as with TCP, and is
to make TFRC more robust in the presence of reordering. In contrast to to make TFRC more robust in the presence of reordering. In contrast to
TCP, if a packet arrives late (after 3 subsequent packets arrived) in TCP, if a packet arrives late (after 3 subsequent packets arrived) in
TFRC, the late packet can fill the hole in TFRC's reception record, and TFRC, the late packet can fill the hole in TFRC's reception record, and
the receiver can recalculate the loss event rate. Future versions of the receiver can recalculate the loss event rate. Future versions of
TFRC might make the requirement for three subsequent packets adaptive TFRC might make the requirement for three subsequent packets adaptive
based on experienced packet reordering, but we do not specify such a based on experienced packet reordering, but we do not specify such a
mechanism here. mechanism here.
For an ECN-capable connection, a marked packet is detected as a
congestion event as soon as it arrives, without having to wait for the
arrival of subsequent packets.
5.2. Translation from Loss History to Loss Events 5.2. Translation from Loss History to Loss Events
TFRC requires that the loss fraction be robust to several consecutive TFRC requires that the loss fraction be robust to several consecutive
packets lost where those packets are part of the same loss event. This packets lost where those packets are part of the same loss event. This
is similar to TCP, which (typically) only performs one halving of the is similar to TCP, which (typically) only performs one halving of the
congestion window during any single RTT. Thus the receiver needs to map congestion window during any single RTT. Thus the receiver needs to map
the packet loss history into a loss event record, where a loss event is the packet loss history into a loss event record, where a loss event is
one or more packets lost in an RTT. To perform this mapping, the one or more packets lost in an RTT. To perform this mapping, the
receiver needs to know the RTT to use, and this is supplied periodically receiver needs to know the RTT to use, and this is supplied periodically
by the sender, typically as control information piggy-backed onto a data by the sender, typically as control information piggy-backed onto a data
packet. TFRC is not sensitive to how the RTT measurement sent to the packet. TFRC is not sensitive to how the RTT measurement sent to the
receiver is made, but we recommend using the sender's calculated RTT, R, receiver is made, but we recommend using the sender's calculated RTT, R,
(see Section 4.2) for this purpose. (see Section 4.2) for this purpose.
To determine whether a lost packet should start a new loss event, or be To determine whether a lost or marked packet should start a new loss
counted as part of an existing loss event, we need to compare the event, or be counted as part of an existing loss event, we need to
sequence numbers and timestamps of the packets that arrived at the 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
receiver. Assume: can be noted directly. For a lost packet, we can interpolate to infer
the nominal "arrival time". Assume:
S_loss is the sequence number of a lost packet. S_loss is the sequence number of a lost packet.
S_before is the sequence number of the last packet to arrive with S_before is the sequence number of the last packet to arrive with
sequence number before S_loss. sequence number before S_loss.
S_after is the sequence number of the first packet to arrive with S_after is the sequence number of the first packet to arrive with
sequence number after S_loss. sequence number after S_loss.
T_before is the reception time of S_before. T_before is the reception time of S_before.
T_after is the reception time of S_after. T_after is the reception time of S_after.
Note that T_before can either be before or after T_after due to Note that T_before can either be before or after T_after due to
reordering. reordering.
We can interpolate the nominal "arrival time" of S_loss at the receiver For a lost packet S_loss, we can interpolate its nominal "arrival time"
from the arrival times of S_before and S_after. Thus at the receiver from the arrival times of S_before and S_after. Thus
T_loss = T_before + ( (T_after - T_before) T_loss = T_before + ( (T_after - T_before)
* (S_loss - S_before)/(S_after - S_before) ) * (S_loss - S_before)/(S_after - S_before) );
Note that if the sequence space wrapped between S_before and S_after, Note that if the sequence space wrapped between S_before and S_after,
then the sequence numbers must be modified to take this into account then the sequence numbers must be modified to take this into account
before performing this calculation. If the largest possible sequence before performing this calculation. If the largest possible sequence
number is S_max, and S_before > S_after, then modifying each 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 number S by S' = (S + (S_max + 1)/2) mod (S_max + 1) would normally be
sufficient. sufficient.
If the lost packet S_old was determined to have started the previous If the lost packet S_old was determined to have started the previous
loss event, and we have just determined that S_new has been lost, then loss event, and we have just determined that S_new has been lost, then
we interpolate the nominal arrival times of S_old and S_new, called we interpolate the nominal arrival times of S_old and S_new, called
T_old and T_new respectively. T_old and T_new respectively.
If T_old + R >= T_new, then S_new is part of the existing loss event. If T_old + R >= T_new, then S_new is part of the existing loss event.
Otherwise S_new is the first packet in a new loss event. Otherwise S_new is the first packet in a new loss event.
skipping to change at page 14, line 14 skipping to change at page 15, line 31
5.4. Average Loss Interval 5.4. Average Loss Interval
To calculate the loss event rate p, we first calculate the average loss 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 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 loss event intervals in such a way that the measured loss event rate
changes smoothly. changes smoothly.
Weights w_0 to w_(n-1) are calculated as: Weights w_0 to w_(n-1) are calculated as:
If i < n/2 If (i < n/2)
w_i = 1 w_i = 1;
Else Else
w_i = 1 - (i - (n/2 - 1))/(n/2 + 1) w_i = 1 - (i - (n/2 - 1))/(n/2 + 1);
Thus if n=8, the values of w_0 to w_7 are: Thus 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 1.0, 1.0, 1.0, 1.0, 0.8, 0.6, 0.4, 0.2
The value n for the number of loss intervals used in calculating the The value n for the number of loss intervals used in calculating the
loss event rate determines TRFC's speed in responding to changes in the loss event rate determines TRFC's speed in responding to changes in the
level of congestion. As currently specified, TFRC should not be used level of congestion. As currently specified, TFRC should not be used
for values of n significantly greater than 8, for traffic that might for values of n significantly greater than 8, for traffic that might
compete in the global Internet with TCP. At the very least, safe compete in the global Internet with TCP. At the very least, safe
skipping to change at page 14, line 35 skipping to change at page 16, line 4
level of congestion. As currently specified, TFRC should not be used level of congestion. As currently specified, TFRC should not be used
for values of n significantly greater than 8, for traffic that might for values of n significantly greater than 8, for traffic that might
compete in the global Internet with TCP. At the very least, safe 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 operation with values of n greater than 8 would require a slight change
to TFRC's mechanisms to include a more severe response to two or more to TFRC's mechanisms to include a more severe response to two or more
round-trip times with heavy packet loss. round-trip times with heavy packet loss.
To calculate the average loss interval we need to decide whether to To calculate the average loss interval we need to decide whether to
include the interval since the most recent packet loss event. We only include the interval since the most recent packet loss event. We only
do this if it is sufficiently large to increase the average loss do this if it is sufficiently large to increase the average loss
interval. interval.
Thus if the most recent loss intervals are I_0 to I_n, with I_0 being Thus 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 the interval since the most recent loss event, then we calculate the
average loss interval I_mean as: average loss interval I_mean as:
I_tot0 = 0 I_tot0 = 0;
I_tot1 = 0 I_tot1 = 0;
W_tot = 0 W_tot = 0;
for i = 0 to n-1 { for (i = 0 to n-1) {
I_tot0 = I_tot0 + (I_i * w_i) I_tot0 = I_tot0 + (I_i * w_i);
W_tot = W_tot + w_i W_tot = W_tot + w_i;
} }
for i = 1 to n { for (i = 1 to n) {
I_tot1 = I_tot1 + (I_i * w_(i-1)) I_tot1 = I_tot1 + (I_i * w_(i-1));
} }
I_tot = max(I_tot0, I_tot1) I_tot = max(I_tot0, I_tot1);
I_mean = I_tot / W_tot;
I_mean = I_tot / W_tot
The loss event rate, p is simply: The loss event rate, p is simply:
p = 1 / I_mean p = 1 / I_mean;
5.5. History Discounting
As described in Section 5.4, the most recent loss interval is only
assigned 1/(.75n) of the total weight in calculating the average loss
interval, regardless of the size of the most recent loss interval. This
section describes an optional history discounting mechanism, discussed
further in [2] and [4], that allows the TFRC receiver to adjust the
weights, concentrating more of the relative weight on the most recent
loss interval, when the most recent loss interval is more than twice as
large as the computed average loss interval.
To carry out history discounting, we associate a discount factor DF_i
with each loss interval L_i, for i > 0, where each discount factor is a
floating point number. The discount array maintains the cumulative
history of discounting for each loss interval. At the beginning, the
values of DF_i in the discount array are initialized to 1:
for (i = 1 to n) {
DF_i = 1;
}
History discounting also uses a general discount factor DF, also a
floating point number, that is also initialized to 1. First we show how
the discount factors are used in calculating the average loss interval,
and then we describe later in this section how the discount factors are
modified over time.
As described in Section 5.4 the average loss interval is calculated
using the n previous loss intervals I_1, ..., I_n, and the interval I_0
that represents the number of packets received since last loss event.
The computation of the average loss interval using the discount factors
is a simple modification of the procedure in Section 5.4, as follows:
I_tot0 = 0;
I_tot1 = 0;
W_tot = 0;
for (i = 0 to n-1) {
I_tot0 = I_tot0 + (I_i * w_i * DF_i * DF);
W_tot = W_tot + w_i * DF_i * DF;
}
for (i = 1 to n) {
I_tot1 = I_tot1 + (I_i * w_(i-1) * DF_i * DF);
}
p = W_tot / max(I_tot0, I_tot1);
The general discounting factor, DF is updated on every packet arrival as
follows. First, the receiver computes the weighted average I_tot of the
loss intervals I_1, ..., I_n:
I_tot = 0;
for (i = 1 to n) {
I_tot = I_tot + (I_i * w_(i-1) * DF_i);
}
This weighted average I_tot is compared against I_0, the number of
packets received since the last loss event. If I_0 is greater than
twice I_tot, then the new loss interval is considerably larger than the
old ones, and the general discount factor DF is updated to decrease the
relative weight on the older intervals, as follows:
if (I_0 > 2 * I_tot) {
DF = 2 * I_tot / I_0;
if (DF < THRESHOLD)
DF = THRESHOLD;
} else
DF = 1;
A nonzero value for THRESHOLD ensures that older loss intervals from an
earlier time of high congestion are not discounted entirely. We
recommend a THRESHOLD of 0.5. Note that with each new packet arrival,
I_0 will increase further, and the discount factor DF will be updated.
When a new loss event occurs, the current interval shifts from I_0 to
I_1, loss interval I_i shifts to interval I_(i+1), and the loss interval
I_n is forgotten. The previous discount factor DF has to be
incorporated into the discount array. Because DF_i carries the discount
factor associated with loss interval I_i, the DF_i array has to be
shifted as well. This is done as follows:
for (i = 1 to n) {
DF_i = DF * DF_i;
}
for (i = n-1 to 0) {
DF_(i+1) = DF_i;
}
I_0 = 1;
DF_0 = 1;
DF = 1;
This completes the description of the optional history discounting
mechanism. We emphasize that this is an optional mechanism whose sole
purpose is to allow TFRC to response somewhat more quickly to the sudden
absence of congestion, as represented by a long current loss interval.
6. Data Receiver Protocol 6. Data Receiver Protocol
The receiver periodically sends feedback messages to the sender. The receiver periodically sends feedback messages to the sender.
Feedback packets should normally be sent at least once per RTT, unless Feedback packets should normally be sent at least once per RTT, unless
the sender is sending at a rate of less than one packet per RTT, in the sender is sending at a rate of less than one packet per RTT, in
which case a feedback packet should be send for every data packet which case a feedback packet should be send for every data packet
received. A feedback packet should also be sent whenever a new loss received. A feedback packet should also be sent whenever a new loss
event is detected without waiting for the end of an RTT, and whenever an event is detected without waiting for the end of an RTT, and whenever an
out-of-order data packet is received that removes a loss event from the out-of-order data packet is received that removes a loss event from the
skipping to change at page 16, line 5 skipping to change at page 19, line 8
6.1. Receiver behavior when a data packet is received 6.1. Receiver behavior when a data packet is received
When a data packet is received, the receiver performs the following When a data packet is received, the receiver performs the following
steps: steps:
1) Add the packet to the packet history. 1) Add the packet to the packet history.
2) Let the previous value of p be p_prev. Calculate the new value of 2) Let the previous value of p be p_prev. Calculate the new value of
p as described in Section 5. p as described in Section 5.
3) If p < p_prev, cause the feedback timer to expire, and perform the 3) If p > p_prev, cause the feedback timer to expire, and perform the
actions described in Section 6.2. actions described in Section 6.2
If p >= p_prev no action need be performed. If p <= p_prev no action need be performed.
However an optimization might check to see if the arrival of the However an optimization might check to see if the arrival of the
packet caused a hole in the packet history to be filled and packet caused a hole in the packet history to be filled and
consequently two loss intervals were merged into one. If this is consequently two loss intervals were merged into one. If this is
the case, the receiver might also send feedback immediately. The the case, the receiver might also send feedback immediately. The
effects of such an optimization are normally expected to be small. effects of such an optimization are normally expected to be small.
6.2. Expiration of feedback timer 6.2. Expiration of feedback timer
When the feedback timer at the receiver expires, the action to be taked When the feedback timer at the receiver expires, the action to be taken
depends on whether data packets have been received since the last depends on whether data packets have been received since the last
feedback was sent. feedback was sent.
Let the maximum sequence number of a packet at the receiver so far be Let the maximum sequence number of a packet at the receiver so far be
S_m, and the value of the RTT measurement included in packet S_m be R_m. S_m, and the value of the RTT measurement included in packet S_m be R_m.
If data packets have been received since the pervious feedback was sent, If data packets have been received since the pervious feedback was sent,
the receiver performs the following steps: the receiver performs the following steps:
1) Calculate the average loss event rate using the algorithm described 1) Calculate the average loss event rate using the algorithm described
above. above.
2) Calculate the measured receive rate, X_sample, based on the packets 2) Calculate the measured receive rate, X_sample, based on the packets
received within the previous R_m seconds. received within the previous R_m seconds.
3) Calculate X_recv as follows: 3) Calculate X_recv as follows:
X_recv = q3*X_sample + (1-q3)*X_recv X_recv = q3*X_sample + (1-q3)*X_recv;
Where q3 is a constant with recommended value 0.5. Where q3 is a constant with recommended value 0.5.
4) Prepare and send a feedback packet containing the information 4) Prepare and send a feedback packet containing the information
described in Section 3.2.2. described in Section 3.2.2
5) Restart the feedback timer to expire after R_m seconds. 5) Restart the feedback timer to expire after R_m seconds.
If no data packets have been received since the last feedback was sent, If no data packets have been received since the last feedback was sent,
no feedback packet is sent, and the feedback timer is restarted to no feedback packet is sent, and the feedback timer is restarted to
expire after R_m seconds. expire after R_m seconds.
6.3. Receiver initialization 6.3. Receiver initialization
The receiver is initialized by the first packet that arrives at the The receiver is initialized by the first packet that arrives at the
skipping to change at page 17, line 21 skipping to change at page 20, line 21
o Set p=0 o Set p=0
o Set X_recv = X_send, where X_send is the sending rate the sender o Set X_recv = X_send, where X_send is the sending rate the sender
reports in the first data packet. reports in the first data packet.
o Prepare and send a feedback packet. o Prepare and send a feedback packet.
o Set the feedback timer to expire after R_i seconds. o Set the feedback timer to expire after R_i seconds.
7. Modifying the Packet Size 7. Security Considerations
8. Security Considerations
TFRC is not a transport protocol in its own right, but a congestion TFRC is not a transport protocol in its own right, but a congestion
control mechanism that is intended to be used in conjunction with a control mechanism that is intended to be used in conjunction with a
transport protocol. Therefore security primarily needs to be considered transport protocol. Therefore security primarily needs to be considered
in the context of a specific transport protocol and its authentication in the context of a specific transport protocol and its authentication
mechanisms. mechanisms.
Congestion control mechanisms can potentially be exploited to create Congestion control mechanisms can potentially be exploited to create
denial of service. This may occur through spoofed feedback. Thus any denial of service. This may occur through spoofed feedback. Thus any
transport protocol that uses TFRC should take care to ensure that transport protocol that uses TFRC should take care to ensure that
feedback is only accepted from the receiver of the data. The precise feedback is only accepted from the receiver of the data. The precise
mechanism to achieve this will however depend on the transport protocol mechanism to achieve this will however depend on the transport protocol
itself. itself.
In addition, congection control mechanisms may potentially be In addition, congestion control mechanisms may potentially be
manipulated by a greedy receiver that wishes to receive more than its manipulated by a greedy receiver that wishes to receive more than its
fair share of network bandwidth. A receiver might do this by claiming fair share of network bandwidth. A receiver might do this by claiming
to have received packets that in fact were lost due to congestion. to have received packets that in fact were lost due to congestion.
Possible defenses against such a receiver would normally include some Possible defenses against such a receiver would normally include some
form of nonce that the receiver must feed back to the sender to prove form of nonce that the receiver must feed back to the sender to prove
receipt. However, the details of such a nonce would depend on the receipt. However, the details of such a nonce would depend on the
transport protocol, and in particular on whether the transport protocol transport protocol, and in particular on whether the transport protocol
is reliable or unreliable. is reliable or unreliable.
9. Authors' Addresses 8. Authors' Addresses
Mark Handley, Jitendra Padhye, Sally Floyd Mark Handley, Jitendra Padhye, Sally Floyd
ACIRI/ICSI ACIRI/ICSI
1947 Center St, Suite 600 1947 Center St, Suite 600
Berkeley, CA 94708 Berkeley, CA 94708
mjh@aciri.org, padhye@aciri.org, floyd@aciri.org mjh@aciri.org, padhye@aciri.org, floyd@aciri.org
Joerg Widmer Joerg Widmer
Lehrstuhl Praktische Informatik IV Lehrstuhl Praktische Informatik IV
Universitat Mannheim Universitat Mannheim
L 15, 16 - Room 415 L 15, 16 - Room 415
D-68131 Mannheim D-68131 Mannheim
Germany Germany
widmer@informatik.uni-mannheim.de widmer@informatik.uni-mannheim.de
10. Acknowledgments 9. Acknowledgments
We would like to acknowledge feedback and discussions on equation-based We would like to acknowledge feedback and discussions on equation-based
congestion control with a wide range of people, including members of the congestion control with a wide range of people, including members of the
Reliable Multicast Research Group, the Reliable Multicast Transport Reliable Multicast Research Group, the Reliable Multicast Transport
Working Group, and the End-to-End Research Group. Working Group, and the End-to-End Research Group. We would like to
thank Eduardo Urzaiz and Shushan Wen for feedback on earlier versions of
this document, and to thank Mark Allman for his extensive feedback from
using the draft to produce a working implementation.
11. References 10. References
[1] Sally Floyd, Mark Handley, Jitendra Padhye, and Joerg Widmer, [1] S. Floyd, M. Handley, J. Padhye, and J. Widmer, "Equation-Based
"Equation-Based Congestion Control for Unicast Applications", Congestion Control for Unicast Applications", August 2000, Proc
August 2000, Proc SIGCOMM 2000. SIGCOMM 2000.
[2] Padhye, J. and Firoiu, V. and Towsley, D. and Kurose, J., "Modeling [2] S. Floyd, M. Handley, J. Padhye, and J. Widmer, "Equation-Based
Congestion Control for Unicast Applications: the Extended Version",
ICSI tech report TR-00-03, March 2000.
[3] Padhye, J. and Firoiu, V. and Towsley, D. and Kurose, J., "Modeling
TCP Throughput: A Simple Model and its Empirical Validation", Proc TCP Throughput: A Simple Model and its Empirical Validation", Proc
ACM SIGCOMM 1998. ACM SIGCOMM 1998.
[4] Widmer, J., Equation-Based Congestion Control, Diploma Thesis,
University of Mannheim, February 2000. URL
"http://www.aciri.org/tfrc/".
[5] H. Schulzrinne, S. Casner, R. Frederick, and V. Jacobson, RTP: A
Transport Protocol for Real-Time Applications, RFC 1889, January
1996.
[6] K. Ramakrishnan and S. Floyd, A Proposal to add Explicit Congestion
Notification (ECN) to IP, RFC 2481, January 1999.
[7] V. Paxson and M. Allman, Computing TCP's Retransmission Timer, RFC
2988, November 2000.
 End of changes. 

This html diff was produced by rfcdiff 1.23, available from http://www.levkowetz.com/ietf/tools/rfcdiff/