rfc8899xml2.original.xml | rfc8899.xml | |||
---|---|---|---|---|
<?xml version='1.0' encoding='utf-8'?> | ||||
<!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | ||||
<rfc | ||||
xmlns:xi="http://www.w3.org/2001/XInclude" | ||||
category="std" | ||||
consensus="true" | ||||
number="8899" | ||||
docName="draft-ietf-tsvwg-datagram-plpmtud-22" | ||||
indexInclude="true" | ||||
ipr="trust200902" | ||||
sortRefs="true" | ||||
submissionType="IETF" | ||||
symRefs="true" | ||||
tocDepth="4" | ||||
tocInclude="true" | ||||
obsoletes="" | ||||
updates="4821, 4960, 6951, 8085, 8261" | ||||
version="3" | ||||
xml:lang="en"> | ||||
<!-- xml2rfc v2v3 conversion 2.39.0 --> | ||||
<front> | ||||
<title abbrev="DPLPMTUD">Packetization Layer Path MTU Discovery for Datagram | ||||
Transports</title> | ||||
<seriesInfo name="RFC" value="8899"/> | ||||
<author fullname="Godred Fairhurst" initials="G" surname="Fairhurst"> | ||||
<organization>University of Aberdeen</organization> | ||||
<address> | ||||
<postal> | ||||
<extaddr>School of Engineering</extaddr> | ||||
<street>Fraser Noble Building</street> | ||||
<city>Aberdeen</city> | ||||
<code>AB24 3UE</code> | ||||
<country>United Kingdom</country> | ||||
</postal> | ||||
<email>gorry@erg.abdn.ac.uk</email> | ||||
</address> | ||||
</author> | ||||
<author fullname="Tom Jones" initials="T" surname="Jones"> | ||||
<organization>University of Aberdeen</organization> | ||||
<address> | ||||
<postal> | ||||
<extaddr>School of Engineering</extaddr> | ||||
<street>Fraser Noble Building</street> | ||||
<city>Aberdeen</city> | ||||
<code>AB24 3UE</code> | ||||
<country>United Kingdom</country> | ||||
</postal> | ||||
<email>tom@erg.abdn.ac.uk</email> | ||||
</address> | ||||
</author> | ||||
<author fullname="Michael Tüxen" initials="M" surname="Tüxen"> | ||||
<organization>Münster University of Applied Sciences</organization> | ||||
<address> | ||||
<postal> | ||||
<street>Stegerwaldstrasse 39</street> | ||||
<code>48565</code> | ||||
<city>Steinfurt</city> | ||||
<country>Germany</country> | ||||
</postal> | ||||
<email>tuexen@fh-muenster.de</email> | ||||
</address> | ||||
</author> | ||||
<author fullname="Irene Rüngeler" initials="I" surname="Rüngeler"> | ||||
<organization>Münster University of Applied Sciences</organization> | ||||
<address> | ||||
<postal> | ||||
<street>Stegerwaldstrasse 39</street> | ||||
<code>48565</code> | ||||
<city>Steinfurt</city> | ||||
<country>Germany</country> | ||||
</postal> | ||||
<email>i.ruengeler@fh-muenster.de</email> | ||||
</address> | ||||
</author> | ||||
<author fullname="Timo Völker" initials="T" surname="Völker"> | ||||
<organization>Münster University of Applied Sciences</organization> | ||||
<address> | ||||
<postal> | ||||
<street>Stegerwaldstrasse 39</street> | ||||
<code>48565</code> | ||||
<city>Steinfurt</city> | ||||
<country>Germany</country> | ||||
</postal> | ||||
<email>timo.voelker@fh-muenster.de</email> | ||||
</address> | ||||
</author> | ||||
<date month="September" year="2020"/> | ||||
<area>Transport</area> | ||||
<workgroup>TSVWG</workgroup> | ||||
<keyword>UDP</keyword> | ||||
<keyword>SCTP</keyword> | ||||
<keyword>Transport</keyword> | ||||
<keyword>PMTUD</keyword> | ||||
<keyword>PLPMTUD</keyword> | ||||
<abstract> | ||||
<t> | ||||
This document specifies Datagram Packetization Layer Path MTU Discovery | ||||
(DPLPMTUD). This is a robust method for Path MTU Discovery | ||||
(PMTUD) for datagram Packetization Layers (PLs). | ||||
It allows a PL, or a datagram | ||||
application that uses a PL, to discover whether a network path can | ||||
support the current size of datagram. This can be used to detect and | ||||
reduce the message size when a sender encounters a packet black hole. | ||||
It can also probe a network path to discover whether the maximum | ||||
packet size can be increased. This provides functionality for datagram | ||||
transports that is equivalent to the PLPMTUD | ||||
specification for TCP, specified in RFC 4821, which it updates. | ||||
It also updates the UDP Usage Guidelines to refer to this method | ||||
for use with UDP datagrams and updates SCTP.</t> | ||||
<t> | ||||
The document provides implementation notes for incorporating | ||||
Datagram PMTUD into IETF datagram transports or applications that use | ||||
datagram transports.</t> | ||||
<t> | ||||
This specification updates RFC 4960, RFC 4821, RFC 6951, RFC 8085, and RFC | ||||
8261.</t> | ||||
</abstract> | ||||
</front> | ||||
<middle> | ||||
<section> | ||||
<name>Introduction</name> | ||||
<t>The IETF has specified datagram transport using UDP, | ||||
Stream Control Transmission Protocol (SCTP), and | ||||
Datagram Congestion Control Protocol (DCCP), | ||||
as well as protocols layered on top of these transports (e.g., SCTP/UDP, | ||||
DCCP/UDP, QUIC/UDP) and direct datagram transport over the IP network | ||||
layer. This document describes a robust method for Path MTU Discovery | ||||
(PMTUD) that can be used with these transport protocols (or the | ||||
applications that use their transport service) to discover an | ||||
appropriate size of packet to use across an Internet path.</t> | ||||
<section anchor="Classic-PMTUD"> | ||||
<name>Classical Path MTU Discovery</name> | ||||
<t>Classical Path Maximum Transmission Unit Discovery (PMTUD) can be | ||||
used with any transport that is able to process ICMP Packet Too Big | ||||
(PTB) messages (e.g., <xref target="RFC1191"/> and <xref target="RFC8201 | ||||
"/>). In this document, the term PTB message is | ||||
applied to both IPv4 ICMP Unreachable messages (Type 3) that carry the | ||||
error Fragmentation Needed (Type 3, Code 4) <xref target="RFC0792"/> and | ||||
ICMPv6 Packet Too Big messages (Type 2) | ||||
<xref target="RFC4443"/>. When a sender receives a PTB message, | ||||
it reduces the effective MTU to the value reported as the link MTU in | ||||
the PTB message. Classical PMTUD specifies a method of periodically incr | ||||
easing | ||||
the packet size in an attempt to discover an increase in the | ||||
supported PMTU. | ||||
The packets sent with a size larger than the current effective PMTU | ||||
are known as probe packets.</t> | ||||
<t>Packets not intended as probe packets are either fragmented to the | ||||
current effective PMTU, or the attempt to send fails with an error | ||||
code. Applications can be provided with a primitive to let them | ||||
read the Maximum Packet Size (MPS), which is derived from the current ef | ||||
fective | ||||
PMTU.</t> | ||||
<t>Classical PMTUD is subject to protocol failures. One failure arises | ||||
when traffic using a packet size larger than the actual PMTU is | ||||
black-holed (all datagrams larger than the actual PMTU are discarded). | ||||
This could arise when the PTB messages are not sent back to the | ||||
sender for some reason (for example, see <xref target="RFC2923"/>).</t> | ||||
<t>Examples of where PTB messages are not delivered include the followin | ||||
g: </t> | ||||
<ul> | ||||
<li>The generation of ICMP messages is usually rate limited. This | ||||
could result in no PTB messages being generated to the sender (see | ||||
<xref target="RFC4443" section="2.4" sectionFormat="of" format="defa | ||||
ult"/>).</li> | ||||
<li>ICMP messages can be filtered by middleboxes, including | ||||
firewalls <xref target="RFC4890"/>. A firewall | ||||
could be configured with a policy to block incoming ICMP messages, | ||||
which would prevent reception of PTB messages by a sending | ||||
endpoint behind this firewall.</li> | ||||
<li>When the router issuing the ICMP message drops a tunneled | ||||
packet, the resulting ICMP message is directed to the tunnel | ||||
ingress. This tunnel endpoint is responsible for forwarding the | ||||
ICMP message, processing the quoted packet within the | ||||
payload field to remove the effect of the tunnel and returning a | ||||
correctly formatted ICMP message to the sender <xref target="I-D.iet | ||||
f-intarea-tunnels"/>. Failure to do this | ||||
prevents the PTB message from reaching the original sender.</li> | ||||
<li>Asymmetry in forwarding can result in there being no return | ||||
route to the original sender, which would prevent an ICMP message | ||||
from being delivered to the sender. This issue can also arise when | ||||
either policy-based or Equal-Cost Multipath (ECMP) routing | ||||
is used or when a middlebox acts as an application load balancer. | ||||
An example of which is an ECMP router choosing a path toward the server | ||||
based on the bytes in the IP payload. In this case, if a packet | ||||
sent by the server encounters a problem after the ECMP router, then | ||||
the ECMP router needs to direct any resulting ICMP message toward | ||||
the original sender.</li> | ||||
<li>There are additional cases where the next-hop destination fails | ||||
to receive a packet because of its size. This could be due to | ||||
misconfiguration of the layer 2 path between nodes, for instance | ||||
the MTU configured in a layer 2 switch, or misconfiguration of the | ||||
Maximum Receive Unit (MRU). If a packet is dropped by the link, | ||||
this will not cause a PTB message to be sent to the original | ||||
sender.</li> | ||||
</ul> | ||||
<t>Another failure could result if a node that is not on the network | ||||
path sends a PTB message that attempts to force a sender to change the | ||||
effective PMTU <xref target="RFC8201"/>. A sender can protect | ||||
itself from reacting to such messages by utilizing the quoted packet | ||||
within a PTB message payload to validate that the received PTB message | ||||
was generated in response to a packet that had actually originated | ||||
from the sender. However, there are situations where a sender would be | ||||
unable to provide this validation. Examples where the validation of the | ||||
PTB message is not possible include the following: </t> | ||||
<ul> | ||||
<li> | ||||
<t>When a router issuing the ICMP message implements RFC 792 <xref t | ||||
arget="RFC0792"/>, it is only required to include the first | ||||
64 bits of the IP payload of the packet within the quoted payload. | ||||
There could be insufficient bytes remaining for the sender to | ||||
interpret the quoted transport information. </t> | ||||
<t> Note: The | ||||
recommendation in RFC 1812 <xref target="RFC1812"/> is that | ||||
IPv4 routers return a quoted packet with as much of the original | ||||
datagram as possible without the length of the ICMP datagram | ||||
exceeding 576 bytes. IPv6 routers include as much of the invoking | ||||
packet as possible without the ICMPv6 packet exceeding 1280 bytes | ||||
<xref target="RFC4443"/>.</t> | ||||
</li> | ||||
<li>The use of tunnels and/or encryption can reduce the size of the qu | ||||
oted | ||||
packet returned to the original source address, increasing the | ||||
risk that there could be insufficient bytes remaining for the | ||||
sender to interpret the quoted transport information.</li> | ||||
<li>Even when the PTB message includes sufficient bytes of the | ||||
quoted packet, the network layer could lack sufficient context to | ||||
validate the message because validation depends on information | ||||
about the active transport flows at an endpoint node (e.g., the | ||||
socket/address pairs being used and other protocol header | ||||
information).</li> | ||||
<li>When a packet is encapsulated/tunneled over an encrypted | ||||
transport, the tunnel/encapsulation ingress might have | ||||
insufficient context, or computational power, to reconstruct the | ||||
transport header that would be needed to perform validation.</li> | ||||
<li> When an ICMP message is generated by a router in a network | ||||
segment that has inserted a header into a packet, the quoted packet | ||||
could contain additional protocol header information that was not | ||||
included in the original sent packet and that the PL sender does | ||||
not process or may not know how to process. This could disrupt the | ||||
ability of the sender to validate this PTB message. </li> | ||||
<li> A Network Address Translation (NAT) device that translates a | ||||
packet header ought to also translate ICMP messages and update | ||||
the ICMP-quoted packet <xref target="RFC5508"/> in | ||||
that message. If this is not correctly translated, | ||||
then the sender would not be able to associate the message | ||||
with the PL that originated the packet, and hence this | ||||
ICMP message cannot be validated.</li> | ||||
</ul> | ||||
</section> | ||||
<section> | ||||
<name>Packetization Layer Path MTU Discovery</name> | ||||
<t>The term Packetization Layer (PL) has been introduced to describe | ||||
the layer that is responsible for placing data blocks into the payload | ||||
of IP packets and selecting an appropriate MPS. This function is often | ||||
performed by a transport protocol (e.g., DCCP, RTP, SCTP, QUIC) | ||||
but can also be performed by other encapsulation methods working | ||||
above the transport layer.</t> | ||||
<t>In contrast to PMTUD, Packetization Layer Path MTU Discovery | ||||
(PLPMTUD) <xref target="RFC4821"/> introduces a method | ||||
that does not rely upon reception | ||||
and validation of PTB messages. It is therefore more robust than | ||||
Classical PMTUD. This has become the recommended approach for | ||||
implementing discovery of the PMTU <xref target="BCP145"/>.</t> | ||||
<t>This document updates <xref target="RFC4821"/> to specify the PLPMTUD | ||||
method for | ||||
datagram PLs and also updates <xref target="BCP145"/> to refer to the me | ||||
thod | ||||
specified in this document for use | ||||
with UDP datagrams instead of the method in <xref target="RFC4821"/>. </ | ||||
t> | ||||
<t>It uses a general strategy in which the PL sends probe packets to | ||||
search for the largest size of unfragmented datagram that can be sent | ||||
over a network path. Probe packets are sent to explore using a larger | ||||
packet size. If a probe packet is successfully delivered (as determined | ||||
by the PL), then the PLPMTU is raised to the size of the successful | ||||
probe. If a black hole is detected (e.g., where packets of size PLPMTU | ||||
are consistently not received), the method reduces the PLPMTU. </t> | ||||
<t>Datagram PLPMTUD introduces flexibility in implementation. | ||||
At one extreme, it can be configured to only perform | ||||
black hole detection and recovery with increased robustness compared to | ||||
Classical PMTUD. At the other extreme, all PTB processing can | ||||
be disabled, and PLPMTUD replaces Classical PMTUD.</t> | ||||
<t>PLPMTUD can also include additional consistency checks without | ||||
increasing the risk that data is lost when probing to discover the | ||||
Path MTU. For example, information available at the PL, or higher | ||||
layers, enables received PTB messages to be validated before being | ||||
utilized.</t> | ||||
</section> | ||||
<section> | ||||
<name>Path MTU Discovery for Datagram Services</name> | ||||
<t><xref target="Spec"/> of this document presents a set of | ||||
algorithms for datagram protocols to discover the largest size of | ||||
unfragmented datagram that can be sent over a network path. The method | ||||
relies upon features of the PL described in <xref target="Requirements"/ | ||||
> and applies to transport protocols | ||||
operating over IPv4 and IPv6. It does not require cooperation from the | ||||
lower layers, although it can utilize PTB messages when these received | ||||
messages are made available to the PL.</t> | ||||
<t>The message size guidelines in Section | ||||
<xref target="BCP145" section="3.2" sectionFormat="bare" format="default | ||||
"/> | ||||
of the UDP Usage Guidelines <xref target="BCP145"/> state that "an appli | ||||
cation <bcp14>SHOULD</bcp14> | ||||
either use the Path MTU information provided by the IP layer or | ||||
implement Path MTU Discovery (PMTUD)" but do not provide a mechanism | ||||
for discovering the largest size of unfragmented datagram that can be | ||||
used on a network path. The present document updates RFC 8085 to | ||||
specify this method in place of PLPMTUD <xref target="RFC4821"/> | ||||
and provides a mechanism for sharing the discovered largest size as the | ||||
MPS (see <xref target="mps"/>).</t> | ||||
<t><xref target="RFC4821" section="10.2" sectionFormat="of" format="defa | ||||
ult"/> recommended a PLPMTUD | ||||
probing method for the Stream Control Transport Protocol (SCTP). SCTP | ||||
utilizes probe packets consisting of a minimal-sized HEARTBEAT chunk | ||||
bundled with a PAD chunk as defined in <xref target="RFC4820"/>. | ||||
However, RFC 4821 did not provide a complete specification. The present | ||||
document replaces that description by providing a complete | ||||
specification.</t> | ||||
<t>The Datagram Congestion Control Protocol (DCCP) <xref target="RFC4340 | ||||
"/> requires implementations to support Classical | ||||
PMTUD and states that a DCCP sender "<bcp14>MUST</bcp14> maintain the MP | ||||
S allowed for | ||||
each active DCCP session". It also defines the current congestion | ||||
control MPS (CCMPS) supported by a network path. This recommends use | ||||
of PMTUD and suggests use of control packets (DCCP-Sync) as path | ||||
probe packets because they do not risk application data loss. The | ||||
method defined in this specification can be used with DCCP.</t> | ||||
<t><xref target="dplpmtud-mechanisms"/> and <xref target="Spec"/> define | ||||
the protocol mechanisms and specification | ||||
for Datagram Packetization Layer Path MTU Discovery (DPLPMTUD). </t> | ||||
<t><xref target="protocol_specific_methods"/> specifies the | ||||
method for datagram transports and provides information to enable the | ||||
implementation of PLPMTUD with other datagram transports and | ||||
applications that use datagram transports.</t> | ||||
<t><xref target="protocol_specific_methods"/> | ||||
also provides recommendations for SCTP endpoints, | ||||
updating <xref target="RFC4960"/>, <xref target="RFC6951"/>, and <xref t | ||||
arget="RFC8261"/> to use the | ||||
method specified in this document instead of the method in <xref target= | ||||
"RFC4821"/>. | ||||
</t> | ||||
</section> | ||||
</section> | ||||
<section> | ||||
<name>Terminology</name> | ||||
<t> | ||||
The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQU | ||||
IRED</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> | ||||
<t>The following terminology is defined. Relevant terms are directly | ||||
copied from <xref target="RFC4821"/>, and the definitions in <xref target= | ||||
"RFC1122"/> apply.</t> | ||||
<dl newline="false"> | ||||
<dt>Acknowledged PL:</dt> | ||||
<dd> A PL that includes a mechanism that can confirm successful | ||||
delivery of datagrams to the remote PL endpoint (e.g., SCTP). | ||||
Typically, the PL receiver returns acknowledgments corresponding to | ||||
the received datagrams, which can be utilized to detect black-holing | ||||
of packets (c.f., Unacknowledged PL). </dd> | ||||
<dt>Actual PMTU:</dt> | ||||
<dd>The actual PMTU is the PMTU of a network path between a sender | ||||
PL and a destination PL, which the DPLPMTUD algorithm seeks to | ||||
determine.</dd> | ||||
<dt>Black Hole:</dt> | ||||
<dd> | ||||
<t>A black hole is encountered when a sender is unaware that | ||||
packets are not being delivered to the destination endpoint. Two | ||||
types of black hole are relevant to DPLPMTUD:</t> | ||||
<ul> | ||||
<li>Packets encounter a packet black hole when packets are not | ||||
delivered to the destination endpoint (e.g., when the sender | ||||
transmits packets of a particular size with a previously known | ||||
effective PMTU, and they are discarded by the network).</li> | ||||
<li> | ||||
An ICMP black hole is encountered when the sender is unaware | ||||
that packets are not delivered to the destination endpoint | ||||
because PTB messages are not received by the originating PL | ||||
sender.</li> | ||||
</ul> | ||||
</dd> | ||||
<dt>Classical Path MTU Discovery:</dt> | ||||
<dd>Classical PMTUD is a process described in <xref target="RFC1191"/> a | ||||
nd <xref target="RFC8201"/> in which nodes | ||||
rely on PTB messages to learn the largest size of unfragmented | ||||
packet that can be used across a network path.</dd> | ||||
<dt>Datagram:</dt> | ||||
<dd>A datagram is a transport-layer protocol data unit, transmitted | ||||
in the payload of an IP packet.</dd> | ||||
<dt>DPLPMTUD:</dt><dd>Datagram Packetization Layer Path MTU Discovery (D | ||||
PLPMTUD), | ||||
PLPMTUD performed using a datagram transport protocol.</dd> | ||||
<dt>Effective PMTU:</dt> | ||||
<dd>The effective PMTU is the current estimated value for PMTU that is | ||||
used by a PMTUD. This is equivalent to the PLPMTU derived by PLPMTUD | ||||
plus the size of any headers added below the PL, including the IP | ||||
layer headers.</dd> | ||||
<dt>EMTU_S:</dt> | ||||
<dd>The effective MTU for sending (EMTU_S) is defined in <xref target="R | ||||
FC1122"/> as "the maximum IP datagram size that may be | ||||
sent, for a particular combination of IP source and destination | ||||
addresses...".</dd> | ||||
<dt>EMTU_R:</dt> | ||||
<dd>The effective MTU for receiving (EMTU_R) is designated in <xref targ | ||||
et="RFC1122"/> as "the largest datagram size that can be | ||||
reassembled".</dd> | ||||
<dt>Link:</dt> | ||||
<dd>A link is a communication facility or medium over which nodes can | ||||
communicate at the link layer, i.e., a layer below the IP layer. | ||||
Examples are Ethernet LANs and Internet (or higher) layer | ||||
tunnels.</dd> | ||||
<dt>Link MTU:</dt> | ||||
<dd> | ||||
<t>The link Maximum Transmission Unit (MTU) is the size in bytes of | ||||
the largest IP packet, including the IP header and payload, that can | ||||
be transmitted over a link. Note that this could more properly be | ||||
called the IP MTU, to be consistent with how other standards | ||||
organizations use the acronym. This includes the IP header but | ||||
excludes link layer headers and other framing that is not part of IP | ||||
or the IP payload. Other standards organizations generally define | ||||
the link MTU to include the link layer headers. This specification | ||||
continues the requirement in <xref target="RFC4821"/> | ||||
that states, | ||||
"All links <bcp14>MUST</bcp14> enforce their MTU: links that might | ||||
non-deterministically deliver packets that are larger than their rated | ||||
MTU <bcp14>MUST</bcp14> consistently discard such packets."</t> | ||||
</dd> | ||||
<dt>MAX_PLPMTU:</dt> | ||||
<dd>The MAX_PLPMTU is the largest size of PLPMTU that DPLPMTUD will | ||||
attempt to use (see the constants defined in <xref target="Constants"/> | ||||
).</dd> | ||||
<dt>MIN_PLPMTU:</dt> | ||||
<dd>The MIN_PLPMTU is the smallest size of PLPMTU that DPLPMTUD will | ||||
attempt to use (see the constants defined in <xref target="Constants"/> | ||||
). </dd> | ||||
<dt>MPS:</dt> | ||||
<dd>The Maximum Packet Size (MPS) is the largest size of | ||||
application data block that can be sent across a network path by a PL | ||||
using a single datagram (see <xref target="mps"/>).</dd> | ||||
<dt>MSL:</dt> | ||||
<dd>The Maximum Segment Lifetime (MSL) is the maximum delay a packet is | ||||
expected to experience across a path, taken as 2 minutes <xref target= | ||||
"BCP145"/>. </dd> | ||||
<dt>Packet:</dt> | ||||
<dd>A packet is the IP header(s) and any extension headers/options | ||||
plus the IP payload.</dd> | ||||
<dt>Packetization Layer (PL):</dt> | ||||
<dd>The PL is a layer of the network stack that places data into | ||||
packets and performs transport protocol functions. Examples of a PL | ||||
include TCP, SCTP, SCTP over UDP, SCTP over DTLS, or QUIC. </dd> | ||||
<dt>Path:</dt> | ||||
<dd>The path is the set of links and routers traversed by a packet | ||||
between a source node and a destination node by a particular | ||||
flow.</dd> | ||||
<dt>Path MTU (PMTU):</dt> | ||||
<dd>The Path MTU (PMTU) is the minimum of the link MTU of all the | ||||
links forming a network path between a source node and a destination | ||||
node, as used by PMTUD.</dd> | ||||
<dt>PTB:</dt> | ||||
<dd> In this document, the term PTB message is applied to both IPv4 | ||||
ICMP Unreachable messages (Type 3) that carry the error Fragmentation | ||||
Needed (Type 3, Code 4) <xref target="RFC0792"/> and ICMPv6 | ||||
Packet Too Big messages (Type 2) <xref target="RFC4443"/>. | ||||
</dd> | ||||
<dt>PTB_SIZE:</dt> | ||||
<dd>The PTB_SIZE is a value reported in a validated PTB message that | ||||
indicates next-hop link MTU of a router along the path.</dd> | ||||
<dt>PL_PTB_SIZE:</dt> | ||||
<dd>The size reported in a validated PTB message, reduced by the size | ||||
of all headers added by layers below the PL. | ||||
</dd> | ||||
<dt>PLPMTU:</dt> | ||||
<dd>The Packetization Layer PMTU is an estimate of the largest size | ||||
of PL datagram that can be sent by a path, controlled by PLPMTUD.</dd | ||||
> | ||||
<dt>PLPMTUD:</dt> | ||||
<dd>Packetization Layer Path MTU Discovery (PLPMTUD), the method | ||||
described in this document for datagram PLs, which is an extension | ||||
to Classical PMTU Discovery.</dd> | ||||
<dt>Probe packet:</dt> | ||||
<dd>A probe packet is a datagram sent with a purposely chosen size | ||||
(typically the current PLPMTU or larger) to detect if packets of | ||||
this size can be successfully sent end-to-end across the network | ||||
path.</dd> | ||||
<dt>Unacknowledged PL:</dt> | ||||
<dd>A PL that does not itself provide a mechanism to confirm delivery | ||||
of datagrams to the remote PL endpoint (e.g., UDP), and therefore | ||||
requires DPLPMTUD to provide a mechanism to detect black-holing of | ||||
packets (c.f., Acknowledged PL).</dd> | ||||
</dl> | ||||
</section> | ||||
<section anchor="Requirements"> | ||||
<name>Features Required to Provide Datagram PLPMTUD</name> | ||||
<t>The principles expressed in <xref target="RFC4821"/> apply to | ||||
the use of the technique with any PL. | ||||
TCP PLPMTUD has been defined using standard TCP protocol mechanisms. | ||||
Unlike TCP, a datagram PL requires additional mechanisms and | ||||
considerations to implement PLPMTUD. </t> | ||||
<t>The requirements for datagram PLPMTUD are: </t> | ||||
<ol> | ||||
<li derivedCounter="1."> Managing the PLPMTU: For datagram PLs, the PLPM | ||||
TU is managed by | ||||
DPLPMTUD. A PL <bcp14>MUST NOT</bcp14> send a datagram (other than a p | ||||
robe packet) | ||||
with a size at the PL that is larger than the current | ||||
PLPMTU.</li> | ||||
<li derivedCounter="2."> Probe packets: The network interface below the | ||||
PL is <bcp14>REQUIRED</bcp14> to | ||||
provide a way to transmit a probe packet that is larger than the | ||||
PLPMTU. In IPv4, a probe packet <bcp14>MUST</bcp14> be sent with the D | ||||
on't | ||||
Fragment (DF) bit set in the IP header and without network layer | ||||
endpoint fragmentation. In IPv6, a probe packet is always sent | ||||
without source fragmentation (as specified in | ||||
<xref target="RFC8201" section="5.4" sectionFormat="of" format="defaul | ||||
t"/>).</li> | ||||
<li derivedCounter="3.">Reception feedback: The destination PL endpoint | ||||
is <bcp14>REQUIRED</bcp14> to | ||||
provide a feedback method that indicates to the DPLPMTUD sender when | ||||
a probe packet has been received by the destination PL endpoint. | ||||
<xref target="protocol_specific_methods"/> provides examples of | ||||
how a PL can provide this acknowledgment of received probe packets. | ||||
</li> | ||||
<li derivedCounter="4.">Probe loss recovery: It is <bcp14>RECOMMENDED</b | ||||
cp14> to use probe packets that | ||||
do not carry any user data that would require retransmission if lost. | ||||
Most datagram transports permit this. If a probe packet contains user | ||||
data requiring retransmission in case of loss, the PL (or layers | ||||
above) is <bcp14>REQUIRED</bcp14> to arrange any retransmission and/or | ||||
repair of any | ||||
resulting loss. The PL is <bcp14>REQUIRED</bcp14> to be robust in the | ||||
case where | ||||
probe packets are lost due to other reasons (including link | ||||
transmission error, congestion).</li> | ||||
<li derivedCounter="5.">PMTU parameters: A DPLPMTUD sender is <bcp14>REC | ||||
OMMENDED</bcp14> to utilize | ||||
information about the maximum size of packet that can be transmitted | ||||
by the sender on the local link (e.g., the local link MTU). A PL | ||||
sender <bcp14>MAY</bcp14> utilize similar information about the maximum | ||||
size of | ||||
network-layer packet that a receiver can accept when this is supplied | ||||
(note this could be less than EMTU_R). This avoids implementations | ||||
trying to send probe packets that cannot be transferred by the local | ||||
link. Too high of a value could reduce the efficiency of the search | ||||
algorithm. Some applications also have a maximum transport protocol | ||||
data unit (PDU) size, in which case there is no benefit from probing | ||||
for a size larger than this (unless a transport allows multiplexing | ||||
multiple applications' PDUs into the same datagram).</li> | ||||
<li derivedCounter="6.">Processing PTB messages: A DPLPMTUD sender <bcp1 | ||||
4>MAY</bcp14> optionally utilize | ||||
PTB messages received from the network layer to help identify when a | ||||
network path does not support the current size of probe packet. Any | ||||
received PTB message <bcp14>MUST</bcp14> be validated before it is use | ||||
d to update | ||||
the PLPMTU discovery information <xref target="RFC8201"/>. | ||||
This validation confirms that the PTB message was sent in response to | ||||
a packet originated by the sender and needs to be performed before | ||||
the PLPMTU discovery method reacts to the PTB message. A PTB message | ||||
<bcp14>MUST NOT</bcp14> be used to increase the PLPMTU <xref target="R | ||||
FC8201"/> | ||||
but could trigger a probe to test for a larger PLPMTU. | ||||
A valid PTB_SIZE is converted to a PL_PTB_SIZE before it is to be | ||||
used in the DPLPMTUD state machine. A PL_PTB_SIZE that is greater | ||||
than that currently probed <bcp14>SHOULD</bcp14> be ignored. (This PTB | ||||
message ought | ||||
to be discarded without further processing but could be utilized as | ||||
an input that enables a resilience mode). | ||||
</li> | ||||
<li derivedCounter="7.">Probing and congestion control: A PL <bcp14>MAY< | ||||
/bcp14> use a congestion | ||||
controller to decide when to send a probe packet. If transmission of | ||||
probe packets is limited by the congestion controller, this could | ||||
result in transmission of probe packets being delayed or suspended | ||||
during congestion. When the transmission of probe packets is not | ||||
controlled by the congestion controller, the interval between probe | ||||
packets <bcp14>MUST</bcp14> be at least one RTT. | ||||
Loss of a probe packet <bcp14>SHOULD NOT</bcp14> be treated as an indi | ||||
cation of | ||||
congestion and <bcp14>SHOULD NOT</bcp14> trigger a congestion control | ||||
reaction <xref target="RFC4821"/> | ||||
because this could result in unnecessary reduction of the sending rate | ||||
. | ||||
An update to the PLPMTU (or MPS) <bcp14>MUST NOT</bcp14> increase the | ||||
congestion | ||||
window measured in bytes <xref target="RFC4821"/>. Therefore, | ||||
an increase in the packet size does not cause an increase in the data | ||||
rate in bytes per second. | ||||
A PL that maintains the congestion window in terms of a limit to | ||||
the number of outstanding fixed-size packets <bcp14>SHOULD</bcp14> ada | ||||
pt this limit | ||||
to compensate for the size of the actual packets. | ||||
The transmission of probe packets can interact with the operation | ||||
of a PL that performs burst mitigation or pacing, and the PL could need | ||||
transmission of probe packets to be regulated by these methods.</li> | ||||
<li derivedCounter="8.">Probing and flow control: Flow control at the P | ||||
L concerns the | ||||
end-to-end flow of data using the PL service. Flow control <bcp14>SHOUL | ||||
D | ||||
NOT</bcp14> apply to DPLPMTU when probe packets use a design that does | ||||
not | ||||
carry user data to the remote application.</li> | ||||
<li derivedCounter="9.">Shared PLPMTU state: The PMTU value | ||||
calculated from the PLPMTU <bcp14>MAY</bcp14> also be stored with the | ||||
corresponding entry associated with the destination in the IP | ||||
layer cache and used by other PL instances. The specification of | ||||
PLPMTUD <xref target="RFC4821"/> states, "If PLPMTUD updates | ||||
the MTU for a particular path, all Packetization Layer sessions that | ||||
share the path representation (as described in Section | ||||
<xref target="RFC4821" section="5.2" sectionFormat="bare" format="defa | ||||
ult"/>) | ||||
<bcp14>SHOULD</bcp14> be notified to make use of the new | ||||
MTU". Such methods <bcp14>MUST</bcp14> be robust to the wide variety o | ||||
f underlying | ||||
network forwarding behaviors. | ||||
<xref target="RFC8201" section="5.2" sectionFormat="of" format="defaul | ||||
t"/> | ||||
provides guidance on the caching of PMTU | ||||
information and also the relation to IPv6 flow labels.</li> | ||||
</ol> | ||||
<t>In addition, the following principles are stated for design of a | ||||
DPLPMTUD method: </t> | ||||
<ul> | ||||
<li>A PL <bcp14>MAY</bcp14> be designed to segment data blocks larger th | ||||
an the MPS | ||||
into multiple datagrams. However, not all datagram PLs support | ||||
segmentation of data blocks. It is <bcp14>RECOMMENDED</bcp14> that met | ||||
hods avoid | ||||
forcing an application to use an arbitrary small MPS for transmission | ||||
while the method is searching for the currently supported PLPMTU. A | ||||
reduced MPS can adversely impact the performance of an | ||||
application.</li> | ||||
<li> To assist applications in choosing a suitable data block size, the | ||||
PL is <bcp14>RECOMMENDED</bcp14> to provide a primitive that | ||||
returns the MPS derived from the PLPMTU to the | ||||
higher layer using the PL. The value of the MPS can change following | ||||
a change in the path or loss of probe packets. </li> | ||||
<li>Path validation: It is <bcp14>RECOMMENDED</bcp14> that methods are r | ||||
obust to | ||||
path changes that could have occurred since the path characteristics | ||||
were last confirmed and to the possibility of inconsistent path | ||||
information being received.</li> | ||||
<li>Datagram reordering: A method is <bcp14>REQUIRED</bcp14> to be robus | ||||
t to the | ||||
possibility that a flow encounters reordering or that the traffic | ||||
(including probe packets) is divided over more than one network | ||||
path.</li> | ||||
<li>Datagram delay and duplication: The feedback | ||||
mechanism is <bcp14>REQUIRED</bcp14> to be robust to the possibility t | ||||
hat packets | ||||
could be significantly delayed or duplicated along a network path.</li | ||||
> | ||||
<li>When to probe: It is <bcp14>RECOMMENDED</bcp14> that methods determi | ||||
ne whether | ||||
the path has changed since it last measured the path. This can help | ||||
determine when to probe the path again.</li> | ||||
</ul> | ||||
</section> | ||||
<section anchor="dplpmtud-mechanisms"> | ||||
<name>DPLPMTUD Mechanisms</name> | ||||
<t>This section lists the protocol mechanisms used in this | ||||
specification.</t> | ||||
<section anchor="Probe"> | ||||
<name>PLPMTU Probe Packets</name> | ||||
<t>The DPLPMTUD method relies upon the PL sender being able to generate | ||||
probe packets with a specific size. TCP is able to generate these probe | ||||
packets by choosing to appropriately segment data being sent <xref targe | ||||
t="RFC4821"/>. In contrast, a datagram PL that constructs a | ||||
probe packet has to either request an application to send a data block | ||||
that is larger than that generated by an application, or to utilize | ||||
padding functions to extend a datagram beyond the size of the | ||||
application data block. Protocols that permit exchange of control | ||||
messages (without an application data block) can generate a probe | ||||
packet by extending a control message with padding data. The total size | ||||
of a probe packet includes all headers and padding added to the payload | ||||
data being sent (e.g., including protocol option fields, | ||||
security-related fields such as an Authenticated Encryption with | ||||
Associated Data (AEAD) tag, and TLS record layer padding). </t> | ||||
<t>A receiver is <bcp14>REQUIRED</bcp14> to be able to distinguish an in | ||||
-band data | ||||
block from any added padding. This is needed to ensure that any added | ||||
padding is not passed on to an application at the receiver.</t> | ||||
<t>This results in three possible ways that a sender can create a | ||||
probe packet: </t> | ||||
<dl> | ||||
<dt>Probing using padding data:</dt> | ||||
<dd>A probe packet that contains only control information together | ||||
with any padding, which is needed to inflate to the size | ||||
of the probe packet. Since these probe packets do not | ||||
carry an application-supplied data block, they do not typically | ||||
require retransmission, although they do still consume network | ||||
capacity and incur endpoint processing.</dd> | ||||
<dt>Probing using application data and padding data:</dt> | ||||
<dd>A probe packet that contains a data block supplied by an | ||||
application that is combined with padding to inflate the length of | ||||
the datagram to the size of the probe packet. </dd> | ||||
<dt>Probing using application data:</dt> | ||||
<dd>A probe packet that contains a data block supplied by an | ||||
application that matches the size of the probe packet. | ||||
This method requests the application to issue a data block of the | ||||
desired probe size. </dd> | ||||
</dl> | ||||
<t>A PL that uses a probe packet carrying application data and that need | ||||
s | ||||
protection from the loss of this probe packet could perform | ||||
transport-layer retransmission/repair of the data block (e.g., by | ||||
retransmitting after loss is detected or by duplicating the data block | ||||
in a datagram without the padding data). This retransmitted data block | ||||
might possibly need to be sent using a smaller PLPMTU, which could | ||||
force the PL to use a smaller packet size to traverse the end-to-end | ||||
path. (This could utilize endpoint network-layer fragmentation or a PL | ||||
that can resegment the data block into multiple datagrams). | ||||
</t> | ||||
<t>DPLPMTUD <bcp14>MAY</bcp14> choose to use only one of these methods t | ||||
o simplify | ||||
the implementation.</t> | ||||
<t>Probe messages sent by a PL <bcp14>MUST</bcp14> contain enough inform | ||||
ation to | ||||
uniquely identify the probe within the Maximum Segment Lifetime (e.g., | ||||
including a unique identifier from the PL or the DPLPMTUD | ||||
implementation), while being robust to reordering and replay of probe | ||||
response and PTB messages.</t> | ||||
</section> | ||||
<section anchor="Valid"> | ||||
<name>Confirmation of Probed Packet Size</name> | ||||
<t>The PL needs a method to determine (confirm) when probe packets | ||||
have been successfully received end-to-end across a network path.</t> | ||||
<t>Transport protocols can include end-to-end methods that detect and | ||||
report reception of specific datagrams that they send (e.g., DCCP, | ||||
SCTP, and QUIC provide keep-alive/heartbeat features). When supported, | ||||
this mechanism <bcp14>MAY</bcp14> also be used by DPLPMTUD to acknowledge | ||||
reception of | ||||
a probe packet.</t> | ||||
<t>A PL that does not acknowledge data reception (e.g., UDP and | ||||
UDP-Lite) is unable itself to detect when the packets that it sends | ||||
are discarded because their size is greater than the actual PMTU. | ||||
These PLs need to rely on an application protocol to detect | ||||
this loss.</t> | ||||
<t><xref target="protocol_specific_methods"/> specifies this | ||||
function for a set of IETF-specified protocols.</t> | ||||
</section> | ||||
<section anchor="mechanism-bhd"> | ||||
<name>Black Hole Detection and Reducing the PLPMTU</name> | ||||
<t> The description that follows uses the set of constants defined in | ||||
<xref target="Constants"/> and variables defined in <xref target="Variab | ||||
les"/>.</t> | ||||
<t>Black hole detection is | ||||
triggered by an indication that the network path could be unable to | ||||
support the current PLPMTU size. </t> | ||||
<t>There are three indicators that can be used to detect black holes:</t | ||||
> | ||||
<ul> | ||||
<li>A validated PTB message can be received that indicates a PL_PTB_SI | ||||
ZE | ||||
less than the current PLPMTU. A DPLPMTUD method <bcp14>MUST NOT</bcp14> | ||||
rely solely on | ||||
this method.</li> | ||||
<li>A PL can use the DPLPMTUD probing mechanism to periodically | ||||
generate probe packets of the size of the current PLPMTU (e.g., | ||||
using the CONFIRMATION_TIMER, <xref target="Timers"/>). A | ||||
timer tracks whether acknowledgments are received. Successive loss | ||||
of probes is an indication that the current path no longer | ||||
supports the PLPMTU (e.g., when the number of probe packets sent | ||||
without receiving an acknowledgment, PROBE_COUNT, becomes greater | ||||
than MAX_PROBES).</li> | ||||
<li>A PL can utilize an event that indicates the network path no | ||||
longer sustains the sender's PLPMTU size. This could use a | ||||
mechanism implemented within the PL to detect excessive loss of | ||||
data sent with a specific packet size and then conclude that this | ||||
excessive loss could be a result of an invalid PLPMTU (as in | ||||
PLPMTUD for TCP <xref target="RFC4821"/>).</li> | ||||
</ul> | ||||
<t>The three methods can result in different transmission patterns for | ||||
packet probes and are expected to result in different responsiveness | ||||
following a change in the actual PMTU.</t> | ||||
<t>A PL <bcp14>MAY</bcp14> inhibit sending probe packets when no applica | ||||
tion data has | ||||
been sent since the previous probe packet. A PL that resumes sending | ||||
user data <bcp14>MAY</bcp14> continue PLPMTU discovery for each path. Th | ||||
is allows it | ||||
to use an up-to-date PLPMTU. However, this could result in additional | ||||
packets being sent.</t> | ||||
<t>When the method detects that the current PLPMTU is not supported, | ||||
DPLPMTUD sets a lower PLPMTU and a lower MPS. The PL then | ||||
confirms that the new PLPMTU can be successfully used across the path. | ||||
A probe packet could need to be smaller than the size of the data | ||||
block generated by the application. </t> | ||||
</section> | ||||
<section anchor="mps"> | ||||
<name>The Maximum Packet Size (MPS)</name> | ||||
<t> The result of probing determines a usable PLPMTU, which is used to | ||||
set the MPS used by the application. The MPS is smaller than the | ||||
PLPMTU because it is reduced by the size of PL headers (including the | ||||
overhead of security-related fields such as an AEAD tag and TLS record | ||||
layer padding). The relationship between the MPS and the PLPMTUD is | ||||
illustrated in <xref target="fig-mps-relationship"/>. </t> | ||||
<figure anchor="fig-mps-relationship"> | ||||
<name>Relationship between MPS and PLPMTU</name> | ||||
<artset> | ||||
<artwork type="svg" name="" alt="" originalSrc="diagrams/mps-relatio | ||||
nship.svg"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" class="diagram" version="1.1" viewBox="0 | ||||
0 560.0 169.0"> | ||||
<g transform="translate(8,16)"> | ||||
<path d="M 144,16 L 168,16" fill="none" stroke="black"/> | ||||
<path d="M 216,16 L 256,16" fill="none" stroke="black"/> | ||||
<path d="M 16,64 L 264,64" fill="none" stroke="black"/> | ||||
<path d="M 16,96 L 264,96" fill="none" stroke="black"/> | ||||
<path d="M 104,128 L 144,128" fill="none" stroke="black"/> | ||||
<path d="M 216,128 L 256,128" fill="none" stroke="black"/> | ||||
<path d="M 16,144 L 96,144" fill="none" stroke="black"/> | ||||
<path d="M 152,144 L 264,144" fill="none" stroke="black"/> | ||||
<path d="M 16,64 L 16,96" fill="none" stroke="black"/> | ||||
<path d="M 72,32 L 72,48" fill="none" stroke="black"/> | ||||
<path d="M 144,16 L 144,48" fill="none" stroke="black"/> | ||||
<path d="M 256,16 L 256,48" fill="none" stroke="black"/> | ||||
<path d="M 264,64 L 264,96" fill="none" stroke="black"/> | ||||
<polygon points="24.000000,144.000000 12.000000,138.399994 12.000000,149.600006" | ||||
transform="rotate(180.000000, 16.000000, 144.000000)" fill="black"/> | ||||
<path d="M 72,48 L 72,56" fill="none" stroke="black"/> | ||||
<polygon points="88.000000,48.000000 76.000000,42.400002 76.000000,53.599998" tr | ||||
ansform="rotate(90.000000, 72.000000, 48.000000)" fill="black"/> | ||||
<polygon points="112.000000,128.000000 100.000000,122.400002 100.000000,133.6000 | ||||
06" transform="rotate(180.000000, 104.000000, 128.000000)" fill="black"/> | ||||
<path d="M 144,48 L 144,56" fill="none" stroke="black"/> | ||||
<polygon points="160.000000,48.000000 148.000000,42.400002 148.000000,53.599998" | ||||
transform="rotate(90.000000, 144.000000, 48.000000)" fill="black"/> | ||||
<path d="M 256,48 L 256,56" fill="none" stroke="black"/> | ||||
<polygon points="272.000000,48.000000 260.000000,42.400002 260.000000,53.599998" | ||||
transform="rotate(90.000000, 256.000000, 48.000000)" fill="black"/> | ||||
<polygon points="264.000000,128.000000 252.000000,122.400002 252.000000,133.6000 | ||||
06" transform="rotate(0.000000, 256.000000, 128.000000)" fill="black"/> | ||||
<polygon points="272.000000,144.000000 260.000000,138.399994 260.000000,149.6000 | ||||
06" transform="rotate(0.000000, 264.000000, 144.000000)" fill="black"/> | ||||
<circle cx="72" cy="80" r="6" fill="black" stroke="black"/> | ||||
<circle cx="80" cy="80" r="6" fill="black" stroke="black"/> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y="132" fill="black" | ||||
font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y="148" fill="black" | ||||
font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y="148" fill="black" | ||||
font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y="20" fill="black" f | ||||
ont-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y="84" fill="black" f | ||||
ont-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y="84" fill="black" f | ||||
ont-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y="132" fill="black" | ||||
font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y="132" fill="black" | ||||
font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y="4" fill="black" fon | ||||
t-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="4" fill="black" fon | ||||
t-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="20" fill="black" fo | ||||
nt-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="84" fill="black" fo | ||||
nt-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y="84" fill="black" f | ||||
ont-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y="132" fill="black" | ||||
font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="4" fill="black" fon | ||||
t-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y="20" fill="black" fo | ||||
nt-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y="84" fill="black" f | ||||
ont-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y="84" fill="black" f | ||||
ont-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y="84" fill="black" f | ||||
ont-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y="148" fill="black" | ||||
font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="4" fill="black" fon | ||||
t-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="4" fill="black" fon | ||||
t-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="20" fill="black" fo | ||||
nt-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y="84" fill="black" f | ||||
ont-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="84" fill="black" fo | ||||
nt-size="1em">|</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y="132" fill="black" | ||||
font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y="132" fill="black" | ||||
font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="4" fill="black" fon | ||||
t-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="4" fill="black" fon | ||||
t-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="20" fill="black" fo | ||||
nt-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="20" fill="black" fo | ||||
nt-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y="84" fill="black" f | ||||
ont-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y="84" fill="black" f | ||||
ont-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y="84" fill="black" f | ||||
ont-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="4" fill="black" fon | ||||
t-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="84" fill="black" fo | ||||
nt-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="84" fill="black" fo | ||||
nt-size="1em">|</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y="84" fill="black" f | ||||
ont-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y="84" fill="black" f | ||||
ont-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y="84" fill="black" f | ||||
ont-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y="4" fill="black" font | ||||
-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="4" fill="black" fon | ||||
t-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="20" fill="black" fo | ||||
nt-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y="20" fill="black" f | ||||
ont-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y="20" fill="black" f | ||||
ont-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y="84" fill="black" f | ||||
ont-size="1em">|</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y="84" fill="black" f | ||||
ont-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y="148" fill="black" | ||||
font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="0" y="4" fill="black" font | ||||
-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="4" fill="black" fon | ||||
t-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y="4" fill="black" fo | ||||
nt-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y="20" fill="black" fo | ||||
nt-size="1em">h</text> | ||||
</g> | ||||
</svg> | ||||
</artwork> | ||||
<artwork type="ascii-art" name="" alt="" originalSrc="diagrams/mps-r | ||||
elationship.txt"><![CDATA[ | ||||
Any additional | ||||
headers .--- MPS -----. | ||||
| | | | ||||
v v v | ||||
+------------------------------+ | ||||
| IP | ** | PL | protocol data | | ||||
+------------------------------+ | ||||
<----- PLPMTU -----> | ||||
<---------- PMTU --------------> | ||||
]]></artwork> | ||||
</artset> | ||||
</figure> | ||||
<t>A PL is unable to send a packet (other than a probe packet) with a | ||||
size larger than the current PLPMTU at the network layer. To avoid this, | ||||
a PL <bcp14>MAY</bcp14> be designed to segment data blocks larger than t | ||||
he MPS into | ||||
multiple datagrams.</t> | ||||
<t> DPLPMTUD seeks to avoid IP fragmentation. An attempt to send a data | ||||
block larger than the MPS will therefore fail if a PL is unable to | ||||
segment data. To determine the largest data block that can be sent, a | ||||
PL <bcp14>SHOULD</bcp14> provide applications with a primitive that retu | ||||
rns the MPS, | ||||
derived from the current PLPMTU.</t> | ||||
<t> If DPLPMTUD results in a change to the MPS, the application needs | ||||
to adapt to the new MPS. A particular case can arise when packets have | ||||
been sent with a size less than the MPS and the PLPMTU was subsequently | ||||
reduced. If these packets are lost, the PL <bcp14>MAY</bcp14> segment the | ||||
data using | ||||
the new MPS. If a PL is unable to resegment a previously sent datagram | ||||
(e.g., <xref target="RFC4960"/>), then the sender either discards | ||||
the datagram or could perform retransmission using network-layer | ||||
fragmentation to form multiple IP packets not larger than the PLPMTU. | ||||
For IPv4, the use of endpoint fragmentation by the sender is preferred | ||||
over clearing the DF bit in the IPv4 header. Operational experience | ||||
reveals that IP fragmentation can reduce the reliability of Internet | ||||
communication <xref target="RFC8900"/>, | ||||
which may reduce the probability of successful retransmission. | ||||
</t> | ||||
</section> | ||||
<section anchor="outgoingpmtu"> | ||||
<name>Disabling the Effect of PMTUD</name> | ||||
<t>A PL implementing this specification <bcp14>MUST</bcp14> suspend netw | ||||
ork layer | ||||
processing of outgoing packets that enforces a PMTU <xref target="RFC1 | ||||
191"/><xref target="RFC8201"/> for each flow | ||||
utilizing DPLPMTUD and instead use DPLPMTUD to control the size of | ||||
packets that are sent by a flow. This removes the need for the | ||||
network layer to drop or to fragment sent packets that have a size | ||||
greater than the PMTU.</t> | ||||
</section> | ||||
<section anchor="mechanism-ptb"> | ||||
<name>Response to PTB Messages</name> | ||||
<t>This method requires the DPLPMTUD sender to validate any received | ||||
PTB message before using the PTB information. The response to a PTB | ||||
message depends on the PL_PTB_SIZE calculated from the PTB_SIZE in the | ||||
PTB message, the state of the PLPMTUD state machine, and the IP | ||||
protocol being used.</t> | ||||
<t><xref target="PTB"/> describes validation for both IPv4 | ||||
ICMP Unreachable messages (Type 3) and ICMPv6 Packet Too Big messages, | ||||
both of which are referred to as PTB messages in this document.</t> | ||||
<section anchor="PTB"> | ||||
<name>Validation of PTB Messages</name> | ||||
<t>This section specifies utilization and validation of PTB messages.< | ||||
/t> | ||||
<ul> | ||||
<li>A simple implementation <bcp14>MAY</bcp14> ignore received PTB m | ||||
essages, and | ||||
in this case, the PLPMTU is not updated when a PTB message is | ||||
received.</li> | ||||
<li>A PL that supports PTB messages <bcp14>MUST</bcp14> validate the | ||||
se messages | ||||
before they are further processed.</li> | ||||
</ul> | ||||
<t>A PL that receives a PTB message from a router or middlebox | ||||
performs ICMP validation (see | ||||
<xref target="RFC8201" section="4" sectionFormat="of" format="default" | ||||
/> and | ||||
<xref target="BCP145" section="5.2" sectionFormat="of" format="default | ||||
"/>). | ||||
Because DPLPMTUD operates at the PL, the | ||||
PL needs to check that each received PTB message is received in | ||||
response to a packet transmitted by the endpoint PL performing | ||||
DPLPMTUD.</t> | ||||
<t>The PL <bcp14>MUST</bcp14> check the protocol information in the qu | ||||
oted packet | ||||
carried in an ICMP PTB message payload to validate the message | ||||
originated from the sending node. This validation includes | ||||
determining that the combination of the IP addresses, the protocol, th | ||||
e | ||||
source port, and destination port match those returned in the | ||||
quoted packet -- this is also necessary for the PTB message to be | ||||
passed to the corresponding PL.</t> | ||||
<t>The validation <bcp14>SHOULD</bcp14> utilize information that is no | ||||
t simple | ||||
for an off-path attacker to determine <xref target="BCP145"/>. For exa | ||||
mple, it could check the value of a | ||||
protocol header field known only to the two PL endpoints. A datagram | ||||
application that uses well-known source and destination ports ought | ||||
to also rely on other information to complete this validation.</t> | ||||
<t>These checks are intended to provide protection from packets that | ||||
originate from a node that is not on the network path. A PTB message | ||||
that does not complete the validation <bcp14>MUST NOT</bcp14> be furth | ||||
er utilized by | ||||
the DPLPMTUD method, as discussed in the Security Considerations | ||||
section (<xref target="Security"/>).</t> | ||||
<t><xref target="validPTB_SIZE"/> describes this processing of | ||||
PTB messages.</t> | ||||
</section> | ||||
<section anchor="validPTB_SIZE"> | ||||
<name>Use of PTB Messages</name> | ||||
<t>PTB messages that have been validated <bcp14>MAY</bcp14> be utilize | ||||
d by the | ||||
DPLPMTUD algorithm but <bcp14>MUST NOT</bcp14> be used directly to set | ||||
the PLPMTU.</t> | ||||
<t>Before using the size reported in the PTB message, it must first be | ||||
converted to a PL_PTB_SIZE. The PL_PTB_SIZE is smaller than the | ||||
PTB_SIZE because it is reduced by headers below the PL, including any | ||||
IP options or extensions added to the PL packet. </t> | ||||
<t>A method that utilizes these PTB messages can improve the speed at | ||||
which the algorithm detects an appropriate PLPMTU by triggering an | ||||
immediate probe for the PL_PTB_SIZE (resulting in a network-layer | ||||
packet of size PTB_SIZE), compared to one that relies solely on | ||||
probing using a timer-based search algorithm. </t> | ||||
<t>A set of checks are intended to provide protection from a router | ||||
that reports an unexpected PTB_SIZE. The PL also needs to check that | ||||
the indicated PL_PTB_SIZE is less than the size used by probe packets | ||||
and at least the minimum size accepted.</t> | ||||
<t> This section provides a summary of how PTB messages can be | ||||
utilized, using the set of constants defined in <xref target="Constants | ||||
"/>. | ||||
This processing depends on the PL_PTB_SIZE and the current value of a | ||||
set of variables: </t> | ||||
<dl newline="true"> | ||||
<dt>PL_PTB_SIZE < MIN_PLPMTU</dt> | ||||
<dd> | ||||
<ul> | ||||
<li>Invalid PL_PTB_SIZE, see <xref target="PTB"/>.</li> | ||||
<li>PTB message ought to be discarded without further | ||||
processing (i.e., PLPMTU is not modified).</li> | ||||
<li>The information could be utilized as an input that | ||||
triggers the enabling of a resilience mode (see <xref target=" | ||||
Resilience"/>).</li> | ||||
</ul> | ||||
</dd> | ||||
<dt>MIN_PLPMTU < PL_PTB_SIZE < BASE_PLPMTU</dt> | ||||
<dd> | ||||
<ul> | ||||
<li>A robust PL <bcp14>MAY</bcp14> enter an error state (see <xr | ||||
ef target="States"/>) for an IPv4 path when the PL_PTB_SIZE | ||||
reported in the PTB message is larger than or equal to 68 | ||||
bytes <xref target="RFC0791"/> and when this is less | ||||
than the BASE_PLPMTU.</li> | ||||
<li>A robust PL <bcp14>MAY</bcp14> enter an error state (see <xr | ||||
ef target="States"/>) for an IPv6 path when the PL_PTB_SIZE | ||||
reported in the PTB message is larger than or equal to 1280 | ||||
bytes <xref target="RFC8200"/> and when this is less | ||||
than the BASE_PLPMTU.</li> | ||||
</ul> | ||||
</dd> | ||||
<dt>BASE_PLPMTU <= PL_PTB_SIZE < PLPMTU</dt> | ||||
<dd> | ||||
<ul> | ||||
<li>This could be an indication of a black hole. The PLPMTU | ||||
<bcp14>SHOULD</bcp14> be set to BASE_PLPMTU (the PLPMTU is red | ||||
uced to the | ||||
BASE_PLPMTU to avoid unnecessary packet loss when a black hole | ||||
is encountered).</li> | ||||
<li> The PL ought to start a search to quickly discover the | ||||
new PLPMTU. The PL_PTB_SIZE reported in the PTB message can be | ||||
used to initialize a search algorithm.</li> | ||||
</ul> | ||||
</dd> | ||||
<dt>PLPMTU < PL_PTB_SIZE < PROBED_SIZE</dt> | ||||
<dd> | ||||
<ul> | ||||
<li>The PLPMTU continues to be valid, but the size of a | ||||
packet used to search (PROBED_SIZE) was larger than the | ||||
actual PMTU.</li> | ||||
<li>The PLPMTU is not updated.</li> | ||||
<li>The PL can use the reported PL_PTB_SIZE from the PTB | ||||
message as the next search point when it resumes the search | ||||
algorithm.</li> | ||||
</ul> | ||||
</dd> | ||||
<dt>PL_PTB_SIZE >= PROBED_SIZE</dt> | ||||
<dd> | ||||
<ul> | ||||
<li>Inconsistent network signal.</li> | ||||
<li>PTB message ought to be discarded without further | ||||
processing (i.e., PLPMTU is not modified).</li> | ||||
<li>The information could be utilized as an input to trigger | ||||
the enabling of a resilience mode.</li> | ||||
</ul> | ||||
</dd> | ||||
</dl> | ||||
</section> | ||||
</section> | ||||
</section> | ||||
<section anchor="Spec"> | ||||
<name>Datagram Packetization Layer PMTUD</name> | ||||
<t>This section specifies Datagram PLPMTUD (DPLPMTUD). The method can be | ||||
introduced at various points (as indicated with * in <xref target="fig-plp | ||||
mtudimplement" format="default"/>) | ||||
in the IP protocol stack to discover the PLPMTU so that an application | ||||
can utilize an appropriate MPS for the current network path. </t> | ||||
<t>DPLPMTUD <bcp14>SHOULD</bcp14> only be performed at one layer between a | ||||
pair of | ||||
endpoints. Therefore, an upper PL or application should avoid using | ||||
DPLPMTUD when this is already enabled in a lower layer. A PL <bcp14>MUST</ | ||||
bcp14> adjust | ||||
the MPS indicated by DPLPMTUD to account for any additional overhead | ||||
introduced by the PL.</t> | ||||
<figure anchor="fig-plpmtudimplement"> | ||||
<name>Examples Where DPLPMTUD Can Be Implemented</name> | ||||
<artset> | ||||
<artwork type="svg" name="" alt="" originalSrc="diagrams/dplpmtud-impl | ||||
-examples.svg"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" class="diagram" version="1.1 | ||||
" viewBox="0 0 600.0 281.0"> | ||||
<g transform="translate(8,16)"> | ||||
<path d="M 0,0 L 184,0" fill="none" stroke="black"/> | ||||
<path d="M 0,32 L 48,32" fill="none" stroke="black"/> | ||||
<path d="M 48,32 L 152,32" fill="none" stroke="black"/> | ||||
<path d="M 152,32 L 184,32" fill="none" stroke="black"/> | ||||
<path d="M 16,64 L 48,64" fill="none" stroke="black"/> | ||||
<path d="M 48,64 L 72,64" fill="none" stroke="black"/> | ||||
<path d="M 128,64 L 152,64" fill="none" stroke="black"/> | ||||
<path d="M 152,64 L 176,64" fill="none" stroke="black"/> | ||||
<path d="M 16,96 L 48,96" fill="none" stroke="black"/> | ||||
<path d="M 48,96 L 72,96" fill="none" stroke="black"/> | ||||
<path d="M 128,96 L 144,96" fill="none" stroke="black"/> | ||||
<path d="M 144,96 L 160,96" fill="none" stroke="black"/> | ||||
<path d="M 160,96 L 176,96" fill="none" stroke="black"/> | ||||
<path d="M 48,128 L 80,128" fill="none" stroke="black"/> | ||||
<path d="M 104,128 L 144,128" fill="none" stroke="black"/> | ||||
<path d="M 64,160 L 80,160" fill="none" stroke="black"/> | ||||
<path d="M 80,160 L 104,160" fill="none" stroke="black"/> | ||||
<path d="M 104,160 L 120,160" fill="none" stroke="black"/> | ||||
<path d="M 64,192 L 96,192" fill="none" stroke="black"/> | ||||
<path d="M 96,192 L 120,192" fill="none" stroke="black"/> | ||||
<path d="M 0,224 L 96,224" fill="none" stroke="black"/> | ||||
<path d="M 96,224 L 160,224" fill="none" stroke="black"/> | ||||
<path d="M 160,224 L 184,224" fill="none" stroke="black"/> | ||||
<path d="M 0,256 L 184,256" fill="none" stroke="black"/> | ||||
<path d="M 0,0 L 0,32" fill="none" stroke="black"/> | ||||
<path d="M 0,224 L 0,256" fill="none" stroke="black"/> | ||||
<path d="M 16,64 L 16,96" fill="none" stroke="black"/> | ||||
<path d="M 48,32 L 48,64" fill="none" stroke="black"/> | ||||
<path d="M 48,96 L 48,128" fill="none" stroke="black"/> | ||||
<path d="M 64,160 L 64,192" fill="none" stroke="black"/> | ||||
<path d="M 72,64 L 72,96" fill="none" stroke="black"/> | ||||
<path d="M 80,128 L 80,160" fill="none" stroke="black"/> | ||||
<path d="M 96,192 L 96,224" fill="none" stroke="black"/> | ||||
<path d="M 104,128 L 104,160" fill="none" stroke="black"/> | ||||
<path d="M 120,160 L 120,192" fill="none" stroke="black"/> | ||||
<path d="M 128,64 L 128,96" fill="none" stroke="black"/> | ||||
<path d="M 144,96 L 144,128" fill="none" stroke="black"/> | ||||
<path d="M 152,32 L 152,64" fill="none" stroke="black"/> | ||||
<path d="M 160,96 L 160,224" fill="none" stroke="black"/> | ||||
<path d="M 176,64 L 176,96" fill="none" stroke="black"/> | ||||
<path d="M 184,0 L 184,32" fill="none" stroke="black"/> | ||||
<path d="M 184,224 L 184,256" fill="none" stroke="black"/> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="180 | ||||
" fill="black" font-size="1em">D</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y="24 | ||||
4" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y="20 | ||||
" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y="20 | ||||
" fill="black" font-size="1em">*</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="84" | ||||
fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="244 | ||||
" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="244 | ||||
" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y="24 | ||||
4" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y="24 | ||||
4" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="20" | ||||
fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y="20 | ||||
" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y="84 | ||||
" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y="24 | ||||
4" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="84" | ||||
fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y="84 | ||||
" fill="black" font-size="1em">*</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y="24 | ||||
4" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="84" | ||||
fill="black" font-size="1em">Q</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="84" | ||||
fill="black" font-size="1em">*</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="244 | ||||
" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="244 | ||||
" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="20" | ||||
fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="20" | ||||
fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y="20 | ||||
" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="20" | ||||
fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="244 | ||||
" fill="black" font-size="1em">w</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="244 | ||||
" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="180 | ||||
" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="244 | ||||
" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="20" | ||||
fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="20" | ||||
fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="180 | ||||
" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y="84 | ||||
" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="244 | ||||
" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y="20 | ||||
" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="84" | ||||
fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y="84 | ||||
" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y="24 | ||||
4" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y="24 | ||||
4" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="20" | ||||
fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y="84 | ||||
" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y="244 | ||||
" fill="black" font-size="1em">N</text> | ||||
</g> | ||||
</svg> | ||||
</artwork> | ||||
<artwork type="ascii-art" name="" alt="" originalSrc="diagrams/dplpmtu | ||||
d-impl-examples.txt"><![CDATA[ | ||||
+----------------------+ | ||||
| Application* | | ||||
+-----+------------+---+ | ||||
| | | ||||
+---+--+ +--+--+ | ||||
| QUIC*| |SCTP*| | ||||
+---+--+ +-+-+-+ | ||||
| | | | ||||
+---+ +----+ | | ||||
| | | | ||||
+-+--+-+ | | ||||
| UDP | | | ||||
+---+--+ | | ||||
| | | ||||
+-----------+-------+--+ | ||||
| Network Interface | | ||||
+----------------------+ | ||||
]]></artwork> | ||||
</artset> | ||||
</figure> | ||||
<t>The central idea of DPLPMTUD is probing by a sender. Probe packets | ||||
are sent to find the maximum size of user message that can be | ||||
completely transferred across the network path from the sender to the | ||||
destination.</t> | ||||
<t>The following sections identify the components needed for | ||||
implementation, provide an overview of the phases of operation, and | ||||
specify the state machine and search algorithm.</t> | ||||
<section anchor="dplpmtud-components"> | ||||
<name>DPLPMTUD Components</name> | ||||
<t>This section describes the timers, constants, and variables of | ||||
DPLPMTUD.</t> | ||||
<section anchor="Timers"> | ||||
<name>Timers</name> | ||||
<t>The method utilizes up to three timers: </t> | ||||
<dl> | ||||
<dt>PROBE_TIMER:</dt> | ||||
<dd> | ||||
<t>The PROBE_TIMER is configured to expire after a period | ||||
longer than the maximum time to receive an acknowledgment to a | ||||
probe packet. This value <bcp14>MUST NOT</bcp14> be smaller than | ||||
1 second | ||||
and <bcp14>SHOULD</bcp14> be larger than 15 seconds. Guidance on | ||||
the selection of | ||||
the timer value is provided in Section | ||||
<xref target="BCP145" section="3.1.1" sectionFormat="bare" forma | ||||
t="default"/> | ||||
of the UDP Usage Guidelines <xref target="BCP145"/>.</t> | ||||
</dd> | ||||
<dt>PMTU_RAISE_TIMER:</dt> | ||||
<dd> | ||||
<t>The PMTU_RAISE_TIMER is configured to the period a sender | ||||
will continue to use the current PLPMTU, after which it | ||||
reenters the Search Phase. This timer has a period of 600 | ||||
seconds, as recommended by PLPMTUD <xref target="RFC4821"/>.</t> | ||||
<t>DPLPMTUD <bcp14>MAY</bcp14> inhibit sending probe packets when | ||||
no | ||||
application data has been sent since the previous probe | ||||
packet. A PL preferring to use an up-to-date PMTU once user | ||||
data is sent again can choose to continue PMTU discovery for | ||||
each path. However, this will result in sending additional | ||||
packets.</t> | ||||
</dd> | ||||
<dt>CONFIRMATION_TIMER:</dt> | ||||
<dd> | ||||
<t>When an acknowledged PL is used, this timer <bcp14>MUST NOT</bc | ||||
p14> be | ||||
used. For other PLs, the CONFIRMATION_TIMER is configured to | ||||
the period a PL sender waits before confirming the current | ||||
PLPMTU is still supported. This is less than the | ||||
PMTU_RAISE_TIMER and used to decrease the PLPMTU (e.g., when a | ||||
black hole is encountered). Confirmation needs to be frequent | ||||
enough when data is flowing that the sending PL does not black | ||||
hole extensive amounts of traffic. Guidance on selection of | ||||
the timer value are provided in Section | ||||
<xref target="BCP145" section="3.1.1" sectionFormat="bare" forma | ||||
t="default"/> | ||||
of the UDP Usage Guidelines <xref target="BCP145"/>.</t> | ||||
<t>DPLPMTUD <bcp14>MAY</bcp14> inhibit sending probe packets when | ||||
no | ||||
application data has been sent since the previous probe | ||||
packet. A PL preferring to use an up-to-date PMTU once user | ||||
data is sent again, can choose to continue PMTU discovery for | ||||
each path. However, this could result in sending additional | ||||
packets.</t> | ||||
</dd> | ||||
</dl> | ||||
<t>DPLPMTUD specifies various timers; however, an implementation could | ||||
choose to realize these timer functions using a single timer.</t> | ||||
</section> | ||||
<section anchor="Constants"> | ||||
<name>Constants</name> | ||||
<t>The following constants are defined: </t> | ||||
<dl> | ||||
<dt>MAX_PROBES:</dt> | ||||
<dd>The MAX_PROBES is the maximum value of the PROBE_COUNT | ||||
counter (see <xref target="Variables"/>). MAX_PROBES represents | ||||
the limit for the number of consecutive probe attempts of any | ||||
size. Search algorithms benefit from a MAX_PROBES value greater | ||||
than 1 because this can provide robustness to isolated packet | ||||
loss. The default value of MAX_PROBES is 3.</dd> | ||||
<dt>MIN_PLPMTU:</dt> | ||||
<dd>The MIN_PLPMTU is the smallest size of PLPMTU that DPLPMTUD | ||||
will attempt to use. An endpoint could need to configure the | ||||
MIN_PLPMTU to provide space for extension headers and other | ||||
encapsulations at layers below the PL. This value can be | ||||
interface and path dependent. For IPv6, this size is greater | ||||
than or equal to the size at the PL that results in an 1280-byte | ||||
IPv6 packet, as specified in <xref target="RFC8200"/>. For | ||||
IPv4, this size is greater than or equal to the size at the PL | ||||
that results in an 68-byte IPv4 packet. Note: An IPv4 router is | ||||
required to be able to forward a datagram of 68 bytes without | ||||
further fragmentation. This is the combined size of an IPv4 | ||||
header and the minimum fragment size of 8 bytes. In addition, | ||||
receivers are required to be able to reassemble fragmented | ||||
datagrams at least up to 576 bytes, as stated in | ||||
<xref target="RFC1122" section="3.3.3" sectionFormat="of" format="d | ||||
efault"/>. </dd> | ||||
<dt>MAX_PLPMTU:</dt> | ||||
<dd>The MAX_PLPMTU is the largest size of PLPMTU. This has to be | ||||
less than or equal to the maximum size of the PL packet that can | ||||
be sent on the outgoing interface (constrained by the local | ||||
interface MTU). When known, this also ought to be less than the | ||||
maximum size of PL packet that can be received by the remote | ||||
endpoint (constrained by EMTU_R). It can be limited by the design | ||||
or configuration of the PL being used. An application, or PL, | ||||
<bcp14>MAY</bcp14> choose a smaller MAX_PLPMTU when there is no ne | ||||
ed to send | ||||
packets larger than a specific size.</dd> | ||||
<dt>BASE_PLPMTU:</dt> | ||||
<dd>The BASE_PLPMTU is a configured size expected to work for | ||||
most paths. The size is equal to or larger than the MIN_PLPMTU | ||||
and smaller than the MAX_PLPMTU. For most PLs, a suitable | ||||
BASE_PLPMTU will be larger than 1200 bytes. When using IPv4, | ||||
there is no currently equivalent size specified, and a default | ||||
BASE_PLPMTU of 1200 bytes is <bcp14>RECOMMENDED</bcp14>.</dd> | ||||
</dl> | ||||
</section> | ||||
<section anchor="Variables"> | ||||
<name>Variables</name> | ||||
<t>This method utilizes a set of variables: </t> | ||||
<dl> | ||||
<dt>PROBED_SIZE:</dt> | ||||
<dd>The PROBED_SIZE is the size of the current probe packet as | ||||
determined at the PL. This is a tentative value for the PLPMTU, | ||||
which is awaiting confirmation by an acknowledgment.</dd> | ||||
<dt>PROBE_COUNT:</dt> | ||||
<dd>The PROBE_COUNT is a count of the number of successive | ||||
unsuccessful probe packets that have been sent. Each time a probe | ||||
packet is acknowledged, the value is set to zero. (Some probe | ||||
loss is expected while searching, therefore loss of a single | ||||
probe is not an indication of a PMTU problem.) </dd> | ||||
</dl> | ||||
<t><xref target="fig-mps" format="default"/> illustrates the relations | ||||
hip between the packet | ||||
size constants and variables at a point of time when the DPLPMTUD | ||||
algorithm performs path probing to increase the size of the PLPMTU. | ||||
A probe packet has been sent of size PROBED_SIZE. Once this is | ||||
acknowledged, the PLPMTU will raise to PROBED_SIZE, allowing the | ||||
DPLPMTUD algorithm to further increase PROBED_SIZE toward sending a pr | ||||
obe | ||||
with the size of the actual PMTU.</t> | ||||
<figure anchor="fig-mps"> | ||||
<name>Relationships between Packet Size Constants and Variables</nam | ||||
e> | ||||
<artset> | ||||
<artwork type="svg" name="" alt="" originalSrc="diagrams/packet-si | ||||
zes-relationships.svg"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" class="diagram" version= | ||||
"1.1" viewBox="0 0 696.0 137.0"> | ||||
<g transform="translate(8,16)"> | ||||
<path d="M 56,16 L 408,16" fill="none" stroke="black"/> | ||||
<path d="M 176,32 L 176,48" fill="none" stroke="black"/> | ||||
<path d="M 248,32 L 248,96" fill="none" stroke="black"/> | ||||
<path d="M 296,32 L 296,64" fill="none" stroke="black"/> | ||||
<path d="M 176,24 L 176,32" fill="none" stroke="black"/> | ||||
<path d="M 248,24 L 248,32" fill="none" stroke="black"/> | ||||
<path d="M 296,24 L 296,32" fill="none" stroke="black"/> | ||||
<polygon points="64.000000,16.000000 52.000000,10.400000 52. | ||||
000000,21.600000" transform="rotate(180.000000, 56.000000, 16.000000)" fill="bla | ||||
ck"/> | ||||
<polygon points="184.000000,48.000000 172.000000,42.400002 1 | ||||
72.000000,53.599998" transform="rotate(90.000000, 176.000000, 48.000000)" fill=" | ||||
black"/> | ||||
<polygon points="256.000000,96.000000 244.000000,90.400002 2 | ||||
44.000000,101.599998" transform="rotate(90.000000, 248.000000, 96.000000)" fill= | ||||
"black"/> | ||||
<polygon points="304.000000,64.000000 292.000000,58.400002 2 | ||||
92.000000,69.599998" transform="rotate(90.000000, 296.000000, 64.000000)" fill=" | ||||
black"/> | ||||
<polygon points="416.000000,16.000000 404.000000,10.400000 4 | ||||
04.000000,21.600000" transform="rotate(0.000000, 408.000000, 16.000000)" fill="b | ||||
lack"/> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="4" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="4" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y | ||||
="68" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y | ||||
="84" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y | ||||
="84" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="116" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="116" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y= | ||||
"4" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y= | ||||
"4" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y | ||||
="84" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y | ||||
="84" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y | ||||
="84" fill="black" font-size="1em">Z</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y= | ||||
"4" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y= | ||||
"4" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="4" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="4" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="4" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y | ||||
="68" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y | ||||
="84" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y= | ||||
"4" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="4" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y | ||||
="68" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y | ||||
="84" fill="black" font-size="1em">D</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="116" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="116" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y= | ||||
"4" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y | ||||
="4" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="4" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y | ||||
="68" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y | ||||
="68" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="68" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y | ||||
="84" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="116" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y= | ||||
"4" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y= | ||||
"4" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y | ||||
="68" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y | ||||
="84" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y | ||||
="4" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="4" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y | ||||
="68" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="68" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y | ||||
="84" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="116" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="4" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="4" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y | ||||
="68" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y | ||||
="68" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="84" fill="black" font-size="1em">P</text> | ||||
</g> | ||||
</svg> | ||||
</artwork> | ||||
<artwork type="ascii-art" name="" alt="" originalSrc="diagrams/pac | ||||
ket-sizes-relationships.txt"><![CDATA[ | ||||
MIN_PLPMTU MAX_PLPMTU | ||||
<-------------------------------------------> | ||||
| | | | ||||
v | | | ||||
BASE_PLPMTU | v | ||||
| PROBED_SIZE | ||||
v | ||||
PLPMTU | ||||
]]></artwork> | ||||
</artset> | ||||
</figure> | ||||
</section> | ||||
<section anchor="phases"> | ||||
<name>Overview of DPLPMTUD Phases</name> | ||||
<t>This section provides a high-level, informative view of the | ||||
DPLPMTUD method, by describing the movement of the method through | ||||
several phases of operation. More detail is available in the state | ||||
machine, <xref target="States"/>.</t> | ||||
<figure anchor="fig-phases"> | ||||
<name>DPLPMTUD Phases</name> | ||||
<artset> | ||||
<artwork type="svg" name="" alt="" originalSrc="diagrams/dplpmtud- | ||||
phases.svg"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" class="diagram" version=" | ||||
1.1" viewBox="0 0 670.0 377.0"> | ||||
<g transform="translate(8,16)"> | ||||
<path d="M 160,0 L 216,0" fill="none" stroke="black"/> | ||||
<path d="M 88,16 L 152,16" fill="none" stroke="black"/> | ||||
<path d="M 224,16 L 360,16" fill="none" stroke="black"/> | ||||
<path d="M 160,32 L 216,32" fill="none" stroke="black"/> | ||||
<path d="M 328,80 L 392,80" fill="none" stroke="black"/> | ||||
<path d="M 328,112 L 392,112" fill="none" stroke="black"/> | ||||
<path d="M 152,160 L 224,160" fill="none" stroke="black"/> | ||||
<path d="M 232,176 L 360,176" fill="none" stroke="black"/> | ||||
<path d="M 152,192 L 224,192" fill="none" stroke="black"/> | ||||
<path d="M 120,320 L 264,320" fill="none" stroke="black"/> | ||||
<path d="M 88,336 L 112,336" fill="none" stroke="black"/> | ||||
<path d="M 120,352 L 264,352" fill="none" stroke="black"/> | ||||
<path d="M 88,16 L 88,336" fill="none" stroke="black"/> | ||||
<path d="M 120,320 L 120,352" fill="none" stroke="black"/> | ||||
<path d="M 152,160 L 152,192" fill="none" stroke="black"/> | ||||
<path d="M 160,0 L 160,32" fill="none" stroke="black"/> | ||||
<path d="M 176,208 L 176,304" fill="none" stroke="black"/> | ||||
<path d="M 184,48 L 184,144" fill="none" stroke="black"/> | ||||
<path d="M 200,208 L 200,304" fill="none" stroke="black"/> | ||||
<path d="M 216,0 L 216,32" fill="none" stroke="black"/> | ||||
<path d="M 224,160 L 224,192" fill="none" stroke="black"/> | ||||
<path d="M 264,320 L 264,352" fill="none" stroke="black"/> | ||||
<path d="M 328,80 L 328,112" fill="none" stroke="black"/> | ||||
<path d="M 360,16 L 360,64" fill="none" stroke="black"/> | ||||
<path d="M 360,128 L 360,176" fill="none" stroke="black"/> | ||||
<path d="M 392,80 L 392,112" fill="none" stroke="black"/> | ||||
<path d="M 176,304 L 176,312" fill="none" stroke="black"/> | ||||
<path d="M 184,40 L 184,48" fill="none" stroke="black"/> | ||||
<path d="M 200,200 L 200,208" fill="none" stroke="black"/> | ||||
<path d="M 360,120 L 360,128" fill="none" stroke="black"/> | ||||
<polygon points="160.000000,16.000000 148.000000,10.400000 1 | ||||
48.000000,21.600000" transform="rotate(0.000000, 152.000000, 16.000000)" fill="b | ||||
lack"/> | ||||
<path d="M 176,200 L 176,208" fill="none" stroke="black"/> | ||||
<polygon points="192.000000,208.000000 180.000000,202.399994 | ||||
180.000000,213.600006" transform="rotate(270.000000, 176.000000, 208.000000)" f | ||||
ill="black"/> | ||||
<path d="M 184,144 L 184,152" fill="none" stroke="black"/> | ||||
<polygon points="200.000000,144.000000 188.000000,138.399994 | ||||
188.000000,149.600006" transform="rotate(90.000000, 184.000000, 144.000000)" fi | ||||
ll="black"/> | ||||
<path d="M 200,304 L 200,312" fill="none" stroke="black"/> | ||||
<polygon points="216.000000,304.000000 204.000000,298.399994 | ||||
204.000000,309.600006" transform="rotate(90.000000, 200.000000, 304.000000)" fi | ||||
ll="black"/> | ||||
<polygon points="240.000000,176.000000 228.000000,170.399994 | ||||
228.000000,181.600006" transform="rotate(180.000000, 232.000000, 176.000000)" f | ||||
ill="black"/> | ||||
<path d="M 360,64 L 360,72" fill="none" stroke="black"/> | ||||
<polygon points="376.000000,64.000000 364.000000,58.400002 3 | ||||
64.000000,69.599998" transform="rotate(90.000000, 360.000000, 64.000000)" fill=" | ||||
black"/> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="100" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y | ||||
="148" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="164" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y | ||||
="180" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="244" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="276" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y | ||||
="340" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="84" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y | ||||
="180" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="20" fill="black" font-size="1em">v</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y | ||||
="260" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="84" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="100" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="116" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="132" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y | ||||
="52" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="148" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="52" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="148" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="276" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="36" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y | ||||
="100" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y= | ||||
"180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="276" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y= | ||||
"164" fill="black" font-size="1em">H</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y | ||||
="164" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y | ||||
="340" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="52" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="148" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="340" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y | ||||
="36" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y | ||||
="100" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y | ||||
="148" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="164" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="260" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y | ||||
="100" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="84" fill="black" font-size="1em">v</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y=" | ||||
180" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y | ||||
="340" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="20" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="84" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y | ||||
="100" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="132" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y=" | ||||
164" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="164" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="164" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y | ||||
="180" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="180" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y | ||||
="276" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y | ||||
="260" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="260" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="20" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y | ||||
="84" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="132" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y | ||||
="260" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y | ||||
="276" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="20" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="100" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="244" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y | ||||
="276" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y | ||||
="20" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y | ||||
="52" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="100" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="132" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y | ||||
="164" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y | ||||
="164" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="180" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="244" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="36" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="148" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="180" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y | ||||
="276" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="340" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="20" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="36" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="52" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y | ||||
="276" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="164" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="180" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y | ||||
="100" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="20" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y | ||||
="52" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y | ||||
="100" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="276" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y | ||||
="340" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y | ||||
="84" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y | ||||
="36" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="520" y | ||||
="52" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="84" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="100" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="116" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="132" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="148" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y= | ||||
"164" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="276" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="180" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y | ||||
="244" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="52" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="20" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y | ||||
="100" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y= | ||||
"164" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y | ||||
="164" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y | ||||
="260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y | ||||
="180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="244" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y | ||||
="36" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="84" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="148" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y= | ||||
"180" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y= | ||||
"164" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y= | ||||
"180" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="36" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y= | ||||
"164" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y | ||||
="164" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="100" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="164" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y | ||||
="340" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y | ||||
="52" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="100" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y= | ||||
"180" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y | ||||
="244" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y | ||||
="276" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="84" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="116" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="116" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="132" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="132" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="148" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="244" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y | ||||
="260" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y | ||||
="276" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="84" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="116" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="116" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="260" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="52" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="0" y=" | ||||
164" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y | ||||
="244" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="20" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="340" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="340" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="36" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y | ||||
="100" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="180" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y | ||||
="244" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="52" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y | ||||
="52" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="164" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="20" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y | ||||
="36" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y | ||||
="36" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="148" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="180" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="276" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y | ||||
="52" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y | ||||
="100" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y | ||||
="36" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="164" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y | ||||
="340" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y | ||||
="20" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="20" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y | ||||
="20" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="52" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="512" y | ||||
="52" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="84" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y | ||||
="84" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="180" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y | ||||
="276" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y | ||||
="116" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="148" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y= | ||||
"164" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y= | ||||
"180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y | ||||
="244" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="340" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y | ||||
="20" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="260" fill="black" font-size="1em">g</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="340" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="164" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="276" fill="black" font-size="1em">m</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="36" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y | ||||
="52" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="116" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y= | ||||
"164" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y | ||||
="260" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="260" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y | ||||
="340" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y | ||||
="132" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y | ||||
="260" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y | ||||
="52" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="100" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y | ||||
="276" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="52" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y | ||||
="116" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y | ||||
="180" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y | ||||
="20" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y | ||||
="100" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="132" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="132" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y | ||||
="148" fill="black" font-size="1em">v</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y= | ||||
"180" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y= | ||||
"180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y | ||||
="180" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y | ||||
="260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y | ||||
="20" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y | ||||
="36" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y | ||||
="100" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y | ||||
="244" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y | ||||
="340" fill="black" font-size="1em">p</text> | ||||
</g> | ||||
</svg> | ||||
</artwork> | ||||
<artwork type="ascii-art" name="" alt="" originalSrc="diagrams/dpl | ||||
pmtud-phases.txt"><![CDATA[ | ||||
+------+ | ||||
+------->| Base |-----------------+ Connectivity | ||||
| +------+ | or BASE_PLPMTU | ||||
| | | confirmation failed | ||||
| | v | ||||
| | Connectivity +-------+ | ||||
| | and BASE_PLPMTU | Error | | ||||
| | confirmed +-------+ | ||||
| | | Consistent | ||||
| v | connectivity | ||||
Black Hole | +--------+ | and BASE_PLPMTU | ||||
detected | | Search |<---------------+ confirmed | ||||
| +--------+ | ||||
| ^ | | ||||
| | | | ||||
| Raise | | Search | ||||
| timer | | algorithm | ||||
| expired | | completed | ||||
| | | | ||||
| | v | ||||
| +-----------------+ | ||||
+---| Search Complete | | ||||
+-----------------+ | ||||
]]></artwork> | ||||
</artset> | ||||
</figure> | ||||
<dl> | ||||
<dt>Base:</dt> | ||||
<dd> | ||||
<t>The Base Phase confirms connectivity to the remote peer | ||||
using packets of the BASE_PLPMTU. The confirmation of | ||||
connectivity is implicit for a connection-oriented PL (where it | ||||
can be performed in a PL connection handshake). A | ||||
connectionless PL sends a probe packet and uses acknowledgment | ||||
of this probe packet to confirm that the remote peer is | ||||
reachable. </t> | ||||
<t>The sender also confirms that BASE_PLPMTU is supported across | ||||
the network path. This may be achieved by using a PL mechanism | ||||
(e.g., using a handshake packet of size BASE_PLPMTU) or by | ||||
sending a probe packet of size BASE_PLPMTU and confirming that | ||||
this is received.</t> | ||||
<t>A probe packet of size BASE_PLPMTU can be sent immediately | ||||
on the initial entry to the Base Phase (following a | ||||
connectivity check). A PL that does not wish to support a path | ||||
with a PLPMTU less than BASE_PLPMTU can simplify the phase into | ||||
a single step by performing the connectivity checks with a | ||||
probe of the BASE_PLPMTU size.</t> | ||||
<t>Once confirmed, DPLPMTUD enters the Search Phase. If the | ||||
Base Phase fails to confirm the BASE_PLPMTU, DPLPMTUD enters | ||||
the Error Phase.</t> | ||||
</dd> | ||||
<dt>Search:</dt> | ||||
<dd> | ||||
<t>The Search Phase utilizes a search algorithm to send probe | ||||
packets to seek to increase the PLPMTU. The algorithm | ||||
concludes when it has found a suitable PLPMTU by entering the | ||||
Search Complete Phase.</t> | ||||
<t>A PL could respond to PTB messages using the PTB to advance | ||||
or terminate the search, see <xref target="mechanism-ptb"/>.</t> | ||||
</dd> | ||||
<dt>Search Complete:</dt> | ||||
<dd> | ||||
<t>The Search Complete Phase is entered when the PLPMTU is | ||||
supported across the network path. A PL can use a | ||||
CONFIRMATION_TIMER to periodically repeat a probe packet for | ||||
the current PLPMTU size. If the sender is unable to confirm | ||||
reachability (e.g., if the CONFIRMATION_TIMER expires) or the | ||||
PL signals a lack of reachability, a black hole has been | ||||
detected and DPLPMTUD enters the Base Phase. </t> | ||||
<t>The PMTU_RAISE_TIMER is used to periodically resume the | ||||
Search Phase to discover if the PLPMTU can be raised. Black | ||||
hole detection causes the sender to enter the Base Phase.</t> | ||||
</dd> | ||||
<dt>Error:</dt> | ||||
<dd> | ||||
<t>The Error Phase is entered when there is conflicting or | ||||
invalid PLPMTU information for the path (e.g., a failure to | ||||
support the BASE_PLPMTU) that causes DPLPMTUD to be unable to | ||||
progress, and the PLPMTU is lowered.</t> | ||||
<t>DPLPMTUD remains in the Error Phase until a consistent view | ||||
of the path can be discovered and it has also been confirmed | ||||
that the path supports the BASE_PLPMTU (or DPLPMTUD is | ||||
suspended).</t> | ||||
</dd> | ||||
</dl> | ||||
<t> A method that only reduces the PLPMTU to a suitable size would be | ||||
sufficient to ensure reliable operation but can be very inefficient | ||||
when the actual PMTU changes or when the method (for whatever reason) | ||||
makes a suboptimal choice for the PLPMTU.</t> | ||||
<t>A full implementation of DPLPMTUD provides an algorithm enabling | ||||
the DPLPMTUD sender to increase the PLPMTU following a change in the | ||||
characteristics of the path, such as when a link is reconfigured | ||||
with a larger MTU, or when there is a change in the set of links | ||||
traversed by an end-to-end flow (e.g., after a routing or path | ||||
failover decision).</t> | ||||
</section> | ||||
</section> | ||||
<section anchor="States"> | ||||
<name>State Machine</name> | ||||
<t>A state machine for DPLPMTUD is depicted in <xref target="fig-states" | ||||
/>. If multipath or multihoming is supported, | ||||
a state machine is needed for each path.</t> | ||||
<t>Note: Not all changes are shown to simplify the | ||||
diagram.</t> | ||||
<figure anchor="fig-states"> | ||||
<name>State Machine for Datagram PLPMTUD</name> | ||||
<artset> | ||||
<artwork type="svg" name="" alt="" originalSrc="diagrams/dplpmtud-st | ||||
atemachine.svg"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" class="diagram" version="1. | ||||
1" viewBox="0 0 700.0 633.0"> | ||||
<g transform="translate(8,16)"> | ||||
<path d="M 0,64 L 128,64" fill="none" stroke="black"/> | ||||
<path d="M 416,64 L 544,64" fill="none" stroke="black"/> | ||||
<path d="M 0,96 L 128,96" fill="none" stroke="black"/> | ||||
<path d="M 416,96 L 544,96" fill="none" stroke="black"/> | ||||
<path d="M 64,144 L 232,144" fill="none" stroke="black"/> | ||||
<path d="M 312,144 L 440,144" fill="none" stroke="black"/> | ||||
<path d="M 208,192 L 336,192" fill="none" stroke="black"/> | ||||
<path d="M 344,208 L 512,208" fill="none" stroke="black"/> | ||||
<path d="M 208,224 L 336,224" fill="none" stroke="black"/> | ||||
<path d="M 64,272 L 232,272" fill="none" stroke="black"/> | ||||
<path d="M 312,272 L 480,272" fill="none" stroke="black"/> | ||||
<path d="M 248,288 L 288,288" fill="none" stroke="black"/> | ||||
<path d="M 104,368 L 440,368" fill="none" stroke="black"/> | ||||
<path d="M 0,416 L 128,416" fill="none" stroke="black"/> | ||||
<path d="M 416,416 L 544,416" fill="none" stroke="black"/> | ||||
<path d="M 0,448 L 128,448" fill="none" stroke="black"/> | ||||
<path d="M 416,448 L 544,448" fill="none" stroke="black"/> | ||||
<path d="M 104,496 L 440,496" fill="none" stroke="black"/> | ||||
<path d="M 24,544 L 64,544" fill="none" stroke="black"/> | ||||
<path d="M 480,544 L 520,544" fill="none" stroke="black"/> | ||||
<path d="M 0,64 L 0,96" fill="none" stroke="black"/> | ||||
<path d="M 0,416 L 0,448" fill="none" stroke="black"/> | ||||
<path d="M 24,0 L 24,48" fill="none" stroke="black"/> | ||||
<path d="M 24,464 L 24,544" fill="none" stroke="black"/> | ||||
<path d="M 64,112 L 64,144" fill="none" stroke="black"/> | ||||
<path d="M 64,272 L 64,400" fill="none" stroke="black"/> | ||||
<path d="M 64,464 L 64,544" fill="none" stroke="black"/> | ||||
<path d="M 104,0 L 104,48" fill="none" stroke="black"/> | ||||
<path d="M 104,368 L 104,400" fill="none" stroke="black"/> | ||||
<path d="M 104,464 L 104,496" fill="none" stroke="black"/> | ||||
<path d="M 128,64 L 128,96" fill="none" stroke="black"/> | ||||
<path d="M 128,416 L 128,448" fill="none" stroke="black"/> | ||||
<path d="M 208,192 L 208,224" fill="none" stroke="black"/> | ||||
<path d="M 232,144 L 232,176" fill="none" stroke="black"/> | ||||
<path d="M 232,240 L 232,272" fill="none" stroke="black"/> | ||||
<path d="M 248,240 L 248,288" fill="none" stroke="black"/> | ||||
<path d="M 288,240 L 288,288" fill="none" stroke="black"/> | ||||
<path d="M 312,144 L 312,176" fill="none" stroke="black"/> | ||||
<path d="M 312,240 L 312,272" fill="none" stroke="black"/> | ||||
<path d="M 336,192 L 336,224" fill="none" stroke="black"/> | ||||
<path d="M 416,64 L 416,96" fill="none" stroke="black"/> | ||||
<path d="M 416,416 L 416,448" fill="none" stroke="black"/> | ||||
<path d="M 440,112 L 440,144" fill="none" stroke="black"/> | ||||
<path d="M 440,368 L 440,400" fill="none" stroke="black"/> | ||||
<path d="M 440,464 L 440,496" fill="none" stroke="black"/> | ||||
<path d="M 480,272 L 480,400" fill="none" stroke="black"/> | ||||
<path d="M 480,464 L 480,544" fill="none" stroke="black"/> | ||||
<path d="M 520,112 L 520,208" fill="none" stroke="black"/> | ||||
<path d="M 520,208 L 520,400" fill="none" stroke="black"/> | ||||
<path d="M 520,464 L 520,544" fill="none" stroke="black"/> | ||||
<path d="M 544,64 L 544,96" fill="none" stroke="black"/> | ||||
<path d="M 544,416 L 544,448" fill="none" stroke="black"/> | ||||
<path d="M 24,456 L 24,464" fill="none" stroke="black"/> | ||||
<path d="M 64,104 L 64,112" fill="none" stroke="black"/> | ||||
<path d="M 64,400 L 64,408" fill="none" stroke="black"/> | ||||
<path d="M 104,400 L 104,408" fill="none" stroke="black"/> | ||||
<path d="M 248,232 L 248,240" fill="none" stroke="black"/> | ||||
<path d="M 312,176 L 312,184" fill="none" stroke="black"/> | ||||
<path d="M 440,456 L 440,464" fill="none" stroke="black"/> | ||||
<path d="M 480,400 L 480,408" fill="none" stroke="black"/> | ||||
<path d="M 480,456 L 480,464" fill="none" stroke="black"/> | ||||
<path d="M 520,104 L 520,112" fill="none" stroke="black"/> | ||||
<path d="M 24,48 L 24,56" fill="none" stroke="black"/> | ||||
<polygon points="40.000000,48.000000 28.000000,42.400002 28.00 | ||||
0000,53.599998" transform="rotate(90.000000, 24.000000, 48.000000)" fill="black" | ||||
/> | ||||
<path d="M 64,456 L 64,464" fill="none" stroke="black"/> | ||||
<polygon points="80.000000,464.000000 68.000000,458.399994 68. | ||||
000000,469.600006" transform="rotate(270.000000, 64.000000, 464.000000)" fill="b | ||||
lack"/> | ||||
<path d="M 104,48 L 104,56" fill="none" stroke="black"/> | ||||
<polygon points="120.000000,48.000000 108.000000,42.400002 108 | ||||
.000000,53.599998" transform="rotate(90.000000, 104.000000, 48.000000)" fill="bl | ||||
ack"/> | ||||
<path d="M 104,456 L 104,464" fill="none" stroke="black"/> | ||||
<polygon points="120.000000,464.000000 108.000000,458.399994 1 | ||||
08.000000,469.600006" transform="rotate(270.000000, 104.000000, 464.000000)" fil | ||||
l="black"/> | ||||
<path d="M 232,176 L 232,184" fill="none" stroke="black"/> | ||||
<polygon points="248.000000,176.000000 236.000000,170.399994 2 | ||||
36.000000,181.600006" transform="rotate(90.000000, 232.000000, 176.000000)" fill | ||||
="black"/> | ||||
<path d="M 232,232 L 232,240" fill="none" stroke="black"/> | ||||
<polygon points="248.000000,240.000000 236.000000,234.399994 2 | ||||
36.000000,245.600006" transform="rotate(270.000000, 232.000000, 240.000000)" fil | ||||
l="black"/> | ||||
<path d="M 288,232 L 288,240" fill="none" stroke="black"/> | ||||
<polygon points="304.000000,240.000000 292.000000,234.399994 2 | ||||
92.000000,245.600006" transform="rotate(270.000000, 288.000000, 240.000000)" fil | ||||
l="black"/> | ||||
<path d="M 312,232 L 312,240" fill="none" stroke="black"/> | ||||
<polygon points="328.000000,240.000000 316.000000,234.399994 3 | ||||
16.000000,245.600006" transform="rotate(270.000000, 312.000000, 240.000000)" fil | ||||
l="black"/> | ||||
<path d="M 440,104 L 440,112" fill="none" stroke="black"/> | ||||
<polygon points="456.000000,112.000000 444.000000,106.400002 4 | ||||
44.000000,117.599998" transform="rotate(270.000000, 440.000000, 112.000000)" fil | ||||
l="black"/> | ||||
<path d="M 440,400 L 440,408" fill="none" stroke="black"/> | ||||
<polygon points="456.000000,400.000000 444.000000,394.399994 4 | ||||
44.000000,405.600006" transform="rotate(90.000000, 440.000000, 400.000000)" fill | ||||
="black"/> | ||||
<polygon points="520.000000,208.000000 508.000000,202.399994 5 | ||||
08.000000,213.600006" transform="rotate(0.000000, 512.000000, 208.000000)" fill= | ||||
"black"/> | ||||
<path d="M 520,400 L 520,408" fill="none" stroke="black"/> | ||||
<polygon points="536.000000,400.000000 524.000000,394.399994 5 | ||||
24.000000,405.600006" transform="rotate(90.000000, 520.000000, 400.000000)" fill | ||||
="black"/> | ||||
<path d="M 520,456 L 520,464" fill="none" stroke="black"/> | ||||
<polygon points="536.000000,464.000000 524.000000,458.399994 5 | ||||
24.000000,469.600006" transform="rotate(270.000000, 520.000000, 464.000000)" fil | ||||
l="black"/> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="1 | ||||
32" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
132" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
324" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
356" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
516" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
548" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="5 | ||||
80" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
436" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
532" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
532" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
532" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
116" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
132" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
548" fill="black" font-size="1em">=</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
612" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
532" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
180" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
260" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
580" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
116" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
308" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
580" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="5 | ||||
96" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
20" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
84" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
116" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
260" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
308" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y="4 | ||||
36" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
532" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
116" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
308" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="528" y=" | ||||
612" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="520" y=" | ||||
596" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
100" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
100" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
116" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
132" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
180" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y=" | ||||
180" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
580" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
132" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
116" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
308" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
324" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
324" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="4 | ||||
36" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="512" y=" | ||||
436" fill="black" font-size="1em">G</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
596" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
116" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
132" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="2 | ||||
60" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
564" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="536" y=" | ||||
580" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
612" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
436" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
532" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
548" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
260" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
324" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
356" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y=" | ||||
564" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y=" | ||||
580" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
36" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
100" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="5 | ||||
80" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
532" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
20" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
100" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
132" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
132" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
212" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="4 | ||||
36" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
532" fill="black" font-size="1em">=</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
132" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
596" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
100" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="5 | ||||
80" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
580" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="2 | ||||
0" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
132" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
132" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
532" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
548" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
116" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="2 | ||||
60" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
436" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
532" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
580" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
564" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
36" fill="black" font-size="1em">v</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
132" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
308" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
532" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
548" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y=" | ||||
84" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
436" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
564" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
116" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="4 | ||||
36" fill="black" font-size="1em">H</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="4 | ||||
36" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
436" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="5 | ||||
32" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
532" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
516" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
564" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
324" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
548" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
564" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
612" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
132" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
20" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
36" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="1 | ||||
16" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
116" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
212" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
436" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
196" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
356" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
100" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
564" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="544" y=" | ||||
564" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
116" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
532" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
612" fill="black" font-size="1em">Z</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
100" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
132" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
580" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
596" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="528" y=" | ||||
596" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
132" fill="black" font-size="1em">v</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="5 | ||||
32" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
532" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="5 | ||||
64" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="512" y=" | ||||
580" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
36" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
100" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
132" fill="black" font-size="1em">Z</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
564" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
580" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
260" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
308" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
516" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
548" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
564" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
580" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
116" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
356" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
580" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
596" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
116" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
324" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
356" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
132" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
308" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
324" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
356" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
516" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
596" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
36" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
100" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
116" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
532" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y=" | ||||
180" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
532" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="0" y="56 | ||||
4" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
580" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
212" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
532" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
532" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
532" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="520" y=" | ||||
564" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
324" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
324" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
436" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
516" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
516" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
548" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
564" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
612" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
132" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
308" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
516" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
20" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="4 | ||||
36" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
516" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
308" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
580" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
596" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
548" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="5 | ||||
64" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
196" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
260" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
100" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
116" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
132" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
260" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
260" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
532" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y="5 | ||||
64" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
596" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
20" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
516" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="2 | ||||
0" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="8 | ||||
4" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
132" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="16" y="5 | ||||
80" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
132" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="4 | ||||
36" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
548" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
548" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
548" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y="56 | ||||
4" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
580" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
116" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
356" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="5 | ||||
64" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
580" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
132" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
580" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
596" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
612" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
36" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
356" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
564" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
564" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
580" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
532" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="8 | ||||
4" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
100" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
132" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
180" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
308" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
324" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
356" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
132" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
324" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
116" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
356" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
532" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
596" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
20" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
324" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
356" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="2 | ||||
0" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
20" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
116" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
516" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
612" fill="black" font-size="1em">D</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
116" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
260" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
308" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
564" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
580" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
260" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
180" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="5 | ||||
96" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
100" fill="black" font-size="1em">x</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="1 | ||||
16" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
100" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
436" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
532" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
132" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
180" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="5 | ||||
64" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="5 | ||||
96" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="8 | ||||
4" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
116" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
324" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
356" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
564" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
580" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="5 | ||||
96" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="2 | ||||
0" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
36" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
100" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
532" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
20" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
36" fill="black" font-size="1em">f</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y=" | ||||
196" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="2 | ||||
60" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
324" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
324" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="520" y=" | ||||
580" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
116" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
516" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="0" y="58 | ||||
0" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
580" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
20" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
84" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
132" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
260" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
516" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
532" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
548" fill="black" font-size="1em">Z</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
132" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="1 | ||||
32" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
132" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
180" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
260" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
116" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
196" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
436" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
564" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
580" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
596" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
324" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
516" fill="black" font-size="1em">b</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
36" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
532" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
580" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
36" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
564" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
100" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
260" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="5 | ||||
80" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
36" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
532" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="456" y=" | ||||
564" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
580" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="544" y=" | ||||
596" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="184" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
356" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
564" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
612" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
180" fill="black" font-size="1em">b</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="4 | ||||
36" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
308" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
324" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
356" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
548" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="8 | ||||
4" fill="black" font-size="1em">D</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
84" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
516" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="5 | ||||
64" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
612" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
612" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y=" | ||||
612" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
132" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
260" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
532" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
580" fill="black" font-size="1em">C</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="5 | ||||
96" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
516" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
548" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
580" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
180" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
260" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
260" fill="black" font-size="1em">h</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
532" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
532" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
596" fill="black" font-size="1em">b</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
36" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
100" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
260" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
324" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="32" y="5 | ||||
80" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
100" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
132" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
532" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="512" y=" | ||||
564" fill="black" font-size="1em">p</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
580" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="5 | ||||
96" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
612" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="8 | ||||
4" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
260" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
516" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
532" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
596" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
612" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
612" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="8 | ||||
4" fill="black" font-size="1em">D</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
116" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="440" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="40" y="5 | ||||
64" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
84" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="4 | ||||
36" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y="58 | ||||
0" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
116" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
180" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
180" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
564" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
564" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
564" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="536" y=" | ||||
564" fill="black" font-size="1em">y</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
612" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
116" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
116" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
132" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
308" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
532" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="368" y=" | ||||
612" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="176" y=" | ||||
20" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
132" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="480" y=" | ||||
180" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
356" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
356" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
596" fill="black" font-size="1em">k</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
612" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
308" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
356" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
532" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
580" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
612" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
180" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
308" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
532" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
532" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
580" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
132" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="8" y="43 | ||||
6" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
532" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="312" y=" | ||||
116" fill="black" font-size="1em">=</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
132" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
612" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="248" y=" | ||||
20" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
356" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="208" y=" | ||||
548" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y="5 | ||||
64" fill="black" font-size="1em">F</text> | ||||
<text text-anchor="middle" font-family="monospace" x="96" y="1 | ||||
32" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
180" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
564" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
612" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
132" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
308" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="304" y=" | ||||
516" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
532" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="5 | ||||
80" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
596" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="544" y=" | ||||
612" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
180" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
196" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
324" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="520" y=" | ||||
612" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
612" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="536" y=" | ||||
612" fill="black" font-size="1em">Z</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="5 | ||||
64" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="2 | ||||
0" fill="black" font-size="1em">t</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
20" fill="black" font-size="1em">i</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="8 | ||||
4" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
116" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
260" fill="black" font-size="1em">l</text> | ||||
<text text-anchor="middle" font-family="monospace" x="240" y=" | ||||
356" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
356" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="536" y=" | ||||
596" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
116" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="416" y=" | ||||
564" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
580" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="160" y=" | ||||
20" fill="black" font-size="1em">d</text> | ||||
<text text-anchor="middle" font-family="monospace" x="280" y=" | ||||
212" fill="black" font-size="1em">S</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
516" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
116" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="296" y=" | ||||
116" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
548" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="528" y=" | ||||
564" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="88" y="2 | ||||
60" fill="black" font-size="1em">a</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="4 | ||||
36" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y="5 | ||||
80" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
580" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
612" fill="black" font-size="1em"><</text> | ||||
<text text-anchor="middle" font-family="monospace" x="544" y=" | ||||
580" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
20" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
260" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="24" y="4 | ||||
36" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="472" y=" | ||||
436" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="264" y=" | ||||
516" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
548" fill="black" font-size="1em">L</text> | ||||
<text text-anchor="middle" font-family="monospace" x="448" y=" | ||||
564" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
596" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="384" y=" | ||||
532" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
548" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="5 | ||||
64" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="136" y=" | ||||
580" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
36" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="256" y=" | ||||
308" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
596" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="512" y=" | ||||
612" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="128" y=" | ||||
580" fill="black" font-size="1em">X</text> | ||||
<text text-anchor="middle" font-family="monospace" x="504" y=" | ||||
596" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
36" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="168" y=" | ||||
116" fill="black" font-size="1em">s</text> | ||||
<text text-anchor="middle" font-family="monospace" x="376" y=" | ||||
132" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="216" y=" | ||||
356" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
516" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="224" y=" | ||||
548" fill="black" font-size="1em">_</text> | ||||
<text text-anchor="middle" font-family="monospace" x="112" y=" | ||||
596" fill="black" font-size="1em">o</text> | ||||
<text text-anchor="middle" font-family="monospace" x="320" y=" | ||||
324" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="352" y=" | ||||
324" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="200" y=" | ||||
356" fill="black" font-size="1em">M</text> | ||||
<text text-anchor="middle" font-family="monospace" x="360" y=" | ||||
516" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="80" y="5 | ||||
96" fill="black" font-size="1em">U</text> | ||||
<text text-anchor="middle" font-family="monospace" x="392" y=" | ||||
612" fill="black" font-size="1em">B</text> | ||||
<text text-anchor="middle" font-family="monospace" x="464" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="488" y=" | ||||
436" fill="black" font-size="1em">H</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
548" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="56" y="5 | ||||
80" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="48" y="8 | ||||
4" fill="black" font-size="1em">I</text> | ||||
<text text-anchor="middle" font-family="monospace" x="64" y="5 | ||||
64" fill="black" font-size="1em">T</text> | ||||
<text text-anchor="middle" font-family="monospace" x="72" y="5 | ||||
80" fill="black" font-size="1em">N</text> | ||||
<text text-anchor="middle" font-family="monospace" x="432" y=" | ||||
612" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="272" y=" | ||||
308" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="192" y=" | ||||
548" fill="black" font-size="1em">:</text> | ||||
<text text-anchor="middle" font-family="monospace" x="328" y=" | ||||
100" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="232" y=" | ||||
324" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="400" y=" | ||||
564" fill="black" font-size="1em">P</text> | ||||
<text text-anchor="middle" font-family="monospace" x="408" y=" | ||||
596" fill="black" font-size="1em">r</text> | ||||
<text text-anchor="middle" font-family="monospace" x="336" y=" | ||||
116" fill="black" font-size="1em">A</text> | ||||
<text text-anchor="middle" font-family="monospace" x="120" y=" | ||||
132" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="144" y=" | ||||
260" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="288" y=" | ||||
516" fill="black" font-size="1em">e</text> | ||||
<text text-anchor="middle" font-family="monospace" x="104" y=" | ||||
532" fill="black" font-size="1em">O</text> | ||||
<text text-anchor="middle" font-family="monospace" x="344" y=" | ||||
580" fill="black" font-size="1em">R</text> | ||||
<text text-anchor="middle" font-family="monospace" x="496" y=" | ||||
612" fill="black" font-size="1em">E</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
20" fill="black" font-size="1em">n</text> | ||||
<text text-anchor="middle" font-family="monospace" x="152" y=" | ||||
596" fill="black" font-size="1em">c</text> | ||||
<text text-anchor="middle" font-family="monospace" x="424" y=" | ||||
596" fill="black" font-size="1em">b</text> | ||||
</g> | ||||
</svg> | ||||
</artwork> | ||||
<artwork type="ascii-art" name="" alt="" originalSrc="diagrams/dplpm | ||||
tud-statemachine.txt"><![CDATA[ | ||||
| | | ||||
| Start | PL indicates loss | ||||
| | of connectivity | ||||
v v | ||||
+---------------+ +---------------+ | ||||
| DISABLED | | ERROR | | ||||
+---------------+ PROBE_TIMER expiry: +---------------+ | ||||
| PL indicates PROBE_COUNT = MAX_PROBES or ^ | | ||||
| connectivity PTB: PL_PTB_SIZE < BASE_PLPMTU | | | ||||
+--------------------+ +------------------+ | | ||||
| | | | ||||
v | BASE_PLPMTU Probe | | ||||
+---------------+ acked | | ||||
| BASE |--------------------->+ | ||||
+---------------+ | | ||||
^ | ^ ^ | | ||||
Black hole detected | | | | Black hole detected | | ||||
+--------------------+ | | +--------------------+ | | ||||
| +----+ | | | ||||
| PROBE_TIMER expiry: | | | ||||
| PROBE_COUNT < MAX_PROBES | | | ||||
| | | | ||||
| PMTU_RAISE_TIMER expiry | | | ||||
| +-----------------------------------------+ | | | ||||
| | | | | | ||||
| | v | v | ||||
+---------------+ +---------------+ | ||||
|SEARCH_COMPLETE| | SEARCHING | | ||||
+---------------+ +---------------+ | ||||
| ^ ^ | | ^ | ||||
| | | | | | | ||||
| | +-----------------------------------------+ | | | ||||
| | MAX_PLPMTU Probe acked or | | | ||||
| | PROBE_TIMER expiry: PROBE_COUNT = MAX_PROBES or | | | ||||
+----+ PTB: PL_PTB_SIZE = PLPMTU +----+ | ||||
CONFIRMATION_TIMER expiry: PROBE_TIMER expiry: | ||||
PROBE_COUNT < MAX_PROBES or PROBE_COUNT < MAX_PROBES or | ||||
PLPMTU Probe acked Probe acked or PTB: | ||||
PLPMTU < PL_PTB_SIZE < PROBED_SIZE | ||||
]]></artwork> | ||||
</artset> | ||||
</figure> | ||||
<t/> | ||||
<t>The following states are defined:</t> | ||||
<dl> | ||||
<dt>DISABLED:</dt> | ||||
<dd>The DISABLED state is the initial state before probing has | ||||
started. It is also entered from any other state, when the PL | ||||
indicates loss of connectivity. This state is left once the PL | ||||
indicates connectivity to the remote PL. When transitioning to the | ||||
BASE state, a probe packet of size BASE_PLPMTU can be sent | ||||
immediately.</dd> | ||||
<dt>BASE:</dt> | ||||
<dd> | ||||
<t>The BASE state is used to confirm that the BASE_PLPMTU size is | ||||
supported by the network path and is designed to allow an | ||||
application to continue working when there are transient | ||||
reductions in the actual PMTU. It also seeks to avoid long | ||||
periods when a sender searching for a larger PLPMTU is unaware | ||||
that packets are not being delivered due to a packet or ICMP | ||||
black hole.</t> | ||||
<t>On entry, the PROBED_SIZE is set to the BASE_PLPMTU size, and | ||||
the PROBE_COUNT is set to zero.</t> | ||||
<t>Each time a probe packet is sent, the PROBE_TIMER is started. | ||||
The state is exited when the probe packet is acknowledged, and | ||||
the PL sender enters the SEARCHING state. | ||||
</t> | ||||
<t>The state is also left when the PROBE_COUNT reaches | ||||
MAX_PROBES or a received PTB message is validated. This causes | ||||
the PL sender to enter the ERROR state.</t> | ||||
</dd> | ||||
<dt>SEARCHING:</dt> | ||||
<dd> | ||||
<t>The SEARCHING state is the main probing state. This state is | ||||
entered when probing for the BASE_PLPMTU completes. </t> | ||||
<t>Each time a probe packet is acknowledged, the PROBE_COUNT is | ||||
set to zero, the PLPMTU is set to the PROBED_SIZE, and then the | ||||
PROBED_SIZE is increased using the search algorithm (as described | ||||
in <xref target="searchincrease"/>).</t> | ||||
<t>When a probe packet is sent and not acknowledged within the | ||||
period of the PROBE_TIMER, the PROBE_COUNT is incremented, and | ||||
a new probe packet is transmitted. </t> | ||||
<t> The state is exited to enter SEARCH_COMPLETE when the | ||||
PROBE_COUNT reaches MAX_PROBES, a validated PTB is received that | ||||
corresponds to the last successfully probed size (PL_PTB_SIZE = | ||||
PLPMTU), or a probe of size MAX_PLPMTU is acknowledged (PLPMTU = | ||||
MAX_PLPMTU).</t> | ||||
<t> When a black hole is detected in the SEARCHING state, this cause | ||||
s | ||||
the PL sender to enter the BASE state. </t> | ||||
</dd> | ||||
<dt>SEARCH_COMPLETE:</dt> | ||||
<dd> | ||||
<t> The SEARCH_COMPLETE state indicates that a search has | ||||
completed. This is the normal maintenance state, where the PL is | ||||
not probing to update the PLPMTU. DPLPMTUD remains in this state | ||||
until either the PMTU_RAISE_TIMER expires or a black hole is | ||||
detected. </t> | ||||
<t>When DPLPMTUD uses an unacknowledged PL and is in the | ||||
SEARCH_COMPLETE state, a CONFIRMATION_TIMER periodically resets | ||||
the PROBE_COUNT and schedules a probe packet with the size of the | ||||
PLPMTU. If MAX_PROBES successive PLPMTUD-sized probes fail to be | ||||
acknowledged, the method enters the BASE state. When used with an | ||||
acknowledged PL (e.g., SCTP), DPLPMTUD <bcp14>SHOULD NOT</bcp14> c | ||||
ontinue to | ||||
generate PLPMTU probes in this state.</t> | ||||
</dd> | ||||
<dt>ERROR:</dt> | ||||
<dd> | ||||
<t>The ERROR state represents the case where either the network | ||||
path is not known to support a PLPMTU of at least the BASE_PLPMTU | ||||
size or when there is contradictory information about the network | ||||
path that would otherwise result in excessive variation in the | ||||
MPS signaled to the higher layer. The state implements a method | ||||
to mitigate oscillation in the state-event engine. It signals a | ||||
conservative value of the MPS to the higher layer by the PL. The | ||||
state is exited when packet probes no longer detect the error. | ||||
The PL sender then enters the SEARCHING state. </t> | ||||
<t>Implementations are permitted to enable endpoint | ||||
fragmentation if the DPLPMTUD is unable to validate MIN_PLPMTU | ||||
within PROBE_COUNT probes. If DPLPMTUD is unable to validate | ||||
MIN_PLPMTU, the implementation will transition to the DISABLED | ||||
state.</t> | ||||
<t>Note: MIN_PLPMTU could be identical to BASE_PLPMTU, | ||||
simplifying the actions in this state.</t> | ||||
</dd> | ||||
</dl> | ||||
</section> | ||||
<section anchor="searchincrease"> | ||||
<name>Search to Increase the PLPMTU</name> | ||||
<t>This section describes the algorithms used by DPLPMTUD to search | ||||
for a larger PLPMTU.</t> | ||||
<section anchor="Increase"> | ||||
<name>Probing for a Larger PLPMTU</name> | ||||
<t>Implementations use a search algorithm across the search range to | ||||
determine whether a larger PLPMTU can be supported across a network | ||||
path.</t> | ||||
<t>The method discovers the search range by confirming the minimum | ||||
PLPMTU and then using the probe method to select a PROBED_SIZE less | ||||
than or equal to MAX_PLPMTU. MAX_PLPMTU is the minimum of the local | ||||
MTU and EMTU_R (when this is learned from the remote endpoint). The | ||||
MAX_PLPMTU <bcp14>MAY</bcp14> be reduced by an application that sets a | ||||
maximum to | ||||
the size of datagrams it will send.</t> | ||||
<t> The PROBE_COUNT is initialized to zero when the first probe with | ||||
a size greater than or equal to PLPMTU is sent. Each probe packet | ||||
successfully sent to the remote peer is confirmed by acknowledgment | ||||
at the PL (see <xref target="Probe"/>).</t> | ||||
<t>Each time a probe packet is sent to the destination, the | ||||
PROBE_TIMER is started. The timer is canceled when the PL receives | ||||
acknowledgment that the probe packet has been successfully sent | ||||
across the path (<xref target="Probe"/>). This confirms that the | ||||
PROBED_SIZE is supported, and the PROBED_SIZE value is then assigned | ||||
to the PLPMTU. The search algorithm can continue to send subsequent | ||||
probe packets of an increasing size.</t> | ||||
<t>If the timer expires before a probe packet is acknowledged, the | ||||
probe has failed to confirm the PROBED_SIZE. Each time the | ||||
PROBE_TIMER expires, the PROBE_COUNT is incremented, the PROBE_TIMER | ||||
is reinitialized, and a new probe of the same size or any other size | ||||
(determined by the search algorithm) can be sent. The maximum number | ||||
of consecutive failed probes is configured (MAX_PROBES). If the | ||||
value of the PROBE_COUNT reaches MAX_PROBES, probing will stop, and | ||||
the PL sender enters the SEARCH_COMPLETE state. </t> | ||||
</section> | ||||
<section> | ||||
<name>Selection of Probe Sizes</name> | ||||
<t>The search algorithm determines a minimum useful gain in | ||||
PLPMTU. It would not be constructive for a PL sender to attempt to | ||||
probe for all sizes. This would incur unnecessary load on the path. | ||||
Implementations <bcp14>SHOULD</bcp14> select the set of probe packet | ||||
sizes to maximize the gain in PLPMTU from each search step.</t> | ||||
<t>Implementations could optimize the search procedure by selecting | ||||
step sizes from a table of common PMTU sizes. When selecting the | ||||
appropriate next size to search, an implementer ought to also | ||||
consider that there can be common sizes of MPS that applications | ||||
seek to use, and there could be common sizes of MTU used within the | ||||
network.</t> | ||||
</section> | ||||
<section anchor="Resilience"> | ||||
<name>Resilience to Inconsistent Path Information</name> | ||||
<t>A decision to increase the PLPMTU needs to be resilient to the | ||||
possibility that information learned about the network path is | ||||
inconsistent. A path is inconsistent when, for example, probe | ||||
packets are lost due to other reasons (i.e., not packet size) or due | ||||
to frequent path changes. Frequent path changes could occur by | ||||
unexpected "flapping" -- where some packets from a flow pass along | ||||
one path, but other packets follow a different path with different | ||||
properties.</t> | ||||
<t>A PL sender is able to detect inconsistency either from the sequenc | ||||
e of | ||||
PLPMTU probes that are acknowledged or from the sequence of PTB messag | ||||
es that it | ||||
receives. When inconsistent path information is detected, a PL | ||||
sender could use an alternate search mode that clamps the offered | ||||
MPS to a smaller value for a period of time. This avoids unnecessary | ||||
loss of packets.</t> | ||||
</section> | ||||
</section> | ||||
<section anchor="robustness"> | ||||
<name>Robustness to Inconsistent Paths</name> | ||||
<t>Some paths could be unable to sustain packets of the BASE_PLPMTU | ||||
size. The Error State could be implemented to provide robustness to | ||||
such paths. This allows fallback to a smaller than desired PLPMTU | ||||
rather than suffer connectivity failure. This could utilize methods | ||||
such as endpoint IP fragmentation to enable the PL sender to | ||||
communicate using packets smaller than the BASE_PLPMTU.</t> | ||||
</section> | ||||
</section> | ||||
<section anchor="protocol_specific_methods"> | ||||
<name>Specification of Protocol-Specific Methods</name> | ||||
<t>DPLPMTUD requires protocol-specific details to be specified for each | ||||
PL that is used.</t> | ||||
<t>The first subsection provides guidance on how to implement the | ||||
DPLPMTUD method as a part of an application using UDP or UDP-Lite. The | ||||
guidance also applies to other datagram services that do not include a | ||||
specific transport protocol (such as a tunnel encapsulation). The | ||||
following subsections describe how DPLPMTUD can be implemented as a part | ||||
of the transport service, allowing applications using the service to | ||||
benefit from discovery of the PLPMTU without themselves needing to | ||||
implement this method when using SCTP and QUIC.</t> | ||||
<section> | ||||
<name>Application Support for DPLPMTUD with UDP or UDP-Lite</name> | ||||
<t>The current specifications of UDP <xref target="RFC0768"/> | ||||
and UDP-Lite <xref target="RFC3828"/> do not define a method in | ||||
the RFC series that supports PLPMTUD. In particular, the UDP transport | ||||
does not provide the transport features needed to implement | ||||
datagram PLPMTUD.</t> | ||||
<t>The DPLPMTUD method can be implemented as a part of an application | ||||
built directly or indirectly on UDP or UDP-Lite but relies on | ||||
higher-layer protocol features to implement the method <xref target="BCP | ||||
145"/>.</t> | ||||
<t>Some primitives used by DPLPMTUD might not be available via the | ||||
Datagram API (e.g., the ability to access the PLPMTU from the IP-layer | ||||
cache or to interpret received PTB messages).</t> | ||||
<t> In addition, it is recommended that PMTU discovery is not performed | ||||
by multiple protocol layers. An application <bcp14>SHOULD</bcp14> avoid u | ||||
sing | ||||
DPLPMTUD when the underlying transport system provides this capability. | ||||
A common method for managing the PLPMTU has benefits, both in the | ||||
ability to share state between different processes and in opportunities t | ||||
o | ||||
coordinate probing for different PL instances. </t> | ||||
<section anchor="UDP-REQ"> | ||||
<name>Application Request</name> | ||||
<t>An application needs an application-layer protocol mechanism | ||||
(such as a message acknowledgment method) that solicits a response | ||||
from a destination endpoint. The method <bcp14>SHOULD</bcp14> allow th | ||||
e sender to | ||||
check the value returned in the response to provide additional | ||||
protection from off-path insertion of data <xref target="BCP145"/>. Su | ||||
itable methods include a parameter known | ||||
only to the two endpoints, such as a session ID or initialized | ||||
sequence number.</t> | ||||
</section> | ||||
<section anchor="UDP-Probe"> | ||||
<name>Application Response</name> | ||||
<t>An application needs an application-layer protocol mechanism to | ||||
communicate the response from the destination endpoint. This | ||||
response could indicate successful reception of the probe across the | ||||
path but could also indicate that some (or all packets) have failed | ||||
to reach the destination.</t> | ||||
</section> | ||||
<section anchor="UDP-probing"> | ||||
<name>Sending Application Probe Packets</name> | ||||
<t>A probe packet can carry an application data block, but the | ||||
successful transmission of this data is at risk when used for | ||||
probing. Some applications might prefer to use a probe packet that | ||||
does not carry an application data block to avoid disruption of data | ||||
transfer.</t> | ||||
</section> | ||||
<section> | ||||
<name>Initial Connectivity</name> | ||||
<t>An application that does not have other higher-layer information | ||||
confirming connectivity with the remote peer <bcp14>SHOULD</bcp14> imp | ||||
lement a | ||||
connectivity mechanism using acknowledged probe packets before | ||||
entering the BASE state.</t> | ||||
</section> | ||||
<section> | ||||
<name>Validating the Path</name> | ||||
<t>An application that does not have other higher-layer information | ||||
confirming correct delivery of datagrams <bcp14>SHOULD</bcp14> impleme | ||||
nt the | ||||
CONFIRMATION_TIMER to periodically send probe packets while in the | ||||
SEARCH_COMPLETE state.</t> | ||||
</section> | ||||
<section anchor="udpopt_ptb_handling"> | ||||
<name>Handling of PTB Messages</name> | ||||
<t>An application that is able and wishes to receive PTB messages | ||||
<bcp14>MUST</bcp14> perform ICMP validation as specified in | ||||
<xref target="BCP145" section="5.2" sectionFormat="of" format="default | ||||
"/>. This requires that the application checks | ||||
each received PTB message to validate that it was is received in | ||||
response to transmitted traffic and that the reported PL_PTB_SIZE is | ||||
less than the current probed size (see <xref target="validPTB_SIZE"/>) | ||||
. | ||||
A validated PTB message <bcp14>MAY</bcp14> be used | ||||
as input to the DPLPMTUD algorithm but <bcp14>MUST NOT</bcp14> be used | ||||
directly to | ||||
set the PLPMTU.</t> | ||||
</section> | ||||
</section> | ||||
<section> | ||||
<name>DPLPMTUD for SCTP</name> | ||||
<t><xref target="RFC4821" section="10.2" sectionFormat="of" format="defa | ||||
ult"/> | ||||
specifies a recommended PLPMTUD probing method for SCTP, and | ||||
<xref target="RFC4960" section="7.3" sectionFormat="of" format="default" | ||||
/> | ||||
recommends an endpoint apply the | ||||
techniques in RFC 4821 on a per-destination-address basis. The | ||||
specification for DPLPMTUD continues the practice of using the PL to | ||||
discover the PMTU but updates RFC4960 with a recommendation to use | ||||
the method specified in this document: The <bcp14>RECOMMENDED</bcp14> me | ||||
thod for | ||||
generating probes is to add a chunk consisting only of padding to an | ||||
SCTP message. The PAD chunk defined in <xref target="RFC4820"/> | ||||
<bcp14>SHOULD</bcp14> be attached to a minimum-length HEARTBEAT (HB) chu | ||||
nk to build a | ||||
probe packet. This enables probing without affecting the transfer of | ||||
user messages and without being limited by congestion control or flow | ||||
control. This is preferred to using DATA chunks (with padding as | ||||
required) as path probes.</t> | ||||
<t><xref target="RFC4960" section="6.9" sectionFormat="of" format="defau | ||||
lt"/> | ||||
describes dividing the | ||||
user messages into DATA chunks sent by the PL when using SCTP. This notes | ||||
that once an SCTP message has been sent, it cannot be resegmented. | ||||
<xref target="RFC4960"/> describes the method for retransmitting DATA | ||||
chunks when the MPS has been reduced, and <xref target="RFC4960" section="6.9 | ||||
" sectionFormat="of"/> | ||||
describes use of IP fragmentation for this case. | ||||
This is unchanged by this document.</t> | ||||
<section anchor="sctp_over_ip"> | ||||
<name>SCTP/IPv4 and SCTP/IPv6</name> | ||||
<section> | ||||
<name>Initial Connectivity</name> | ||||
<t>The base protocol is specified in <xref target="RFC4960"/>. This | ||||
provides an acknowledged PL. A | ||||
sender can therefore enter the BASE state as soon as connectivity | ||||
has been confirmed. </t> | ||||
</section> | ||||
<section anchor="sctp_over_ip_probing"> | ||||
<name>Sending SCTP Probe Packets</name> | ||||
<t>Probe packets consist of an SCTP common header followed by a | ||||
HEARTBEAT chunk and a PAD chunk. The PAD chunk is used to control | ||||
the length of the probe packet. The HEARTBEAT chunk is used to | ||||
trigger the sending of a HEARTBEAT ACK chunk. The reception of the | ||||
HEARTBEAT ACK chunk acknowledges reception of a successful | ||||
probe. A successful probe updates the association and path | ||||
counters, but an unsuccessful probe is discounted (assumed | ||||
to be a result of choosing too large a PLPMTU).</t> | ||||
<t>The SCTP sender needs to be able to determine the total size of | ||||
a probe packet. The HEARTBEAT chunk could carry a Heartbeat | ||||
Information parameter that includes, besides the information | ||||
suggested in <xref target="RFC4960"/>, the probe size to help | ||||
an implementation associate a HEARTBEAT ACK with the size of probe | ||||
that was sent. The sender could also use other methods, such as | ||||
sending a nonce and verifying the information returned also | ||||
contains the corresponding nonce. The length of the PAD chunk is | ||||
computed by reducing the probing size by the size of the SCTP | ||||
common header and the HEARTBEAT chunk. The payload of the PAD | ||||
chunk contains arbitrary data. When transmitted at the IP layer, | ||||
the PMTU size also includes the IPv4 or IPv6 header(s).</t> | ||||
<t> Probing can start directly after the PL handshake; this can be | ||||
done before data is sent. Assuming this behavior (i.e., the PMTU | ||||
is smaller than or equal to the interface MTU), this process will | ||||
take several round-trip time periods, dependent on the number of | ||||
DPLPMTUD probes sent. The Heartbeat timer can be used to implement | ||||
the PROBE_TIMER.</t> | ||||
</section> | ||||
<section> | ||||
<name>Validating the Path with SCTP</name> | ||||
<t>Since SCTP provides an acknowledged PL, a sender <bcp14>MUST NOT< | ||||
/bcp14> | ||||
implement the CONFIRMATION_TIMER while in the SEARCH_COMPLETE | ||||
state.</t> | ||||
</section> | ||||
<section anchor="sctp_over_ip_ptb_handling"> | ||||
<name>PTB Message Handling by SCTP</name> | ||||
<t>Normal ICMP validation <bcp14>MUST</bcp14> be performed as specif | ||||
ied in | ||||
<xref target="RFC4960" section="C" sectionFormat="of" format="defaul | ||||
t"/>. | ||||
This requires that the first 8 bytes of the SCTP common header are q | ||||
uoted in the | ||||
payload of the PTB message, which can be the case for ICMPv4 and | ||||
is normally the case for ICMPv6.</t> | ||||
<t>When a PTB message has been validated, the PL_PTB_SIZE | ||||
calculated from the PTB_SIZE reported in the PTB message <bcp14>SHOU | ||||
LD</bcp14> be | ||||
used with the DPLPMTUD algorithm, provided that the reported | ||||
PL_PTB_SIZE is less than the current probe size (see <xref target="m | ||||
echanism-ptb"/>).</t> | ||||
</section> | ||||
</section> | ||||
<section> | ||||
<name>DPLPMTUD for SCTP/UDP</name> | ||||
<t>The UDP encapsulation of SCTP is specified in <xref target="RFC6951 | ||||
"/>.</t> | ||||
<t>This specification updates the reference to RFC 4821 in Section | ||||
<xref target="RFC6951" section="5.6" sectionFormat="bare" format="defa | ||||
ult"/> | ||||
of RFC 6951 to refer to this document (RFC 8899). RFC 6951 is updated | ||||
by the addition of the following sentence at the end of | ||||
Section <xref target="RFC6951" section="5.6" sectionFormat="bare" form | ||||
at="default"/>: </t> | ||||
<blockquote> | ||||
<t>The <bcp14>RECOMMENDED</bcp14> method for determining the MTU of | ||||
the | ||||
path is specified in RFC 8899.</t> | ||||
</blockquote> | ||||
<section> | ||||
<name>Initial Connectivity</name> | ||||
<t>A sender can enter the BASE state as soon as SCTP connectivity | ||||
has been confirmed.</t> | ||||
</section> | ||||
<section anchor="sctp_over_udp_probing"> | ||||
<name>Sending SCTP/UDP Probe Packets</name> | ||||
<t>Packet probing can be performed as specified in <xref target="sct | ||||
p_over_ip_probing"/>. The size of the probe | ||||
packet includes the 8 bytes of UDP header. This has to be | ||||
considered when filling the probe packet with the PAD chunk. </t> | ||||
</section> | ||||
<section> | ||||
<name>Validating the Path with SCTP/UDP</name> | ||||
<t> SCTP provides an acknowledged PL; therefore, a sender does not | ||||
implement the CONFIRMATION_TIMER while in the SEARCH_COMPLETE | ||||
state. </t> | ||||
</section> | ||||
<section anchor="sctp_over_udp_ptb_handling"> | ||||
<name>Handling of PTB Messages by SCTP/UDP</name> | ||||
<t>ICMP validation <bcp14>MUST</bcp14> be performed for PTB messages | ||||
as specified in | ||||
<xref target="RFC4960" section="C" sectionFormat="of" format="defaul | ||||
t"/>. | ||||
This requires that | ||||
the first 8 bytes of the SCTP common header are contained in the | ||||
PTB message, which can be the case for ICMPv4 (but note the UDP | ||||
header also consumes a part of the quoted packet header) and is | ||||
normally the case for ICMPv6. When the validation is completed, the | ||||
PL_PTB_SIZE calculated from the PTB_SIZE in the PTB message <bcp14>S | ||||
HOULD</bcp14> | ||||
be used with the DPLPMTUD providing that the reported PL_PTB_SIZE | ||||
is less than the current probe size.</t> | ||||
</section> | ||||
</section> | ||||
<section> | ||||
<name>DPLPMTUD for SCTP/DTLS</name> | ||||
<t>The Datagram Transport Layer Security (DTLS) encapsulation of SCTP | ||||
is specified in <xref target="RFC8261"/>. This is used for | ||||
data channels in WebRTC implementations. This specification updates | ||||
the reference to RFC 4821 in Section | ||||
<xref target="RFC8261" section="5" sectionFormat="bare" format="defaul | ||||
t"/> | ||||
of RFC 8261 to refer to this document (RFC 8899). | ||||
</t> | ||||
<section> | ||||
<name>Initial Connectivity</name> | ||||
<t>A sender can enter the BASE state as soon as SCTP connectivity | ||||
has been confirmed.</t> | ||||
</section> | ||||
<section anchor="sctp_over_dtls_probing"> | ||||
<name>Sending SCTP/DTLS Probe Packets</name> | ||||
<t>Packet probing can be done as specified in <xref target="sctp_ove | ||||
r_ip_probing"/>. The maximum payload is | ||||
reduced by the size of the DTLS headers, which has to be considered | ||||
when filling the PAD chunk. The size of the probe packet includes | ||||
the DTLS PL headers. This has to be considered when filling the | ||||
probe packet with the PAD chunk. </t> | ||||
</section> | ||||
<section> | ||||
<name>Validating the Path with SCTP/DTLS</name> | ||||
<t>Since SCTP provides an acknowledged PL, a sender <bcp14>MUST NOT< | ||||
/bcp14> | ||||
implement the CONFIRMATION_TIMER while in the SEARCH_COMPLETE | ||||
state.</t> | ||||
</section> | ||||
<section anchor="sctp_over_dtls_ptb_handling"> | ||||
<name>Handling of PTB Messages by SCTP/DTLS</name> | ||||
<t><xref target="RFC4960"/> does not specify a way to | ||||
validate SCTP/DTLS ICMP message payload and neither does this | ||||
document. This can prevent processing of PTB messages at the | ||||
PL.</t> | ||||
</section> | ||||
</section> | ||||
</section> | ||||
<section> | ||||
<name>DPLPMTUD for QUIC</name> | ||||
<t>QUIC <xref target="I-D.ietf-quic-transport"/> is a UDP-based | ||||
PL that provides reception feedback. The UDP payload includes a QUIC | ||||
packet header, a protected payload, and any authentication fields. It | ||||
supports padding and packet coalescence that can be used to construct | ||||
probe packets. From the perspective of DPLPMTUD, QUIC can function as | ||||
an acknowledged PL. <xref target="I-D.ietf-quic-transport"/> | ||||
describes the method for using DPLPMTUD with QUIC packets.</t> | ||||
</section> | ||||
</section> | ||||
<section anchor="IANA"> | ||||
<name>IANA Considerations</name> | ||||
<t>This document has no IANA actions.</t> | ||||
</section> | ||||
<section anchor="Security"> | ||||
<name>Security Considerations</name> | ||||
<t>The security considerations for the use of UDP and SCTP are provided | ||||
in the referenced RFCs.</t> | ||||
<t> To avoid excessive load, the interval between individual probe packets | ||||
<bcp14>MUST</bcp14> be at least one RTT, and the interval between rounds o | ||||
f probing is | ||||
determined by the PMTU_RAISE_TIMER. </t> | ||||
<t>A PL sender needs to ensure that the method used to confirm reception | ||||
of probe packets protects from off-path attackers injecting | ||||
packets into the path. This protection is provided in IETF-defined | ||||
protocols (e.g., TCP, SCTP) using a randomly initialized sequence | ||||
number. A description of one way to do this when using UDP is provided | ||||
in Section | ||||
<xref target="BCP145" section="5.1" sectionFormat="bare" format="default"/ | ||||
> | ||||
of <xref target="BCP145"/>).</t> | ||||
<t>There are cases where ICMP Packet Too Big (PTB) messages are not | ||||
delivered due to policy, configuration, or equipment design | ||||
(see <xref target="Classic-PMTUD"/>). This method therefore does not rely | ||||
upon PTB messages being received but is able to utilize these when they | ||||
are received by the sender. PTB messages could potentially be used to | ||||
cause a node to inappropriately reduce the PLPMTU. A node supporting | ||||
DPLPMTUD <bcp14>MUST</bcp14> therefore appropriately validate the payload | ||||
of PTB | ||||
messages to ensure these are received in response to transmitted traffic | ||||
(i.e., a reported error condition that corresponds to a datagram | ||||
actually sent by the path layer, see <xref target="PTB"/>).</t> | ||||
<t>An on-path attacker able to create a PTB message could forge PTB | ||||
messages that include a valid quoted IP packet. Such an attack could be | ||||
used to drive down the PLPMTU. An on-path device could similarly force a | ||||
reduction of the PLPMTU by implementing a policy that drops packets | ||||
larger than a configured size. There are two ways this method can be | ||||
mitigated against such attacks: first, by ensuring that a PL sender never | ||||
reduces the PLPMTU below the base size solely in response to receiving a | ||||
PTB message. This is achieved by first entering the BASE state when such | ||||
a message is received. Second, the design does not require processing of | ||||
PTB messages; a PL sender could therefore suspend processing of PTB | ||||
messages (e.g., in a robustness mode after detecting that subsequent | ||||
probes actually confirm that a size larger than the PTB_SIZE is supported | ||||
by a path).</t> | ||||
<t>Parsing the quoted packet inside a PTB message can | ||||
introduce additional per-packet processing at the PL sender. | ||||
This processing <bcp14>SHOULD</bcp14> be limited to avoid a | ||||
denial-of-service attack when arbitrary headers are included. Rate-limitin | ||||
g | ||||
the processing could result in PTB messages not being | ||||
received by a PL; however, the DPLPMTUD method is robust to such | ||||
loss.</t> | ||||
<t>The successful processing of an ICMP message can trigger a probe | ||||
when the reported PTB size is valid, but this does not | ||||
directly update the PLPMTU for the path. This prevents a message | ||||
attempting to black hole data by indicating a size larger than | ||||
supported by the path.</t> | ||||
<t>It is possible that the information about a path is not stable. This | ||||
could be a result of forwarding across more than one path that has a | ||||
different actual PMTU or a single path presents a varying PMTU. The | ||||
design of a PLPMTUD implementation <bcp14>SHOULD</bcp14> consider how to m | ||||
itigate the | ||||
effects of varying path information. One possible mitigation is to | ||||
provide robustness (see <xref target="robustness"/>) in the method | ||||
that avoids oscillation in the MPS.</t> | ||||
<t> | ||||
DPLPMTUD methods can introduce padding data to inflate the length | ||||
of the datagram to the total size required for a probe packet. The | ||||
total size of a probe packet includes all headers and padding added | ||||
to the payload data being sent (e.g., including security-related | ||||
fields such as an AEAD tag and TLS record layer padding). The value | ||||
of the padding data does not influence the DPLPMTUD search algorithm, | ||||
and therefore needs to be set consistent with the policy of the PL. | ||||
</t> | ||||
<t> If a PL can make use of cryptographic confidentiality or | ||||
data-integrity mechanisms, then the design ought to avoid adding anything | ||||
(e.g., padding) to DPLPMTUD probe packets that is not also protected by | ||||
those cryptographic mechanisms. </t> | ||||
</section> | ||||
</middle> | ||||
<back> | ||||
<displayreference target="I-D.ietf-intarea-tunnels" to="TUNNELS"/> | ||||
<displayreference target="I-D.ietf-quic-transport" to="QUIC"/> | ||||
<references> | ||||
<name>References</name> | ||||
<references> | ||||
<name>Normative References</name> | ||||
<reference anchor='BCP145' target='https://www.rfc-editor.org/info/bcp145'> | ||||
<front> | ||||
<title>UDP Usage Guidelines</title> | ||||
<author initials='L.' surname='Eggert' fullname='L. Eggert'><organization /> | ||||
</author> | ||||
<author initials='G.' surname='Fairhurst' fullname='G. Fairhurst'><organizat | ||||
ion /></author> | ||||
<author initials='G.' surname='Shepherd' fullname='G. Shepherd'><organizatio | ||||
n /></author> | ||||
<date year='2017' month='March' /> | ||||
</front> | ||||
<seriesInfo name='BCP' value='145'/> | ||||
<seriesInfo name='RFC' value='8085'/> | ||||
</reference> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.0768.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.0791.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.1191.xml"/> | ||||
<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.3828.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4820.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4960.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.6951.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.8200.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.8201.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.8261.xml"/> | ||||
</references> | ||||
<references> | ||||
<name>Informative References</name> | ||||
<reference anchor='RFC8900' target='https://www.rfc-editor.org/info/rfc8900'> | ||||
<front> | ||||
<title>IP Fragmentation Considered Fragile</title> | ||||
<author initials='R' surname='Bonica' fullname='Ron Bonica'> | ||||
<organization /> | ||||
</author> | ||||
<author initials='F' surname='Baker' fullname='Fred Baker'> | ||||
<organization /> | ||||
</author> | ||||
<author initials='G' surname='Huston' fullname='Geoff Huston'> | ||||
<organization /> | ||||
</author> | ||||
<author initials='R' surname='Hinden' fullname='Robert M. Hinden'> | ||||
<organization /> | ||||
</author> | ||||
<author initials='O' surname='Troan' fullname='Ole Troan'> | ||||
<organization /> | ||||
</author> | ||||
<author initials='F' surname='Gont' fullname='Fernando Gont'> | ||||
<organization /> | ||||
</author> | ||||
<date month='September' year='2020' /> | ||||
</front> | ||||
<seriesInfo name="RFC" value="8900"/> | ||||
<seriesInfo name="BCP" value="230"/> | ||||
</reference> | ||||
<xi:include href="https://datatracker.ietf.org/doc/bibxml3/reference.I-D | ||||
.draft-ietf-intarea-tunnels.xml"/> | ||||
<reference anchor="I-D.ietf-quic-transport"> | ||||
<front> | ||||
<title>QUIC: A UDP-Based Multiplexed and Secure Transport</title> | ||||
<author initials="J" surname="Iyengar" fullname="Jana Iyengar" role="editor"> | ||||
<organization/> | ||||
</author> | ||||
<author initials="M" surname="Thomson" fullname="Martin Thomson" role="editor"> | ||||
<organization/> | ||||
</author> | ||||
<date month="June" day="10" year="2020"/> | ||||
</front> | ||||
<seriesInfo name="Internet-Draft" value="draft-ietf-quic-transport-29"/> | ||||
</reference> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.0792.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.1122.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.1812.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.2923.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4340.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4443.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4821.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.4890.xml"/> | ||||
<xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
ence.RFC.5508.xml"/> | ||||
</references> | ||||
</references> | ||||
<section anchor="Acknowledgments" numbered="false"> | ||||
<name>Acknowledgments</name> | ||||
<t>This work was partially funded by the European Union Horizon 2020 | ||||
Research and Innovation Programme under grant agreement No. 644334, | ||||
"A New, Evolutive API and Transport-Layer Architecture for the Internet" | ||||
(NEAT). The views expressed are solely those of the author(s).</t> | ||||
<t> | ||||
Thanks to all who have commented or contributed, the TSVWG and QUIC | ||||
working groups, and <contact fullname="Mathew Calder"/> and | ||||
<contact fullname="Julius Flohr"/> for providing early | ||||
implementations. | ||||
</t> | ||||
</section> | ||||
</back> | ||||
</rfc> | ||||
End of changes. 1 change blocks. | ||||
lines changed or deleted | lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |