<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.17 (Ruby 3.3.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-welzl-iccrg-pacing-00" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.22.0 -->
  <front>
    <title abbrev="Pacing in Transport Protocols">Pacing in Transport Protocols</title>
    <seriesInfo name="Internet-Draft" value="draft-welzl-iccrg-pacing-00"/>
    <author initials="M." surname="Welzl" fullname="Michael Welzl">
      <organization>University of Oslo</organization>
      <address>
        <postal>
          <street>PO Box 1080 Blindern</street>
          <city>0316  Oslo</city>
          <country>Norway</country>
        </postal>
        <email>michawe@ifi.uio.no</email>
        <uri>http://welzl.at/</uri>
      </address>
    </author>
    <author initials="W." surname="Eddy" fullname="Wesley Eddy">
      <organization>MTI Systems</organization>
      <address>
        <postal>
          <street>25111 Country Club Blvd, Suite 295</street>
          <city>North Olmsted, OH 44070</city>
          <country>United States of America</country>
        </postal>
        <email>wes@mti-systems.com</email>
      </address>
    </author>
    <date year="2024" month="July" day="06"/>
    <area>IRTF</area>
    <workgroup>Internet Congestion Control</workgroup>
    <keyword>next generation</keyword>
    <keyword>unicorn</keyword>
    <keyword>sparkling distributed ledger</keyword>
    <abstract>
      <?line 62?>

<t>Applications or congestion control mechanisms can produce bursty traffic which can cause unnecessary queuing and packet loss. To reduce the burstiness of traffic, the concept of evenly spacing out the traffic from a data sender over a round-trip time known as "pacing" has been used in many transport protocol implementations. This document gives an overview of pacing and how some known pacing implementations work.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://mwelzl.github.io/draft-iccrg-pacing/draft-welzl-iccrg-pacing.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-welzl-iccrg-pacing/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Internet Congestion Control Research Group mailing list (<eref target="mailto:iccrg@irtf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/iccrg"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/iccrg/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/mwelzl/draft-iccrg-pacing"/>.</t>
    </note>
  </front>
  <middle>
    <?line 67?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>Applications commonly generate either bulk data (e.g. files) or bursts of data (e.g. segments of media) that transport protocols deliver into the network based on congestion control algorithms.</t>
      <t>RFCs describing congestion control generally refer to a congestion window (cwnd) state variable as an upper limit for either the number of unacknowledged packets or bytes that a sender is allowed to emit. This limits the sender's transmission rate at the granularity of a round-trip time (RTT). If the sender transmits the entire cwnd sized data in an instant, this can result in unnecessarily high queuing and eventually packet losses at the bottleneck. Such consequences are detrimental to users' applications in terms of both responsiveness and goodput. To solve this problem, the concept of pacing was introduced. Pacing allows to send the same cwnd sized data but spread it across a round-trip time more evenly.</t>
      <t>Congestion control specifications always allow to send less than the cwnd, or temporarily emit packets at a lower rate. Accordingly, it is in line with these specifications to pace packets. Pacing is known to have advantages -- if some packets arrive at a bottleneck as a burst (all packets being back-to-back), loss can be more likely to happen than in a case where there are time gaps between packets (e.g., when they are spread out over the RTT). It also means that pacing is less likely to cause any sudden, ephemeral increases in queuing delay. Since keeping the queues short reduces packet losses, pacing can also yield higher goodput by reducing the time lost in loss recovery.</t>
      <t>Because of its known advantages, pacing has become common in implementations of congestion controlled transports. It is also an integral element of the "BBR" congestion control mechanism <xref target="I-D.cardwell-iccrg-bbr-congestion-control"/>.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="pacing-general-considerations-and-consequences">
      <name>Pacing: general considerations and consequences</name>
      <section anchor="losstypes">
        <name>More likely to saturate a bottleneck</name>
        <t>We can distinguish between two reasons for packet losses that are due to congestion at a bottleneck with a DropTail (FIFO) queue:</t>
        <ol spacing="normal" type="1"><li>
            <t>A flight of N packets arrives. The amount of data in this flight exceeds the amount of data that can be transmitted by the bottleneck during the flight's arrival plus the queue length, i.e. some data do not fit into the queue.</t>
          </li>
          <li>
            <t>The bottleneck is fully saturated. The queue is full, and packets drain from it more slowly than new packets arrive.</t>
          </li>
        </ol>
        <t>The second type of loss matches the typical expectation of a congestion control algorithm: the cwnd value when loss happens is indicative of the bottleneck being fully saturated. When the first type of loss happens, however, a sender's cwnd can be much smaller than the Bandwidth*Delay Product (BDP) of the path (the amount of data that can be in flight, ignoring the queue). In the absence of other traffic, the probability for the first type of loss to happen depends on the queue length and the ratio between the departure and the arrival rate during the flight's arrival. By introducing time gaps between the packets of a burst, this ratio is increased, i.e. the difference between the departure and the arrival rate becomes smaller, and the second type of loss is more likely.</t>
        <t>For example, consider a network path with a bottleneck capacity of 50 Mbit/s, a queue length of 15000 bytes (or 10 packets of size 1500 bytes) and an RTT of 30 ms. Assume that all packets emitted by the sender have a size of 1500 bytes. Then, the BDP equals 125 packets. The bottleneck of this network path is fully saturated when a (BDP + queue length) amount of bytes are in flight: 135 packets.</t>
        <t>In this network, the first type of loss can happen as follows: say, N=40 packets arrive at this bottleneck at a rate of 100 Mbit/s. In an otherwise empty network and assuming an initial window of 10 packets and no delayed ACKs, this occurs in the third round of slow start without pacing, provided that the capacities of all links before the bottleneck are at least 100 Mbit/s.
In this case, an overshoot will occur: packets are forwarded with half their arrival rate, i.e. less than 20 packets can be forwarded during the burst's arrival. The remaining 20 (or more) packets cannot fit into the 10-packet queue. A cwnd of 40 packets is much smaller than the (BDP + queue) limit of 135 packets, and the bottleneck is not fully saturated.</t>
        <t>Let us now assume that the flight of 40 packets is instead paced, such that the arrival rate only mildly exceeds the departure rate -- e.g., they arrive at a rate of 60 Mbit/s. When the last packet of this flight arrives at the bottleneck, the bottleneck should already have forwarded 5/6 * 39 = 32.5 packets. Since only complete packets can be sent, the bottleneck has really forwarded 32 packets, and the remaining 40-32 = 8 packets fit in the queue. No loss occurs.</t>
        <t>This example explains how pacing can enable a rate increase to last longer than without pacing. This makes it more likely that a bottleneck is saturated, such that cwnd reflects the BDP plus the queue length (loss type 2).</t>
        <section anchor="backing-off-after-the-increase">
          <name>Backing off after the increase</name>
          <t>The two loss types explained in <xref target="losstypes"/> require a different back-off factor to allow the queue to drain and congestion to dissipate. Specifically, in the single-sender single-bottleneck example above, when a slow start overshoot occurs as loss type 2, a back-off function such as: ssthresh = cwnd * beta with beta &gt;= 0.5 is guaranteed to cause a second loss after the end of loss recovery. This is because, when cwnd exceeds a fully saturated bottleneck (i.e., cwnd &gt; BDP + queue length), cwnd will have grown further by another (BDP + queue length) by the time the sender learns about the loss. In this case, beta = 0.5 will cause ssthresh to exceed (BDP + queue length) again.</t>
          <t>Since pacing makes loss type 2 more likely, beta &lt; 0.5 may be a better choice after slow start overshoot when pacing is used.</t>
        </section>
        <section anchor="able-to-work-with-smaller-queues">
          <name>Able to work with smaller queues</name>
          <t>The probability of loss type 1 in <xref target="losstypes"/> is indirectly proportional to the queue length. Pacing therefore enables a rate increase to continue with a smaller queue at the bottleneck than in the case without pacing.</t>
        </section>
      </section>
      <section anchor="getting-good-rtt-estimates">
        <name>Getting good RTT estimates</name>
        <t>Since pacing algorithms generally attempt to spread out packets evenly across an RTT, it is important to have a good RTT estimate. Especially in the beginning of a transfer, when sending the initial window, the only RTT estimate available may be from the connection establishment handshake. Being based on only one sample, this is a very unreliable estimate, and using it to pace the initial window can cause unnecessary delay. This may be the reason why the Linux TCP implementation does not pace the first 10 packets (see <xref target="linux"/>). As a possible improvement, the initial RTT estimate could also be based on a previous connection (temporal sharing) or on another ongoing connection (ensemble sharing) <xref target="RFC9040"/>.</t>
      </section>
    </section>
    <section anchor="implementation-examples">
      <name>Implementation examples</name>
      <section anchor="linux">
        <name>Linux TCP</name>
        <t>The following description is based on Linux kernel version 6.8.9.</t>
        <t>There are two ways to enable pacing in Linux: 1) via a socket option, 2) by configuring the FQ queue discipline. We describe case 1.</t>
        <t>Independent of the value of the Initial Window (IW), the first 10 (hardcoded) packets are not paced. Later, 10 packets will generally be sent without pacing every 2^32 packets.</t>
        <t>Every time an ACK arrives, a pacing rate is calculated, as: factor * MSS * cwnd / SRTT, where "factor" is a configurable value that, by default, is 2 in slow start and 1.2 in congestion avoidance. MSS is the sender maximum segment size <xref target="RFC5681"/>, and SRTT is the smoothed round-trip time <xref target="RFC6298"/> [TODO check: Linux calculates SRTT different from the standard, though RFC 6298 relaxes the rules, so maybe it's ok?]
The sender transmits data in line with the calculated pacing rate; this is approximated by calculating the rate per millisecond, and generally sending the resulting amount of data per millisecond as a small burst, every millisecond. As an exception, the per-millisecond amount of data can be a little larger when the peer is very close, depending on a configurable value (per default, when the minimum RTT is less than 3 milliseconds).</t>
        <t>If the pacing rate is smaller than 2 packets per millisecond, these bursts will become 2 packets in size, and they will not be sent every millisecond but with a varying time delay (depending on the pacing rate).
If the pacing rate is larger than 64 Kbyte per millisecond, these bursts will be 64 Kbyte in size, and they will not be sent every millisecond but with a varying time delay (depending on the pacing rate).
Bursts can always be smaller than described above, or be "nothing", if a limiting factor such as the receiver window (rwnd) <xref target="RFC5681"/> or the current cwnd disallows transmission.
If the previous packet was not sent when expected by the pacing logic, but more than half of a pacing gap ago (e.g., due to a cwnd limitation), the pacing gap is halved.</t>
        <t><strong>TEMPORARY NOTE - TO BE REMOVED:</strong> This description is based on the longer Linux pacing analysis text that is currently available at: <eref target="https://docs.google.com/document/d/1h5hN9isFjT76YjaCphHZdW9LCRYqV4y3GKwRKxgqEO0/edit?usp=sharing">https://docs.google.com/document/d/1h5hN9isFjT76YjaCphHZdW9LCRYqV4y3GKwRKxgqEO0/edit?usp=sharing</eref>  - comments or corrections are very welcome!</t>
      </section>
      <section anchor="apple-oses">
        <name>Apple OSes</name>
        <t>(TODO)</t>
      </section>
      <section anchor="quic-bbr-implementations">
        <name>QUIC BBR implementations</name>
        <t>Pacing capability is expected in QUIC senders.  While standard QUIC congestion control <xref target="RFC9002"/> is based on TCP Reno, which is not defined to include pacing (but also does not prohibit it), QUIC congestion control requires either pacing or some other burst limitation (<xref section="7.7" sectionFormat="of" target="RFC9002"/>).  BBR congestion control implementations are common in QUIC stacks, and pacing is integral to BBR, so this document focuses on it.</t>
        <t>Pacing in QUIC stacks commonly involves:</t>
        <ol spacing="normal" type="1"><li>
            <t>Access to lower-level (e.g. OS and hardware) capabilities needed for effective pacing.</t>
          </li>
          <li>
            <t>Managing additional timers related to pacing, along with those already needed for retransmission, and other events.</t>
          </li>
          <li>
            <t>Details of the actual pacing algorithm (e.g. granularity of bursts allowed, etc.).</t>
          </li>
        </ol>
        <t>Examples of different approaches to dealing with these challenges in ways that work on multiple operating systems and hardware platforms can be found in open source QUIC stacks, such as Google's QUIC implementation and Meta's "mvfst". These provide examples for some of the concepts discussed below.</t>
        <t>Unlike TCP implementations that typically run within the operating system kernel, QUIC implementations more typically run in user space and are thus faced with more challenges regarding timing and coupling with the underlying protocol stack and hardware needed to achieve pacing.  For instance, if an application trying to do pacing is running on a highly loaded system, it may often "wake up late" and miss the times that it intends to pace packets.</t>
        <t>When a large amount of data needs to be sent, pacing naively could result in an excessive number of timers to be managed and adjusted along with all of the other timers that the QUIC stack and rest of the application require.  The Hashed Hierarchical Timing Wheel <xref target="VL87"/> provides one approach for such cases, but implementations may also simply schedule the next send event based on the current pacing rate, and then schedule subsequent events as needed, rather than adjusting timers for them.  In any case, typically a pacing algorithm should allow for some amount of burstiness, in order to efficiently use the hardware as well as to be responsive for bursty (but low overall rate) applications, and to avoid excessive timer management.</t>
        <t>Pacing can be done based on different approaches such as a token-based or tokenless algorithm.  For instance, a tokenless algorithm (e.g. as used in mvfst) might compute a regular interval time and batch size (number of packets) to be released every interval and achieve the pacing rate.  This allows specific future transmissions to be scheduled.  In contrast, a token-based algorithm accumulates tokens to permit transmission based on the pacing rate, using a "leaky bucket" to control bursts.  In this case the size of bursts may be more granular, depending on how much time has elapsed between evaluations.</t>
        <t>The additional notion of "burst tokens" (or other burst allowance) may be present in order to rapidly transmit data if coming out of a quiescent period (e.g. when a flow has been application-limited without data to send, e.g. as used in Google's implementation).  A number of burst tokens, representing packets that can be sent unpaced, is initialized to some value (e.g. 10) when a flow starts or becomes quiescent.  If burst tokens are available, outgoing packets are sent immediately, without pacing, up to the limit permitted by the congestion window, and the burst tokens are depleted by each packet sent.  The number of burst tokens is reduced to zero on congestion events.  When coming out of quiescence, it is set to the minimum of the initial burst size, or the amount of packets that the congestion window (in bytes) represents.</t>
        <t>There may be additional "lumpy tokens" that further allow unpaced packets after the burst tokens have been consumed, and the congestion window does not limit sending.  The amount of lumpy tokens that might be present is determined using heuristics, generally limiting to a small number of packets (e.g. 1 or 2).</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>While congestion control designs, including aspects such as pacing, could result in unwanted competing traffic, they do not directly result in new security considerations.</t>
      <t>Transport protocols that provide authentication (including those using encryption), or are carried over protocols that provide authentication, can protect their congestion control algorithm from network attack. This is orthogonal to the congestion control rules.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="I-D.cardwell-iccrg-bbr-congestion-control">
          <front>
            <title>BBR Congestion Control</title>
            <author fullname="Neal Cardwell" initials="N." surname="Cardwell">
              <organization>Google</organization>
            </author>
            <author fullname="Yuchung Cheng" initials="Y." surname="Cheng">
              <organization>Google</organization>
            </author>
            <author fullname="Soheil Hassas Yeganeh" initials="S. H." surname="Yeganeh">
              <organization>Google</organization>
            </author>
            <author fullname="Ian Swett" initials="I." surname="Swett">
              <organization>Google</organization>
            </author>
            <author fullname="Van Jacobson" initials="V." surname="Jacobson">
              <organization>Google</organization>
            </author>
            <date day="7" month="March" year="2022"/>
            <abstract>
              <t>   This document specifies the BBR congestion control algorithm.  BBR
   ("Bottleneck Bandwidth and Round-trip propagation time") uses recent
   measurements of a transport connection's delivery rate, round-trip
   time, and packet loss rate to build an explicit model of the network
   path.  BBR then uses this model to control both how fast it sends
   data and the maximum volume of data it allows in flight in the
   network at any time.  Relative to loss-based congestion control
   algorithms such as Reno [RFC5681] or CUBIC [RFC8312], BBR offers
   substantially higher throughput for bottlenecks with shallow buffers
   or random losses, and substantially lower queueing delays for
   bottlenecks with deep buffers (avoiding "bufferbloat").  BBR can be
   implemented in any transport protocol that supports packet-delivery
   acknowledgment.  Thus far, open source implementations are available
   for TCP [RFC793] and QUIC [RFC9000].  This document specifies version
   2 of the BBR algorithm, also sometimes referred to as BBRv2 or bbr2.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-cardwell-iccrg-bbr-congestion-control-02"/>
        </reference>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner"/>
            <date month="March" year="1997"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="2119"/>
          <seriesInfo name="DOI" value="10.17487/RFC2119"/>
        </reference>
        <reference anchor="RFC8174">
          <front>
            <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
            <author fullname="B. Leiba" initials="B." surname="Leiba"/>
            <date month="May" year="2017"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="RFC9002">
          <front>
            <title>QUIC Loss Detection and Congestion Control</title>
            <author fullname="J. Iyengar" initials="J." role="editor" surname="Iyengar"/>
            <author fullname="I. Swett" initials="I." role="editor" surname="Swett"/>
            <date month="May" year="2021"/>
            <abstract>
              <t>This document describes loss detection and congestion control mechanisms for QUIC.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9002"/>
          <seriesInfo name="DOI" value="10.17487/RFC9002"/>
        </reference>
        <reference anchor="VL87">
          <front>
            <title>Hashed and hierarchical timing wheels: data structures for the efficient implementation of a timer facility</title>
            <author initials="G." surname="Varghese">
              <organization/>
            </author>
            <author initials="T." surname="Tauck">
              <organization/>
            </author>
            <date year="1987" month="November" day="01"/>
          </front>
          <seriesInfo name="DOI" value="10.1145/37499.37504"/>
        </reference>
        <reference anchor="RFC9040">
          <front>
            <title>TCP Control Block Interdependence</title>
            <author fullname="J. Touch" initials="J." surname="Touch"/>
            <author fullname="M. Welzl" initials="M." surname="Welzl"/>
            <author fullname="S. Islam" initials="S." surname="Islam"/>
            <date month="July" year="2021"/>
            <abstract>
              <t>This memo provides guidance to TCP implementers that is intended to help improve connection convergence to steady-state operation without affecting interoperability. It updates and replaces RFC 2140's description of sharing TCP state, as typically represented in TCP Control Blocks, among similar concurrent or consecutive connections.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9040"/>
          <seriesInfo name="DOI" value="10.17487/RFC9040"/>
        </reference>
        <reference anchor="RFC5681">
          <front>
            <title>TCP Congestion Control</title>
            <author fullname="M. Allman" initials="M." surname="Allman"/>
            <author fullname="V. Paxson" initials="V." surname="Paxson"/>
            <author fullname="E. Blanton" initials="E." surname="Blanton"/>
            <date month="September" year="2009"/>
            <abstract>
              <t>This document defines TCP's four intertwined congestion control algorithms: slow start, congestion avoidance, fast retransmit, and fast recovery. In addition, the document specifies how TCP should begin transmission after a relatively long idle period, as well as discussing various acknowledgment generation methods. This document obsoletes RFC 2581. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5681"/>
          <seriesInfo name="DOI" value="10.17487/RFC5681"/>
        </reference>
        <reference anchor="RFC6298">
          <front>
            <title>Computing TCP's Retransmission Timer</title>
            <author fullname="V. Paxson" initials="V." surname="Paxson"/>
            <author fullname="M. Allman" initials="M." surname="Allman"/>
            <author fullname="J. Chu" initials="J." surname="Chu"/>
            <author fullname="M. Sargent" initials="M." surname="Sargent"/>
            <date month="June" year="2011"/>
            <abstract>
              <t>This document defines the standard algorithm that Transmission Control Protocol (TCP) senders are required to use to compute and manage their retransmission timer. It expands on the discussion in Section 4.2.3.1 of RFC 1122 and upgrades the requirement of supporting the algorithm from a SHOULD to a MUST. This document obsoletes RFC 2988. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6298"/>
          <seriesInfo name="DOI" value="10.17487/RFC6298"/>
        </reference>
      </references>
    </references>
    <?line 202?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA8Vb63Ibx5X+j6foUD9CagGQ0F3c2A4pUTbLkqhQtFXeVLaq
MdMAJhzMwNMzpBiV3mWfZZ9sv++c7rkAtJP9sbWpikXMpfv0uX7nMpPJZFRn
de6OzQebZMXSZIW5qmzhN2VVmw9VWZdJmfuRnc8rd/PPnkps7ZZldXeMBxbl
aJSWSWHXWDyt7KKe3Lr8H/kkS5JqOdnIQpOjo5Fv5uvM+6ws6rsNnj0/u3pj
zANjc18em72sSN3G4T9FvTc2ey7N6rLKbM4f5yen+Kes8Nfl1Zu9UdGs5646
HqWg43iUlIV3hW/8samrxo1A/uORrZw9js/fltX1siqbDa8UtasKV5tXZbF0
vgY9/LOuynxvdO3u8Gx6PDITU7jPtVm6wlWWD/FSU2RJWcmffmOr65w8SjNf
V9m8qV1qcpcuXTW6cUUDwoz5lzY1Rhmyd+m8s1WyMt/zNd5Y2ywnb8jKP2dV
vZiW1ZI3+BhurOp6448PD/kcL2U3bpo5feyQFw7nVXnr3aGswBeXWb1q5nh1
LVI6VIn1ZcWncjDW1/0N5Ompvj3NynveO/wt4U9X9RrHHNmmXpUV2TLB/w10
BxJ7NzWf+IZcUSV6lyUr6/LedZzm2PxU4HSVz+o7Uy7Mhc9LuQfmOwdSP1yY
0/KzmR29ODKnObWJgsL/ErxxbI4ez56Z7q2kbMB9XH9fVrf2Tq455faa29+6
P2eLbNpk5bTQN5oqOzZkB7ihzLD14fAsn6bmLE3vekf55Hzu7rqrcpB3V+fm
452v3doPTvDo6Ww2g1oIZeZV3sxxkJt0bD42We3Mo5dPe+cB3fXKXORrrINH
Ln4wT54cPT8aHg4so1Z+rClOcu1k7aossf3j3jr/53WdTbxSNE3K9WhUlNUa
Wn8DJR7RxLtfxly+efXy6OiR/P3z2xfPj2W14F32frB+hS1tkZpVBtOhUiY2
x/01jeV25VwOVsFyLQ/eJHVTgTZsYeqVM26xyJIMPsBk603u1vhLrI/EWy7i
KrOAVuVgwp5s3GkV/zcJ/waJfD81P9tquYJh3f/A1dRc2Sa5lqviTszs5Yvn
k9lscjRT6YBjzpMJcY/XF+d46mg6mz15evj4+ZOXL6ePnz89ejIaTSYTY+c4
lk3q0ehks8lxdpLv6bySzvYTtX2zdtC1IvNrbxJbmE1Vpk3izLypPNQc65Ad
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
BnM0QAAA

-->

</rfc>
