TCP Friendly Rate Control (TFRC): Protocol Specification
obsoleted by
- rfc-5348 — TCP Friendly Rate Control (TFRC): Protocol Specification
Extracted elements (26)
TFRC is receiver-based: the receiver calculates the loss event rate and feeds it back to the sender. This suits servers handling many concurrent connections by offloading computation to clients, and is also better suited as a building block for multicast congestion control.
TFRC trades slower response to bandwidth changes for smoother throughput compared to TCP. It is suitable for telephony and streaming media where a relatively smooth sending rate matters, but TCP or AIMD should be preferred for bulk transfer because TFRC avoids TCP's halving of sending rate on a single drop.
The receiver-based TFRC variant is specified (rather than sender-based) because it is robust to feedback packet loss without requiring reliable delivery, better offloads work from servers to clients, and is a better building block for multicast congestion control. Sender-based variants would have tighter transport protocol requirements.
The throughput equation sets t_RTO=4*R as a simplification. A more accurate calculation is possible but experiments show reasonable fairness with existing TCP implementations. Setting b=1 is recommended because many TCP implementations do not use delayed acknowledgements.
A lost packet is detected only upon arrival of at least three packets with higher sequence numbers than the missing packet, matching TCP's reordering robustness threshold. An ECN-marked packet, however, is treated as a congestion event immediately on arrival.
If a retransmission is required by the transport protocol, the retransmitted packet MUST use a new sequence number (not the original), so TFRC can distinguish delayed from retransmitted packets. Protocols that must retransmit with the original sequence number must resolve the ambiguity themselves.
If no feedback is received for two round-trip times, the nofeedback timer fires and the sender SHOULD halve its sending rate by modifying X_recv. If no RTT sample exists yet, the sender cuts X directly by half down to s/t_mbi minimum (one packet per 64 seconds).
If the sender has been idle since the nofeedback timer was set and X_recv is less than four packets per RTT, X_recv MUST NOT be halved on timer expiration. This ensures the allowed rate never drops below two packets per RTT due to idleness.
On receiving feedback, the sender SHOULD update RTT using R = q*R + (1-q)*R_sample with recommended q=0.9, set t_RTO=4*R, and update the sending rate: if p>0, X = max(min(X_calc, 2*X_recv), s/t_mbi); if p==0 (slow-start), double X at most once per RTT up to 2*X_recv.
TFRC SHOULD NOT be used with n significantly greater than 8 loss intervals for traffic competing on the global Internet with TCP. Safe operation with larger n would require a more severe response to two or more RTTs of heavy loss.
The receiver MUST send a feedback packet at least once per RTT. If the sender transmits less than one packet per RTT, the receiver MUST send a feedback packet for every data packet received. A feedback packet MUST also be sent immediately whenever a new loss event is detected or an out-of-order packet removes a loss event.
The sender MUST initialize X to 1 packet/second and set the nofeedback timer to expire after 2 seconds. The initial value of tld (time last doubled during slow-start) is set to -1; initial values of R and t_RTO are undefined until first feedback is received.
When a data packet arrives that increases p (loss event rate), the receiver MUST immediately trigger the feedback timer expiration procedure, causing prompt feedback to the sender. If p does not increase, no immediate action is required.
After the first loss event, TFRC does not use the raw packet count to the first loss as the initial loss interval. Instead, it finds the value p for which the throughput equation yields a sending rate within 5% of X_recv, and sets the initial loss interval to 1/p, because the sending rate changes rapidly during slow-start.
Each TFRC data packet MUST contain: (1) a sequence number incremented by one per packet with sufficient width to avoid wrap-around collisions in recent history; (2) a millisecond-resolution timestamp ts_i used by the receiver to group losses into events and echoed for RTT estimation; (3) the sender's current RTT estimate R_i for use by the receiver in loss event grouping.
Each TFRC feedback packet contains: (1) t_recvdata, the timestamp of the last received data packet; (2) t_delay, the elapsed time between last data packet receipt and feedback generation; (3) X_recv, the estimated receive rate since the last feedback; (4) the receiver's current loss event rate estimate p.
Multiple lost or marked packets within one RTT are grouped into a single loss event. A new loss is part of an existing event if T_new <= T_old + R (using interpolated nominal arrival times). Lost packet arrival time is interpolated linearly between surrounding received packets' timestamps.
On feedback timer expiration, if data packets have been received, the receiver calculates the average loss event rate and X_recv over the previous R_m seconds, sends a feedback packet, and restarts the feedback timer for R_m seconds. If no data was received, the timer is restarted without sending feedback.
Packet scheduling computes inter-packet interval t_ipi = s/X_inst. To handle coarse OS scheduling granularity, each packet's nominal send time is calculated from the previous packet's nominal time (not actual time), and delta=min(t_ipi/2, t_gran/2) allows early transmission. t_gran defaults to 10ms.
TFRC uses the TCP throughput equation X = s / (R*sqrt(2*b*p/3) + t_RTO*(3*sqrt(3*b*p/8)*p*(1+32*p^2))), where X is transmit rate in bytes/second, s is packet size, R is RTT, p is loss event rate, t_RTO is retransmission timeout, and b is packets acknowledged per ACK. Simplified with t_RTO=4*R and b=1.
The average loss interval I_mean is computed over the n most recent loss event intervals (recommended n=8) using linearly decreasing weights: w_i=1 for i<n/2 and w_i=1-(i-(n/2-1))/(n/2+1) otherwise. The loss event rate p = 1/I_mean.
The optional history discounting mechanism (Section 5.5) associates per-interval discount factors DF_i and a general discount factor DF (initialized to 1). When the current loss-free interval I_0 exceeds twice the weighted average I_mean, DF is reduced to 2*I_mean/I_0, clamped to a THRESHOLD of 0.5, concentrating weight on recent history.
The optional oscillation prevention mechanism (Section 4.5) maintains R_sqmean as an EWMA of sqrt(RTT). The instantaneous transmit rate is modified to X_inst = X * R_sqmean / sqrt(R_sample), reducing rate when RTT is growing. Recommended when statistical multiplexing is low.
A greedy receiver can inflate its share by falsely claiming receipt of lost (congested) packets, causing the sender to compute an artificially low loss rate and increase throughput unfairly. Defenses typically involve a nonce the receiver must echo back to the sender to prove actual receipt; details are transport-protocol-specific.
Protocols combining ECN with TFRC should incorporate the ECN nonce mechanism to prevent a receiver from concealing marked packets (accidentaly or maliciously), which would otherwise cause the sender to underestimate congestion. ECN nonce details are outside the scope of this document.
Spoofed feedback packets can be used to manipulate the sender's rate, creating a denial-of-service risk. Any transport protocol using TFRC MUST ensure feedback is accepted only from the legitimate receiver of the data; the mechanism depends on the transport protocol's authentication design.