rfc8699xml2.original.xml   rfc8699.xml 
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!-- One method to get references from the online citation libraries.
There has to be one entity for each item to be referenced.
An alternate method (rfc include) is described in the references. -->
<!ENTITY RFC2119 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.2119.xml">
<!ENTITY RFC3124 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.3124.xml">
<!ENTITY RFC5348 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.5348.xml">
<!ENTITY RFC7478 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.7478.xml">
<!ENTITY RFC7656 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.7656.xml">
<!ENTITY RFC8087 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.8087.xml">
<!ENTITY RFC8382 SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bibxml/referen
ce.RFC.8382.xml">
<!ENTITY I-D.narten-iana-considerations-rfc2434bis SYSTEM "http://xml2rfc.tools.
ietf.org/public/rfc/bibxml3/reference.I-D.narten-iana-considerations-rfc2434bis.
xml">
<!ENTITY I-D.ietf-rmcat-nada SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bi
bxml3/reference.I-D.draft-ietf-rmcat-nada-11.xml">
<!ENTITY I-D.ietf-rmcat-gcc SYSTEM "http://xml2rfc.tools.ietf.org/public/rfc/bib
xml3/reference.I-D.draft-ietf-rmcat-gcc-02.xml">
<!ENTITY I-D.ietf-rmcat-eval-test PUBLIC "" "http://xml2rfc.tools.ietf.org/publi
c/rfc/bibxml3/reference.I-D.ietf-rmcat-eval-test.xml">
<!ENTITY I-D.ietf-rtcweb-overview PUBLIC "" "http://xml2rfc.tools.ietf.org/publi
c/rfc/bibxml3/reference.I-D.ietf-rtcweb-overview.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="3"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?> <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent">
<?rfc subcompact="no" ?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?> <rfc xmlns:xi="http://www.w3.org/2001/XInclude" number="8699" category="exp"
<rfc category="exp" docName="draft-ietf-rmcat-coupled-cc-09" ipr="trust200902"> consensus="true" docName="draft-ietf-rmcat-coupled-cc-09"
ipr="trust200902" obsoletes="" updates="" submissionType="IETF"
xml:lang="en" tocInclude="true" symRefs="true" sortRefs="true"
version="3">
<!-- ***** FRONT MATTER ***** --> <!-- xml2rfc v2v3 conversion 2.33.0 -->
<front> <front>
<title>Coupled Congestion Control for RTP Media</title>
<title>Coupled congestion control for RTP media</title> <seriesInfo name="RFC" value="8699"/>
<seriesInfo name="Internet-Draft" value="draft-ietf-rmcat-coupled-cc-09"/>
<author fullname="Safiqul Islam" initials="S.I." surname="Islam"> <author fullname="Safiqul Islam" initials="S." surname="Islam">
<organization>University of Oslo</organization> <organization>University of Oslo</organization>
<address> <address>
<postal> <postal>
<street>PO Box 1080 Blindern</street> <street>PO Box 1080 Blindern</street>
<code>N-0316</code> <code>N-0316</code>
<city>Oslo</city> <city>Oslo</city>
<region></region> <region/>
<country>Norway</country> <country>Norway</country>
</postal> </postal>
<phone>+47 22 84 08 37</phone> <phone>+47 22 84 08 37</phone>
<email>safiquli@ifi.uio.no</email> <email>safiquli@ifi.uio.no</email>
</address> </address>
</author> </author>
<author fullname="Michael Welzl" initials="M." surname="Welzl">
<author fullname="Michael Welzl" initials="M.W." surname="Welzl">
<organization>University of Oslo</organization> <organization>University of Oslo</organization>
<address> <address>
<postal> <postal>
<street>PO Box 1080 Blindern</street> <street>PO Box 1080 Blindern</street>
<code>N-0316</code> <code>N-0316</code>
<city>Oslo</city> <city>Oslo</city>
<region></region> <region/>
<country>Norway</country> <country>Norway</country>
</postal> </postal>
<phone>+47 22 85 24 20</phone> <phone>+47 22 85 24 20</phone>
<email>michawe@ifi.uio.no</email> <email>michawe@ifi.uio.no</email>
</address> </address>
</author> </author>
<author fullname="Stein Gjessing" initials="S." surname="Gjessing">
<author fullname="Stein Gjessing" initials="S.G." surname="Gjessing"> <organization>University of Oslo</organization>
<organization>University of Oslo</organization> <address>
<address> <postal>
<postal> <street>PO Box 1080 Blindern</street>
<street>PO Box 1080 Blindern</street> <code>N-0316</code>
<code>N-0316</code> <city>Oslo</city>
<city>Oslo</city> <region/>
<region></region> <country>Norway</country>
<country>Norway</country> </postal>
</postal> <phone>+47 22 85 24 44</phone>
<phone>+47 22 85 24 44</phone> <email>steing@ifi.uio.no</email>
<email>steing@ifi.uio.no</email> </address>
</address> </author>
</author> <date month="January" year="2020"/>
<date year="2019" />
<area>Transport</area> <area>Transport</area>
<workgroup>RTP Media Congestion Avoidance Techniques (rmcat)</workgroup> <workgroup>RTP Media Congestion Avoidance Techniques (rmcat)</workgroup>
<keyword>tcp</keyword> <keyword>tcp</keyword>
<abstract> <abstract>
<t>When multiple congestion controlled Real-time Transport Protocol ( <t>When multiple congestion-controlled Real-time Transport Protocol
RTP) sessions traverse the same network bottleneck, combining their controls can (RTP) sessions traverse the same network bottleneck, combining their
improve the total on-the-wire behavior in terms of delay, loss and fairness. Th controls can improve the total on-the-wire behavior in terms of delay,
is document describes such a method for flows that have the same sender, in a wa loss, and fairness. This document describes such a method for flows that
y that is as flexible and simple as possible while minimizing the amount of chan have the same sender, in a way that is as flexible and simple as
ges needed to existing RTP applications. It specifies how to apply the method fo possible while minimizing the number of changes needed to existing RTP
r the Network-Assisted Dynamic Adaptation (NADA) congestion control algorithm, a applications. This document also specifies how to apply the method for the
nd provides suggestions on how to apply it to other congestion control algorithm Network-Assisted Dynamic Adaptation (NADA) congestion control algorithm
s.</t> and provides suggestions on how to apply it to other congestion control
algorithms.</t>
</abstract> </abstract>
</front> </front>
<middle> <middle>
<section title="Introduction" anchor='sec-intro'>
<t>When there is enough data to send, a congestion controller attempts to <section anchor="sec-intro" numbered="true" toc="default">
increase its sending rate until the path's capacity has been reached. <name>Introduction</name>
Some controllers detect path capacity by increasing the sending rate <t>When there is enough data to send, a congestion controller attempts
further, until packets are ECN-marked <xref target="RFC8087"/> or dropped, a to increase its sending rate until the path's capacity has been reached.
nd then decreasing Some controllers detect path capacity by increasing the sending rate
the sending rate until that stops happening. This process inevitably further, until packets are
creates undesirable queuing delay when multiple congestion-controlled ECN-marked <xref target="RFC8087" format="default"/> or dropped, and
connections traverse the same network bottleneck, and each connection then decreasing the sending rate until that stops happening. This
overshoots the path capacity as it determines its sending rate. </t> process inevitably creates undesirable queuing delay when multiple
congestion-controlled connections traverse the same network bottleneck,
<t>The Congestion Manager (CM) <xref target="RFC3124"/> couples flows by providi and each connection overshoots the path capacity as it determines its
ng a single congestion controller. It is hard to implement because it requires a sending rate. </t>
n additional congestion controller and removes all per-connection congestion con
trol functionality, which is quite a significant change to existing RTP based ap
plications. This document presents a method to combine the behavior of congestio
n control mechanisms that is easier to implement than the Congestion Manager <xr
ef target="RFC3124"/> and also requires less significant changes to existing RTP
based applications. It attempts to roughly approximate the CM behavior by shari
ng information between existing congestion controllers. It is able to honor user
-specified priorities, which is required by rtcweb <xref target="I-D.ietf-rtcweb
-overview"/> <xref target="RFC7478"/>.</t>
<t>The described mechanisms are believed safe to use, but are experimental and a
re presented for wider review and operational evaluation.</t>
<t>The Congestion Manager (CM) <xref target="RFC3124" format="default"/>
couples flows by providing a single congestion controller. It is hard to
implement because it requires an additional congestion controller and
removes all per-connection congestion control functionality, which is
quite a significant change to existing RTP-based applications. This
document presents a method to combine the behavior of congestion control
mechanisms that is easier to implement than the Congestion Manager <xref
target="RFC3124" format="default"/> and also requires fewer significant
changes to existing RTP-based applications. It attempts to roughly
approximate the CM behavior by sharing information between existing
congestion controllers. It is able to honor user-specified priorities,
which is required by WebRTC <xref target="I-D.ietf-rtcweb-overview"
format="default"/> <xref target="RFC7478" format="default"/>.</t>
<t>The described mechanisms are believed safe to use, but they are
experimental and are presented for wider review and operational
evaluation.</t>
</section> </section>
<section anchor="sec-def" numbered="true" toc="default">
<name>Definitions</name>
<section title="Definitions" anchor='sec-def'> <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>",
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>",
document are to be interpreted as described in <xref "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
target="RFC2119">RFC 2119</xref>.</t> "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are
to be interpreted as described in BCP&nbsp;14 <xref target="RFC2119"/>
<t><list style="hanging" hangIndent="6"> <xref target="RFC8174"/> when, and only when, they appear in all
<t hangText="Available Bandwidth:"> capitals, as shown here.</t>
<vspace />
The available bandwidth is the nominal link capacity minus the amount
of traffic that traversed the link during a certain time interval, divided by t
hat time interval.</t>
<t hangText="Bottleneck:">
<vspace />
The first link with the smallest available bandwidth along the path b
etween a sender and receiver.</t>
<t hangText="Flow:">
<vspace />
A flow is the entity that congestion control is operating on. It coul
d, for example, be a transport layer connection, or an RTP stream <xref target="
RFC7656"/>, whether or not this RTP stream is multiplexed onto an RTP session wi
th other RTP streams.</t>
<t hangText="Flow Group Identifier (FGI):">
<vspace />
A unique identifier for each subset of flows that is limited by a com
mon bottleneck.</t>
<t hangText="Flow State Exchange (FSE):">
<vspace />
The entity that maintains information that is exchanged between flows
.</t>
<t hangText="Flow Group (FG):">
<vspace />
A group of flows having the same FGI.</t>
<t hangText="Shared Bottleneck Detection (SBD):">
<vspace />
The entity that determines which flows traverse the same bottleneck i
n the network, or the process of doing so.</t>
</list></t>
<dl newline="true" spacing="normal" indent="6">
<dt>Available Bandwidth:</dt>
<dd>
The available bandwidth is the nominal link capacity minus the
amount of traffic that traversed the link during a certain time
interval, divided by that time interval.</dd>
<dt>Bottleneck:</dt>
<dd>
The first link with the smallest available bandwidth along the path b
etween a sender and receiver.</dd>
<dt>Flow:</dt>
<dd>
A flow is the entity that congestion control is operating on. It
could, for example, be a transport-layer connection or an RTP
stream <xref target="RFC7656" format="default"/>, regardless of
whether or not this RTP stream is multiplexed onto an RTP session
with other RTP streams.</dd>
<dt>Flow Group Identifier (FGI):</dt>
<dd>
A unique identifier for each subset of flows that is limited by a com
mon bottleneck.</dd>
<dt>Flow State Exchange (FSE):</dt>
<dd>
The entity that maintains information that is exchanged between flows
.</dd>
<dt>Flow Group (FG):</dt>
<dd>
A group of flows having the same FGI.</dd>
<dt>Shared Bottleneck Detection (SBD):</dt>
<dd>
The entity that determines which flows traverse the same
bottleneck in the network or the process of doing so.</dd>
</dl>
</section> </section>
<section anchor="sec-limits" numbered="true" toc="default">
<section title="Limitations" anchor='sec-limits'> <name>Limitations</name>
<t><list style="hanging" hangIndent="6"> <dl newline="true" spacing="normal" indent="6">
<t hangText="Sender-side only:"> <dt>Sender-side only:</dt>
<vspace /> <dd>
Shared bottlenecks can exist when multiple flows originate from the same s Shared bottlenecks can exist when multiple flows originate from the same
ender, or when flows from different senders reach the same receiver (see <xref t sender or when flows from different senders reach the same receiver (see
arget="RFC8382"/>, section 3). Coupled congestion control as described here only <xref target="RFC8382" sectionFormat="of" section="3" />). Coupled
supports the former case, not the latter, as it operates inside a single host o congestion control, as described here, only supports the former case, not
n the sender side. the latter, as it operates inside a single host on the sender side.
</t> </dd>
<t hangText="Shared bottlenecks do not change quickly:"> <dt>Shared bottlenecks do not change quickly:</dt>
<vspace /> <dd>
As per the definition above, a bottleneck depends on cross traffic, and sin As per the definition above, a bottleneck depends on cross traffic, and
ce such traffic can heavily fluctuate, bottlenecks can change at a high frequenc since such traffic can heavily fluctuate, bottlenecks can change at a
y (e.g., there can be oscillation between two or more links). This means that, w high frequency (e.g., there can be oscillation between two or more
hen flows are partially routed along different paths, they may quickly change be links). This means that, when flows are partially routed along different
tween sharing and not sharing a bottleneck. For simplicity, here it is assumed t paths, they may quickly change between sharing and not sharing a
hat a shared bottleneck is valid for a time interval that is significantly longe bottleneck. For simplicity, here it is assumed that a shared bottleneck
r than the interval at which congestion controllers operate. Note that, for the is valid for a time interval that is significantly longer than the
only SBD mechanism defined in this document (multiplexing on the same five-tuple interval at which congestion controllers operate. Note that, for the only
), the notion of a shared bottleneck stays correct even in the presence of fast SBD mechanism defined in this document (multiplexing on the same
traffic fluctuations: since all flows that are assumed to share a bottleneck are five-tuple), the notion of a shared bottleneck stays correct even in the
routed in the same way, if the bottleneck changes, it will still be shared.</t> presence of fast traffic fluctuations; since all flows that are assumed
</list></t> to share a bottleneck are routed in the same way, if the bottleneck
</section> changes, it will still be shared.</dd>
</dl>
<section title="Architectural overview" anchor='sec-arch'> </section>
<t>Figure 1 shows the elements of the architecture for coupled congestion <section anchor="sec-arch" numbered="true" toc="default">
control: the Flow State Exchange (FSE), Shared Bottleneck Detection (SBD) and Fl <name>Architectural Overview</name>
ows. The FSE is a storage element that can be implemented in two ways: active an <t><xref target="fig_1"/> shows the elements of the architecture for coupl
d passive. In the active version, it initiates communication with flows and SBD. ed
However, in the passive version, it does not actively initiate communication wi congestion control: the Flow State Exchange (FSE), Shared Bottleneck
th flows and SBD; its only active role is internal state maintenance (e.g., an i Detection (SBD), and Flows. The FSE is a storage element that can be
mplementation could use soft state to remove a flow's data after long periods of implemented in two ways: active and passive. In the active version, it
inactivity). Every time a flow's congestion control mechanism would normally up initiates communication with flows and SBD. However, in the passive
date its sending rate, the flow instead updates information in the FSE and perfo version, it does not actively initiate communication with flows and SBD;
rms a query on the FSE, leading to a sending rate that can be different from wha its only active role is internal state maintenance (e.g., an
t the congestion controller originally determined. Using information about/from implementation could use soft state to remove a flow's data after long
the currently active flows, SBD updates the FSE with the correct Flow Group Iden periods of inactivity). Every time a flow's congestion control mechanism
tifiers (FGIs). would normally update its sending rate, the flow instead updates
</t> information in the FSE and performs a query on the FSE, leading to a
sending rate that can be different from what the congestion controller
<t> This document describes both active and passive versions. While the pas originally determined. Using information about/from the currently active
sive algorithm works better for congestion controls with RTT-independent converg flows, SBD updates the FSE with the correct Flow Group Identifiers
ence, it can still produce oscillations on short time scales. The passive algor (FGIs).
ithm, described in <xref target="example-alg-pas"/>, is </t>
therefore considered as highly experimental and not safe to deploy <t> This document describes both active and passive versions. While the
outside of testbed environments. Figure 2 shows the interaction between flo passive algorithm works better for congestion controls with
ws and the FSE, using the variable names defined in <xref target="fse-variables" RTT-independent convergence, it can still produce oscillations on short
/>.</t> time scales. The passive algorithm, described in <xref
target="example-alg-pas" format="default"/>, is therefore considered
<figure align="center"> highly experimental and not safe to deploy outside of testbed
<artwork align="center"> environments. <xref target="fig_2"/> shows the interaction between flows
<![CDATA[ and the FSE using the variable names defined in <xref
target="fse-variables" format="default"/>.</t>
<figure anchor="fig_1" title="Coupled congestion control architecture" > <a
rtwork align="center" name="" type="" alt=""><![CDATA[------- <--- Flow 1
| FSE | <--- Flow 2 .. | FSE | <--- Flow 2 ..
------- <--- .. Flow N ------- <--- .. Flow N
^ ^
| | | |
------- | ------- |
| SBD | <-------| | SBD | <-------|
]]> ------- ]]></artwork></figure>
</artwork>
<postamble>Figure 1: Coupled congestion control architecture</pos
tamble>
</figure>
<figure align="center">
<artwork align="center">
<![CDATA[
Flow#1(cc) FSE Flow#2(cc) <figure anchor="fig_2" title="Flow-FSE interactions"> <artwork align="cente r" name="" type="" alt=""><![CDATA[Flow#1(cc) FSE Flow#2(cc)
---------- --- ---------- ---------- --- ----------
#1 JOIN ----register--> REGISTER #1 JOIN ----register--> REGISTER
REGISTER <--register-- JOIN #1 REGISTER <--register-- JOIN #1
#2 CC_R(1) ----UPDATE----> UPDATE (in) #2 CC_R(1) ----UPDATE----> UPDATE (in)
#3 NEW RATE <---FSE_R(1)-- UPDATE (out) --FSE_R(2)-> #3 NEW RATE #3 NEW RATE <---FSE_R(1)-- UPDATE (out) --FSE_R(2)-> #3 NEW RATE
]]> ]]></artwork></figure>
</artwork>
<postamble>Figure 2: Flow-FSE interaction</postamble>
</figure>
<t>Since everything shown in Figure 1 is assumed to operate on a single host (th
e sender) only, this document only describes aspects that have an influence on t
he resulting on-the-wire behavior. It does not, for instance, define how many bi
ts must be used to represent FGIs, or in which way the entities communicate.</t>
<t>Implementations can take various forms: for instance, all the elements in the <t>Since everything shown in <xref target="fig_1"/> is assumed to operate
figure could be implemented within a single application, thereby operating on f on a single
lows generated by that application only. Another alternative could be to impleme host (the sender) only, this document only describes aspects that have
nt both the FSE and SBD together in a separate process which different applicati an influence on the resulting on-the-wire behavior. It does not, for
ons communicate with via some form of Inter-Process Communication (IPC). Such an instance, define how many bits must be used to represent FGIs or in
implementation would extend the scope to flows generated by multiple applicatio which way the entities communicate.</t>
ns. The FSE and SBD could also be included in the Operating System kernel. Howev <t>Implementations can take various forms; for instance, all the
er, only one type of coupling algorithm should be used for all flows. Combinatio elements in the figure could be implemented within a single application,
ns of multiple algorithms at different aggregation levels (e.g., the Operating S thereby operating on flows generated by that application only. Another
ystem coupling application aggregates with one algorithm, and applications coupl alternative could be to implement both the FSE and SBD together in a
ing their flows with another) have not been tested and are therefore not recomme separate process that different applications communicate with via some
nded. </t> form of Inter-Process Communication (IPC). Such an implementation would
extend the scope to flows generated by multiple applications. The FSE
and SBD could also be included in the Operating System kernel. However,
only one type of coupling algorithm should be used for all
flows. Combinations of multiple algorithms at different aggregation
levels (e.g., the Operating System coupling application aggregates with
one algorithm, and applications coupling their flows with another) have
not been tested and are therefore not recommended. </t>
</section> </section>
<section anchor="roles" numbered="true" toc="default">
<name>Roles</name>
<t>This section gives an overview of the roles of the elements of
coupled congestion control and provides an example of how coupled
congestion control can operate.</t>
<section numbered="true" toc="default">
<name>SBD</name>
<t>SBD uses knowledge about the flows to determine which flows belong
in the same Flow Group (FG) and assigns FGIs accordingly. This
knowledge can be derived in three basic ways:
<section title="Roles" anchor='roles'> </t>
<t>This section gives an overview of the roles of the elements of coupled <ol spacing="normal" type="1">
congestion control, and provides an example of how coupled congestion control ca <li>From multiplexing: It can be based on the simple assumption that
n operate.</t> packets sharing the same five-tuple (IP source and destination
<section title="SBD"> address, protocol, and transport-layer port number pair) and having
<t>SBD uses knowledge about the flows to determine which flows belong in the same values for the Differentiated Services Code Point (DSCP)
the same Flow Group (FG), and assigns FGIs accordingly. and the ECN field in the IP header are typically treated in the same
This knowledge can be derived in three basic ways: way along the path. This method is the only one specified in this
document; SBD <bcp14>MAY</bcp14> consider all flows that use the
same five-tuple, DSCP, and ECN field value to belong to the same
FG. This classification applies to certain tunnels or RTP flows
that are multiplexed over one transport (cf. <xref
target="TRANSPORT-MULTIPLEX" format="default"/>). Such multiplexing
is also a recommended usage of RTP in WebRTC <xref
target="I-D.ietf-rtcweb-rtp-usage" format="default"/>.</li>
<li>Via configuration: e.g., by assuming that a common wireless uplink
is also a shared bottleneck.</li>
<li>From measurements: e.g., by considering correlations among
measured delay and loss as an indication of a shared
bottleneck.</li>
</ol>
<list style="numbers"> <t>The methods above have some essential trade-offs. For example,
<t>From multiplexing: it can be based on the simple assumption that pack multiplexing is a completely reliable measure, but it is limited
ets sharing the same five-tuple (IP source in scope to two endpoints (i.e., it cannot be applied to couple
and destination address, protocol, and transport layer port number pair) congestion controllers of one sender talking to multiple receivers). A
and having the same values for the measurement-based SBD mechanism is described in <xref target="RFC8382"
Differentiated Services Code Point (DSCP) and the ECN field in the IP he format="default"/>. Measurements can never be 100% reliable, in
ader are typically treated in the same way along the path. particular because they are based on the past, but applying coupled
This method is the only one specified in this document: SBD MAY consider congestion control involves making an assumption about the future; it is
all flows that use the same therefore recommended to implement cautionary measures, e.g., by
five-tuple, DSCP and ECN field value to belong to the same FG. This clas disabling coupled congestion control if enabling it causes a
sification applies to certain tunnels, or RTP flows significant increase in delay and/or packet loss. Measurements also
that are multiplexed over one transport (cf. <xref target="transport-mul take time, which entails a certain delay for turning on coupling
tiplex"/>). Such multiplexing is also (refer to <xref target="RFC8382" format="default"/> for details).
a recommended usage of RTP in rtcweb <xref target="rtcweb-rtp-usage"/>.<
/t>
<t>Via configuration: e.g. by assuming that a common wireless uplink is
also a shared bottleneck.</t>
<t>From measurements: e.g. by considering correlations among measured de
lay and loss as an indication of a shared bottleneck.</t>
</list>
</t>
<t>The methods above have some essential trade-offs: e.g., multiplexing is a
completely reliable measure, however it
is limited in scope to two end points (i.e., it cannot be applied to couple
congestion controllers of one sender
talking to multiple receivers). A measurement-based SBD mechanism is describ
ed in <xref target="RFC8382"/>. Measurements can never be
100% reliable, in particular because they are based on the past but applying
coupled congestion control means to
make an assumption about the future; it is therefore recommended to implemen
t cautionary measures, e.g. by
disabling coupled congestion control if enabling it causes a significant inc
rease in delay and/or packet loss.
Measurements also take time, which entails a certain delay for turning o
n coupling (refer to <xref target="RFC8382"/> for details).
Using system configuration to decide about shared bottlenecks can be mor
e efficient (faster to obtain) than using measurements,
but it relies on assumptions about the network environment.</t>
When this is possible, it can be more efficient to statically configure shared
bottlenecks (e.g., via a system configuration or user input) based on
assumptions about the network environment.</t>
</section> </section>
<section title="FSE" anchor="fse-variables"> <section anchor="fse-variables" numbered="true" toc="default">
<t>The FSE contains a list of all flows that have registered with it. For <name>FSE</name>
each flow, it stores the following: <t>The FSE contains a list of all flows that have registered with
<list style="symbols"> it. For each flow, the FSE stores the following:
<t>a unique flow number f to identify the flow.</t> </t>
<t>the FGI of the FG that it belongs to (based on the definitions in th <ul spacing="normal">
is document, a flow has only one bottleneck, and can therefore be in only one FG <li>a unique flow number f to identify the flow.</li>
).</t> <li>the FGI of the FG that it belongs to (based on the definitions
<t>a priority P(f), which is a positive number, greater than zero.</t> in this document, a flow has only one bottleneck and can therefore
<t>The rate used by the flow in bits per second, FSE_R(f). </t> be in only one FG).</li>
<t>The desired rate DR(f) of flow f. This can be smaller than FSE_R(f) if
the application feeding into the flow has less data to send than FSE_R(f) would
allow, or if a maximum value is imposed on the rate.
In the absence of such limits DR(f) must be
set to the sending rate provided by the congestion control module of f
low f.</t>
</list>
Note that the absolute range of priorities does not matter: the algorithm wo
rks with
a flow's priority portion of the sum of all priority values. For example,
if there are two flows, flow 1 with priority 1 and flow 2 with priority 2, the
sum of the priorities is 3. Then, flow 1 will be assigned 1/3 of the aggregate s
ending rate and flow 2 will be assigned 2/3 of the aggregate sending rate. Prior
ities can be mapped to the "very-low", "low", "medium" or "high" priority levels
described in <xref target="I-D.ietf-rtcweb-transports"/> by simply using the va
lues 1, 2, 4 and 8, respectively.
</t>
<t>In the FSE, each FG contains one static variable S_CR which is the sum of
the calculated rates of all flows in the same FG. This value is used to calcula
te the sending rate. </t>
<t>The information listed here is enough to implement the sample flow alg <li>a priority P(f), which is a number greater than zero.</li>
orithm given below. FSE implementations could easily be extended to store, e.g., <li>The rate used by the flow in bits per second, FSE_R(f). </li>
a flow's current sending rate for statistics gathering or future potential opti <li>The desired rate DR(f) of flow f. This can be smaller than
mizations.</t> FSE_R(f) if the application feeding into the flow has less data to
send than FSE_R(f) would allow or if a maximum value is imposed on
the rate. In the absence of such limits, DR(f) must be set to the
sending rate provided by the congestion control module of flow
f.</li>
</ul>
<t>
Note that the absolute range of priorities does not matter; the algorithm
works with a flow's priority portion of the sum of all priority
values. For example, if there are two flows, flow 1 with priority 1 and
flow 2 with priority 2, the sum of the priorities is 3. Then, flow 1 will
be assigned 1/3 of the aggregate sending rate, and flow 2 will be assigned
2/3 of the aggregate sending rate. Priorities can be mapped to the
"very-low", "low", "medium", or "high" priority levels described in <xref
target="I-D.ietf-rtcweb-transports" format="default"/> by simply using the
values 1, 2, 4, and 8, respectively.
</t>
<t>In the FSE, each FG contains one static variable, S_CR, which is the
sum of the calculated rates of all flows in the same FG. This value is
used to calculate the sending rate. </t>
<t>The information listed here is enough to implement the sample flow
algorithm given below. FSE implementations could easily be extended to
store, e.g., a flow's current sending rate for statistics gathering or
future potential optimizations.</t>
</section> </section>
<section title="Flows" anchor='flows'>
<t>Flows register themselves with SBD and FSE when they start, deregister
from the FSE when they stop, and carry out an UPDATE function call every time t
heir congestion controller calculates a new sending rate. Via UPDATE, they provi
de the newly calculated rate and optionally (if the algorithm supports it) the d
esired rate. The desired rate is less than the calculated rate in case of applic
ation-limited flows; otherwise, it is the same as the calculated rate.</t>
<t>Below, two example algorithms are described. While other algorithms could be <section anchor="flows" numbered="true" toc="default">
used instead, the same algorithm must be applied to all flows. Names of variable <name>Flows</name>
s used in the algorithms are explained below. <t>Flows register themselves with SBD and FSE when they start,
<list style="symbols"> deregister from the FSE when they stop, and carry out an UPDATE
<t> CC_R(f) - The rate received from the congestion controller of flow f when it function call every time their congestion controller calculates a new
calls UPDATE.</t> sending rate. Via UPDATE, they provide the newly calculated rate and,
<t> FSE_R(f) - The rate calculated by the FSE for flow f.</t> optionally (if the algorithm supports it), the desired rate. The
<t> DR(f) - The desired rate of flow f.</t> desired rate is less than the calculated rate in case of
<t> S_CR - The sum of the calculated rates of all flows in the same FG; this val application-limited flows; otherwise, it is the same as the calculated
ue is used to calculate the sending rate.</t> rate.</t>
<t> FG - A group of flows having the same FGI, and hence sharing the same bottle <t>Below, two example algorithms are described. While other algorithms
neck.</t> could be used instead, the same algorithm must be applied to all
<t> P(f) - The priority of flow f which is received from the flow’s congestion c flows. Names of variables used in the algorithms are explained below.
ontroller; the FSE uses this variable for calculating FSE_R(f).</t>
<t> S_P - The sum of all the priorities.</t>
<t> TLO - The total leftover rate: the sum of rates that could not be assigned t
o
flows that were limited by their desired rate.</t>
<t> AR - The aggregate rate that is assigned to flows that are not limited by th
eir desired rate.</t>
</list>
</t> </t>
<section title="Example algorithm 1 - Active FSE" anchor='example-alg-act'> <dl newline="false" indent="10" spacing="normal">
<t>This algorithm was designed to be the simplest possible method to assign ra <dt>CC_R(f)</dt><dd>The rate received from the congestion controller o
tes according to the priorities of flows. Simulations results in <xref target="f f
se"></xref> indicate that it does however not significantly reduce queuing delay flow f when it calls UPDATE.</dd>
and packet loss.</t> <dt>FSE_R(f)</dt><dd>The rate calculated by the FSE for flow f.</dd>
<t><list style="format (%d)"> <dt>DR(f)</dt><dd>The desired rate of flow f.</dd>
<t>When a flow f starts, it registers itself with SBD and the FSE. FSE_R(f) <dt>S_CR</dt><dd>The sum of the calculated rates of all flows in the s
is initialized with the congestion controller's initial rate. SBD will assign th ame
e correct FGI. When a flow is assigned an FGI, it adds its FSE_R(f) to S_CR.</t> FG; this value is used to calculate the sending rate.</dd>
<t>When a flow f stops or pauses, its entry is removed from the list.</t> <dt>FG</dt><dd>A group of flows having the same FGI and hence, sharing
<t>Every time the congestion controller of the flow f determines a new sendi the same bottleneck.</dd>
ng rate CC_R(f), the flow calls UPDATE, which carries out the tasks listed below <dt>P(f)</dt><dd>The priority of flow f, which is received from the fl
to derive the new sending rates for all the flows in the FG. A flow's UPDATE fu ow's congestion controller; the FSE uses this variable for calculating FSE_R(f).
nction uses three local (i.e. per-flow) temporary variables: S_P, TLO and AR. </dd>
<list style="format (%c)"> <dt>S_P</dt><dd>The sum of all the priorities.</dd>
<dt>TLO</dt><dd>The total leftover rate; the sum of rates that could n
ot be assigned to
flows that were limited by their desired rate.</dd>
<dt>AR</dt><dd>The aggregate rate that is assigned to flows that are n
ot limited by their desired rate.</dd>
</dl>
<section anchor="example-alg-act" numbered="true" toc="default">
<name>Example Algorithm 1 - Active FSE</name>
<t> It updates S_CR. <t>This algorithm was designed to be the simplest possible method to
<figure align="left"> assign rates according to the priorities of flows. Simulation
<artwork align="left"> results in <xref target="FSE" format="default"/> indicate that it
<![CDATA[ does not, however, significantly reduce queuing delay and packet
S_CR = S_CR + CC_R(f) - FSE_R(f)]]> loss.</t>
</artwork>
</figure>
</t>
<t> It calculates the sum of all the priorities, S_P, and initializes FSE_R. <ol spacing="normal" type="(%d)">
<figure align="left"> <li>When a flow f starts, it registers itself with SBD and the
<artwork align="left"> FSE. FSE_R(f) is initialized with the congestion controller's
<![CDATA[ initial rate. SBD will assign the correct FGI. When a flow is
assigned an FGI, it adds its FSE_R(f) to S_CR.</li>
<li>When a flow f stops or pauses, its entry is removed from the lis
t.</li>
<li>
<t>Every time the congestion controller of the flow f determines
a new sending rate CC_R(f), the flow calls UPDATE, which carries
out the tasks listed below to derive the new sending rates for
all the flows in the FG. A flow's UPDATE function uses three
local (i.e., per-flow) temporary variables: S_P, TLO, and AR.
</t>
<ol spacing="normal" type="(%c)">
<li>
<t> It updates S_CR.
</t>
<sourcecode type="pseudocode"><![CDATA[
S_CR = S_CR + CC_R(f) - FSE_R(f) ]]></sourcecode>
</li>
<li>
<t> It calculates the sum of all the priorities, S_P, and init
ializes FSE_R.
</t>
<sourcecode type="pseudocode"><![CDATA[
S_P = 0 S_P = 0
for all flows i in FG do for all flows i in FG do
S_P = S_P + P(i) S_P = S_P + P(i)
FSE_R(i) = 0 FSE_R(i) = 0
end for]]> end for ]]></sourcecode>
</artwork> </li>
</figure> <li>
</t> <t> It distributes S_CR among all flows, ensuring that each fl
ow's desired rate
<t> It distributes S_CR among all flows, ensuring that each flow's desired r
ate
is not exceeded. is not exceeded.
<figure align="left"> </t>
<artwork align="left"> <sourcecode type="pseudocode"><![CDATA[
<![CDATA[
TLO = S_CR TLO = S_CR
while(TLO-AR>0 and S_P>0) while(TLO-AR>0 and S_P>0)
AR = 0 AR = 0
for all flows i in FG do for all flows i in FG do
if FSE_R[i] < DR[i] then if FSE_R[i] < DR[i] then
if TLO * P[i] / S_P >= DR[i] then if TLO * P[i] / S_P >= DR[i] then
TLO = TLO - DR[i] TLO = TLO - DR[i]
FSE_R[i] = DR[i] FSE_R[i] = DR[i]
S_P = S_P - P[i] S_P = S_P - P[i]
else else
FSE_R[i] = TLO * P[i] / S_P FSE_R[i] = TLO * P[i] / S_P
AR = AR + TLO * P[i] / S_P AR = AR + TLO * P[i] / S_P
end if end if
end if end if
end for end for
end while]]> end while ]]></sourcecode>
</artwork> </li>
</figure> <li>
</t> <t> It distributes FSE_R to all the flows.
</t>
<t> It distributes FSE_R to all the flows. <sourcecode type="pseudocode"><![CDATA[
<figure align="left">
<artwork align="left">
<![CDATA[
for all flows i in FG do for all flows i in FG do
send FSE_R(i) to the flow i send FSE_R(i) to the flow i
end for]]> end for ]]></sourcecode>
</artwork> </li>
</figure> </ol>
</t> </li>
</ol>
</list></t> </section>
<section anchor="example-alg-act-cons" numbered="true" toc="default">
</list></t> <name>Example Algorithm 2 - Conservative Active FSE</name>
<t>This algorithm changes algorithm 1 to conservatively emulate the
</section> behavior of a single flow by proportionally reducing the aggregate
rate on congestion. Simulation results in <xref target="FSE"
<section title="Example algorithm 2 - Conservative Active FSE" anchor='example- format="default"/> indicate that it can significantly reduce queuing
alg-act-cons'> delay and packet loss.
<t>This algorithm changes algorithm 1 to conservatively emulate the behavio </t>
r of a single flow by proportionally reducing the aggregate rate on congestion.
Simulations results in <xref target="fse"></xref> indicate that it can significa
ntly reduce queuing delay and packet loss. <!--It misses some features that we w
ould like to incorporate in future versions of this document (e.g. letting bulk
transfers immediately use the bandwidth that is not used by application-limited
flows); if these features make the algorithm significantly more complex, this wi
ll be included as a third variant of the algorithm.--></t>
<t>Step (a) of the UPDATE function is changed as described below. This also in
troduces a local variable DELTA, which is used to calculate the difference betwe
en CC_R(f) and the previously stored FSE_R(f). To prevent flows from either igno
ring congestion or overreacting, a timer keeps them from changing their rates im
mediately after the common rate reduction that follows a congestion event. This
timer is set to 2 RTTs of the flow that experienced congestion because it is ass
umed that a congestion event can persist for up to one RTT of that flow, with an
other RTT added to compensate for fluctuations in the measured RTT value.
<list style="format (%c)">
<t> It updates S_CR based on DELTA. <t>Step (a) of the UPDATE function is changed as described
<figure align="left"> below. This also introduces a local variable DELTA, which is used to
<artwork align="left"> calculate the difference between CC_R(f) and the previously stored
<![CDATA[ FSE_R(f). To prevent flows from either ignoring congestion or
overreacting, a timer keeps them from changing their rates
immediately after the common rate reduction that follows a
congestion event. This timer is set to two RTTs of the flow that
experienced congestion because it is assumed that a congestion event
can persist for up to one RTT of that flow, with another RTT added
to compensate for fluctuations in the measured RTT value.
</t>
<ol type="(%c)" spacing="normal">
<li>
<t> It updates S_CR based on DELTA.
</t>
<sourcecode type="pseudocode"><![CDATA[
if Timer has expired or was not set then if Timer has expired or was not set then
DELTA = CC_R(f) - FSE_R(f) DELTA = CC_R(f) - FSE_R(f)
if DELTA < 0 then // Reduce S_CR proportionally if DELTA < 0 then // Reduce S_CR proportionally
S_CR = S_CR * CC_R(f) / FSE_R(f) S_CR = S_CR * CC_R(f) / FSE_R(f)
Set Timer for 2 RTTs Set Timer for 2 RTTs
else else
S_CR = S_CR + DELTA S_CR = S_CR + DELTA
end if end if
end if ]]> end if ]]></sourcecode>
</artwork> </li>
</figure> </ol>
</t> </section>
</list></t> </section>
</section>
</section>
</section>
<section anchor="Application" title="Application">
<t>This section specifies how the FSE can be applied to specific congestion
control mechanisms and makes general recommendations that facilitate applying t
he FSE to future congestion controls.</t>
<section anchor="app-NADA" title="NADA">
<t>Network-Assisted Dynamic Adapation (NADA) <xref target="I-D.ietf-rmcat-n
ada"></xref> is a congestion control scheme for rtcweb. It calculates a referenc
e rate r_ref upon receiving an acknowledgment, and then, based on the reference
rate, it calculates a video target rate r_vin and a sending rate for the flows,
r_send.</t>
<t>When applying the FSE to NADA, the UPDATE function call described in <xr
ef target="flows"></xref> gives the FSE NADA's reference rate r_ref. The recomme
nded algorithm for NADA is the Active FSE in <xref target="example-alg-act"></xr
ef>. In step 3 (c), when the FSE_R(i) is "sent" to the flow i, this means updati
ng r_ref(r_vin and r_send) of flow i with the value of FSE_R(i).</t>
<!-- <t>NADA simulation results are available from
http://heim.ifi.uio.no/safiquli/coupled-cc/. The next version of this docum
ent will refer to a technical report that will be made available at the same URL
.</t> -->
</section> </section>
<section anchor="Application" numbered="true" toc="default">
<name>Application</name>
<t>This section specifies how the FSE can be applied to specific
congestion control mechanisms and makes general recommendations that
facilitate applying the FSE to future congestion controls.</t>
<section anchor="app-general" title="General recommendations"> <section anchor="app-NADA" numbered="true" toc="default">
<t>This section provides general advice for applying the FSE to congestion c <name>NADA</name>
ontrol mechanisms.</t> <t>Network-Assisted Dynamic Adaptation (NADA) <xref
<t><list style="hanging" hangIndent="6"> target="RFC8698" format="default"/> is a congestion
<t hangText="Receiver-side calculations:"> control scheme for WebRTC. It calculates a reference rate r_ref upon
<vspace /> receiving an acknowledgment and then, based on the reference rate,
When receiver-side calculations make assumptions about the rate of the s calculates a video target rate r_vin and a sending rate for the flows,
ender, the calculations need to be synchronized or the receiver needs to be upda r_send.</t>
ted accordingly. This applies to TFRC <xref target="RFC5348"/>, for example, whe
re simulations showed somewhat less favorable results when using the FSE without
a receiver-side change <xref target="fse" />.</t>
<t hangText="Stateful algorithms:">
<vspace />
When a congestion control algorithm is stateful (e.g., TCP, with Slow St
art, Congestion Avoidance and Fast Recovery), these states should be carefully c
onsidered such that the
overall state of the aggregate flow is correct. This may require sharing
more information in the UPDATE call.
</t>
<t hangText="Rate jumps:"> <t>When applying the FSE to NADA, the UPDATE function call described in <xref
<vspace /> target="flows" format="default"/> gives the FSE NADA's reference rate
The FSE-based coupling algorithms can let a flow quickly increase its ra r_ref. The recommended algorithm for NADA is the Active FSE in <xref
te to its fair share, e.g. when a new flow joins or after a quiescent period. In target="example-alg-act" format="default"/>. In step 3 (d), when the FSE_R(i) i
case of window-based congestion controls, this may produce a burst which should s "sent" to
be mitigated in some way. An example of how this could be done without using a the flow i, r_ref (r_vin and r_send) of flow i is updated with the value of FSE
timer is presented in <xref target="anrw2016"/>, using TCP as an example. _R(i).</t>
</t>
</list></t> </section>
<section anchor="app-general" numbered="true" toc="default">
<name>General Recommendations</name>
<t>This section provides general advice for applying the FSE to congesti
on control mechanisms.</t>
<dl newline="true" spacing="normal" indent="6">
<dt>Receiver-side calculations:</dt>
<dd>
When receiver-side calculations make assumptions about the rate of the
sender, the calculations need to be synchronized, or the receiver needs
to be updated accordingly. This applies to TCP Friendly Rate Control
(TFRC) <xref target="RFC5348" format="default"/>, for example, where
simulations showed somewhat less favorable results when using the FSE
without a receiver-side change <xref target="FSE"
format="default"/>.</dd>
<dt>Stateful algorithms:</dt>
<dd>
When a congestion control algorithm is stateful (e.g., during the TCP sl
ow
start, congestion avoidance, or fast recovery phase), these states shoul
d
be carefully considered such that the overall state of the aggregate
flow is correct. This may require sharing more information in the
UPDATE call.
</dd>
<dt>Rate jumps:</dt>
<dd>
The FSE-based coupling algorithms can let a flow quickly increase its
rate to its fair share, e.g., when a new flow joins or after a
quiescent period. In case of window-based congestion controls, this
may produce a burst that should be mitigated in some way. An example
of how this could be done without using a timer is presented in <xref
target="ANRW2016" format="default"/>, using TCP as an example.
</dd>
</dl>
</section>
</section> </section>
<section anchor="expected-feedback" numbered="true" toc="default">
<name>Expected Feedback from Experiments</name>
<t>The algorithm described in this memo has so far been evaluated using
simulations covering all the tests for more than one flow from <xref
target="I-D.ietf-rmcat-eval-test" format="default"/> (see <xref
target="IETF-93" format="default"/> and <xref target="IETF-94"
format="default"/>). Experiments should confirm these results using at
least the NADA congestion control algorithm with real-life code (e.g.,
browsers communicating over an emulated network covering the conditions
in <xref target="I-D.ietf-rmcat-eval-test" format="default"/>). The
tests with real-life code should be repeated afterwards in real network
environments and monitored. Experiments should investigate cases where
the media coder's output rate is below the rate that is calculated by
the coupling algorithm (FSE_R(i) in algorithms 1 (<xref
target="example-alg-act"/>) and 2 (<xref
target="example-alg-act-cons"/>)). Implementers and testers are invited
to document their findings in an Internet-Draft.</t>
</section> </section>
<section anchor="expected-feedback" title="Expected feedback from experi <section anchor="IANA" numbered="true" toc="default">
ments"> <name>IANA Considerations</name>
<t>The algorithm described in this memo has so far been evaluated using s <t>This document has no IANA actions.</t>
imulations covering all the tests for more than one flow from
<xref target="I-D.ietf-rmcat-eval-test"/> (see <xref target="IET
F-93"/>, <xref target="IETF-94"/>). Experiments should confirm these results usi
ng at least the NADA congestion
control algorithm with real-life code (e.g., browsers communica
ting over an emulated network covering the conditions in <xref target="I-D.ietf-
rmcat-eval-test"/>.
The tests with real-life code should be repeated afterwards in re
al network environments and monitored. Experiments should investigate cases wher
e the media coder's output rate is below the rate that is calculated by the coup
ling algorithm (FSE_R(i) in algorithms 1 and 2, section 5.3). Implementers and t
esters are invited to document their findings in an Internet draft. </t>
</section> </section>
<section anchor="Security" numbered="true" toc="default">
<section anchor="Acknowledgements" title="Acknowledgements"> <name>Security Considerations</name>
<t>This document has benefitted from discussions with and feedback from A <t>In scenarios where the architecture described in this document is
ndreas Petlund, Anna Brunstrom, Colin Perkins, David Hayes, David Ros (who also applied across applications, various cheating possibilities arise, e.g.,
gave the FSE its name), Ingemar Johansson, Karen Nielsen, Kristian Hiorth, Mirja supporting wrong values for the calculated rate, desired rate, or
Kuehlewind, Martin Stiemerling, Spencer Dawkins, Varun Singh, Xiaoqing Zhu, and priority of a flow. In the worst case, such cheating could either
Zaheduzzaman Sarker. The authors would like to especially thank Xiaoqing Zhu an prevent other flows from sending or make them send at a rate that is
d Stefan Holmer for helping with NADA and GCC, and Anna Brunstrom as well as Jul unreasonably large. The end result would be unfair behavior at the
ius Flohr for helping us correct the active algorithm for the case of applicatio network bottleneck, akin to what could be achieved with any UDP-based
n-limited flows.</t> application. Hence, since this is no worse than UDP in general, there
<t>This work was partially funded by the European Community under its Sev seems to be no significant harm in using this in the absence of UDP rate
enth Framework Programme through the Reducing Internet Transport Latency (RITE) limiters.</t>
project (ICT-317700).</t> <t>In the case of a single-user system, it should also be in the
interest of any application programmer to give the user the best
possible experience by using reasonable flow priorities or even letting
the user choose them. In a multi-user system, this interest may not be
given, and one could imagine the worst case of an "arms race" situation
where applications end up setting their priorities to the maximum
value. If all applications do this, the end result is a fair allocation
in which the priority mechanism is implicitly eliminated and no major
harm is done.</t>
<t> Implementers should also be aware of the Security Considerations
sections of <xref target="RFC3124" format="default"/>, <xref
target="RFC5348" format="default"/>, and <xref target="RFC7478"
format="default"/>.</t>
</section> </section>
</middle>
<section anchor="IANA" title="IANA Considerations"> <back>
<t>This memo includes no request to IANA.</t>
</section>
<section anchor="Security" title="Security Considerations"> <displayreference target="I-D.ietf-rmcat-eval-test" to="RMCAT-PROPOSALS"/>
<t>In scenarios where the architecture described in this document is appli <displayreference target="I-D.ietf-rmcat-gcc" to="GCC-RTCWEB"/>
ed across applications, various cheating possibilities arise: e.g., supporting w <displayreference target="I-D.ietf-rtcweb-transports" to="WEBRTC-TRANS"/>
rong values for the calculated rate, the desired rate, or the priority of a flow <displayreference target="I-D.ietf-rtcweb-rtp-usage" to="RTCWEB-RTP-USAGE"/>
. In the worst case, such cheating could either prevent other flows from sending <displayreference target="I-D.ietf-rtcweb-overview" to="RTCWEB-OVERVIEW"/>
or make them send at a rate that is unreasonably large. The end result would be
unfair behavior at the network bottleneck, akin to what could be achieved with
any UDP based application. Hence, since this is no worse than UDP in general, th
ere seems to be no significant harm in using this in the absence of UDP rate lim
iters.</t>
<t>In the case of a single-user system, it should also be in the interest of any <references>
application programmer to give the user the best possible experience by using r <name>References</name>
easonable flow priorities or even letting the user choose them. In a multi-user
system, this interest may not be given, and one could imagine the worst case of
an "arms race" situation, where applications end up setting their priorities to
the maximum value. If all applications do this, the end result is a fair allocat
ion in which the priority mechanism is implicitly eliminated, and no major harm
is done.</t>
<t> Implementers should also be aware of the Security Considerations sections o <references>
f <xref target="RFC3124"/>, <xref target="RFC5348"/>, and <xref target="RFC7478" <name>Normative References</name>
/>.</t>
</section>
</middle>
<!-- *****BACK MATTER ***** --> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.2119.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.8174.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.3124.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.5348.xml"/>
<back> <reference anchor="RFC8698" target="https://www.rfc-editor.org/info/rfc8698">
<front>
<title>Network-Assisted Dynamic Adaptation (NADA): A Unified Congestion
Control Scheme for Real-Time Media</title>
<author initials='X' surname='Zhu' fullname='Xiaoqing Zhu'>
<organization/>
</author>
<author initials='R' surname='Pan' fullname='Rong Pan'>
<organization/>
</author>
<author initials='M' surname='Ramalho' fullname='Michael A. Ramalho'>
<organization/>
</author>
<author initials='S' surname='Mena' fullname='Sergio Mena de la Cruz'>
<organization/>
</author>
<date month='January' year='2020'/>
</front>
<seriesInfo name="RFC" value="8698"/>
<seriesInfo name="DOI" value="10.17487/RFC8698"/>
</reference>
<references title="Normative References"> </references>
<!--?rfc include="http://xml.resource.org/public/rfc/bibxml/reference.RFC. <references>
2119.xml"?--> <name>Informative References</name>
&RFC2119; <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
&RFC3124; ence.RFC.7656.xml"/>
&RFC5348; <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
&I-D.ietf-rmcat-nada; ence.RFC.8087.xml"/>
</references> <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.8382.xml"/>
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer
ence.RFC.7478.xml"/>
<references title="Informative References"> <!-- I-D.ietf-rmcat-eval-test: I-D exists -->
<xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml3/reference.
I-D.ietf-rmcat-eval-test.xml"/>
&RFC7656; <!-- I-D.draft-ietf-rmcat-gcc-02: Expired -->
&RFC8087; <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml3/reference.
&RFC8382; I-D.ietf-rmcat-gcc.xml"/>
&I-D.ietf-rmcat-eval-test;
&I-D.ietf-rmcat-gcc;
<reference anchor="I-D.ietf-rtcweb-transports" target=""> <!-- I-D.ietf-rtcweb-transports: I-D exists-->
<front> <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml3/reference.
<title>Transports for WebRTC</title> I-D.ietf-rtcweb-transports.xml"/>
<author initials="H." surname="Alvestrand" fullname="H. A
lvestrand"></author>
<date month="October" year="2016"/>
</front>
<seriesInfo name="Internet-draft" value="draft-ietf-rtcwe
b-transports-17.txt"/>
</reference>
&RFC7478; <!-- I-D.ietf-rtcweb-overview: I-D exists -->
&I-D.ietf-rtcweb-overview; <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml3/reference.
I-D.ietf-rtcweb-overview.xml"/>
<reference anchor="transport-multiplex" target=""> <!-- I-D.ietf-rtcweb-rtp-usage: I-D exists-->
<front> <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml3/reference.
<title>Multiple RTP Sessions on a Single Lower-Layer Tran I-D.ietf-rtcweb-rtp-usage.xml"/>
sport</title>
<author initials="M." surname="Westerlund" fullname="M. W
esterlund"></author>
<author initials="C." surname="Perkins" fullname="C. Perk
ins"></author>
<date month="October" year="2013"/>
</front>
<seriesInfo name="Internet-draft" value="draft-westerlund
-avtcore-transport-multiplexing-07.txt"/>
</reference>
<reference anchor="rtcweb-rtp-usage" target=""> <!-- draft-westerlund-avtcore-transport-multiplexing-07: Expired -
<front> unable to use short way-->
<title>Web Real-Time Communication (WebRTC): Media Transp
ort and Use of RTP</title>
<author initials="C." surname="Perkins" fullname="C. Perk
ins"></author>
<author initials="M." surname="Westerlund" fullname="M. W
esterlund"></author>
<author initials="J." surname="Ott" fullname="J. Ott"></a
uthor>
<date month="March" year="2016"/>
</front>
<seriesInfo name="Internet-draft" value="draft-ietf-rtcwe
b-rtp-usage-26.txt"/>
</reference>
<reference anchor="fse"> <reference anchor='TRANSPORT-MULTIPLEX' target="">
<front> <front>
<title>Coupled Congestion Control for RTP Media</title> <title>Multiple RTP Sessions on a Single Lower-Layer Transport</title>
<author initials="S.I." surname="Islam" fullname="S. Islam"> </author> <author initials='M.' surname='Westerlund' fullname='Magnus Westerlund'>
<author initials="M.W." surname="Welzl" fullname="M. Welzl" > </author> <organization />
<author initials="S.G." surname="Gjessing" fullname="S Gjessing" > </autho </author>
r> <author initials='C.' surname='Perkins' fullname='Colin Perkins'>
<author initials="N.K." surname="Khademi" fullname="N Khademi" > </author> <organization />
<date year="2014" /> </author>
</front> <date month='October' year='2013' />
<seriesInfo name="ACM SIGCOMM Capacity Sharing Workshop (CSWS 2014) and ACM </front>
SIGCOMM CCR 44(4) 2014; extended version available as a technical report from ht <seriesInfo name='Internet-Draft' value='draft-westerlund-avtcore-transport-mult
tp://safiquli.at.ifi.uio.no/paper/fse-tech-report.pdf" value="" /> iplexing-07'/>
</reference> </reference>
<reference anchor="fse-noms"> <reference anchor="FSE" target="http://safiquli.at.ifi.uio.no/paper/fse-tech
<front> -report.pdf">
<title>Managing Real-Time Media Flows through a Flow State Exchange< <front>
/title> <title>Coupled Congestion Control for RTP Media</title>
<author initials="S.I." surname="Islam" fullname="S. Islam"> </autho <author initials="S." surname="Islam" fullname="S. Islam"/>
r> <author initials="M." surname="Welzl" fullname="M. Welzl"/>
<author initials="M.W." surname="Welzl" fullname="M. Welzl" > </auth <author initials="S." surname="Gjessing" fullname="S Gjessing"/>
or> <author initials="N." surname="Khademi" fullname="N Khademi"/>
<author initials="D.H" surname="Hayes" fullname="D Hayes" > </author <date month="March" year="2014"/>
> </front>
<author initials="S.G." surname="Gjessing" fullname="S Gjessing" > < <refcontent>ACM SIGCOMM Capacity Sharing Workshop (CSWS 2014) and ACM SIGCOMM
/author> CCR 44(4) 2014
<date year="2016" /> </refcontent>
</front> </reference>
<seriesInfo name="IEEE NOMS 2016, Istanbul, Turkey" value="" />
</reference>
<reference anchor="IETF-93" <reference anchor="FSE-NOMS">
target="https://www.ietf.org/proceedings/93/rmcat.html"> <front>
<front> <title>Managing real-time media flows through a flow state exchange<
<title>Updates on Coupled Congestion Control for RTP Media</title> /title>
<seriesInfo name="DOI" value="10.1109/NOMS.2016.7502803"/>
<author initials="S." surname="Islam" fullname="Safiqul Islam"/>
<author initials="M." surname="Welzl" fullname="Michael Welzl"/>
<author initials="D." surname="Hayes" fullname="David Hayes"/>
<author initials="S." surname="Gjessing" fullname="Stein Gjessing"/>
</front>
<refcontent>IEEE NOMS 2016
</refcontent>
</reference>
<author initials="S.I." surname="Islam" fullname="S. Islam"> </auth <reference anchor="IETF-93" target="https://www.ietf.org/proceedings/93/
or> rmcat.html">
<author initials="M.W." surname="Welzl" fullname="M. Welzl" > </auth <front>
or> <title>Updates on 'Coupled
<author initials="S.G." surname="Gjessing" fullname="S Gjessing" > < Congestion Control for RTP Media'
/author> </title>
<date month= "July" year = "2015"/> <author initials="S." surname="Islam" fullname="Safiqul Islam"/>
</front> <author initials="M." surname="Welzl" fullname="Michael Welzl"/>
</reference> <author initials="S." surname="Gjessing" fullname="S Gjessing"/>
<date month="July" year="2015"/>
</front>
<seriesInfo name="IETF" value="93" />
<refcontent>RTP Media Congestion Avoidance Techniques (rmcat) Working Group</ref
content>
</reference>
<reference anchor="IETF-94" <reference anchor="IETF-94" target="https://www.ietf.org/proceedings/94/
target="https://www.ietf.org/proceedings/94/rmcat.html"> rmcat.html">
<front> <front>
<title>Updates on Coupled Congestion Control for RTP Media</title> <title>Updates on 'Coupled Congestion Control for RTP Media'</title>
<author initials="S." surname="Islam" fullname="Safiqul Islam"/>
<author initials="M." surname="Welzl" fullname="M. Welzl"/>
<author initials="S." surname="Gjessing" fullname="S Gjessing"/>
<date month="November" year="2015"/>
</front>
<seriesInfo name="IETF" value="94" />
<refcontent>RTP Media Congestion Avoidance Techniques (rmcat) Working Group</ref
content>
</reference>
<author initials="S.I." surname="Islam" fullname="S. Islam"> </auth <reference anchor="ANRW2016">
or> <front>
<author initials="M.W." surname="Welzl" fullname="M. Welzl" > </auth <title>Start Me Up: Determining and Sharing TCP's Initial Congestion
or> Window</title>
<author initials="S.G." surname="Gjessing" fullname="S Gjessing" > < <seriesInfo name="Proceedings of the 2016 Applied Networking Research
/author> Workshop" value="Pages 52-54"/>
<date month= "November" year = "2015"/> <seriesInfo name="DOI" value="10.1145/2959424.2959440"/>
</front> <author initials="S." surname="Islam" fullname="Safiqul Islam"/>
</reference> <author initials="M." surname="Welzl" fullname="Michael Welzl"/>
<date month="July" year="2016"/>
</front>
<refcontent>ACM, IRTF, ISOC Applied Networking Research Workshop 2016 (ANRW 2016
)
</refcontent>
</reference>
<reference anchor="anrw2016"> </references>
<front>
<title>Start Me Up:Determining and Sharing TCP’s Initial Congestion
Window</title>
<author initials="S.I." surname="Islam" fullname="S. Islam"> </autho
r>
<author initials="M.W." surname="Welzl" fullname="M. Welzl" > </auth
or>
<date year="2016" />
</front>
<seriesInfo name="ACM, IRTF, ISOC Applied Networking Research Workshop 2
016 (ANRW 2016)" value="" />
</reference>
</references> </references>
<section anchor="app-GCC" title="Application to GCC"> <section anchor="app-GCC" numbered="true" toc="default">
<t>Google Congestion Control (GCC) <xref target="I-D.ietf-rmcat-gcc"></x <name>Application to GCC</name>
ref> is another congestion control scheme for RTP flows that <t>Google Congestion Control (GCC) <xref target="I-D.ietf-rmcat-gcc"
is under development. GCC is not yet finalised, but at the time of t format="default"/> is another congestion control scheme for RTP flows
his writing, the that is under development. GCC is not yet finalized, but at the time of
rate control of GCC employs two parts: controlling the bandwidth est this writing, the rate control of GCC employs two parts: controlling the
imate based on delay, and controlling the bandwidth estimate bandwidth estimate based on delay and controlling the bandwidth
based on loss. Both are designed to estimate the available bandwidth, A_ estimate based on loss. Both are designed to estimate the available
hat. </t> bandwidth, A_hat. </t>
<t>When applying the FSE to GCC, the UPDATE function call described in
<t>When applying the FSE to GCC, the UPDATE function call described in < <xref target="flows" format="default"/> gives the FSE GCC's estimate of
xref target="flows"></xref> gives the FSE GCC's estimate of available bandwidth available bandwidth A_hat. The recommended algorithm for GCC is the
A_hat. The recommended algorithm for GCC is the Active FSE in <xref target="exam Active FSE in <xref target="example-alg-act" format="default"/>. In
ple-alg-act"></xref>. In step 3 (c), when the FSE_R(i) is "sent" to the flow i, step 3 (d) of this algorithm, when the FSE_R(i) is "sent" to the flow i,
this means updating A_hat of flow i with the value of FSE_R(i).</t> A_hat of flow i is updated with the value of FSE_R(i).</t>
</section>
<section anchor="scheduling" numbered="true" toc="default">
<name>Scheduling</name>
<t> When flows originate from the same host, it would be possible to use
only one sender-side congestion controller that determines the
overall allowed sending rate and then use a local scheduler to assign a
proportion of this rate to each RTP session. This way, priorities could
also be implemented as a function of the scheduler. The Congestion
Manager (CM) <xref target="RFC3124" format="default"/> also uses such a
scheduling function.</t>
</section> </section>
<section title="Scheduling" anchor='scheduling'> <section anchor="example-alg-pas" numbered="true" toc="default">
<name>Example Algorithm - Passive FSE</name>
<t> When flows originate from the same host, it would be possible to use onl <t>Active algorithms calculate the rates for all the flows in the FG and
y one single sender-side congestion controller which determines the overall allo actively distribute them. In a passive algorithm, UPDATE returns a rate
wed sending rate, and then use a local scheduler to assign a proportion of this that should be used instead of the rate that the congestion controller
rate to each RTP session. This way, priorities could also be implemented as a fu has determined. This can make a passive algorithm easier to implement;
nction of the scheduler. The Congestion Manager (CM) <xref target="RFC3124"/> al however, when round-trip times of flows are unequal, flows with shorter RT
so uses such a scheduling function.</t> Ts
</section> may (depending on the congestion control algorithm) update and react to
the overall FSE state more often than flows with longer RTTs, which can
<section title="Example algorithm - Passive FSE" anchor='example-alg-pas'> produce unwanted side effects. This problem is more significant when the
<t>Active algorithms calculate the rates for all the flows in the FG and activ congestion control convergence depends on the RTT. While the passive
ely distribute them. In a passive algorithm, UPDATE returns a rate that should b algorithm works better for congestion controls with RTT-independent
e used instead of the rate that the congestion controller has determined. This c convergence, it can still produce oscillations on short time scales. The
an make a passive algorithm easier to implement; however, when round-trip times algorithm described below is therefore considered highly experimental
of flows are unequal, and not safe to deploy outside of testbed environments. Results of a
shorter-RTT flows may (depending on the congestion control algorithm) update and simplified passive FSE algorithm with both NADA and GCC can be found in
react to the overall FSE state more often than longer-RTT flows, which can prod <xref target="FSE-NOMS" format="default"/>.</t>
uce unwanted side effects. This problem is more significant when the congestion <t>In the passive version of the FSE, TLO (Total Leftover Rate) is a
control convergence depends on the RTT. While the passive algorithm works better static variable per FG that is initialized to 0. Additionally, S_CR is
for congestion controls with RTT-independent convergence, it can still produce limited to increase or decrease as conservatively as a flow's congestion
oscillations on short time scales. The algorithm described below is therefore co controller decides in order to prohibit sudden rate jumps.
nsidered as highly experimental and not safe to deploy outside of testbed enviro
nments. Results of a simplified passive FSE algorithm with both NADA and GCC can
be found in <xref target="fse-noms"></xref>.</t>
<t>In the passive version of the FSE, TLO (the Total Leftover Rate) is a stati
c variable per FG which is initialized to 0. Additionally, S_CR is limited to in
crease or decrease as conservatively as a flow's congestion controller decides i
n order to prohibit sudden rate jumps.<!--At most, it can be the sum of these ca
lculated rates, as seen by the flow during its last rate update.--></t>
<t><list style="format (%d)"> </t>
<t>When a flow f starts, it registers itself with SBD and the FSE. FSE_R(f) <ol spacing="normal" type="(%d)">
and DR(f) are initialized with the congestion controller's initial rate. SBD wil <li>When a flow f starts, it registers itself with SBD and the
l assign the correct FGI. When a flow is assigned an FGI, it adds its FSE_R(f) t FSE. FSE_R(f) and DR(f) are initialized with the congestion
o S_CR.</t> controller's initial rate. SBD will assign the correct FGI. When a
<t>When a flow f stops or pauses, it sets its DR(f) to 0 and sets P(f) to -1 flow is assigned an FGI, it adds its FSE_R(f) to S_CR.</li>
.</t> <li>When a flow f stops or pauses, it sets its DR(f) to 0 and sets P(f)
<t>Every time the congestion controller of the flow f determines a new sendi to -1.</li>
ng rate CC_R(f), assuming the flow's new desired rate new_DR(f) to be "infinity" <li>
in case of a bulk data transfer with an unknown maximum rate, the flow calls UP <t>Every time the congestion controller of the flow f determines a
DATE, which carries out the tasks listed below to derive the flow's new sending new sending rate CC_R(f), assuming the flow's new desired rate
rate, Rate(f). A flow's UPDATE function uses a few local (i.e. per-flow) tempora new_DR(f) to be "infinity" in case of a bulk data transfer with an
ry variables, which are all initialized to 0: DELTA, new_S_CR and S_P. unknown maximum rate, the flow calls UPDATE, which carries out the
<list style="format (%c)"> tasks listed below to derive the flow's new sending rate, Rate(f). A
<t>For all the flows in its FG (including itself), it calculates the sum flow's UPDATE function uses a few local (i.e., per-flow) temporary
of all the calculated rates, new_S_CR. Then it calculates DELTA: the difference variables, which are all initialized to 0: DELTA, new_S_CR, and S_P.
between FSE_R(f) and CC_R(f). </t>
<figure align="left">
<artwork align="left">
<![CDATA[
for all flows i in FG do
new_S_CR = new_S_CR + FSE_R(i)
end for
DELTA = CC_R(f) - FSE_R(f)]]>
</artwork>
</figure>
</t>
<t>It updates S_CR, FSE_R(f) and DR(f). <ol spacing="normal" type="(%c)">
<figure align="left"> <li>
<artwork align="left"> <t>For all the flows in its FG (including itself), it calculates
<![CDATA[ the sum of all the calculated rates, new_S_CR. Then, it
FSE_R(f) = CC_R(f) calculates DELTA: the difference between FSE_R(f) and CC_R(f).
if DELTA > 0 then // the flow's rate has increased </t>
S_CR = S_CR + DELTA <sourcecode type="pseudocode"><![CDATA[
else if DELTA < 0 then for all flows i in FG do
S_CR = new_S_CR + DELTA new_S_CR = new_S_CR + FSE_R(i)
end if end for
DR(f) = min(new_DR(f),FSE_R(f))]]> DELTA = CC_R(f) - FSE_R(f) ]]></sourcecode>
</artwork> </li>
</figure> <li>
</t> <t>It updates S_CR, FSE_R(f), and DR(f).
</t>
<sourcecode type="pseudocode"><![CDATA[
FSE_R(f) = CC_R(f)
if DELTA > 0 then // the flow's rate has increased
S_CR = S_CR + DELTA
else if DELTA < 0 then
S_CR = new_S_CR + DELTA
end if
DR(f) = min(new_DR(f),FSE_R(f)) ]]></sourcecode>
</li>
<t>It calculates the leftover rate TLO, removes the terminated flows fro <li>
m the FSE and calculates the sum of all the priorities, S_P. <t>It calculates the leftover rate TLO, removes the terminated
<figure align="left"> flows from the FSE, and calculates the sum of all the priorities,
<artwork align="left"> S_P.
<![CDATA[ </t>
<sourcecode type="pseudocode"><![CDATA[
for all flows i in FG do for all flows i in FG do
if P(i)<0 then if P(i)<0 then
delete flow delete flow
else else
S_P = S_P + P(i) S_P = S_P + P(i)
end if end if
end for end for
if DR(f) < FSE_R(f) then if DR(f) < FSE_R(f) then
TLO = TLO + (P(f)/S_P) * S_CR - DR(f)) TLO = TLO + (P(f)/S_P) * S_CR - DR(f))
end if]]> end if ]]></sourcecode>
</artwork> </li>
</figure> <li>
</t> <t>It calculates the sending rate, Rate(f).
</t>
<t>It calculates the sending rate, Rate(f). <sourcecode type="pseudocode"><![CDATA[
<figure align="left">
<artwork align="left">
<![CDATA[
Rate(f) = min(new_DR(f), (P(f)*S_CR)/S_P + TLO) Rate(f) = min(new_DR(f), (P(f)*S_CR)/S_P + TLO)
if Rate(f) != new_DR(f) and TLO > 0 then if Rate(f) != new_DR(f) and TLO > 0 then
TLO = 0 // f has 'taken' TLO TLO = 0 // f has 'taken' TLO
end if]]> end if ]]></sourcecode>
</artwork> </li>
</figure> <li>
</t> <t>It updates DR(f) and FSE_R(f) with Rate(f).
</t>
<t>It updates DR(f) and FSE_R(f) with Rate(f). <sourcecode type="pseudocode"><![CDATA[
<figure align="left">
<artwork align="left">
<![CDATA[
if Rate(f) > DR(f) then if Rate(f) > DR(f) then
DR(f) = Rate(f) DR(f) = Rate(f)
end if end if
FSE_R(f) = Rate(f)]]> FSE_R(f) = Rate(f) ]]></sourcecode>
</artwork> </li>
</figure> </ol>
</t> </li>
</ol>
</list></t> <t>The goals of the flow algorithm are to achieve prioritization,
improve network utilization in the face of application-limited flows,
</list></t> and impose limits on the increase behavior such that the negative impact
<t>The goals of the flow algorithm are to achieve prioritization, improv of multiple flows trying to increase their rate together is
e network utilization in the face of application-limited flows, and impose limit minimized. It does that by assigning a flow a sending rate that may not
s on the increase behavior such that the negative impact of multiple flows tryin be what the flow's congestion controller expected. It therefore builds
g to increase their rate together is minimized. It does that by assigning a flow on the assumption that no significant inefficiencies arise from
a sending rate that may not be what the flow's congestion controller expected. temporary application-limited behavior or from quickly jumping to a rate
It therefore builds on the assumption that no significant inefficiencies arise f that is higher than the congestion controller intended. How problematic
rom temporary application-limited behavior or from quickly jumping to a rate tha these issues really are depends on the controllers in use and requires
t is higher than the congestion controller intended. How problematic these issue careful per-controller experimentation. The coupled congestion control
s really are depends on the controllers in use and requires careful per-controll mechanism described here also does not require all controllers to be
er experimentation. The coupled congestion control mechanism described here also equal; effects of heterogeneous controllers, or homogeneous controllers
does not require all controllers to be equal; effects of heterogeneous controll being in different states, are also subject to experimentation.</t>
ers, or homogeneous controllers being in different states, are also subject to e
xperimentation.</t>
<t>This algorithm gives all the leftover rate of application-limited
flows to the first
flow that updates its sending rate, provided that this flow needs it
all (otherwise, its own leftover rate can be taken by the next flow that upda
tes its rate). Other policies could be applied, e.g. to divide the leftover rat
e of a flow
equally among all other flows in the FGI.</t>
<section anchor="example-op" title="Example operation (passive)">
<t>In order to illustrate the operation of the passive coupled congestion
control algorithm, this section presents a toy example of two flows that use it
. Let us assume that both flows traverse a common 10 Mbit/s bottleneck and use a
simplistic congestion controller that starts out with 1 Mbit/s, increases its r
ate by 1 Mbit/s in the absence of congestion and decreases it by 2 Mbit/s in the
presence of congestion. For simplicity, flows are assumed to always operate in
a round-robin fashion. Rate numbers below without units are assumed to be in Mbi
t/s. For illustration purposes, the actual sending rate is also shown for every
flow in FSE diagrams even though it is not really stored in the FSE.</t>
<t>Flow #1 begins. It is a bulk data transfer and considers itself to have top p <t>This algorithm gives the leftover rate of application-limited
riority. This is the FSE after the flow algorithm's step 1:</t> flows to the first flow that updates its sending rate, provided that
<figure align="left"> this flow needs it all (otherwise, its own leftover rate can be taken by
<artwork align="left"> the next flow that updates its rate). Other policies could be applied,
<![CDATA[ e.g., to divide the leftover rate of a flow equally among all other flows
in the FGI.</t>
<section anchor="example-op" numbered="true" toc="default">
<name>Example Operation (Passive)</name>
<t>In order to illustrate the operation of the passive coupled
congestion control algorithm, this section presents a toy example of
two flows that use it. Let us assume that both flows traverse a common
10 Mbit/s bottleneck and use a simplistic congestion controller that
starts out with 1 Mbit/s, increases its rate by 1 Mbit/s in the
absence of congestion, and decreases it by 2 Mbit/s in the presence of
congestion. For simplicity, flows are assumed to always operate in a
round-robin fashion. Rate numbers below without units are assumed to
be in Mbit/s. For illustration purposes, the actual sending rate is
also shown for every flow in FSE diagrams even though it is not really
stored in the FSE.</t>
<t>Flow #1 begins. It is a bulk data transfer and considers itself to
have top priority. This is the FSE after the flow algorithm's step
1:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[------------------
----------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 1 | 1 | 1 | | 1 | 1 | 1 | 1 | 1 | 1 |
---------------------------------------- ----------------------------------------
S_CR = 1, TLO = 0 S_CR = 1, TLO = 0 ]]></artwork>
<t>Its congestion controller gradually increases its rate. Eventually,
]]> at some point, the FSE should look like this:</t>
</artwork> <artwork align="left" name="" type="" alt=""><![CDATA[------------------
</figure> -----------------------
<t>Its congestion controller gradually increases its rate. Eventually, at some p
oint, the FSE should look like this:</t>
<figure align="left">
<artwork align="left">
<![CDATA[
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 10 | 10 | 10 | | 1 | 1 | 1 | 10 | 10 | 10 |
----------------------------------------- -----------------------------------------
S_CR = 10, TLO = 0 S_CR = 10, TLO = 0 ]]></artwork>
<t>Now, another flow joins. It is also a bulk data transfer and has a
]]> lower priority (0.5):</t>
</artwork> <artwork align="left" name="" type="" alt=""><![CDATA[------------------
</figure> ------------------------
<t>Now another flow joins. It is also a bulk data transfer, and has a lower prio
rity (0.5):</t>
<figure align="left">
<artwork align="left">
<![CDATA[
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 10 | 10 | 10 | | 1 | 1 | 1 | 10 | 10 | 10 |
| 2 | 1 | 0.5 | 1 | 1 | 1 | | 2 | 1 | 0.5 | 1 | 1 | 1 |
------------------------------------------ ------------------------------------------
S_CR = 11, TLO = 0 S_CR = 11, TLO = 0 ]]></artwork>
<t>Now, assume that the first flow updates its rate to 8, because the
total sending rate of 11 exceeds the total capacity. Let us take a
closer look at what happens in step 3 of the flow algorithm.</t>
]]> <t>CC_R(1) = 8. new_DR(1) = infinity.</t>
</artwork> <ol spacing="normal" type="(3%c)">
</figure> <li>new_S_CR = 11; DELTA = 8 - 10 = -2.</li>
<t>Now assume that the first flow updates its rate to 8, because the total sendi <li>FSE_R(1) = 8. DELTA is negative, hence S_CR = 9; DR(1) = 8</li>
ng rate of 11 exceeds the total capacity. <li>S_P = 1.5.</li>
Let us take a closer look at what happens in step 3 of the flow algorithm.</t> <li>new sending rate Rate(1) = min(infinity, 1/1.5 * 9 + 0) = 6.</li>
<figure align="left"> <li>FSE_R(1) = 6.</li>
<artwork align="left"> </ol>
<![CDATA[
CC_R(1) = 8. new_DR(1) = infinity.
3 a) new_S_CR = 11; DELTA = 8 - 10 = -2.
3 b) FSE_R(1) = 8. DELTA is negative, hence S_CR = 9;
DR(1) = 8.
3 c) S_P = 1.5.
3 d) new sending rate Rate(1) = min(infinity, 1/1.5 * 9 + 0) = 6.
3 e) FSE_R(1) = 6.
The resulting FSE looks as follows: <t>The resulting FSE looks as follows:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[
------------------------------------------- -------------------------------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 6 | 8 | 6 | | 1 | 1 | 1 | 6 | 8 | 6 |
| 2 | 1 | 0.5 | 1 | 1 | 1 | | 2 | 1 | 0.5 | 1 | 1 | 1 |
------------------------------------------- -------------------------------------------
S_CR = 9, TLO = 0 S_CR = 9, TLO = 0 ]]></artwork>
]]> <t>The effect is that flow #1 is sending with 6 Mbit/s instead of the
</artwork> 8 Mbit/s that the congestion controller derived. Let us now assume
</figure> that flow #2 updates its rate. Its congestion controller detects that
<t>The effect is that flow #1 is sending with 6 Mbit/s instead of the 8 Mbit/s t the network is not fully saturated (the actual total sending rate is
hat the congestion controller derived. Let us now assume that flow #2 updates it 6+1=7) and increases its rate.</t>
s rate. Its congestion controller detects that the network is not fully saturate
d (the actual total sending rate is 6+1=7) and increases its rate.</t>
<figure align="left">
<artwork align="left">
<![CDATA[
CC_R(2) = 2. new_DR(2) = infinity.
3 a) new_S_CR = 7; DELTA = 2 - 1 = 1.
3 b) FSE_R(2) = 2. DELTA is positive, hence S_CR = 9 + 1 = 10;
DR(2) = 2.
3 c) S_P = 1.5.
3 d) Rate(2) = min(infinity, 0.5/1.5 * 10 + 0) = 3.33.
3 e) DR(2) = FSE_R(2) = 3.33.
The resulting FSE looks as follows: <t>CC_R(2) = 2. new_DR(2) = infinity.</t>
<ol spacing="normal" type="(3%c)">
<li>new_S_CR = 7; DELTA = 2 - 1 = 1.</li>
<li>FSE_R(2) = 2. DELTA is positive, hence S_CR = 9 + 1 = 10; DR(2) = 2.</li>
<li>S_P = 1.5.</li>
<li>Rate(2) = min(infinity, 0.5/1.5 * 10 + 0) = 3.33.</li>
<li>DR(2) = FSE_R(2) = 3.33.</li>
</ol>
<t>The resulting FSE looks as follows:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[
------------------------------------------- -------------------------------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 6 | 8 | 6 | | 1 | 1 | 1 | 6 | 8 | 6 |
| 2 | 1 | 0.5 | 3.33 | 3.33 | 3.33 | | 2 | 1 | 0.5 | 3.33 | 3.33 | 3.33 |
------------------------------------------- -------------------------------------------
S_CR = 10, TLO = 0 S_CR = 10, TLO = 0 ]]></artwork>
<t>The effect is that flow #2 is now sending with 3.33 Mbit/s, which
is close to half of the rate of flow #1 and leads to a total
utilization of 6(#1) + 3.33(#2) = 9.33 Mbit/s. Flow #2's congestion
controller has increased its rate faster than the controller actually
expected. Now, flow #1 updates its rate. Its congestion controller
detects that the network is not fully saturated and increases its
rate. Additionally, the application feeding into flow #1 limits the
flow's sending rate to at most 2 Mbit/s.</t>
]]> <t>CC_R(1) = 7. new_DR(1) = 2.</t>
</artwork>
</figure>
<t>The effect is that flow #2 is now sending with 3.33 Mbit/s, which is
close to half of the rate of flow #1 and leads to a total utilization of 6(#1) +
3.33(#2) = 9.33 Mbit/s. Flow #2's congestion controller has increased its rate
faster than the controller actually expected. Now, flow #1 updates its rate. Its
congestion controller detects that the network is not fully saturated and incre
ases its rate. Additionally, the application feeding into flow #1 limits the flo
w's sending rate to at most 2 Mbit/s.</t>
<figure align="left">
<artwork align="left">
<![CDATA[
CC_R(1) = 7. new_DR(1) = 2.
3 a) new_S_CR = 9.33; DELTA = 1.
3 b) FSE_R(1) = 7, DELTA is positive, hence S_CR = 10 + 1 = 11;
DR(1) = min(2, 7) = 2.
3 c) S_P = 1.5; DR(1) < FSE_R(1), hence TLO = 1/1.5 * 11 - 2 = 5.33.
3 d) Rate(1) = min(2, 1/1.5 * 11 + 5.33) = 2.
3 e) FSE_R(1) = 2.
The resulting FSE looks as follows: <ol spacing="normal" type="(3%c)">
<li>new_S_CR = 9.33; DELTA = 1.</li>
<li>FSE_R(1) = 7, DELTA is positive, hence S_CR = 10 + 1 = 11; DR(1) = min(2, 7)
= 2. </li>
<li>S_P = 1.5; DR(1) &lt; FSE_R(1), hence TLO = 1/1.5 * 11 - 2 = 5.33.</li>
<li>Rate(1) = min(2, 1/1.5 * 11 + 5.33) = 2.</li>
<li>FSE_R(1) = 2.</li>
</ol>
<t>The resulting FSE looks as follows:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[
------------------------------------------- -------------------------------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 2 | 2 | 2 | | 1 | 1 | 1 | 2 | 2 | 2 |
| 2 | 1 | 0.5 | 3.33 | 3.33 | 3.33 | | 2 | 1 | 0.5 | 3.33 | 3.33 | 3.33 |
------------------------------------------- -------------------------------------------
S_CR = 11, TLO = 5.33 S_CR = 11, TLO = 5.33 ]]></artwork>
]]> <t>Now, the total rate of the two flows is 2 + 3.33 = 5.33 Mbit/s,
</artwork> i.e., the network is significantly underutilized due to the limitation
</figure> of flow #1. Flow #2 updates its rate. Its congestion controller
<t>Now, the total rate of the two flows is 2 + 3.33 = 5.33 Mbit/s, i.e. the netw detects that the network is not fully saturated and increases its
ork is significantly underutilized due to the limitation of flow #1. Flow #2 upd rate.</t>
ates its rate. Its congestion controller detects that the network is not fully s
aturated and increases its rate.</t>
<figure align="left">
<artwork align="left">
<![CDATA[
CC_R(2) = 4.33. new_DR(2) = infinity.
3 a) new_S_CR = 5.33; DELTA = 1.
3 b) FSE_R(2) = 4.33. DELTA is positive, hence S_CR = 12;
DR(2) = 4.33.
3 c) S_P = 1.5.
3 d) Rate(2) = min(infinity, 0.5/1.5 * 12 + 5.33 ) = 9.33.
3 e) FSE_R(2) = 9.33, DR(2) = 9.33.
The resulting FSE looks as follows: <t>CC_R(2) = 4.33. new_DR(2) = infinity.</t>
<ol spacing="normal" type="(3%c)">
<li>new_S_CR = 5.33; DELTA = 1.</li>
<li>FSE_R(2) = 4.33. DELTA is positive, hence S_CR = 12; DR(2) = 4.33.</li>
<li>S_P = 1.5.</li>
<li>Rate(2) = min(infinity, 0.5/1.5 * 12 + 5.33 ) = 9.33.</li>
<li>FSE_R(2) = 9.33, DR(2) = 9.33.</li>
</ol>
<t>The resulting FSE looks as follows:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[
------------------------------------------- -------------------------------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 1 | 1 | 1 | 2 | 2 | 2 | | 1 | 1 | 1 | 2 | 2 | 2 |
| 2 | 1 | 0.5 | 9.33 | 9.33 | 9.33 | | 2 | 1 | 0.5 | 9.33 | 9.33 | 9.33 |
------------------------------------------- -------------------------------------------
S_CR = 12, TLO = 0 S_CR = 12, TLO = 0 ]]></artwork>
<t>Now, the total rate of the two flows is 2 + 9.33 = 11.33
Mbit/s. Finally, flow #1 terminates. It sets P(1) to -1 and DR(1) to
0. Let us assume that it terminated late enough for flow #2 to still
experience the network in a congested state, i.e., flow #2 decreases
its rate in the next iteration.</t>
]]> <t>CC_R(2) = 7.33. new_DR(2) = infinity.</t>
</artwork>
</figure>
<t>Now, the total rate of the two flows is 2 + 9.33 = 11.33 Mbit/s. Finally, flo
w #1 terminates. It sets P(1) to -1 and DR(1) to 0. Let us assume that it termin
ated late enough for flow #2 to still experience the network in a congested stat
e, i.e. flow #2 decreases its rate in the next iteration.</t>
<figure align="left"> <ol spacing="normal" type="(3%c)">
<artwork align="left"> <li>new_S_CR = 11.33; DELTA = -2.</li>
<![CDATA[ <li>FSE_R(2) = 7.33. DELTA is negative, hence S_CR = 9.33; DR(2) = 7.33.</li>
CC_R(2) = 7.33. new_DR(2) = infinity. <li>Flow 1 has P(1) = -1, hence it is deleted from the FSE. S_P = 0.5.</li>
3 a) new_S_CR = 11.33; DELTA = -2. <li>Rate(2) = min(infinity, 0.5/0.5*9.33 + 0) = 9.33.</li>
3 b) FSE_R(2) = 7.33. DELTA is negative, hence S_CR = 9.33; <li>FSE_R(2) = DR(2) = 9.33.</li>
DR(2) = 7.33. </ol>
3 c) Flow 1 has P(1) = -1, hence it is deleted from the FSE.
S_P = 0.5.
3 d) Rate(2) = min(infinity, 0.5/0.5*9.33 + 0) = 9.33.
3 e) FSE_R(2) = DR(2) = 9.33.
The resulting FSE looks as follows: <t>The resulting FSE looks as follows:</t>
<artwork align="left" name="" type="" alt=""><![CDATA[
------------------------------------------- -------------------------------------------
| # | FGI | P | FSE_R | DR | Rate | | # | FGI | P | FSE_R | DR | Rate |
| | | | | | | | | | | | | |
| 2 | 1 | 0.5 | 9.33 | 9.33 | 9.33 | | 2 | 1 | 0.5 | 9.33 | 9.33 | 9.33 |
------------------------------------------- -------------------------------------------
S_CR = 9.33, TLO = 0 S_CR = 9.33, TLO = 0 ]]></artwork>
]]>
</artwork>
</figure>
</section>
</section>
<section title="Change log">
<section title="draft-welzl-rmcat-coupled-cc">
<section title="Changes from -00 to -01">
<t>
<list style="symbols">
<t> Added change log. </t>
<t> Updated the example algorithm and its operation.</t>
</list>
</t>
</section>
<section title="Changes from -01 to -02">
<t>
<list style="symbols">
<t>Included an active version of the algorithm which is simpler.</
t>
<t>Replaced "greedy flow" with "bulk data transfer" and "non-greed
y" with "application-limited".</t>
<t>Updated new_CR to CC_R, and CR to FSE_R for better understandin
g. </t>
</list>
</t>
</section>
<section title="Changes from -02 to -03">
<t>
<list style="symbols">
<t>Included an active conservative version of the algorithm which
reduces queue growth and packet loss; added a reference to a technical report th
at shows these benefits with simulations.</t>
<t>Moved the passive variant of the algorithm to appendix.</t>
</list>
</t>
</section>
<section title="Changes from -03 to -04">
<t>
<list style="symbols">
<t>Extended SBD section.</t>
<t>Added a note about window-based controllers.</t>
</list>
</t>
</section>
<section title="Changes from -04 to -05">
<t>
<list style="symbols">
<t>Added a section about applying the FSE to specific congestion c
ontrol algorithms, with a subsection specifying its use with NADA.</t>
</list>
</t>
</section> </section>
</section> </section>
<section anchor="Acknowledgements" numbered="false" toc="default">
<section title="draft-ietf-rmcat-coupled-cc"> <name>Acknowledgements</name>
<t>This document benefited from discussions with and feedback from
<section title="Changes from draft-welzl-rmcat-coupled-cc-05"> <contact fullname="Andreas Petlund"/>, <contact fullname="Anna Brunstrom"/
<t> >,
<list style="symbols"> <contact fullname="Colin Perkins"/>, <contact fullname="David Hayes"/>,
<t>Moved scheduling section to the appendix.</t> <contact fullname="David Ros"/>
</list> (who also gave the FSE its name), <contact fullname="Ingemar Johansson"/>,
</t> <contact fullname="Karen Nielsen"/>,
</section> <contact fullname="Kristian Hiorth"/>, <contact fullname="Mirja Kuehlewind
"/>,
<section title="Changes from -00 to -01"> <contact fullname="Martin Stiemerling"/>, <contact fullname="Spencer Dawk
<t> ins"/>,
<list style="symbols"> <contact fullname="Varun Singh"/>, <contact fullname="Xiaoqing Zhu"/>, and
<t>Included how to apply the algorithm to GCC.</t> <contact fullname="Zaheduzzaman Sarker"/>. The authors would
<t>Updated variable names of NADA to be in line with the latest version. like to especially thank <contact fullname="Xiaoqing Zhu"/> and <contact f
</t> ullname="Stefan Holmer"/> for helping with
<t>Added a reference to <xref target="I-D.ietf-rtcweb-transports"/> to m NADA and GCC, and <contact fullname="Anna Brunstrom"/> as well as <contact
ake a connection to the prioritization text there.</t> fullname="Julius Flohr"/> for helping us
</list> correct the active algorithm for the case of application-limited
</t> flows.</t>
</section> <t>This work was partially funded by the European Community under its
Seventh Framework Program through the Reducing Internet Transport
<section title="Changes from -01 to -02"> Latency (RITE) project (ICT-317700).</t>
<t>
<list style="symbols">
<t>Minor changes.</t>
<t>Moved references of NADA and GCC from informative to normativ
e. </t>
<t>Added a reference for the passive variant of the algorithm.</
t>
</list>
</t>
</section>
<section title="Changes from -02 to -03">
<t>
<list style="symbols">
<t>Minor changes.</t>
<t>Added a section about expected feedback from experiments.</t>
</list>
</t>
</section>
<section title="Changes from -03 to -04">
<t>
<list style="symbols">
<t> Described the names of variables used in the algorithms.
</t>
<t> Added a diagram to illustrate the interaction between fl
ows and the FSE. </t>
<t> Added text on the trade-off of using the configuration b
ased approach.</t>
<t> Minor changes to enhance the readability.</t>
</list>
</t>
</section>
<section title="Changes from -04 to -05">
<t>
<list style="symbols">
<t> Changed several occurrences of "NADA and GCC" to "NADA", inc
luding the abstract.</t>
<t> Moved the application to GCC to an appendix, and made the GC
C reference informative.</t>
<t> Provided a few more general recommendations on applying the
coupling algorithm.</t>
</list>
</t>
</section>
<section title="Changes from -05 to -06">
<t>
<list style="symbols">
<t> Incorporated comments by Colin Perkins.</t>
</list>
</t>
</section>
<section title="Changes from -06 to -07">
<t>
<list style="symbols">
<t>Addressed OPSDIR, SECDIR, GENART, AD and IESG comments.</t>
</list>
</t>
</section>
<section title="Changes from -07 to -08">
<t>
<list style="symbols">
<t>Updated the algorithms in section 5 to support application-li
mited flows. Moved definition of Desired Rate from appendix to section 5. Update
d references.</t>
</list>
</t>
</section>
<section title="Changes from -08 to -09">
<t>
<list style="symbols">
<t>Minor improvement of the algorithms in section 5.</t>
</list>
</t>
</section> </section>
</section>
</section>
</back> </back>
</rfc> </rfc>
 End of changes. 101 change blocks. 
1104 lines changed or deleted 915 lines changed or added

This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/