draft-thornburgh-adobe-rtmfp-10.txt   rfc7016.txt 
Network Working Group M. Thornburgh Internet Engineering Task Force (IETF) M. Thornburgh
Internet-Draft Adobe Request for Comments: 7016 Adobe
Intended status: Informational July 10, 2013 Category: Informational November 2013
Expires: January 11, 2014 ISSN: 2070-1721
Adobe's Secure Real-Time Media Flow Protocol Adobe's Secure Real-Time Media Flow Protocol
draft-thornburgh-adobe-rtmfp-10
Abstract Abstract
This memo describes Adobe's Secure Real-Time Media Flow Protocol This memo describes Adobe's Secure Real-Time Media Flow Protocol
(RTMFP), an endpoint-to-endpoint communication protocol designed to (RTMFP), an endpoint-to-endpoint communication protocol designed to
securely transport parallel flows of real-time video, audio, and data securely transport parallel flows of real-time video, audio, and data
messages, as well as bulk data, over IP networks. RTMFP has features messages, as well as bulk data, over IP networks. RTMFP has features
making it effective for peer-to-peer (P2P) as well as client-server that make it effective for peer-to-peer (P2P) as well as client-
communications, even when Network Address Translators (NATs) are server communications, even when Network Address Translators (NATs)
used. are used.
Status of this Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This document is not an Internet Standards Track specification; it is
provisions of BCP 78 and BCP 79. This document may not be modified, published for informational purposes.
and derivative works of it may not be created, except to format it
for publication as an RFC or to translate it into languages other
than English.
Internet-Drafts are working documents of the Internet Engineering This document is a product of the Internet Engineering Task Force
Task Force (IETF). Note that other groups may also distribute (IETF). It has been approved for publication by the Internet
working documents as Internet-Drafts. The list of current Internet- Engineering Steering Group (IESG). Not all documents approved by the
Drafts is at http://datatracker.ietf.org/drafts/current/. IESG are a candidate for any level of Internet Standard; see Section
2 of RFC 5741.
Internet-Drafts are draft documents valid for a maximum of six months Information about the current status of this document, any errata,
and may be updated, replaced, or obsoleted by other documents at any and how to provide feedback on it may be obtained at
time. It is inappropriate to use Internet-Drafts as reference http://www.rfc-editor.org/info/rfc7016.
material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 11, 2014. IESG Note
This document represents technology developed outside the processes
of the IETF and the IETF community has determined that it is useful
to publish it as an RFC in its current form. It is a product of the
IETF only in that it has received public review and has been approved
for publication by the Internet Engineering Steering Group (IESG),
but the content of the document does not represent a consensus of the
IETF.
Copyright Notice Copyright Notice
Copyright (c) 2013 IETF Trust and the persons identified as the Copyright (c) 2013 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of (http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
This document may not be modified, and derivative works of it may not
be created, except to format it for publication as an RFC or to
translate it into languages other than English.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 5 1. Introduction ....................................................5
1.1. Design Highlights of RTMFP . . . . . . . . . . . . . . . 6 1.1. Design Highlights of RTMFP .................................6
1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 7 1.2. Terminology ................................................7
2. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2. Syntax ..........................................................8
2.1. Common Elements . . . . . . . . . . . . . . . . . . . . . 8 2.1. Common Elements ............................................8
2.1.1. Elementary Types and Constructs . . . . . . . . . . . 8 2.1.1. Elementary Types and Constructs .....................8
2.1.2. Variable Length Unsigned Integer (VLU) . . . . . . . 9 2.1.2. Variable Length Unsigned Integer (VLU) .............10
2.1.3. Option . . . . . . . . . . . . . . . . . . . . . . . 10 2.1.3. Option .............................................10
2.1.4. Option List . . . . . . . . . . . . . . . . . . . . . 11 2.1.4. Option List ........................................11
2.1.5. Internet Socket Address (Address) . . . . . . . . . . 12 2.1.5. Internet Socket Address (Address) ..................12
2.2. Network Layer . . . . . . . . . . . . . . . . . . . . . . 13 2.2. Network Layer .............................................13
2.2.1. Encapsulation . . . . . . . . . . . . . . . . . . . . 13 2.2.1. Encapsulation ......................................13
2.2.2. Multiplex . . . . . . . . . . . . . . . . . . . . . . 13 2.2.2. Multiplex ..........................................13
2.2.3. Encryption . . . . . . . . . . . . . . . . . . . . . 14 2.2.3. Encryption .........................................14
2.2.4. Packet . . . . . . . . . . . . . . . . . . . . . . . 15 2.2.4. Packet .............................................15
2.3. Chunks . . . . . . . . . . . . . . . . . . . . . . . . . 18 2.3. Chunks ....................................................18
2.3.1. Packet Fragment Chunk . . . . . . . . . . . . . . . . 20 2.3.1. Packet Fragment Chunk ..............................20
2.3.2. Initiator Hello Chunk (IHello) . . . . . . . . . . . 21 2.3.2. Initiator Hello Chunk (IHello) .....................21
2.3.3. Forwarded Initiator Hello Chunk (FIHello) . . . . . . 21 2.3.3. Forwarded Initiator Hello Chunk (FIHello) ..........22
2.3.4. Responder Hello Chunk (RHello) . . . . . . . . . . . 22 2.3.4. Responder Hello Chunk (RHello) .....................23
2.3.5. Responder Redirect Chunk (Redirect) . . . . . . . . . 23 2.3.5. Responder Redirect Chunk (Redirect) ................24
2.3.6. RHello Cookie Change Chunk . . . . . . . . . . . . . 25 2.3.6. RHello Cookie Change Chunk .........................26
2.3.7. Initiator Initial Keying Chunk (IIKeying) . . . . . . 26 2.3.7. Initiator Initial Keying Chunk (IIKeying) ..........27
2.3.8. Responder Initial Keying Chunk (RIKeying) . . . . . . 27 2.3.8. Responder Initial Keying Chunk (RIKeying) ..........29
2.3.9. Ping Chunk . . . . . . . . . . . . . . . . . . . . . 29 2.3.9. Ping Chunk .........................................31
2.3.10. Ping Reply Chunk . . . . . . . . . . . . . . . . . . 30 2.3.10. Ping Reply Chunk ..................................32
2.3.11. User Data Chunk . . . . . . . . . . . . . . . . . . . 30 2.3.11. User Data Chunk ...................................33
2.3.11.1. Options for User Data . . . . . . . . . . . . . 32 2.3.11.1. Options for User Data ....................35
2.3.11.1.1. User's Per-Flow Metadata . . . . . . . . . . 33 2.3.11.1.1. User's Per-Flow Metadata ......35
2.3.11.1.2. Return Flow Association . . . . . . . . . . 33 2.3.11.1.2. Return Flow Association .......36
2.3.12. Next User Data Chunk . . . . . . . . . . . . . . . . 34 2.3.12. Next User Data Chunk ..............................37
2.3.13. Data Acknowledgement Bitmap Chunk (Bitmap Ack) . . . 36 2.3.13. Data Acknowledgement Bitmap Chunk (Bitmap Ack) ....39
2.3.14. Data Acknowledgement Ranges Chunk (Range Ack) . . . . 38 2.3.14. Data Acknowledgement Ranges Chunk (Range Ack) .....41
2.3.15. Buffer Probe Chunk . . . . . . . . . . . . . . . . . 40 2.3.15. Buffer Probe Chunk ................................43
2.3.16. Flow Exception Report Chunk . . . . . . . . . . . . . 41 2.3.16. Flow Exception Report Chunk .......................43
2.3.17. Session Close Request Chunk (Close) . . . . . . . . . 42 2.3.17. Session Close Request Chunk (Close) ...............44
2.3.18. Session Close Acknowledgement Chunk (Close Ack) . . . 42 2.3.18. Session Close Acknowledgement Chunk (Close Ack) ...44
3. Operation . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3. Operation ......................................................45
3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 43 3.1. Overview ..................................................45
3.2. Endpoint Identity . . . . . . . . . . . . . . . . . . . . 44 3.2. Endpoint Identity .........................................46
3.3. Packet Multiplex . . . . . . . . . . . . . . . . . . . . 46 3.3. Packet Multiplex ..........................................48
3.4. Packet Fragmentation . . . . . . . . . . . . . . . . . . 46 3.4. Packet Fragmentation ......................................48
3.5. Sessions . . . . . . . . . . . . . . . . . . . . . . . . 48 3.5. Sessions ..................................................50
3.5.1. Startup . . . . . . . . . . . . . . . . . . . . . . . 50 3.5.1. Startup ............................................53
3.5.1.1. Normal Handshake . . . . . . . . . . . . . . . . 50 3.5.1.1. Normal Handshake ..........................53
3.5.1.1.1. Initiator . . . . . . . . . . . . . . . . . 51 3.5.1.1.1. Initiator ......................54
3.5.1.1.2. Responder . . . . . . . . . . . . . . . . . 53 3.5.1.1.2. Responder ......................55
3.5.1.2. Cookie Change . . . . . . . . . . . . . . . . . 55 3.5.1.2. Cookie Change .............................57
3.5.1.3. Glare . . . . . . . . . . . . . . . . . . . . . 57 3.5.1.3. Glare .....................................59
3.5.1.4. Redirector . . . . . . . . . . . . . . . . . . . 58 3.5.1.4. Redirector ................................60
3.5.1.5. Forwarder . . . . . . . . . . . . . . . . . . . 59 3.5.1.5. Forwarder .................................61
3.5.1.6. Redirector and Forwarder with NAT . . . . . . . 61 3.5.1.6. Redirector and Forwarder with NAT .........63
3.5.1.7. Load Distribution and Fault Tolerance . . . . . 64 3.5.1.7. Load Distribution and Fault Tolerance .....66
3.5.2. Congestion Control . . . . . . . . . . . . . . . . . 65 3.5.2. Congestion Control .................................67
3.5.2.1. Time Critical Reverse Notification . . . . . . . 66 3.5.2.1. Time Critical Reverse Notification ........68
3.5.2.2. Retransmission Timeout . . . . . . . . . . . . . 66 3.5.2.2. Retransmission Timeout ....................68
3.5.2.3. Burst Avoidance . . . . . . . . . . . . . . . . 68 3.5.2.3. Burst Avoidance ...........................71
3.5.3. Address Mobility . . . . . . . . . . . . . . . . . . 69 3.5.3. Address Mobility ...................................71
3.5.4. Ping . . . . . . . . . . . . . . . . . . . . . . . . 69 3.5.4. Ping ...............................................72
3.5.4.1. Keepalive . . . . . . . . . . . . . . . . . . . 70 3.5.4.1. Keepalive .................................72
3.5.4.2. Address Mobility . . . . . . . . . . . . . . . . 70 3.5.4.2. Address Mobility ..........................73
3.5.4.3. Path MTU Discovery . . . . . . . . . . . . . . . 71 3.5.4.3. Path MTU Discovery ........................74
3.5.5. Close . . . . . . . . . . . . . . . . . . . . . . . . 71 3.5.5. Close ..............................................74
3.6. Flows . . . . . . . . . . . . . . . . . . . . . . . . . . 72 3.6. Flows .....................................................75
3.6.1. Overview . . . . . . . . . . . . . . . . . . . . . . 72 3.6.1. Overview ...........................................75
3.6.1.1. Identity . . . . . . . . . . . . . . . . . . . . 73 3.6.1.1. Identity ..................................75
3.6.1.2. Messages and Sequencing . . . . . . . . . . . . 73 3.6.1.2. Messages and Sequencing ...................76
3.6.1.3. Lifetime . . . . . . . . . . . . . . . . . . . . 74 3.6.1.3. Lifetime ..................................77
3.6.2. Sender . . . . . . . . . . . . . . . . . . . . . . . 75
3.6.2.1. Startup . . . . . . . . . . . . . . . . . . . . 77 3.6.2. Sender .............................................78
3.6.2.2. Queuing Data . . . . . . . . . . . . . . . . . . 78 3.6.2.1. Startup ...................................80
3.6.2.3. Sending Data . . . . . . . . . . . . . . . . . . 78 3.6.2.2. Queuing Data ..............................80
3.6.2.3.1. Startup Options . . . . . . . . . . . . . . 80 3.6.2.3. Sending Data ..............................81
3.6.2.3.2. Send Next Data . . . . . . . . . . . . . . . 80 3.6.2.3.1. Startup Options ................83
3.6.2.4. Processing Acknowledgements . . . . . . . . . . 81 3.6.2.3.2. Send Next Data .................83
3.6.2.5. Negative Acknowledgement and Loss . . . . . . . 81 3.6.2.4. Processing Acknowledgements ...............83
3.6.2.6. Timeout . . . . . . . . . . . . . . . . . . . . 82 3.6.2.5. Negative Acknowledgement and Loss .........84
3.6.2.7. Abandoning Data . . . . . . . . . . . . . . . . 83 3.6.2.6. Timeout ...................................85
3.6.2.7.1. Forward Sequence Number Update . . . . . . . 83 3.6.2.7. Abandoning Data ...........................86
3.6.2.8. Examples . . . . . . . . . . . . . . . . . . . . 84 3.6.2.7.1. Forward Sequence Number
3.6.2.9. Flow Control . . . . . . . . . . . . . . . . . . 85 Update .........................86
3.6.2.9.1. Buffer Probe . . . . . . . . . . . . . . . . 86 3.6.2.8. Examples ..................................87
3.6.2.10. Exception . . . . . . . . . . . . . . . . . . . 86 3.6.2.9. Flow Control ..............................89
3.6.2.11. Close . . . . . . . . . . . . . . . . . . . . . 86 3.6.2.9.1. Buffer Probe ...................89
3.6.3. Receiver . . . . . . . . . . . . . . . . . . . . . . 87 3.6.2.10. Exception ................................89
3.6.3.1. Startup . . . . . . . . . . . . . . . . . . . . 89 3.6.2.11. Close ....................................90
3.6.3.2. Receiving Data . . . . . . . . . . . . . . . . . 90 3.6.3. Receiver ...........................................90
3.6.3.3. Buffering and Delivering Data . . . . . . . . . 92 3.6.3.1. Startup ...................................93
3.6.3.4. Acknowledging Data . . . . . . . . . . . . . . . 94 3.6.3.2. Receiving Data ............................94
3.6.3.4.1. Timing . . . . . . . . . . . . . . . . . . . 94 3.6.3.3. Buffering and Delivering Data .............95
3.6.3.4.2. Size and Truncation . . . . . . . . . . . . 95 3.6.3.4. Acknowledging Data ........................97
3.6.3.4.3. Constructing . . . . . . . . . . . . . . . . 96 3.6.3.4.1. Timing .........................98
3.6.3.4.4. Delayed Acknowledgement . . . . . . . . . . 96 3.6.3.4.2. Size and Truncation ............99
3.6.3.4.5. Obligatory Acknowledgement . . . . . . . . . 96 3.6.3.4.3. Constructing ...................99
3.6.3.4.6. Opportunistic Acknowledgement . . . . . . . 97 3.6.3.4.4. Delayed Acknowledgement .......100
3.6.3.4.7. Example . . . . . . . . . . . . . . . . . . 97 3.6.3.4.5. Obligatory Acknowledgement ....100
3.6.3.5. Flow Control . . . . . . . . . . . . . . . . . . 98 3.6.3.4.6. Opportunistic
3.6.3.6. Receiving a Buffer Probe . . . . . . . . . . . . 99 Acknowledgement ...............100
3.6.3.7. Rejecting a Flow . . . . . . . . . . . . . . . . 100 3.6.3.4.7. Example .......................101
3.6.3.8. Close . . . . . . . . . . . . . . . . . . . . . 100 3.6.3.5. Flow Control .............................102
4. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 101 3.6.3.6. Receiving a Buffer Probe .................103
5. Security Considerations . . . . . . . . . . . . . . . . . . . 101 3.6.3.7. Rejecting a Flow .........................103
6. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 103 3.6.3.8. Close ....................................104
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 103 4. IANA Considerations ...........................................104
7.1. Normative References . . . . . . . . . . . . . . . . . . 103 5. Security Considerations .......................................105
7.2. Informative References . . . . . . . . . . . . . . . . . 103 6. Acknowledgements ..............................................106
Appendix A. Example Congestion Control Algorithm . . . . . . . . 104 7. References ....................................................107
A.1. Discussion . . . . . . . . . . . . . . . . . . . . . . . 104 7.1. Normative References .....................................107
A.2. Algorithm . . . . . . . . . . . . . . . . . . . . . . . . 105 7.2. Informative References ...................................107
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 108 Appendix A. Example Congestion Control Algorithm .................108
A.1. Discussion ................................................108
A.2. Algorithm .................................................110
1. Introduction 1. Introduction
Adobe's Secure Real-Time Media Flow Protocol (RTMFP) is intended for Adobe's Secure Real-Time Media Flow Protocol (RTMFP) is intended for
use as a general purpose endpoint-to-endpoint data transport service use as a general purpose endpoint-to-endpoint data transport service
in IP networks. It has features that make it well suited to the in IP networks. It has features that make it well suited to the
transport of real-time media (such as low-delay video, audio, and transport of real-time media (such as low-delay video, audio, and
data) as well as bulk data, and for client-server as well as peer-to- data) as well as bulk data, and for client-server as well as peer-to-
peer (P2P) communication. These features include independent peer (P2P) communication. These features include independent
parallel message flows which may have different delivery priorities, parallel message flows that may have different delivery priorities,
variable message reliability (from TCP-like full reliability to UDP- variable message reliability (from TCP-like full reliability to
like best effort), multi-point congestion control, and built-in UDP-like best effort), multi-point congestion control, and built-in
security. Session multiplexing and facilities to support UDP hole- security. Session multiplexing and facilities to support UDP
punching simplify Network Address Translator (NAT) traversal in peer- hole-punching simplify Network Address Translator (NAT) traversal in
to-peer systems. peer-to-peer systems.
RTMFP is implemented in Flash Player, Adobe Integrated Runtime (AIR), RTMFP is implemented in Flash Player, Adobe Integrated Runtime (AIR),
and Adobe Media Server (AMS, formerly Flash Media Server or FMS), all and Adobe Media Server (AMS, formerly Flash Media Server or FMS), all
from Adobe Systems Incorporated, and is used as the foundation from Adobe Systems Incorporated, and is used as the foundation
transport protocol for real-time video, audio, and data transport protocol for real-time video, audio, and data
communication, both client-server and P2P, in those products. At the communication, both client-server and P2P, in those products. At the
time of writing, the Adobe Flash Player runtime is installed on more time of writing, the Adobe Flash Player runtime is installed on more
than one billion end-user desktop computers. than one billion end-user desktop computers.
RTMFP was developed by Adobe Systems Incorporated, and is not the RTMFP was developed by Adobe Systems Incorporated and is not the
product of an IETF activity. product of an IETF activity.
This memo describes the syntax and operation of the Secure Real-Time This memo describes the syntax and operation of the Secure Real-Time
Media Flow Protocol. Media Flow Protocol.
This memo describes a general security framework that, when combined This memo describes a general security framework that, when combined
with an application-specific Cryptography Profile, can be used to with an application-specific Cryptography Profile, can be used to
establish a confidential and authenticated session between endpoints. establish a confidential and authenticated session between endpoints.
The application-specific Cryptography Profile, not defined herein, The application-specific Cryptography Profile, not defined herein,
would detail the specific cryptographic algorithms, data formats, and would detail the specific cryptographic algorithms, data formats, and
semantics to be used within this framework. Interoperation between semantics to be used within this framework. Interoperation between
applications of RTMFP requires common or compatible Cryptography applications of RTMFP requires common or compatible Cryptography
Profiles. Profiles.
Note to implementers: at the time of writing, the Cryptography Note to implementers: at the time of writing, the Cryptography
Profile used by the above mentioned Adobe products is not publicly Profile used by the above-mentioned Adobe products is not publicly
described by Adobe. Implementers should investigate the availability described by Adobe. Implementers should investigate the availability
of documentation of that Cryptography Profile prior to implementing of documentation of that Cryptography Profile prior to implementing
RTMFP for the purpose of interoperation with the above mentioned RTMFP for the purpose of interoperation with the above-mentioned
Adobe products. Adobe products.
1.1. Design Highlights of RTMFP 1.1. Design Highlights of RTMFP
Between any pair of communicating endpoints is a single, Between any pair of communicating endpoints is a single,
bidirectional, secured, congestion controlled session. bidirectional, secured, congestion controlled session.
Unidirectional flows convey messages from one end to the other within Unidirectional flows convey messages from one end to the other within
the session. An endpoint can have concurrent sessions with multiple the session. An endpoint can have concurrent sessions with multiple
other far endpoints. other far endpoints.
Design highlights of RTMFP include: Design highlights of RTMFP include the following:
o The security framework is an inherent part of the basic protocol. o The security framework is an inherent part of the basic protocol.
The application designer chooses the cryptographic formats and The application designer chooses the cryptographic formats and
algorithms to suit the needs of the application, and may update algorithms to suit the needs of the application, and may update
them as the state of the security arts progresses. them as the state of the security arts progresses.
o Cryptographic Endpoint Discriminators can resist port scanning. o Cryptographic Endpoint Discriminators can resist port scanning.
o All header, control, and framing information, except for network o All header, control, and framing information, except for network
addressing information and a session identifier, is encrypted addressing information and a session identifier, is encrypted
skipping to change at page 6, line 48 skipping to change at page 6, line 48
o Messages of any size may be sent with full, partial, or no o Messages of any size may be sent with full, partial, or no
reliability (sender's choice). Messages may be delivered to the reliability (sender's choice). Messages may be delivered to the
receiving user in original queuing order or network arrival order receiving user in original queuing order or network arrival order
(receiver's choice). (receiver's choice).
o Flows are named with arbitrary, user-defined metadata o Flows are named with arbitrary, user-defined metadata
(Section 2.3.11.1.1) rather than port or stream numbers. (Section 2.3.11.1.1) rather than port or stream numbers.
o The sequence numbers of each flow are independent of all other o The sequence numbers of each flow are independent of all other
flows, and are not permanently bound to a session-wide flows and are not permanently bound to a session-wide transmission
transmission ordering. This allows real-time priority decisions ordering. This allows real-time priority decisions to be made at
to be made at transmission or retransmission time. transmission or retransmission time.
o Each flow has its own receive window, and therefore independent o Each flow has its own receive window and, therefore, independent
flow control. flow control.
o Round-trips are expensive, and are minimized or eliminated when o Round trips are expensive and are minimized or eliminated when
possible. possible.
o After a session is established, flows begin by sending the flow's o After a session is established, flows begin by sending the flow's
messages with no additional handshake (and associated round- messages with no additional handshake (and associated round
trips). trips).
o Transmitting bytes on the network is much more expensive than o Transmitting bytes on the network is much more expensive than
moving bytes in a CPU or memory. Wasted bytes are minimized or moving bytes in a CPU or memory. Wasted bytes are minimized or
eliminated when possible and practical, and variable length eliminated when possible and practical, and variable length
encodings are used, even at the expense of breaking 32-bit encodings are used, even at the expense of breaking 32-bit
alignment and making the text diagrams in this specification look alignment and making the text diagrams in this specification look
awkward. awkward.
o P2P lookup and peer introduction (including UDP hole punching for o P2P lookup and peer introduction (including UDP hole-punching for
NAT and firewall traversal) is supported directly by the session NAT and firewall traversal) are supported directly by the session
startup handshake. startup handshake.
o Session identifiers allow an endpoint to multiplex many sessions o Session identifiers allow an endpoint to multiplex many sessions
over a single local transport address while allowing sessions to over a single local transport address while allowing sessions to
survive changes in transport address (as may happen in mobile or survive changes in transport address (as may happen in mobile or
wireless deployments). wireless deployments).
The syntax of the protocol is detailed in Section 2. The operation The syntax of the protocol is detailed in Section 2. The operation
of the protocol is detailed in Section 3. of the protocol is detailed in Section 3.
skipping to change at page 8, line 15 skipping to change at page 8, line 27
necessarily imply field alignment on a multiple of the ruler width. necessarily imply field alignment on a multiple of the ruler width.
Unless specified otherwise, reserved fields SHOULD be set to 0 by a Unless specified otherwise, reserved fields SHOULD be set to 0 by a
sender and MUST be ignored by a receiver. sender and MUST be ignored by a receiver.
The procedural syntax of this specification defines correct and The procedural syntax of this specification defines correct and
error-free encoded inputs to a parser. The procedural syntax does error-free encoded inputs to a parser. The procedural syntax does
not describe a fully featured parser, including error detection and not describe a fully featured parser, including error detection and
handling. Implementations MUST include means to identify error handling. Implementations MUST include means to identify error
circumstances, including truncations causing elementary or composed circumstances, including truncations causing elementary or composed
types to not fit inside containing structures, fields or elements. types to not fit inside containing structures, fields, or elements.
Unless specified otherwise, an error circumstance SHALL abort the Unless specified otherwise, an error circumstance SHALL abort the
parsing and processing of an element and its enclosing elements, up parsing and processing of an element and its enclosing elements, up
to the containing packet. to the containing packet.
2.1. Common Elements 2.1. Common Elements
This section lists types and structures that are used throughout this This section lists types and structures that are used throughout this
specification. specification.
2.1.1. Elementary Types and Constructs 2.1.1. Elementary Types and Constructs
This section lists the elementary types and constructs out of which This section lists the elementary types and constructs out of which
all of the following sections' definitions are built. all of the following sections' definitions are built.
uint8_t var; uint8_t var;
An unsigned integer 8 bits (one byte) in length and byte aligned. An unsigned integer 8 bits (one byte) in length and byte aligned.
uint16_t var; uint16_t var;
An unsigned integer 16 bits in length, in network byte order ("big An unsigned integer 16 bits in length, in network byte order ("big
endian") and byte aligned. endian") and byte aligned.
uint32_t var; uint32_t var;
An unsigned integer 32 bits in length, in network byte order and byte An unsigned integer 32 bits in length, in network byte order and
aligned. byte aligned.
uint128_t var; uint128_t var;
An unsigned integer 128 bits in length, in network byte order and An unsigned integer 128 bits in length, in network byte order and
byte aligned. byte aligned.
uintn_t var :bitsize; uintn_t var :bitsize;
An unsigned integer of any other size, potentially not byte aligned. An unsigned integer of any other size, potentially not byte
aligned. Its size in bits is specified explicitly by bitsize.
Its size in bits is specified explicitly by bitsize.
bool_t var :1; bool_t var :1;
A boolean flag having the value true (1 or set) or false (0 or clear) A boolean flag having the value true (1 or set) or false (0 or
and being one bit in length. clear) and being one bit in length.
type var[num]; type var[num];
A packed array of type with length num*sizeof(type)*8 bits. A packed array of type with length num*sizeof(type)*8 bits.
struct name_t { ... } name :bitsize; struct name_t { ... } name :bitsize;
A packed structure. Its size in bits is specified by bitsize. A packed structure. Its size in bits is specified by bitsize.
remainder(); remainder();
The number of bytes from the current offset to the end of the The number of bytes from the current offset to the end of the
enclosing structure. enclosing structure.
type var[remainder()]; type var[remainder()];
A packed array of type, its size extending to the end of the A packed array of type, its size extending to the end of the
enclosing structure. enclosing structure.
Note that a bitsize of "variable" indicates that the size of the Note that a bitsize of "variable" indicates that the size of the
structure is determined by the sizes of its interior components. A structure is determined by the sizes of its interior components. A
bitsize of "n*8" indicates that the size of the structure is a whole bitsize of "n*8" indicates that the size of the structure is a whole
number of bytes and is byte aligned. number of bytes and is byte aligned.
2.1.2. Variable Length Unsigned Integer (VLU) 2.1.2. Variable Length Unsigned Integer (VLU)
A VLU encodes any finite non-negative integer into one or more bytes. A VLU encodes any finite non-negative integer into one or more bytes.
For each encoded byte, if the high bit is set, the next byte is also For each encoded byte, if the high bit is set, the next byte is also
skipping to change at page 10, line 22 skipping to change at page 10, line 30
struct vlu_t struct vlu_t
{ {
value = 0; value = 0;
do { do {
bool_t more :1; bool_t more :1;
uintn_t digit :7; uintn_t digit :7;
value = (value * 128) + digit; value = (value * 128) + digit;
} while(more); } while(more);
} :variable*8; } :variable*8;
+-------------/-+ +-------------/-+
| \ | | \ |
+-------------/-+ +-------------/-+
Figure 1: VLU depiction in following diagrams Figure 1: VLU Depiction in Following Diagrams
Unless stated otherwise in this specification, implementations SHOULD Unless stated otherwise in this specification, implementations SHOULD
handle VLUs encoding unsigned integers at least 64 bits in length handle VLUs encoding unsigned integers at least 64 bits in length
(that is, encoding a maximum value of at least 2^64 - 1). (that is, encoding a maximum value of at least 2^64 - 1).
2.1.3. Option 2.1.3. Option
An Option is a Length-Type-Value triplet. Length and Type are An Option is a Length-Type-Value triplet. Length and Type are
encoded in VLU format. Length is the number of bytes of payload encoded in VLU format. Length is the number of bytes of payload
following the Length field. The payload comprises the Type and Value following the Length field. The payload comprises the Type and Value
fields. Type identifies the kind of option this is. The syntax of fields. Type identifies the kind of option this is. The syntax of
the Value field is determined by the type of option. the Value field is determined by the type of option.
An option can have a length of zero, in which case it has no type and An Option can have a length of zero, in which case it has no type and
no value and is empty. An empty option is called a "Marker". no value and is empty. An empty Option is called a "Marker".
+-------------/-+~~~~~~~~~~~~~/~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +-------------/-+~~~~~~~~~~~~~/~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| length \ | type \ | value | | length \ | type \ | value |
+-------------/-+~~~~~~~~~~~~~/~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +-------------/-+~~~~~~~~~~~~~/~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
^ ^ ^ ^
+-------- length bytes long (may be 0) ---------+ +-------- length bytes long (may be 0) ---------+
struct option_t struct option_t
{ {
vlu_t length :variable*8; // "L" vlu_t length :variable*8; // "L"
skipping to change at page 11, line 27 skipping to change at page 11, line 30
vlu_t type :variable*8; // "T" vlu_t type :variable*8; // "T"
uint8_t value[remainder()]; // "V" uint8_t value[remainder()]; // "V"
} payload :length*8; } payload :length*8;
} }
} :variable*8; } :variable*8;
+---/---/-------+ +---/---/-------+
| L \ T \ V | | L \ T \ V |
+---/---/-------+ +---/---/-------+
Figure 2: Option depiction in following diagrams Figure 2: Option Depiction in Following Diagrams
2.1.4. Option List 2.1.4. Option List
An Option List is a sequence of zero or more non-empty Options An Option List is a sequence of zero or more non-empty Options
terminated by a Marker. terminated by a Marker.
+~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+ +~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+
| L \ T \ V |...............| L \ T \ V | 0 \ | | L \ T \ V |...............| L \ T \ V | 0 \ |
+~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+ +~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+
^ ^ Marker ^ ^ Marker
skipping to change at page 12, line 7 skipping to change at page 12, line 7
struct optionList_t struct optionList_t
{ {
do do
{ {
option_t option :variable*8; option_t option :variable*8;
} while(option.length > 0); } while(option.length > 0);
} :variable*8; } :variable*8;
2.1.5. Internet Socket Address (Address) 2.1.5. Internet Socket Address (Address)
When communicating an Internet Socket Address (a combination of a 32- When communicating an Internet socket address (a combination of a
bit IPv4 [RFC0791] or 128-bit IPv6 [RFC2460] address and a 16-bit 32-bit IPv4 [RFC0791] or 128-bit IPv6 [RFC2460] address and a 16-bit
port number) to another RTMFP, this encoding is used. This encoding port number) to another RTMFP, this encoding is used. This encoding
additionally allows an address to be tagged with an origin type, additionally allows an address to be tagged with an origin type,
which an RTMFP MAY use to modify the use or disposition of the which an RTMFP MAY use to modify the use or disposition of the
address. address.
1 1
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|8 9 0 1 2 3 4 5 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-----/.../-----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-----/.../-----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|I| | O | internet | | |I| | O | Internet | |
|P|0 0 0 0 0| R | address | port | |P|0 0 0 0 0| R | address | port |
|6| rsv | I |32 or 128 bits | | |6| rsv | I |32 or 128 bits | |
+-+-+-+-+-+-+-+-+-----/.../-----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-----/.../-----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
struct address_t struct address_t
{ {
bool_t inet6 :1; // "IP6" bool_t inet6 :1; // "IP6"
uintn_t reserved :5 = 0; // "rsv" uintn_t reserved :5 = 0; // "rsv"
uintn_t origin :2; // "ORI" uintn_t origin :2; // "ORI"
if(inet6) if(inet6)
uint128_t ipAddress; uint128_t ipAddress;
else else
uint32_t ipAddress; uint32_t ipAddress;
uint16_t port; uint16_t port;
} :variable*8; } :variable*8;
inet6 : If set, the Internet address is a 128-bit IPv6 address. If inet6: If set, the Internet address is a 128-bit IPv6 address. If
clear, the Internet address is a 32-bit IPv4 address. clear, the Internet address is a 32-bit IPv4 address.
origin : The origin tag of this address. Possible values are: origin: The origin tag of this address. Possible values are:
0 : Unknown, unspecified, or "other" 0: Unknown, unspecified, or "other"
1 : Address was reported by the origin as a local, directly- 1: Address was reported by the origin as a local, directly
attached interface address attached interface address
2 : Address was observed to be the source address from which a 2: Address was observed to be the source address from which a
packet was received (a "reflexive transport address" in the packet was received (a "reflexive transport address" in the
terminology of [RFC5389]) terminology of [RFC5389])
3 : Address is a relay, proxy, or introducer (a Redirector and/or 3: Address is a relay, proxy, or introducer (a Redirector
Forwarder) and/or Forwarder)
ipAddress : The Internet address, in network byte order. ipAddress: The Internet address, in network byte order.
port : The 16 bit port number, in network byte order. port: The 16-bit port number, in network byte order.
2.2. Network Layer 2.2. Network Layer
2.2.1. Encapsulation 2.2.1. Encapsulation
RTMFP Multiplex packets are usually carried in UDP [RFC0768] RTMFP Multiplex packets are usually carried in UDP [RFC0768]
datagrams so that they may transit commonly deployed NATs and datagrams so that they may transit commonly deployed NATs and
firewalls, and so that RTMFP may be implemented on commonly deployed firewalls, and so that RTMFP may be implemented on commonly deployed
operating systems without special privileges or permissions. operating systems without special privileges or permissions.
RTMFP Multiplex packets MAY be carried by any suitable datagram RTMFP Multiplex packets MAY be carried by any suitable datagram
transport or encapsulation where endpoints are addressed by an transport or encapsulation where endpoints are addressed by an
Internet socket address (that is, an IPv4 or IPv6 address and a 16- Internet socket address (that is, an IPv4 or IPv6 address and a
bit port number). 16-bit port number).
The choice of port numbers is not mandated by this specification. The choice of port numbers is not mandated by this specification.
Higher protocol layers or the application define the port numbers Higher protocol layers or the application define the port
used. numbers used.
2.2.2. Multiplex 2.2.2. Multiplex
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| scrambled session ID (SSID) | | Scrambled Session ID (SSID) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| e first32[0] | | e first32[0] |
|- - - - - - n - - - - - - - - - - - - - - - - - - - - - - - -| |- - - - - - n - - - - - - - - - - - - - - - - - - - - - - - -|
| c first32[1] | | c first32[1] |
+- - - - - - r - - - - - - - - - - - - - - - - - - - - - - - -+ +- - - - - - r - - - - - - - - - - - - - - - - - - - - - - - -+
| y | | y |
| pted packet | | pted packet |
+---------------------------------------------------------------/ +---------------------------------------------------------------/
struct multiplex_t struct multiplex_t
skipping to change at page 14, line 4 skipping to change at page 14, line 4
uint32_t scrambledSessionID; // "SSID" uint32_t scrambledSessionID; // "SSID"
union { union {
uint32_t first32[2]; // see note uint32_t first32[2]; // see note
uint8_t encryptedPacket[remainder()]; uint8_t encryptedPacket[remainder()];
} :(encapsulation.length - 4)*8; } :(encapsulation.length - 4)*8;
// if encryptedPacket is less than 8 bytes long, treat it // if encryptedPacket is less than 8 bytes long, treat it
// as if it were end-padded with 0s for the following: // as if it were end-padded with 0s for the following:
sessionID = scrambledSessionID XOR first32[0] XOR first32[1]; sessionID = scrambledSessionID XOR first32[0] XOR first32[1];
} :encapsulation.length*8; } :encapsulation.length*8;
The 32-bit Scrambled Session ID is the 32-bit Session ID modified by The 32-bit Scrambled Session ID is the 32-bit session ID modified by
performing a bitwise exclusive-or with the bitwise exclusive-or of performing a bitwise exclusive-or with the bitwise exclusive-or of
the first two 32-bit words of the encrypted packet. the first two 32-bit words of the encrypted packet.
The Session ID is a 32-bit value that the receiver has requested to The session ID is a 32-bit value that the receiver has requested to
be used by the sender when sending packets to this receiver be used by the sender when sending packets to this receiver
(Section 2.3.7, Section 2.3.8). The Session ID identifies the (Sections 2.3.7 and 2.3.8). The session ID identifies the session to
Session to which this packet belongs and the decryption key to be which this packet belongs and the decryption key to be used to
used to decrypt the encrypted packet. decrypt the encrypted packet.
Note: Session ID 0 (prior to scrambling) denotes the startup pseudo- Note: Session ID 0 (prior to scrambling) denotes the startup pseudo-
session and implies the Default Session Key. session and implies the Default Session Key.
Note: If the encrypted packet is less than 8 bytes long, then for the Note: If the encrypted packet is less than 8 bytes long, then for the
scrambling operation, perform the exclusive-or as though the scrambling operation, perform the exclusive-or as though the
encrypted packet were end-padded with enough 0-bytes to bring its encrypted packet were end-padded with enough 0-bytes to bring its
length to 8. length to 8.
2.2.3. Encryption 2.2.3. Encryption
skipping to change at page 14, line 47 skipping to change at page 14, line 47
attacks, data integrity SHOULD comprise duplicate packet detection, attacks, data integrity SHOULD comprise duplicate packet detection,
for example by means of a session-wide packet sequence number. The for example by means of a session-wide packet sequence number. The
packet encryption layer SHALL discard a received packet that does not packet encryption layer SHALL discard a received packet that does not
pass integrity or authenticity tests. pass integrity or authenticity tests.
Note that the structures described below are of plain, unencrypted Note that the structures described below are of plain, unencrypted
packets. Encrypted packets MUST be decrypted according to the packets. Encrypted packets MUST be decrypted according to the
Session Key associated with the Multiplex Session ID before being Session Key associated with the Multiplex Session ID before being
interpreted according to this specification. interpreted according to this specification.
The cryptography profile defines a well-known Default Session Key The Cryptography Profile defines a well-known Default Session Key
that is used at session startup, during which per-session key(s) are that is used at session startup, during which per-session key(s) are
negotiated by the two endpoints. A Session ID of zero denotes use of negotiated by the two endpoints. A session ID of zero denotes use of
the Default Session Key. The Default Session Key is also used with the Default Session Key. The Default Session Key is also used with
non-zero Session IDs during the latter phases of session startup non-zero session IDs during the latter phases of session startup
(Section 2.3.6, Section 2.3.8). See Security Considerations (Sections 2.3.6 and 2.3.8). See Security Considerations (Section 5)
(Section 5) for more about the Default Session Key. for more about the Default Session Key.
2.2.4. Packet 2.2.4. Packet
An (unencrypted, plain) RTMFP Packet consists of a variable sized An (unencrypted, plain) RTMFP packet consists of a variable sized
common header, zero or more chunks, and padding. Padding can be common header, zero or more chunks, and padding. Padding can be
inserted by the encryption layer of the sender to meet cipher block inserted by the encryption layer of the sender to meet cipher block
size constraints, and is ignored by the receiver. A sender's size constraints and is ignored by the receiver. A sender's
encryption layer MAY pad the end of a packet with bytes with value encryption layer MAY pad the end of a packet with bytes with value
0xff such that the resulting packet is a natural and appropriate size 0xff such that the resulting packet is a natural and appropriate size
for the cipher. Alternatively, the Cryptography Profile MAY define for the cipher. Alternatively, the Cryptography Profile MAY define
its own framing and padding scheme, if needed, such that decrypted its own framing and padding scheme, if needed, such that decrypted
packets are compatible with the syntax defined in this section. packets are compatible with the syntax defined in this section.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|T|T| r |T|T| M | |T|T| r |T|T| M |
|C|C| s |S|S| O | |C|C| s |S|S| O |
skipping to change at page 17, line 4 skipping to change at page 17, line 4
{ {
uint8_t chunkType; uint8_t chunkType;
uint16_t chunkLength; uint16_t chunkLength;
if(remainder() < chunkLength) if(remainder() < chunkLength)
break; break;
uint8_t chunkPayload[chunkLength]; uint8_t chunkPayload[chunkLength];
} // chunks } // chunks
uint8_t padding[remainder()]; uint8_t padding[remainder()];
} }
} :plainPacket.length*8; } :plainPacket.length*8;
timeCritical : Time Critical Forward Notification. If set, timeCritical: Time Critical Forward Notification. If set, indicates
indicates that this packet contains real-time user data. that this packet contains real-time user data.
timeCriticalReverse : Time Critical Reverse Notification. If set, timeCriticalReverse: Time Critical Reverse Notification. If set,
indicates that the sender is currently receiving packets on other indicates that the sender is currently receiving packets on other
sessions that have the timeCritical flag set. sessions that have the timeCritical flag set.
timestampPresent : If set, indicates that the timestamp field is timestampPresent: If set, indicates that the timestamp field is
present. If clear, there is no timestamp field. present. If clear, there is no timestamp field.
timestampEchoPresent : If set, indicates that the timestamp echo timestampEchoPresent: If set, indicates that the timestamp echo
field is present. If clear, there is no timestamp echo field. field is present. If clear, there is no timestamp echo field.
mode : The mode of this packet. See below for additional discussion mode: The mode of this packet. See below for additional discussion
of packet modes. Possible values are: of packet modes. Possible values are:
0 : Forbidden value 0: Forbidden value
1 : Initiator Mark 1: Initiator Mark
2 : Responder Mark 2: Responder Mark
3 : Startup 3: Startup
timestamp : If the timestampPresent flag is set, this field is timestamp: If the timestampPresent flag is set, this field is
present and contains the low 16 bits of the sender's 250 Hz clock present and contains the low 16 bits of the sender's 250 Hz clock
(4 milliseconds per tick) at transmit time. The sender's clock (4 milliseconds per tick) at transmit time. The sender's clock
MAY have its origin at any time in the past. MAY have its origin at any time in the past.
timestampEcho : If the timestampEchoPresent flag is set, this field timestampEcho: If the timestampEchoPresent flag is set, this field
is present and contains the sender's estimate of what the is present and contains the sender's estimate of what the
timestamp field of a packet received from the other end would be timestamp field of a packet received from the other end would be
at the time this packet was transmitted, using the method at the time this packet was transmitted, using the method
described in Section 3.5.2.2. described in Section 3.5.2.2.
chunks : Zero or more chunks follow the header. It is RECOMMENDED chunks: Zero or more chunks follow the header. It is RECOMMENDED
that a packet contain at least one chunk. that a packet contain at least one chunk.
padding : Zero or more bytes of padding follow the chunks. The padding: Zero or more bytes of padding follow the chunks. The
following conditions indicate padding: following conditions indicate padding:
* Fewer than three bytes (the size of a chunk header) remain in * Fewer than three bytes (the size of a chunk header) remain in
the packet. the packet.
* The chunkLength field of what would be the current chunk header * The chunkLength field of what would be the current chunk header
indicates that the hypothetical chunk payload wouldn't fit in indicates that the hypothetical chunk payload wouldn't fit in
the remaining bytes of the packet. the remaining bytes of the packet.
Packet mode 0 is not allowed. Packets marked with this mode are Packet mode 0 is not allowed. Packets marked with this mode are
invalid and MUST be discarded. invalid and MUST be discarded.
The original initiator of a session MUST mark all non-startup packets The original initiator of a session MUST mark all non-startup packets
it sends in that session with packet mode 1 "Initiator Mark". It it sends in that session with packet mode 1 ("Initiator Mark"). It
SHOULD ignore any packet received in that session with packet mode 1. SHOULD ignore any packet received in that session with packet mode 1.
The original responder of a session MUST mark all non-startup packets The original responder of a session MUST mark all non-startup packets
it sends in that session with packet mode 2 "Responder Mark". It it sends in that session with packet mode 2 ("Responder Mark"). It
SHOULD ignore any packet received in that session with packet mode 2. SHOULD ignore any packet received in that session with packet mode 2.
Packet mode 3 is for session startup. Session startup chunks are Packet mode 3 is for session startup. Session startup chunks are
only allowed in packets with this mode. only allowed in packets with this mode.
Chunks that are not for session startup are only allowed in packets Chunks that are not for session startup are only allowed in packets
with modes 1 or 2. with modes 1 or 2.
2.3. Chunks 2.3. Chunks
skipping to change at page 18, line 39 skipping to change at page 18, line 39
| chunkPayload (chunkLength bytes, may be zero) | | chunkPayload (chunkLength bytes, may be zero) |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
struct chunk_t struct chunk_t
{ {
uint8_t chunkType; uint8_t chunkType;
uint16_t chunkLength; uint16_t chunkLength;
uint8_t chunkPayload[chunkLength]; uint8_t chunkPayload[chunkLength];
} :variable*8; } :variable*8;
chunkType : The chunk type code. chunkType: The chunk type code.
chunkLength : The size, in bytes, of the chunk payload. chunkLength: The size, in bytes, of the chunk payload.
chunkPayload : The type-specific payload of this chunk, chunkLength chunkPayload: The type-specific payload of this chunk,
bytes in length (may be empty). chunkLength bytes in length (may be empty).
Defined chunk types are enumerated here in the order they might be Defined chunk types are enumerated here in the order they might be
encountered in the course of a typical session. The following chunk encountered in the course of a typical session. The following chunk
type codes are defined: type codes are defined:
0x7f : Packet Fragment (Section 2.3.1) 0x7f: Packet Fragment (Section 2.3.1)
0x30 : Initiator Hello (Section 2.3.2) 0x30: Initiator Hello (Section 2.3.2)
0x0f : Forwarded Initiator Hello (Section 2.3.3) 0x0f: Forwarded Initiator Hello (Section 2.3.3)
0x70 : Responder Hello (Section 2.3.4) 0x70: Responder Hello (Section 2.3.4)
0x71 : Responder Redirect (Section 2.3.5) 0x71: Responder Redirect (Section 2.3.5)
0x79 : RHello Cookie Change (Section 2.3.6) 0x79: RHello Cookie Change (Section 2.3.6)
0x38 : Initiator Initial Keying (Section 2.3.7) 0x38: Initiator Initial Keying (Section 2.3.7)
0x78 : Responder Initial Keying (Section 2.3.8) 0x78: Responder Initial Keying (Section 2.3.8)
0x01 : Ping (Section 2.3.9) 0x01: Ping (Section 2.3.9)
0x41 : Ping Reply (Section 2.3.10) 0x41: Ping Reply (Section 2.3.10)
0x10 : User Data (Section 2.3.11) 0x10: User Data (Section 2.3.11)
0x11 : Next User Data (Section 2.3.12) 0x11: Next User Data (Section 2.3.12)
0x50 : Data Acknowledgement Bitmap (Section 2.3.13) 0x50: Data Acknowledgement Bitmap (Section 2.3.13)
0x51 : Data Acknowledgement Ranges (Section 2.3.14) 0x51: Data Acknowledgement Ranges (Section 2.3.14)
0x18 : Buffer Probe (Section 2.3.15) 0x18: Buffer Probe (Section 2.3.15)
0x5e : Flow Exception Report (Section 2.3.16) 0x5e: Flow Exception Report (Section 2.3.16)
0x0c : Session Close Request (Section 2.3.17) 0x0c: Session Close Request (Section 2.3.17)
0x4c : Session Close Acknowledgement (Section 2.3.18) 0x4c: Session Close Acknowledgement (Section 2.3.18)
0x00 : Ignore/Padding 0x00: Ignore/Padding
0xff : Ignore/Padding 0xff: Ignore/Padding
A receiver MUST ignore a chunk having an unrecognized chunk type A receiver MUST ignore a chunk having an unrecognized chunk type
code. A receiver MUST ignore a chunk appearing in a packet having a code. A receiver MUST ignore a chunk appearing in a packet having a
mode inappropriate to that chunk type. mode inappropriate to that chunk type.
Unless specified otherwise, if a chunk has a syntax or processing Unless specified otherwise, if a chunk has a syntax or processing
error (for example, the chunk's payload field is not long enough to error (for example, the chunk's payload field is not long enough to
contain the specified syntax elements), the chunk SHALL be ignored as contain the specified syntax elements), the chunk SHALL be ignored as
though it was not present in the packet, and parsing and processing though it was not present in the packet, and parsing and processing
SHALL commence with the next chunk in the packet, if any. SHALL commence with the next chunk in the packet, if any.
skipping to change at page 20, line 36 skipping to change at page 20, line 41
struct fragmentChunkPayload_t struct fragmentChunkPayload_t
{ {
bool_t moreFragments :1; // M bool_t moreFragments :1; // M
uintn_t reserved :7; uintn_t reserved :7;
vlu_t packetID :variable*8; vlu_t packetID :variable*8;
vlu_t fragmentNum :variable*8; vlu_t fragmentNum :variable*8;
uint8_t packetFragment[remainder()]; uint8_t packetFragment[remainder()];
} :chunkLength*8; } :chunkLength*8;
moreFragments : If set, the indicated packet comprises additional moreFragments: If set, the indicated packet comprises additional
fragments. If clear, this fragment is the final fragment of the fragments. If clear, this fragment is the final fragment of the
packet. packet.
reserved : Reserved for future use. reserved: Reserved for future use.
packetID : VLU, the identifier of this segmented packet. All packetID: VLU, the identifier of this segmented packet. All
fragments of the same packet have the same packetID. fragments of the same packet have the same packetID.
fragmentNum : VLU, the index of this fragment of the indicated fragmentNum: VLU, the index of this fragment of the indicated
packet. The first fragment of the packet MUST be index 0. packet. The first fragment of the packet MUST be index 0.
Fragments are numbered consecutively. Fragments are numbered consecutively.
packetFragment : The bytes of the indicated segment of the indicated packetFragment: The bytes of the indicated segment of the indicated
original plain RTMFP packet. A packetFragment MUST NOT be empty. original plain RTMFP packet. A packetFragment MUST NOT be empty.
The use of this mechanism is detailed in Section 3.4. The use of this mechanism is detailed in Section 3.4.
2.3.2. Initiator Hello Chunk (IHello) 2.3.2. Initiator Hello Chunk (IHello)
This chunk is sent by the initiator of a new session to begin the This chunk is sent by the initiator of a new session to begin the
startup handshake. This chunk is only allowed in a packet with startup handshake. This chunk is only allowed in a packet with
Session ID 0, encrypted with the default session key, and having Session ID 0, encrypted with the Default Session Key, and having
packet mode 3 (Startup). packet mode 3 (Startup).
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x30 | chunkLength | | 0x30 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| epdLength \ | endpointDiscriminator (epdLength bytes) | | epdLength \ | endpointDiscriminator (epdLength bytes) |
+-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------/
+---------------------------------------------------------------+ +---------------------------------------------------------------+
| tag | | tag |
+---------------------------------------------------------------/ +---------------------------------------------------------------/
struct ihelloChunkPayload_t struct ihelloChunkPayload_t
{ {
vlu_t epdLength :variable*8; vlu_t epdLength :variable*8;
uint8_t endpointDiscriminator[epdLength]; uint8_t endpointDiscriminator[epdLength];
uint8_t tag[remainder()]; uint8_t tag[remainder()];
} :chunkLength*8; } :chunkLength*8;
epdLength : VLU, the length of the following endpointDiscriminator epdLength: VLU, the length of the following endpointDiscriminator
field in bytes. field in bytes.
endpointDiscriminator : The Endpoint Discriminator for the identity endpointDiscriminator: The Endpoint Discriminator for the identity
with which the initiator wants to communicate. with which the initiator wants to communicate.
tag : Initiator-provided data to be returned in a Responder Hello's tag: Initiator-provided data to be returned in a Responder Hello's
tagEcho field. The tag/tagEcho is used to match Responder Hellos tagEcho field. The tag/tagEcho is used to match Responder Hellos
to the initiator's session startup state independent of the to the initiator's session startup state independent of the
responder's address. responder's address.
The use of IHello is detailed in Section 3.5.1. The use of IHello is detailed in Section 3.5.1.
2.3.3. Forwarded Initiator Hello Chunk (FIHello) 2.3.3. Forwarded Initiator Hello Chunk (FIHello)
This chunk is sent on behalf of an initiator by a Forwarder. It is This chunk is sent on behalf of an initiator by a Forwarder. It is
only allowed in packets of an established session having packet mode only allowed in packets of an established session having packet
1 or 2. A receiver MAY treat this chunk as though it was an mode 1 or 2. A receiver MAY treat this chunk as though it was an
Initiator Hello received directly from replyAddress. Alternatively, Initiator Hello received directly from replyAddress. Alternatively,
if the receiver is selected by the Endpoint Discriminator, it MAY if the receiver is selected by the Endpoint Discriminator, it MAY
respond to replyAddress with an Implied Redirect (Section 2.3.5). respond to replyAddress with an Implied Redirect (Section 2.3.5).
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x0f | chunkLength | | 0x0f | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| epdLength \ | endpointDiscriminator (epdLength bytes) | | epdLength \ | endpointDiscriminator (epdLength bytes) |
skipping to change at page 22, line 30 skipping to change at page 22, line 36
+---------------------------------------------------------------/ +---------------------------------------------------------------/
struct fihelloChunkPayload_t struct fihelloChunkPayload_t
{ {
vlu_t epdLength :variable*8; vlu_t epdLength :variable*8;
uint8_t endpointDiscriminator[epdLength]; uint8_t endpointDiscriminator[epdLength];
address_t replyAddress :variable*8; address_t replyAddress :variable*8;
uint8_t tag[remainder()]; uint8_t tag[remainder()];
} :chunkLength*8; } :chunkLength*8;
epdLength : VLU, the length of the following endpointDiscriminator epdLength: VLU, the length of the following endpointDiscriminator
field in bytes. field in bytes.
endpointDiscriminator : The Endpoint Discriminator for the identity endpointDiscriminator: The Endpoint Discriminator for the identity
with which the original initiator wants to communicate, copied with which the original initiator wants to communicate, copied
from the original Initiator Hello. from the original Initiator Hello.
replyAddress : Address format (Section 2.1.5), the address that the replyAddress: Address format (Section 2.1.5), the address that the
forwarding node derived from the received Initiator Hello, to forwarding node derived from the received Initiator Hello, to
which the receiver should respond. which the receiver should respond.
tag : Copied from the original Initiator Hello. tag: Copied from the original Initiator Hello.
The use of FIHello is detailed in Section 3.5.1.5. The use of FIHello is detailed in Section 3.5.1.5.
2.3.4. Responder Hello Chunk (RHello) 2.3.4. Responder Hello Chunk (RHello)
This chunk is sent by a responder in response to an Initiator Hello This chunk is sent by a responder in response to an Initiator Hello
or Forwarded Initiator Hello if the Endpoint Discriminator indicates or Forwarded Initiator Hello if the Endpoint Discriminator indicates
the responder's identity. This chunk is only allowed in a packet the responder's identity. This chunk is only allowed in a packet
with Session ID 0, encrypted with the default session key, and having with Session ID 0, encrypted with the Default Session Key, and having
packet mode 3 (Startup). packet mode 3 (Startup).
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x70 | chunkLength | | 0x70 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| tagLength \ | tagEcho (tagLength bytes) | | tagLength \ | tagEcho (tagLength bytes) |
+-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------/
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
skipping to change at page 23, line 28 skipping to change at page 23, line 36
struct rhelloChunkPayload_t struct rhelloChunkPayload_t
{ {
vlu_t tagLength :variable*8; vlu_t tagLength :variable*8;
uint8_t tagEcho[tagLength]; uint8_t tagEcho[tagLength];
vlu_t cookieLength :variable*8; vlu_t cookieLength :variable*8;
uint8_t cookie[cookieLength]; uint8_t cookie[cookieLength];
uint8_t responderCertificate[remainder()]; uint8_t responderCertificate[remainder()];
} :chunkLength*8; } :chunkLength*8;
tagLength : VLU, the length of the following tagEcho field in bytes. tagLength: VLU, the length of the following tagEcho field in bytes.
tagEcho : The tag from the Initiator Hello, unaltered. tagEcho: The tag from the Initiator Hello, unaltered.
cookieLength : VLU, the length of the following cookie field in cookieLength: VLU, the length of the following cookie field
bytes. in bytes.
cookie : Responder-created state data to authenticate a future cookie: Responder-created state data to authenticate a future
Initiator Initial Keying message (in order to prevent denial of Initiator Initial Keying message (in order to prevent denial-of-
service attacks). service attacks).
responderCertificate : The responder's cryptographic credentials. responderCertificate: The responder's cryptographic credentials.
Note: this specification doesn't mandate a specific choice of Note: This specification doesn't mandate a specific choice of
certificate format. The Cryptography Profile determines the syntax, certificate format. The Cryptography Profile determines the syntax,
algorithms, and interpretation of the responderCertificate. algorithms, and interpretation of the responderCertificate.
The use of RHello is detailed in Section 3.5.1. The use of RHello is detailed in Section 3.5.1.
2.3.5. Responder Redirect Chunk (Redirect) 2.3.5. Responder Redirect Chunk (Redirect)
This chunk is sent in response to an Initiator Hello or Forwarded This chunk is sent in response to an Initiator Hello or Forwarded
Initiator Hello to indicate that the requested endpoint can be Initiator Hello to indicate that the requested endpoint can be
reached at one or more of the indicated address(es). A receiver can reached at one or more of the indicated addresses. A receiver can
add none, some, or all of the indicated address(es) to the set of add none, some, or all of the indicated addresses to the set of
addresses to which it is sending Initiator Hello messages for the addresses to which it is sending Initiator Hello messages for the
opening session associated with tagEcho. This chunk is only allowed opening session associated with tagEcho. This chunk is only allowed
in a packet with Session ID 0, encrypted with the default session in a packet with Session ID 0, encrypted with the Default Session
key, and having packet mode 3 (Startup). Key, and having packet mode 3 (Startup).
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x71 | chunkLength | | 0x71 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| tagLength \ | tagEcho (tagLength bytes) | | tagLength \ | tagEcho (tagLength bytes) |
+-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------/
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| redirectDestination 1 | | redirectDestination 1 |
skipping to change at page 24, line 39 skipping to change at page 25, line 35
addressCount = 0; addressCount = 0;
while(remainder() > 0) while(remainder() > 0)
{ {
address_t redirectDestination :variable*8; address_t redirectDestination :variable*8;
addressCount++; addressCount++;
} }
if(0 == addressCount) if(0 == addressCount)
redirectDestination = packetSourceAddress(); redirectDestination = packetSourceAddress();
} :chunkLength*8; } :chunkLength*8;
tagLength : VLU, the length of the following tagEcho field in bytes. tagLength: VLU, the length of the following tagEcho field in bytes.
tagEcho : The tag from the Initiator Hello, unaltered. tagEcho: The tag from the Initiator Hello, unaltered.
redirectDestination : (Zero or more) Address format (Section 2.1.5), redirectDestination: (Zero or more) Address format (Section 2.1.5)
addresses to add to the opening set for the indicated session. addresses to add to the opening set for the indicated session.
If this chunk lists zero redirectDestination addresses, then this is If this chunk lists zero redirectDestination addresses, then this is
an Implied Redirect, and the indicated address is the address from an Implied Redirect, and the indicated address is the address from
which the packet containing this chunk was received. which the packet containing this chunk was received.
The use of Redirect is detailed in Section 3.5.1.1.1, The use of Redirect is detailed in Sections 3.5.1.1.1, 3.5.1.1.2,
Section 3.5.1.1.2, and Section 3.5.1.4. and 3.5.1.4.
2.3.6. RHello Cookie Change Chunk 2.3.6. RHello Cookie Change Chunk
This chunk SHOULD be sent by a responder to an initiator in response This chunk SHOULD be sent by a responder to an initiator in response
to an Initiator Initial Keying if that chunk's cookie appears to have to an Initiator Initial Keying if that chunk's cookie appears to have
been created by the responder but the cookie is incorrect (for been created by the responder but the cookie is incorrect (for
example, it includes a hash of the initiator's address, but the example, it includes a hash of the initiator's address, but the
initiator's address is different than the one which elicited the initiator's address is different than the one that elicited the
Responder Hello containing the original cookie). Responder Hello containing the original cookie).
This chunk is only allowed in a packet encrypted with the default This chunk is only allowed in a packet encrypted with the Default
session key and having packet mode 3, and with the Session ID Session Key and having packet mode 3, and with the session ID
indicated in the initiatorSessionID field of the Initiator Initial indicated in the initiatorSessionID field of the Initiator Initial
Keying to which this is a response. Keying to which this is a response.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x79 | chunkLength | | 0x79 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| oldCookieLen\ | oldCookie (oldCookieLen bytes) | | oldCookieLen\ | oldCookie (oldCookieLen bytes) |
+-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------/
skipping to change at page 25, line 37 skipping to change at page 26, line 37
| newCookie | | newCookie |
+---------------------------------------------------------------/ +---------------------------------------------------------------/
struct rhelloCookieChangeChunkPayload_t struct rhelloCookieChangeChunkPayload_t
{ {
vlu_t oldCookieLen :variable*8; vlu_t oldCookieLen :variable*8;
uint8_t oldCookie[oldCookieLen]; uint8_t oldCookie[oldCookieLen];
uint8_t newCookie[remainder()]; uint8_t newCookie[remainder()];
} :chunkLength*8; } :chunkLength*8;
oldCookieLen : VLU, the length of the following oldCookie field in oldCookieLen: VLU, the length of the following oldCookie field
bytes. in bytes.
oldCookie : The cookie that was sent in a previous Responder Hello oldCookie: The cookie that was sent in a previous Responder Hello
and Initiator Initial Keying. and Initiator Initial Keying.
newCookie : The new cookie that the responder would like sent (and newCookie: The new cookie that the responder would like sent (and
signed) in a replacement Initiator Initial Keying. The old and signed) in a replacement Initiator Initial Keying. The old and
new cookies need not have the same lengths. new cookies need not have the same lengths.
On receipt of this chunk, the initiator SHOULD compute, sign, and On receipt of this chunk, the initiator SHOULD compute, sign, and
send a new Initiator Initial Keying having newCookie in place of send a new Initiator Initial Keying having newCookie in place of
oldCookie. The use of this chunk is detailed in Section 3.5.1.2. oldCookie. The use of this chunk is detailed in Section 3.5.1.2.
2.3.7. Initiator Initial Keying Chunk (IIKeying) 2.3.7. Initiator Initial Keying Chunk (IIKeying)
This chunk is sent by an initiator to establish a session with a This chunk is sent by an initiator to establish a session with a
responder. The initiator MUST have obtained a valid cookie to use responder. The initiator MUST have obtained a valid cookie to use
with the responder, typically by receiving a Responder Hello from it. with the responder, typically by receiving a Responder Hello from it.
This chunk is only allowed in a packet with Session ID 0, encrypted This chunk is only allowed in a packet with Session ID 0, encrypted
with the default session key, and having packet mode 3 (Startup). with the Default Session Key, and having packet mode 3 (Startup).
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x38 | chunkLength | | 0x38 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| initiatorSessionID | | initiatorSessionID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| cookieLength\ | cookieEcho | | cookieLength\ | cookieEcho |
skipping to change at page 26, line 48 skipping to change at page 27, line 48
vlu_t cookieLength :variable*8; vlu_t cookieLength :variable*8;
uint8_t cookieEcho[cookieLength]; uint8_t cookieEcho[cookieLength];
vlu_t certLength :variable*8; vlu_t certLength :variable*8;
uint8_t initiatorCertificate[certLength]; uint8_t initiatorCertificate[certLength];
vlu_t skicLength :variable*8; vlu_t skicLength :variable*8;
uint8_t sessionKeyInitiatorComponent[skicLength]; uint8_t sessionKeyInitiatorComponent[skicLength];
} initiatorSignedParameters :variable*8; } initiatorSignedParameters :variable*8;
uint8_t signature[remainder()]; uint8_t signature[remainder()];
} :chunkLength*8; } :chunkLength*8;
initiatorSessionID : The Session ID to be used by the responder when initiatorSessionID: The session ID to be used by the responder when
sending packets to the Initiator. sending packets to the initiator.
cookieLength : VLU, the length of the following cookieEcho field in cookieLength: VLU, the length of the following cookieEcho field
bytes. in bytes.
cookieEcho : The cookie from the Responder Hello, unaltered. cookieEcho: The cookie from the Responder Hello, unaltered.
certLength : VLU, the length of the following initiatorCertificate certLength: VLU, the length of the following initiatorCertificate
field in bytes. field in bytes.
initiatorCertificate : The initiator's identity credentials. initiatorCertificate: The initiator's identity credentials.
skicLength : VLU, the length of the following skicLength: VLU, the length of the following
sessionKeyInitiatorComponent field in bytes. sessionKeyInitiatorComponent field in bytes.
sessionKeyInitiatorComponent : The initiator's portion of the sessionKeyInitiatorComponent: The initiator's portion of the session
session key negotiation according to the Cryptography Profile. key negotiation according to the Cryptography Profile.
initiatorSignedParameters : The payload portion of this chunk up to initiatorSignedParameters: The payload portion of this chunk up to
the signature field. the signature field.
signature : The initiator's digital signature of the signature: The initiator's digital signature of the
initiatorSignedParameters according to the Cryptography Profile. initiatorSignedParameters according to the Cryptography Profile.
Note: this specification doesn't mandate a specific choice of Note: This specification doesn't mandate a specific choice of
cryptography. The Cryptography Profile determines the syntax, cryptography. The Cryptography Profile determines the syntax,
algorithms, and interpretation of the initiatorCertificate, algorithms, and interpretation of the initiatorCertificate,
responderCertificate, sessionKeyInitiatorComponent, responderCertificate, sessionKeyInitiatorComponent,
sessionKeyResponderComponent, and signature, and how the sessionKeyResponderComponent, and signature, and how the
sessionKeyInitiatorComponent and sessionKeyResponderComponent are sessionKeyInitiatorComponent and sessionKeyResponderComponent are
combined to derive the session keys. combined to derive the session keys.
The use of IIKeying is detailed in Section 3.5.1. The use of IIKeying is detailed in Section 3.5.1.
2.3.8. Responder Initial Keying Chunk (RIKeying) 2.3.8. Responder Initial Keying Chunk (RIKeying)
This chunk is sent by a responder in response to an Initiator Initial This chunk is sent by a responder in response to an Initiator Initial
Keying as the final phase of session startup. This chunk is only Keying as the final phase of session startup. This chunk is only
allowed in a packet encrypted with the default session key, having allowed in a packet encrypted with the Default Session Key, having
packet mode 3 (Startup), and sent to the initiator with the Session packet mode 3 (Startup), and sent to the initiator with the
ID specified by the initiatorSessionID field from the Initiator session ID specified by the initiatorSessionID field from the
Initial Keying. Initiator Initial Keying.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x78 | chunkLength | | 0x78 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| responderSessionID | | responderSessionID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-----------------------------------------------+ +-------------/-+-----------------------------------------------+
| skrcLength \ | sessionKeyResponderComponent | | skrcLength \ | sessionKeyResponderComponent |
skipping to change at page 28, line 36 skipping to change at page 29, line 45
} responderSignedParametersPortion :variable*8; } responderSignedParametersPortion :variable*8;
uint8_t signature[remainder()]; uint8_t signature[remainder()];
} :chunkLength*8; } :chunkLength*8;
struct struct
{ {
responderSignedParametersPortion; responderSignedParametersPortion;
sessionKeyInitiatorComponent; sessionKeyInitiatorComponent;
} responderSignedParameters; } responderSignedParameters;
responderSessionID : The Session ID to be used by the Initiator when responderSessionID: The session ID to be used by the initiator when
sending packets to the Responder. sending packets to the responder.
skrcLength : VLU, the length of the following skrcLength: VLU, the length of the following
sessionKeyResponderComponent field in bytes. sessionKeyResponderComponent field in bytes.
sessionKeyResponderComponent : The responder's portion of the sessionKeyResponderComponent: The responder's portion of the session
session key negotiation according to the Cryptography Profile. key negotiation according to the Cryptography Profile.
responderSignedParametersPortion : The payload portion of this chunk responderSignedParametersPortion: The payload portion of this chunk
up to the signature field. up to the signature field.
signature : The responder's digital signature of the signature: The responder's digital signature of the
responderSignedParameters (see below) according to the responderSignedParameters (see below) according to the
Cryptography Profile. Cryptography Profile.
responderSignedParameters : The concatenation of the responderSignedParameters: The concatenation of the
responderSignedParametersPortion (the payload portion of this responderSignedParametersPortion (the payload portion of this
chunk up to the signature field) and the chunk up to the signature field) and the
sessionKeyInitiatorComponent from the Initiator Initial Keying to sessionKeyInitiatorComponent from the Initiator Initial Keying to
which this chunk is a response. which this chunk is a response.
Note: this specification doesn't mandate a specific choice of Note: This specification doesn't mandate a specific choice of
cryptography. The Cryptography Profile determines the syntax, cryptography. The Cryptography Profile determines the syntax,
algorithms, and interpretation of the initiatorCertificate, algorithms, and interpretation of the initiatorCertificate,
responderCertificate, sessionKeyInitiatorComponent, responderCertificate, sessionKeyInitiatorComponent,
sessionKeyResponderComponent, and signature, and how the sessionKeyResponderComponent, and signature, and how the
sessionKeyInitiatorComponent and sessionKeyResponderComponent are sessionKeyInitiatorComponent and sessionKeyResponderComponent are
combined to derive the session keys. combined to derive the session keys.
Once the responder has computed the sessionKeyResponderComponent, it Once the responder has computed the sessionKeyResponderComponent, it
has all of the information and state necessary for an established has all of the information and state necessary for an established
session with the initiator. Once the responder has sent this chunk session with the initiator. Once the responder has sent this chunk
skipping to change at page 30, line 4 skipping to change at page 31, line 23
| 0x01 | chunkLength | | 0x01 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| message | | message |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
struct pingChunkPayload_t struct pingChunkPayload_t
{ {
uint8_t message[chunkLength]; uint8_t message[chunkLength];
} :chunkLength*8; } :chunkLength*8;
message : The (potentially empty) message that is expected to be
message: The (potentially empty) message that is expected to be
returned by the other end of the session in a Ping Reply. returned by the other end of the session in a Ping Reply.
The receiver of this chunk SHOULD reply as immediately as is The receiver of this chunk SHOULD reply as immediately as is
practical with a Ping Reply. practical with a Ping Reply.
Ping and the expected Ping Reply are typically used for session Ping and the expected Ping Reply are typically used for session
keepalive, endpoint address change verification, and path MTU keepalive, endpoint address change verification, and path MTU
discovery. See Section 3.5.4 for details. discovery. See Section 3.5.4 for details.
2.3.10. Ping Reply Chunk 2.3.10. Ping Reply Chunk
skipping to change at page 30, line 33 skipping to change at page 32, line 24
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| messageEcho | | messageEcho |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
struct pingReplyChunkPayload_t struct pingReplyChunkPayload_t
{ {
uint8_t messageEcho[chunkLength]; uint8_t messageEcho[chunkLength];
} :chunkLength*8; } :chunkLength*8;
messageEcho : The message from the Ping to which this is a response, messageEcho: The message from the Ping to which this is a response,
unaltered. unaltered.
2.3.11. User Data Chunk 2.3.11. User Data Chunk
This chunk is the basic unit of transmission for the user messages of This chunk is the basic unit of transmission for the user messages of
a flow. A user message comprises one or more fragments. Each a flow. A user message comprises one or more fragments. Each
fragment is carried in its own chunk and has a unique sequence number fragment is carried in its own chunk and has a unique sequence number
in its flow. It is only allowed in a packet belonging to an in its flow. It is only allowed in a packet belonging to an
established session and having packet mode 1 or 2. established session and having packet mode 1 or 2.
skipping to change at page 31, line 28 skipping to change at page 33, line 36
| L \ T \ V |... options ...| L \ T \ V | 0 \ | | L \ T \ V |... options ...| L \ T \ V | 0 \ |
\~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/ \~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| userData | | userData |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
struct userDataChunkPayload_t struct userDataChunkPayload_t
{ {
bool_t optionsPresent :1; // "OPT" bool_t optionsPresent :1; // "OPT"
uintn_t reserved1 :1; // "rsv" uintn_t reserved1 :1; // "rsv"
uintn_t fragmentControl :2; // "FRA uintn_t fragmentControl :2; // "FRA"
// 0=whole, 1=begin, 2=end, 3=middle // 0=whole, 1=begin, 2=end, 3=middle
uintn_t reserved2 :2; // "rsv" uintn_t reserved2 :2; // "rsv"
bool_t abandon :1; // "ABN" bool_t abandon :1; // "ABN"
bool_t final :1; // "FIN" bool_t final :1; // "FIN"
vlu_t flowID :variable*8; vlu_t flowID :variable*8;
vlu_t sequenceNumber :variable*8; // "seq#" vlu_t sequenceNumber :variable*8; // "seq#"
vlu_t fsnOffset :variable*8; vlu_t fsnOffset :variable*8;
forwardSequenceNumber = sequenceNumber - fsnOffset; forwardSequenceNumber = sequenceNumber - fsnOffset;
if(optionsPresent) if(optionsPresent)
optionList_t options :variable*8; optionList_t options :variable*8;
uint8_t userData[remainder()]; uint8_t userData[remainder()];
} :chunkLength*8; } :chunkLength*8;
optionsPresent : If set, indicates the presence of an option list optionsPresent: If set, indicates the presence of an option list
before the user data. If clear, there is no option list in this before the user data. If clear, there is no option list in this
chunk. chunk.
fragmentControl : Indicates how this fragment is assembled, fragmentControl: Indicates how this fragment is assembled,
potentially with others, into a complete user message. Possible potentially with others, into a complete user message. Possible
values: values:
0 : This fragment is a complete message. 0: This fragment is a complete message.
1 : This fragment is the first of a multi-fragment message. 1: This fragment is the first of a multi-fragment message.
2 : This fragment is the last of a multi-fragment message. 2: This fragment is the last of a multi-fragment message.
3 : This fragment is in the middle of a multi-fragment message. 3: This fragment is in the middle of a multi-fragment message.
A single-fragment user message has a fragment control of A single-fragment user message has a fragment control of
"0-whole". When a message has more than one fragment, the first "0-whole". When a message has more than one fragment, the first
fragment has a fragment control of "1-begin", then zero or more fragment has a fragment control of "1-begin", then zero or more
"3-middle" fragments, and finally a "2-end" fragment. The "3-middle" fragments, and finally a "2-end" fragment. The
sequence numbers of a multi-fragment message MUST be contiguous. sequence numbers of a multi-fragment message MUST be contiguous.
abandon : If set, this sequence number has been abandoned by the abandon: If set, this sequence number has been abandoned by the
sender. The userData, if any, MUST be ignored. sender. The userData, if any, MUST be ignored.
final : If set, this is the last sequence number of the flow. final: If set, this is the last sequence number of the flow.
flowID : VLU, the flow identifier. flowID: VLU, the flow identifier.
sequenceNumber : VLU, the sequence number of this fragment. sequenceNumber: VLU, the sequence number of this fragment.
Fragments are assigned contiguous increasing sequence numbers in a Fragments are assigned contiguous increasing sequence numbers in a
flow. The first sequence number of a flow SHOULD be 1. The first flow. The first sequence number of a flow SHOULD be 1. The first
sequence number of a flow MUST be greater than zero. Sequence sequence number of a flow MUST be greater than zero. Sequence
numbers are unbounded and do not wrap. numbers are unbounded and do not wrap.
fsnOffset : VLU, the difference between the Sequence Number and the fsnOffset: VLU, the difference between the sequence number and the
Forward Sequence Number. This field MUST NOT be zero if the Forward Sequence Number. This field MUST NOT be zero if the
abandon flag is not set. This field MUST NOT be greater than abandon flag is not set. This field MUST NOT be greater than
sequenceNumber. sequenceNumber.
forwardSequenceNumber : The flow sender will not send (or resend) forwardSequenceNumber: The flow sender will not send (or resend) any
any fragment with a sequence number less than or equal to the fragment with a sequence number less than or equal to the Forward
forward sequence number. Sequence Number.
options : If the optionsPresent flag is set, a list of zero or more options: If the optionsPresent flag is set, a list of zero or more
Options terminated by a Marker is present. See Section 2.3.11.1 Options terminated by a Marker is present. See Section 2.3.11.1
for defined options. for defined options.
userData : The actual user data for this fragment. userData: The actual user data for this fragment.
The use of User Data is detailed in Section 3.6.2. The use of User Data is detailed in Section 3.6.2.
2.3.11.1. Options for User Data 2.3.11.1. Options for User Data
This section lists options that may appear in User Data option lists. This section lists options that may appear in User Data option lists.
A conforming implementation MUST support the options in this section. A conforming implementation MUST support the options in this section.
A flow receiver MUST reject a flow containing a flow option that is A flow receiver MUST reject a flow containing a flow option that is
not understood if the option type is less than 8192 (0x2000). A flow not understood if the option type is less than 8192 (0x2000). A flow
receiver MUST ignore any flow option that is not understood if the receiver MUST ignore any flow option that is not understood if the
option type is 8192 or greater. option type is 8192 or greater.
The following option type codes are defined for User Data: The following option type codes are defined for User Data:
0x00 : Users's Per-Flow Metadata (Section 2.3.11.1.1) 0x00: User's Per-Flow Metadata (Section 2.3.11.1.1)
0x0a : Return Flow Association (Section 2.3.11.1.2) 0x0a: Return Flow Association (Section 2.3.11.1.2)
2.3.11.1.1. User's Per-Flow Metadata 2.3.11.1.1. User's Per-Flow Metadata
This option conveys the user's per-flow metadata for the flow to This option conveys the user's per-flow metadata for the flow to
which it's attached. which it's attached.
+-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| length \ | 0x00 \ | userMetadata | | length \ | 0x00 \ | userMetadata |
+-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
skipping to change at page 34, line 14 skipping to change at page 36, line 20
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
| length \ | 0x0a \ | flowID \ | | length \ | 0x0a \ | flowID \ |
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
struct returnFlowAssociationOptionValue_t struct returnFlowAssociationOptionValue_t
{ {
vlu_t flowID :variable*8; vlu_t flowID :variable*8;
} :variable*8; } :variable*8;
Consider endpoints A and B. Endpoint A begins a flow with identifier Consider endpoints A and B. Endpoint A begins a flow with
5 to endpoint B. A is the flow sender for A's flowID=5 and B is the identifier 5 to endpoint B. A is the flow sender for A's flowID=5,
flow receiver for A's flowID=5. B begins a return flow with and B is the flow receiver for A's flowID=5. B begins a return flow
identifier 7 to A in response to A's flowID=5. B is the flow sender with identifier 7 to A in response to A's flowID=5. B is the flow
for B's flowID=7 and A is the flow receiver for B's flowID=7. B sender for B's flowID=7, and A is the flow receiver for B's flowID=7.
sends this option with flowID set to 5 to indicate that B's flowID=7 B sends this option with flowID set to 5 to indicate that B's
is in response to and associated with A's flowID=5. flowID=7 is in response to and associated with A's flowID=5.
If there is a return association, the flow sender MUST send this If there is a return association, the flow sender MUST send this
option with the first User Data chunk for this flow in each packet option with the first User Data chunk for this flow in each packet
until an acknowledgement for this flow is received. A flow sender until an acknowledgement for this flow is received. A flow sender
SHOULD NOT send this option more than once for each flow in any one SHOULD NOT send this option more than once for each flow in any one
packet. A flow sender SHOULD NOT send this option for a flow once packet. A flow sender SHOULD NOT send this option for a flow once
the flow has been acknowledged. the flow has been acknowledged.
A flow MUST NOT indicate more than one return association. A flow MUST NOT indicate more than one return association.
A flow MUST indicate its return association, if any, upon its first A flow MUST indicate its return association, if any, upon its first
transmission of a User Data chunk. A return association can't be transmission of a User Data chunk. A return association can't be
added to a sending flow after it begins. added to a sending flow after it begins.
A flow receiver MUST reject a new receiving flow having a return flow A flow receiver MUST reject a new receiving flow having a return flow
association that does not indicate an F_OPEN sending flow. association that does not indicate an F_OPEN sending flow.
2.3.12. Next User Data Chunk 2.3.12. Next User Data Chunk
This chunk is equivalent to the User Data Chunk for purposes of This chunk is equivalent to the User Data chunk for purposes of
sending the user messages of a flow. When used, it MUST follow a sending the user messages of a flow. When used, it MUST follow a
User Data or another Next User Data chunk in the same packet. User Data chunk or another Next User Data chunk in the same packet.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x11 | chunkLength | | 0x11 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|O|r| F | r |A|F| |O|r| F | r |A|F|
|P|s| R | s |B|I| |P|s| R | s |B|I|
|T|v| A | v |N|N| |T|v| A | v |N|N|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
skipping to change at page 35, line 25 skipping to change at page 37, line 31
| L \ T \ V |... options ...| L \ T \ V | 0 \ | | L \ T \ V |... options ...| L \ T \ V | 0 \ |
\~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/ \~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| userData | | userData |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
struct nextUserDataChunkPayload_t struct nextUserDataChunkPayload_t
{ {
bool_t optionsPresent :1; // "OPT" bool_t optionsPresent :1; // "OPT"
uintn_t reserved1 :1; // "rsv" uintn_t reserved1 :1; // "rsv"
uintn_t fragmentControl :2; // "FRA uintn_t fragmentControl :2; // "FRA"
// 0=whole, 1=begin, 2=end, 3=middle // 0=whole, 1=begin, 2=end, 3=middle
uintn_t reserved2 :2; // "rsv" uintn_t reserved2 :2; // "rsv"
bool_t abandon :1; // "ABN" bool_t abandon :1; // "ABN"
bool_t final :1; // "FIN" bool_t final :1; // "FIN"
if(optionsPresent) if(optionsPresent)
optionList_t options :variable*8; optionList_t options :variable*8;
uint8_t userData[remainder()]; uint8_t userData[remainder()];
} :chunkLength*8; } :chunkLength*8;
This chunk is considered to be for the same flowID as the most This chunk is considered to be for the same flowID as the most
recently preceding User Data or Next User Data chunk in the same recently preceding User Data or Next User Data chunk in the same
packet, having the same Forward Sequence Number, and having the next packet, having the same Forward Sequence Number, and having the next
sequence number. The optionsPresent, fragmentControl, abandon, and sequence number. The optionsPresent, fragmentControl, abandon, and
final flags, and the options (if present) have the same final flags, and the options (if present), have the same
interpretation as for the User Data chunk. interpretation as for the User Data chunk.
... ...
----------+------------------------------------ ----------+------------------------------------
10 00 07 | User Data chunk, length=7 10 00 07 | User Data chunk, length=7
00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0 00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0
02 05 03 | flowID=2, seq#=5, fsn=(5-3)=2 02 05 03 | flowID=2, seq#=5, fsn=(5-3)=2
00 01 02 | data 3 bytes: 00, 01, 02 00 01 02 | data 3 bytes: 00, 01, 02
----------+------------------------------------ ----------+------------------------------------
11 00 04 | Next User Data chunk,length=4 11 00 04 | Next User Data chunk,length=4
00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0 00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0
| flowID=2, seq#=6, fsn=2 | flowID=2, seq#=6, fsn=2
03 04 05 | data 3 bytes: 03, 04, 05 03 04 05 | data 3 bytes: 03, 04, 05
----------+------------------------------------ ----------+------------------------------------
11 00 04 | Next User Data chunk, length=4 11 00 04 | Next User Data chunk, length=4
00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0 00 | OPT=0, FRA=0 "whole", ABN=0, FIN=0
| flowID=2, seq#=7, fsn=2 | flowID=2, seq#=7, fsn=2
06 07 08 | data 3 bytes: 06, 07, 08 06 07 08 | data 3 bytes: 06, 07, 08
----------+------------------------------------ ----------+------------------------------------
Figure 3: Sequential messages in one packet using Next User Data Figure 3: Sequential Messages in One Packet Using Next User Data
The use of Next User Data is detailed in Section 3.6.2.3.2. The use of Next User Data is detailed in Section 3.6.2.3.2.
2.3.13. Data Acknowledgement Bitmap Chunk (Bitmap Ack) 2.3.13. Data Acknowledgement Bitmap Chunk (Bitmap Ack)
This chunk is sent by the flow receiver to indicate to the flow This chunk is sent by the flow receiver to indicate to the flow
sender the User Data fragment sequence numbers that have been sender the User Data fragment sequence numbers that have been
received for one flow. It is only allowed in a packet belonging to received for one flow. It is only allowed in a packet belonging to
an established session and having packet mode 1 or 2. an established session and having packet mode 1 or 2.
The flow receiver can choose to acknowledge User Data with this chunk The flow receiver can choose to acknowledge User Data with this chunk
or with a Range Ack. It SHOULD choose whichever format has the most or with a Range Ack. It SHOULD choose whichever format has the most
compact encoding of the sequence numbers received. compact encoding of the sequence numbers received.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x50 | chunkLength | | 0x50 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
| flowID \ | bufAvail \ | cumAck \ | | flowID \ | bufAvail \ | cumAck \ |
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
skipping to change at page 37, line 38 skipping to change at page 40, line 4
{ {
for(bitPosition = 8; bitPosition > 0; bitPosition--) for(bitPosition = 8; bitPosition > 0; bitPosition--)
{ {
bool_t bit :1; bool_t bit :1;
if(bit) if(bit)
acknowledge(ackCursor + bitPosition); acknowledge(ackCursor + bitPosition);
} }
ackCursor += 8; ackCursor += 8;
} }
} :chunkLength*8; } :chunkLength*8;
flowID: VLU, the flow identifier.
flowID : VLU, the flow identifier. bufferBlocksAvailable: VLU, the number of 1024-byte blocks of User
bufferBlocksAvailable : VLU, the number of 1024-byte blocks of User
Data that the receiver is currently able to accept. Data that the receiver is currently able to accept.
Section 3.6.3.5 describes how to calculate this value. Section 3.6.3.5 describes how to calculate this value.
cumulativeAck : VLU, the acknowledgement of every fragment sequence cumulativeAck: VLU, the acknowledgement of every fragment sequence
number in this flow that is less than or equal to this value. number in this flow that is less than or equal to this value.
This MUST NOT be less than the highest forward sequence number This MUST NOT be less than the highest Forward Sequence Number
received in this flow. received in this flow.
bit field : A sequence of zero or more bytes representing a bit bit field: A sequence of zero or more bytes representing a bit field
field of received fragment sequence numbers after the cumulative of received fragment sequence numbers after the cumulative
acknowledgement, least significant bit first. A set bit indicates acknowledgement, least significant bit first. A set bit indicates
receipt of a sequence number. A clear bit indicates that sequence receipt of a sequence number. A clear bit indicates that sequence
number was not received. The least significant bit of the first number was not received. The least significant bit of the first
byte is the second sequence number following the cumulative byte is the second sequence number following the cumulative
acknowledgement, the next bit is the third sequence number acknowledgement, the next bit is the third sequence number
following, and so on. following, and so on.
50 00 05 | Bitmap Ack, length=5 bytes Figure 4 shows an example Bitmap Ack indicating acknowledgement of
05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16 fragment sequence numbers 0 through 16, 18, 21 through 24, 27,
79 06 | 01111001 00000110 = 18, 21, 22, 23, 24, 27, 28 and 28.
Example bitmap ack indicating acknowledgement of fragment sequence 50 00 05 | Bitmap Ack, length=5 bytes
numbers 0 through 16, 18, 21 through 24, 27 and 28. 05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16
79 06 | 01111001 00000110 = 18, 21, 22, 23, 24, 27, 28
Figure 4 Figure 4: Example Bitmap Ack
2.3.14. Data Acknowledgement Ranges Chunk (Range Ack) 2.3.14. Data Acknowledgement Ranges Chunk (Range Ack)
This chunk is sent by the flow receiver to indicate to the flow This chunk is sent by the flow receiver to indicate to the flow
sender the User Data fragment sequence numbers that have been sender the User Data fragment sequence numbers that have been
received for one flow. It is only allowed in a packet belonging to received for one flow. It is only allowed in a packet belonging to
an established session and having packet mode 1 or 2. an established session and having packet mode 1 or 2.
The flow receiver can choose to acknowledge User Data with this chunk The flow receiver can choose to acknowledge User Data with this chunk
or with a Bitmap Ack. It SHOULD choose whichever format has the most or with a Bitmap Ack. It SHOULD choose whichever format has the most
compact encoding of the sequence numbers received. compact encoding of the sequence numbers received.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x51 | chunkLength | | 0x51 | chunkLength |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
| flowID \ | bufAvail \ | cumAck \ | | flowID \ | bufAvail \ | cumAck \ |
+-------------/-+-------------/-+-------------/-+ +-------------/-+-------------/-+-------------/-+
+~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+ +~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+
skipping to change at page 39, line 42 skipping to change at page 42, line 4
vlu_t receivedMinusOne :variable*8; // "#recv-1" vlu_t receivedMinusOne :variable*8; // "#recv-1"
ackCursor++; ackCursor++;
rangeFrom = ackCursor + holesMinusOne + 1; rangeFrom = ackCursor + holesMinusOne + 1;
rangeTo = rangeFrom + receivedMinusOne; rangeTo = rangeFrom + receivedMinusOne;
acknowledge(rangeFrom through rangeTo); acknowledge(rangeFrom through rangeTo);
ackCursor = rangeTo; ackCursor = rangeTo;
} }
} :chunkLength*8; } :chunkLength*8;
flowID: VLU, the flow identifier.
flowID : VLU, the flow identifier. bufferBlocksAvailable: VLU, the number of 1024-byte blocks of User
bufferBlocksAvailable : VLU, the number of 1024-byte blocks of User
Data that the receiver is currently able to accept. Data that the receiver is currently able to accept.
Section 3.6.3.5 describes how to calculate this value. Section 3.6.3.5 describes how to calculate this value.
cumulativeAck : VLU, the acknowledgement of every fragment sequence cumulativeAck: VLU, the acknowledgement of every fragment sequence
number in this flow that is less than or equal to this value. number in this flow that is less than or equal to this value.
This MUST NOT be less than the highest forward sequence number This MUST NOT be less than the highest Forward Sequence Number
received in this flow. received in this flow.
holesMinusOne / receivedMinusOne : Zero or more acknowledgement holesMinusOne / receivedMinusOne: Zero or more acknowledgement
ranges, run-length encoded. Runs are encoded as zero or more ranges, run-length encoded. Runs are encoded as zero or more
pairs of VLUs indicating the number (minus one) of missing pairs of VLUs indicating the number (minus one) of missing
sequence numbers followed by the number (minus one) of received sequence numbers followed by the number (minus one) of received
sequence numbers, starting at the cumulative acknowledgement. sequence numbers, starting at the cumulative acknowledgement.
NOTE: If a parser syntax error is encountered here (that is, if NOTE: If a parser syntax error is encountered here (that is, if
the chunk is truncated such that not enough bytes remain to the chunk is truncated such that not enough bytes remain to
completely encode both VLUs of the acknowledgement range), then completely encode both VLUs of the acknowledgement range), then
treat and process this chunk as though it was properly formed up treat and process this chunk as though it was properly formed up
to the last completely encoded range. to the last completely encoded range.
51 00 07 | Range Ack, length=7 Figure 5 shows an example Range Ack indicating acknowledgement of
05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16 fragment sequence numbers 0 through 16, 18, 21, 22, 23, and 24.
00 00 | holes=1, received=1 -- missing 17, received 18
01 03 | holes=2, received=4 -- missing 19..20, received 21..24
Example range ack indicating acknowledgement of fragment sequence
numbers 0 through 16, 18, 21, 22, 23, 24.
Figure 5
51 00 07 | Range Ack, length=9 51 00 07 | Range Ack, length=7
05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16 05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16
00 00 | holes=1, received=1 -- missing 17, received 18 00 00 | holes=1, received=1 -- missing 17, received 18
01 83 | holes=2, received=VLU parse error, ignore this range 01 03 | holes=2, received=4 -- missing 19..20, received 21..24
Example range ack indicating acknowledgement of fragment sequence Figure 5: Example Range Ack
numbers 0 through 16 and 18, with a truncated last range. Note the
truncation and parse error does not abort the entire chunk in this
case.
Figure 6 Figure 6 shows an example Range Ack indicating acknowledgement of
fragment sequence numbers 0 through 16 and 18, with a truncated
last range. Note that the truncation and parse error does not
abort the entire chunk in this case.
51 00 07 | Range Ack, length=9
05 7f 10 | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16
00 00 | holes=1, received=1 -- missing 17, received 18
01 83 | holes=2, received=VLU parse error, ignore this range
Figure 6: Example Truncated Range Ack
2.3.15. Buffer Probe Chunk 2.3.15. Buffer Probe Chunk
This chunk is sent by the flow sender in order to request the current This chunk is sent by the flow sender in order to request the current
available receive buffer (in the form of a Data Acknowledgement) for available receive buffer (in the form of a Data Acknowledgement) for
a flow. It is only allowed in a packet belonging to an established a flow. It is only allowed in a packet belonging to an established
session and having packet mode 1 or 2. session and having packet mode 1 or 2.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
skipping to change at page 41, line 18 skipping to change at page 43, line 25
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+ +-------------/-+
| flowID \ | | flowID \ |
+-------------/-+ +-------------/-+
struct bufferProbeChunkPayload_t struct bufferProbeChunkPayload_t
{ {
vlu_t flowID :variable*8; vlu_t flowID :variable*8;
} :chunkLength*8; } :chunkLength*8;
flowID : VLU, the flow identifier. flowID: VLU, the flow identifier.
The receiver of this chunk SHOULD reply as immediately as is The receiver of this chunk SHOULD reply as immediately as is
practical with a Data Acknowledgement. practical with a Data Acknowledgement.
2.3.16. Flow Exception Report Chunk 2.3.16. Flow Exception Report Chunk
This chunk is sent by the flow receiver to indicate that it is not This chunk is sent by the flow receiver to indicate that it is not
(or is no longer) interested in the flow and would like the flow (or is no longer) interested in the flow and would like the flow
sender to close the flow. This chunk SHOULD precede every Data sender to close the flow. This chunk SHOULD precede every Data
Acknowledgement chunk for the same flow in this condition. Acknowledgement chunk for the same flow in this condition.
skipping to change at page 41, line 46 skipping to change at page 44, line 4
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-------------/-+-------------/-+ +-------------/-+-------------/-+
| flowID \ | exception \ | | flowID \ | exception \ |
+-------------/-+-------------/-+ +-------------/-+-------------/-+
struct flowExceptionReportChunkPayload_t struct flowExceptionReportChunkPayload_t
{ {
vlu_t flowID :variable*8; vlu_t flowID :variable*8;
vlu_t exception :variable*8; vlu_t exception :variable*8;
} :chunkLength*8; } :chunkLength*8;
flowID: VLU, the flow identifier.
flowID : VLU, the flow identifier. exception: VLU, the application-defined exception code being
exception : VLU, the application-defined exception code being
reported. reported.
A receiving RTMFP might reject a flow automatically, for example if A receiving RTMFP might reject a flow automatically, for example if
it is missing metadata, or if an invalid return association is it is missing metadata, or if an invalid return association is
specified. In circumstances where an RTMFP rejects a flow specified. In circumstances where an RTMFP rejects a flow
automatically, the exception code MUST be 0. The application can automatically, the exception code MUST be 0. The application can
specify any exception code, including 0, when rejecting a flow. All specify any exception code, including 0, when rejecting a flow. All
non-zero exception codes are reserved for the application. non-zero exception codes are reserved for the application.
2.3.17. Session Close Request Chunk (Close) 2.3.17. Session Close Request Chunk (Close)
skipping to change at page 42, line 28 skipping to change at page 44, line 34
| 0x0c | 0 | | 0x0c | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This chunk has no payload. This chunk has no payload.
The use of Close is detailed in Section 3.5.5. The use of Close is detailed in Section 3.5.5.
2.3.18. Session Close Acknowledgement Chunk (Close Ack) 2.3.18. Session Close Acknowledgement Chunk (Close Ack)
This chunk is sent in response to a Session Close Request to indicate This chunk is sent in response to a Session Close Request to indicate
the sender has terminated the session. It is only allowed in a that the sender has terminated the session. It is only allowed in a
packet belonging to an established or closing session and having packet belonging to an established or closing session and having
packet mode 1 or 2. packet mode 1 or 2.
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x4c | 0 | | 0x4c | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This chunk has no payload. This chunk has no payload.
skipping to change at page 43, line 4 skipping to change at page 45, line 6
0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 0x4c | 0 | | 0x4c | 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This chunk has no payload. This chunk has no payload.
The use of Close Ack is detailed in Section 3.5.5. The use of Close Ack is detailed in Section 3.5.5.
3. Operation 3. Operation
3.1. Overview 3.1. Overview
+--------+ +--------+ +--------+ +--------+
| Peer A | S E S S I O N | Peer B | | Peer A | S E S S I O N | Peer B |
| /=============================\ | | /=============================\ |
| || Flows || | | || Flows || |
| ||---------------------------->|| | | ||---------------------------->|| |
| ||---------------------------->|| | | ||---------------------------->|| |
| ||<----------------------------|| | | ||<----------------------------|| |
| ||<----------------------------|| | | ||<----------------------------|| |
| ||<----------------------------|| | | ||<----------------------------|| |
| \=============================/ | | \=============================/ |
| | | | | | | |
| | +--------+ | | +--------+
| | | |
| | +--------+ | | +--------+
| | S E S S I O N | Peer C | | | S E S S I O N | Peer C |
| /=============================\ | | /=============================\ |
| || Flows || | | || Flows || |
| ||---------------------------->|| | | ||---------------------------->|| |
| ||<----------------------------|| | | ||<----------------------------|| |
| ||<----------------------------|| | | ||<----------------------------|| |
| \=============================/ | | \=============================/ |
| | | | | | | |
+--------+ +--------+ +--------+ +--------+
Figure 7: Sessions between pairs of communicating endpoints Figure 7: Sessions between Pairs of Communicating Endpoints
Between any pair of communicating endpoints is a single, Between any pair of communicating endpoints is a single,
bidirectional, secured, congestion controlled session. bidirectional, secured, congestion controlled session.
Unidirectional flows convey messages from one end to the other within Unidirectional flows convey messages from one end to the other within
the session. the session.
An endpoint initiates a session to a far end when communication is An endpoint initiates a session to a far end when communication is
desired. An initiator begins with one or more candidate destination desired. An initiator begins with one or more candidate destination
socket addresses, and may learn and try more candidate addresses socket addresses, and it may learn and try more candidate addresses
during startup handshaking. Eventually a first suitable response is during startup handshaking. Eventually, a first suitable response is
received, and that endpoint is selected. Startup proceeds to the received, and that endpoint is selected. Startup proceeds to the
selected endpoint. In the case of session startup glare, one selected endpoint. In the case of session startup glare, one
endpoint is the prevailing initiator and the other assumes the role endpoint is the prevailing initiator and the other assumes the role
of responder. Encryption keys and session identifiers are negotiated of responder. Encryption keys and session identifiers are negotiated
between the endpoints, and the session is established. between the endpoints, and the session is established.
Each endpoint may begin sending message flows to the other end. For Each endpoint may begin sending message flows to the other end. For
each flow, the far end may accept it and deliver its messages to the each flow, the far end may accept it and deliver its messages to the
user, or it may reject the flow and transmit an exception to the user, or it may reject the flow and transmit an exception to the
sender. The flow receiver may close and reject a flow at a later sender. The flow receiver may close and reject a flow at a later
time, after first accepting it. The flow receiver acknowledges all time, after first accepting it. The flow receiver acknowledges all
data sent to it regardless of whether the flow was accepted. data sent to it, regardless of whether the flow was accepted.
Acknowledgements drive a congestion control mechanism. Acknowledgements drive a congestion control mechanism.
An endpoint may have concurrent sessions with other far endpoints. An endpoint may have concurrent sessions with other far endpoints.
The multiple sessions are distinguished by a session identifier The multiple sessions are distinguished by a session identifier
rather than by socket address. This allows an endpoint's address to rather than by socket address. This allows an endpoint's address to
change mid-session without having to tear down and re-establish a change mid-session without having to tear down and re-establish a
session. The existing cryptographic state for a session can be used session. The existing cryptographic state for a session can be used
to verify a change of address while protecting against session to verify a change of address while protecting against session
hijacking or denial-of-service. hijacking or denial of service.
A sender may indicate to a receiver that some user messages are of a A sender may indicate to a receiver that some user messages are of a
time-critical or real-time nature. A receiver may indicate to time critical or real-time nature. A receiver may indicate to
senders on concurrent sessions that it is receiving time-critical senders on concurrent sessions that it is receiving time critical
messages from another endpoint. The other senders SHOULD modify messages from another endpoint. The other senders SHOULD modify
their congestion control parameters to yield capacity to the session their congestion control parameters to yield capacity to the session
carrying time-critical messages. carrying time critical messages.
A sender may close a flow. The flow is completed when the receiver A sender may close a flow. The flow is completed when the receiver
has no outstanding gaps before the final fragment of the flow. The has no outstanding gaps before the final fragment of the flow. The
sender and receiver reserve a completed flow's identifier for a time sender and receiver reserve a completed flow's identifier for a time
to allow in flight messages to drain from the network. to allow in-flight messages to drain from the network.
Eventually, neither end will have any flows open to the other. The Eventually, neither end will have any flows open to the other. The
session will be idle and quiescent. Either end may reliably close session will be idle and quiescent. Either end may reliably close
the session to recover its resources. the session to recover its resources.
In certain circumstances, an endpoint may be ceasing operation and In certain circumstances, an endpoint may be ceasing operation and
not have time to wait for acknowledgement of a reliable session not have time to wait for acknowledgement of a reliable session
close. In this case the halting endpoint may send an abrupt session close. In this case, the halting endpoint may send an abrupt session
close to advise the far end that it is halting immediately. close to advise the far end that it is halting immediately.
3.2. Endpoint Identity 3.2. Endpoint Identity
Each RTMFP endpoint has an identity. The identity is encoded in a Each RTMFP endpoint has an identity. The identity is encoded in a
certificate. This specification doesn't mandate any particular certificate. This specification doesn't mandate any particular
certificate format, cryptographic algorithms, or cryptographic certificate format, cryptographic algorithms, or cryptographic
properties for certificates. properties for certificates.
An endpoint is named by an Endpoint Discriminator. This An endpoint is named by an Endpoint Discriminator. This
specification doesn't mandate any particular format for Endpoint specification doesn't mandate any particular format for Endpoint
Discriminators. Discriminators.
An Endpoint Discriminator MAY select more than one identity, and MAY An Endpoint Discriminator MAY select more than one identity and MAY
match more than one distinct certificate. match more than one distinct certificate.
Multiple distinct Endpoint Discriminators MAY match one certificate. Multiple distinct Endpoint Discriminators MAY match one certificate.
It is RECOMMENDED that multiple endpoints not have the same identity. It is RECOMMENDED that multiple endpoints not have the same identity.
Entities with the same identity are indistinguishable during session Entities with the same identity are indistinguishable during session
startup, which could be undesirable in some applications. startup; this situation could be undesirable in some applications.
An endpoint MAY have more than one address. An endpoint MAY have more than one address.
The Cryptography Profile implements the following functions for The Cryptography Profile implements the following functions for
identities, certificates, and Endpoint Discriminators, whose identities, certificates, and Endpoint Discriminators, whose
operation MUST be deterministic: operation MUST be deterministic:
o Test whether a given certificate is authentic. Authenticity can o Test whether a given certificate is authentic. Authenticity can
comprise verifying an issuer signature chain in a public key comprise verifying an issuer signature chain in a public key
infrastructure. infrastructure.
skipping to change at page 45, line 30 skipping to change at page 47, line 32
certificate. certificate.
o Test whether a given Endpoint Discriminator selects the local o Test whether a given Endpoint Discriminator selects the local
endpoint. endpoint.
o Generate a Canonical Endpoint Discriminator for a given o Generate a Canonical Endpoint Discriminator for a given
certificate. Canonical Endpoint Discriminators for distinct certificate. Canonical Endpoint Discriminators for distinct
identities SHOULD be distinct. If two distinct identities have identities SHOULD be distinct. If two distinct identities have
the same Canonical Endpoint Discriminator, an initiator might the same Canonical Endpoint Discriminator, an initiator might
abort a new opening session to the second identity abort a new opening session to the second identity
(Section 3.5.1.1.1), which might not be desired. (Section 3.5.1.1.1); this behavior might not be desirable.
o Given a certificate, a message, and a digital signature over the o Given a certificate, a message, and a digital signature over the
message, test whether the signature is valid and generated by the message, test whether the signature is valid and generated by the
owner of the certificate. owner of the certificate.
o Generate a digital signature for a given message corresponding to o Generate a digital signature for a given message corresponding to
the near identity. the near identity.
o Given the near identity and a far certificate, determine which one o Given the near identity and a far certificate, determine which one
shall prevail as Initiator and which shall assume the Responder shall prevail as Initiator and which shall assume the Responder
role in the case of startup glare. The far end MUST arrive at the role in the case of startup glare. The far end MUST arrive at the
same conclusion. A comparison function can comprise performing a same conclusion. A comparison function can comprise performing a
lexicographic ordering of the binary certificates, and declaring lexicographic ordering of the binary certificates, declaring the
the far identity the prevailing endpoint if the far certificate is far identity the prevailing endpoint if the far certificate is
ordered before the near certificate, and otherwise declaring the ordered before the near certificate, and otherwise declaring the
near identity to be the prevailing endpoint. near identity to be the prevailing endpoint.
o Given a first certificate and a second certificate, test whether a o Given a first certificate and a second certificate, test whether a
new incoming session from the second shall override an existing new incoming session from the second shall override an existing
session with the first. It is RECOMMENDED that the test comprise session with the first. It is RECOMMENDED that the test comprise
testing whether the certificates are bitwise identical. testing whether the certificates are bitwise identical.
All other semantics for certificates and Endpoint Discriminators are All other semantics for certificates and Endpoint Discriminators are
determined by the Cryptography Profile and the application. determined by the Cryptography Profile and the application.
3.3. Packet Multiplex 3.3. Packet Multiplex
An RTMFP typically has one or more interfaces through which it An RTMFP typically has one or more interfaces through which it
communicates with other RTMFP endpoints. RTMFP can communicate with communicates with other RTMFP endpoints. RTMFP can communicate with
multiple distinct other RTMFP endpoints through each local interface. multiple distinct other RTMFP endpoints through each local interface.
Session multiplexing over a shared interface can facilitate peer-to- Session multiplexing over a shared interface can facilitate peer-to-
peer communications through a NAT, by enabling third party endpoints peer communications through a NAT, by enabling third-party endpoints
such as Forwarders (Section 3.5.1.5) and Redirectors such as Forwarders (Section 3.5.1.5) and Redirectors
(Section 3.5.1.4) to observe the translated public address and inform (Section 3.5.1.4) to observe the translated public address and inform
peers of the translation. peers of the translation.
An interface is typically a UDP socket (Section 2.2.1), but MAY be An interface is typically a UDP socket (Section 2.2.1) but MAY be any
any suitable datagram transport service where endpoints can be suitable datagram transport service where endpoints can be addressed
addressed by IPv4 or IPv6 socket addresses. by IPv4 or IPv6 socket addresses.
RTMFP uses a session ID to multiplex and demultiplex communications RTMFP uses a session ID to multiplex and demultiplex communications
with distinct endpoints (Section 2.2.2), in addition to the endpoint with distinct endpoints (Section 2.2.2), in addition to the endpoint
socket address. This allows an RTMFP to detect a far-end address socket address. This allows an RTMFP to detect a far-end address
change (as might happen for example in mobile and wireless scenarios) change (as might happen, for example, in mobile and wireless
and for communication sessions to survive address changes. This also scenarios) and allows communication sessions to survive address
allows an RTMFP to act as a Forwarder or Redirector for an endpoint changes. This also allows an RTMFP to act as a Forwarder or
with which it has an active session, by distinguishing startup Redirector for an endpoint with which it has an active session, by
packets from those of the active session. distinguishing startup packets from those of the active session.
On receiving a packet, an RTMFP decodes the session ID to look up the On receiving a packet, an RTMFP decodes the session ID to look up the
corresponding session information context and decryption key. corresponding session information context and decryption key.
Session ID 0 is reserved for session startup and MUST NOT be used for Session ID 0 is reserved for session startup and MUST NOT be used for
an active session. A packet for session ID 0 uses the Default an active session. A packet for Session ID 0 uses the Default
Session Key as defined by the Cryptography Profile. Session Key as defined by the Cryptography Profile.
3.4. Packet Fragmentation 3.4. Packet Fragmentation
When an RTMFP packet (Section 2.2.4) is unavoidably larger than the When an RTMFP packet (Section 2.2.4) is unavoidably larger than the
path MTU (such as a startup packet containing an RHello path MTU (such as a startup packet containing an RHello
(Section 2.3.4) or IIKeying (Section 2.3.7) chunk with a large (Section 2.3.4) or IIKeying (Section 2.3.7) chunk with a large
certificate), it can be fragmented into segments that do not exceed certificate), it can be fragmented into segments that do not exceed
the path MTU using the Packet Fragment chunk (Section 2.3.1). the path MTU by using the Packet Fragment chunk (Section 2.3.1).
The packet fragmentation mechanism SHOULD be used only to segment The packet fragmentation mechanism SHOULD be used only to segment
unavoidably large packets. Accordingly, this mechanism SHOULD be unavoidably large packets. Accordingly, this mechanism SHOULD be
employed only during session startup with session ID 0. This employed only during session startup with Session ID 0. This
mechanism MUST NOT be used instead of the natural fragmentation mechanism MUST NOT be used instead of the natural fragmentation
mechanism of the User Data (Section 2.3.11) and Next User Data mechanism of the User Data (Section 2.3.11) and Next User Data
(Section 2.3.12) chunks for dividing the messages of the user's data (Section 2.3.12) chunks for dividing the messages of the user's data
flows into segments that do not exceed the path MTU. flows into segments that do not exceed the path MTU.
A fragmented plain RTMFP packet is reassembled by concatenating the A fragmented plain RTMFP packet is reassembled by concatenating the
packetFragment fields of the fragments for the packet in contiguous packetFragment fields of the fragments for the packet in contiguous
ascending order, starting from index 0 through and including the ascending order, starting from index 0 through and including the
final fragment. final fragment.
When reassembling packets for Session ID 0, a receiver SHOULD When reassembling packets for Session ID 0, a receiver SHOULD
identify the packets by both the socket address from which the packet identify the packets by the socket address from which the packet
containing the fragment was received as well as the indicated containing the fragment was received, as well as the indicated
packetID. packetID.
A receiver SHOULD allow up to 60 seconds to completely receive a A receiver SHOULD allow up to 60 seconds to completely receive a
fragmented packet for which progress is being made. A packet is fragmented packet for which progress is being made. A packet is
progressing if at least one new fragment for it was received in the progressing if at least one new fragment for it was received in the
last second. last second.
A receiver MUST discard a Packet Fragment chunk having an empty A receiver MUST discard a Packet Fragment chunk having an empty
packetFragment field. packetFragment field.
skipping to change at page 47, line 35 skipping to change at page 49, line 43
receiver MUST discard any new Packet Fragment chunk received in a receiver MUST discard any new Packet Fragment chunk received in a
packet with a mode different from the mode of the packet containing packet with a mode different from the mode of the packet containing
the first received fragment. A receiver MUST discard any reassembled the first received fragment. A receiver MUST discard any reassembled
packet with a mode different than the packets containing its packet with a mode different than the packets containing its
fragments. fragments.
In order to avoid jamming the network, the sender MUST rate limit In order to avoid jamming the network, the sender MUST rate limit
packet transmission. In the absence of specific path capacity packet transmission. In the absence of specific path capacity
information (for instance, during session startup), a sender SHOULD information (for instance, during session startup), a sender SHOULD
NOT send more than 4380 bytes nor more than four packets per distinct NOT send more than 4380 bytes nor more than four packets per distinct
endpoint every 200ms. endpoint every 200 ms.
To avoid resource exhaustion, a receiver SHOULD limit the number of To avoid resource exhaustion, a receiver SHOULD limit the number of
concurrent packet reassembly buffers and the size of each buffer. concurrent packet reassembly buffers and the size of each buffer.
Limits can depend on the expected size of reassembled packets, the Limits can depend, for example, on the expected size of reassembled
rate at which fragmented packets are expected to be received and packets, on the rate at which fragmented packets are expected to be
degree of interleaving, and the expected function of the receiver. received, on the expected degree of interleaving, and on the expected
Limits can depend on the available resources of the receiver. There function of the receiver. Limits can depend on the available
can be different limits for packets with Session ID 0 and packets for resources of the receiver. There can be different limits for packets
established sessions. For example, a busy server might need to allow with Session ID 0 and packets for established sessions. For example,
for several hundred concurrent packet reassembly buffers to a busy server might need to allow for several hundred concurrent
accommodate hundreds of connection requests per second with packet reassembly buffers to accommodate hundreds of connection
potentially interleaved fragments, but a client device with requests per second with potentially interleaved fragments, but a
constrained resources could allow just a few reassembly buffers. In client device with constrained resources could allow just a few
the absence of specific information regarding the expected size of reassembly buffers. In the absence of specific information regarding
reassembled packets, a receiver should set the limit for each packet the expected size of reassembled packets, a receiver should set the
reassembly buffer to 65536 bytes. limit for each packet reassembly buffer to 65536 bytes.
3.5. Sessions 3.5. Sessions
A session is the protocol relationship between a pair of A session is the protocol relationship between a pair of
communicating endpoints, comprising the shared and endpoint-specific communicating endpoints, comprising the shared and endpoint-specific
information context necessary to carry out the communication. The information context necessary to carry out the communication. The
session context at each end includes at least: session context at each end includes at least:
o TS_RX: the last timestamp received from the far end; o TS_RX: the last timestamp received from the far end;
skipping to change at page 48, line 27 skipping to change at page 50, line 34
o TS_ECHO_TX: the last timestamp echo sent to the far end; o TS_ECHO_TX: the last timestamp echo sent to the far end;
o MRTO: the measured retransmission timeout; o MRTO: the measured retransmission timeout;
o ERTO: the effective retransmission timeout; o ERTO: the effective retransmission timeout;
o Cryptographic keys for encrypting and decrypting packets, and for o Cryptographic keys for encrypting and decrypting packets, and for
verifying the validity of packets, according to the Cryptography verifying the validity of packets, according to the Cryptography
Profile; Profile;
o Cryptographic near and far nonces, according to the Cryptography o Cryptographic near and far nonces according to the Cryptography
Profile, the near nonce being the far end's far nonce, and vice Profile, where the near nonce is the far end's far nonce, and vice
versa; versa;
o The certificate of the far end; o The certificate of the far end;
o The receive session identifier, used by the far end when sending o The receive session identifier, used by the far end when sending
packets to this end; packets to this end;
o The send session identifier to use when sending packets to the far o The send session identifier to use when sending packets to the far
end; end;
o DESTADDR: the socket address to which to send packets to the far o DESTADDR: the destination socket address to use when sending
end; packets to the far end;
o The set of all sending flow contexts (Section 3.6.2); o The set of all sending flow contexts (Section 3.6.2);
o The set of all receiving flow contexts (Section 3.6.3); o The set of all receiving flow contexts (Section 3.6.3);
o The transmission budget, which controls the rate at which data is o The transmission budget, which controls the rate at which data is
sent into the network (for example, a congestion window); sent into the network (for example, a congestion window);
o S_OUTSTANDING_BYTES: the total amount of user message data o S_OUTSTANDING_BYTES: the total amount of user message data
outstanding, or in flight, in the network; that is the sum of the outstanding, or in flight, in the network -- that is, the sum of
F_OUTSTANDING_BYTES of each sending flow in the session; the F_OUTSTANDING_BYTES of each sending flow in the session;
o RX_DATA_PACKETS: a count of the number of received packets o RX_DATA_PACKETS: a count of the number of received packets
containing at least one User Data chunk since the last containing at least one User Data chunk since the last
acknowledgement was sent, initially 0; acknowledgement was sent, initially 0;
o ACK_NOW: a boolean flag indicating whether an acknowledgement o ACK_NOW: a boolean flag indicating whether an acknowledgement
should be sent immediately, initially false; should be sent immediately, initially false;
o DELACK_ALARM: an alarm to trigger an acknowledgement after a o DELACK_ALARM: an alarm to trigger an acknowledgement after a
delay, initially unset; delay, initially unset;
o The state, at any time being one of the following values: the o The state, at any time being one of the following values: the
opening states S_IHELLO_SENT and S_KEYING_SENT; the open state opening states S_IHELLO_SENT and S_KEYING_SENT, the open state
S_OPEN; the closing states S_NEARCLOSE and S_FARCLOSE_LINGER; and S_OPEN, the closing states S_NEARCLOSE and S_FARCLOSE_LINGER, and
the closed states S_CLOSED and S_OPEN_FAILED; and the closed states S_CLOSED and S_OPEN_FAILED; and
o The role of this end of the session, which is either Initiator or o The role -- either Initiator or Responder -- of this end of the
Responder. session.
Note: this diagram is only a summary of state transitions and their Note: The following diagram is only a summary of state transitions
causing events, and is not a complete operational specification. and their causing events, and is not a complete operational
specification.
rcv IIKeying Glare rcv IIKeying Glare
far prevails +-------------+ ultimate open timeout far prevails +-------------+ ultimate open timeout
+--------------|S_IHELLO_SENT|-------------+ +--------------|S_IHELLO_SENT|-------------+
| +-------------+ | | +-------------+ |
| |rcv RHello | | |rcv RHello |
| | v | | v
| v +-------------+ | v +-------------+
|<-----------(duplicate session?) |S_OPEN_FAILED| |<-----------(duplicate session?) |S_OPEN_FAILED|
| yes |no +-------------+ | yes |no +-------------+
| | ^ | | ^
| rcv IIKeying Glare v | | rcv IIKeying Glare v |
| far prevails +-------------+ | | far prevails +-------------+ |
|<-------------|S_KEYING_SENT|-------------+ |<-------------|S_KEYING_SENT|-------------+
| +-------------+ ultimate open timeout | +-------------+ ultimate open timeout
| |rcv RIKeying | |rcv RIKeying
| | | |
| rcv v | rcv v
| +-+ IIKeying +--------+ rcv Close Request | +-+ IIKeying +--------+ rcv Close Request
| |X|---------->| S_OPEN |--------------------+ | |X|---------->| S_OPEN |--------------------+
| +-+ +--------+ | | +-+ +--------+ |
| | |ABRUPT CLOSE | | | |ABRUPT CLOSE |
| ORDERLY CLOSE| |or rcv Close Ack | | ORDERLY CLOSE| |or rcv Close Ack |
| | |or rcv IIKeying | | | |or rcv IIKeying |
| | | session override | | | | session override |
| | +-------+ | | | +-------+ |
| v | v | v | v
| +-----------+ | +-----------------+ | +-----------+ | +-----------------+
| |S_NEARCLOSE| | |S_FARCLOSE_LINGER| | |S_NEARCLOSE| | |S_FARCLOSE_LINGER|
| +-----------+ | +-----------------+ | +-----------+ | +-----------------+
| rcv Close Ack| | |rcv Close Ack | rcv Close Ack| | |rcv Close Ack
| or 90 seconds| v |or 19 seconds | or 90 seconds| v |or 19 seconds
| | +--------+ | | | +--------+ |
| +------>|S_CLOSED|<---------+ | +------>|S_CLOSED|<---------+
+-------------------------->| | +-------------------------->| |
+--------+ +--------+
Figure 8: Session state diagram Figure 8: Session State Diagram
3.5.1. Startup 3.5.1. Startup
3.5.1.1. Normal Handshake 3.5.1.1. Normal Handshake
RTMFP sessions are established with a 4-way handshake in two round RTMFP sessions are established with a 4-way handshake in two round
trips. The Initiator begins by sending an IHello to one or more trips. The initiator begins by sending an IHello to one or more
candidate addresses for the desired destination endpoint. A candidate addresses for the desired destination endpoint. A
Responder statelessly sends an RHello in response. The first correct responder statelessly sends an RHello in response. The first correct
RHello received at the Initiator is selected; all others are ignored. RHello received at the initiator is selected; all others are ignored.
The Initiator computes its half of the session keying and sends an The initiator computes its half of the session keying and sends an
IIKeying. The Responder receives the IIKeying, and if it is IIKeying. The responder receives the IIKeying and, if it is
acceptable, computes its half of the session keying, at which point acceptable, computes its half of the session keying, at which point
it can also compute the shared session keying and session nonces. it can also compute the shared session keying and session nonces.
The Responder creates a new S_OPEN session with the Initiator, and The responder creates a new S_OPEN session with the initiator and
sends an RIKeying. The Initiator receives the RIKeying, and if it is sends an RIKeying. The initiator receives the RIKeying and, if it is
acceptable, it computes the shared session keying and session nonces. acceptable, computes the shared session keying and session nonces.
The Initiator's session is now S_OPEN. The initiator's session is now S_OPEN.
. Initiator Responder . . Initiator Responder .
| IHello | | IHello |
|(EPD,Tag) | |(EPD,Tag) |
S_IHELLO_SENT |(SID=0) | S_IHELLO_SENT |(SID=0) |
|------------------------------->| |------------------------------->|
| | | |
| RHello | | RHello |
| (Tag,Cookie,RCert)| | (Tag,Cookie,RCert)|
| (SID=0)| | (SID=0)|
|<-------------------------------| |<-------------------------------|
S_KEYING_SENT | | S_KEYING_SENT | |
| IIKeying | | IIKeying |
|(ISID,Cookie,ICert,SKIC,ISig) | |(ISID,Cookie,ICert,SKIC,ISig) |
|(SID=0) | |(SID=0) |
|------------------------------->| |------------------------------->|
| | | |
| RIKeying | | RIKeying |
| (RSID,SKRC,RSig)| | (RSID,SKRC,RSig)|
| (SID=ISID,Key=Default)| S_OPEN | (SID=ISID,Key=Default)| S_OPEN
|<-------------------------------| |<-------------------------------|
S_OPEN | | S_OPEN | |
| S E S S I O N | | S E S S I O N |
|<-------------------(SID=ISID)--| |<-------------------(SID=ISID)--|
|--(SID=RSID)------------------->| |--(SID=RSID)------------------->|
Figure 9: Normal handshake Figure 9: Normal Handshake
In the following sections the handshake is detailed from the In the following sections, the handshake is detailed from the
perspectives of the Initiator and Responder. perspectives of the initiator and responder.
3.5.1.1.1. Initiator 3.5.1.1.1. Initiator
The Initiator determines that a session is needed for an Endpoint The initiator determines that a session is needed for an Endpoint
Discriminator. The Initiator creates state for a new opening session Discriminator. The initiator creates state for a new opening session
and begins with a candidate endpoint address set containing at least and begins with a candidate endpoint address set containing at least
one address. The new session is placed in the S_IHELLO_SENT state. one address. The new session is placed in the S_IHELLO_SENT state.
If the session does not move to the S_OPEN state before an ultimate If the session does not move to the S_OPEN state before an ultimate
open timeout, the session has failed and moves to the S_OPEN_FAILED open timeout, the session has failed and moves to the S_OPEN_FAILED
state. The RECOMMENDED ultimate open timeout is 95 seconds. state. The RECOMMENDED ultimate open timeout is 95 seconds.
The Initiator chooses a new, unique Tag not used by any currently The initiator chooses a new, unique tag not used by any currently
opening session. It is RECOMMENDED that the Tag be cryptographically opening session. It is RECOMMENDED that the tag be cryptographically
pseudorandom and be at least 8 bytes in length, so that it is hard to pseudorandom and be at least 8 bytes in length, so that it is hard to
guess. The Initiator constructs an IHello chunk (Section 2.3.2) with guess. The initiator constructs an IHello chunk (Section 2.3.2) with
the Endpoint Discriminator and the Tag. the Endpoint Discriminator and the tag.
While the Initiator is in the S_IHELLO_SENT state, it sends the While the initiator is in the S_IHELLO_SENT state, it sends the
IHello to each candidate endpoint address in the set, on a backoff IHello to each candidate endpoint address in the set, on a backoff
schedule. The backoff SHOULD NOT be less than multiplicative with schedule. The backoff SHOULD NOT be less than multiplicative, with
not less than 1.5 seconds added to the interval between each attempt. not less than 1.5 seconds added to the interval between each attempt.
The backoff SHOULD be scheduled separately for each candidate The backoff SHOULD be scheduled separately for each candidate
address, since new candidates can be added over time. address, since new candidates can be added over time.
If the Initiator receives a Redirect chunk (Section 2.3.5) with a Tag If the initiator receives a Redirect chunk (Section 2.3.5) with a tag
Echo matching this session, AND this session is in the S_IHELLO_SENT echo matching this session, AND this session is in the S_IHELLO_SENT
state, then for each redirect destination indicated in the Redirect: state, then for each redirect destination indicated in the Redirect:
if the candidate endpoint address set contains fewer than if the candidate endpoint address set contains fewer than
REDIRECT_THRESHOLD addresses, add the indicated redirect destination REDIRECT_THRESHOLD addresses, add the indicated redirect destination
to the candidate endpoint address set. REDIRECT_THRESHOLD SHOULD NOT to the candidate endpoint address set. REDIRECT_THRESHOLD SHOULD NOT
be more than 24. be more than 24.
If the Initiator receives an RHello chunk (Section 2.3.4) with a Tag If the initiator receives an RHello chunk (Section 2.3.4) with a tag
Echo matching this session, AND this session is in the S_IHELLO_SENT echo matching this session, AND this session is in the S_IHELLO_SENT
state, AND the Responder certificate matches the desired Endpoint state, AND the responder certificate matches the desired Endpoint
Discriminator, AND the certificate is authentic according to the Discriminator, AND the certificate is authentic according to the
Cryptography Profile, then: Cryptography Profile, then:
1. If the Canonical Endpoint Discriminator for the responder 1. If the Canonical Endpoint Discriminator for the responder
certificate matches the Canonical Endpoint Discriminator of certificate matches the Canonical Endpoint Discriminator of
another existing session in the S_KEYING_SENT or S_OPEN states, another existing session in the S_KEYING_SENT or S_OPEN states,
AND the certificate of the other opening session matches the AND the certificate of the other opening session matches the
desired Endpoint Discriminator, then: this session is a duplicate desired Endpoint Discriminator, then this session is a duplicate
and SHOULD be aborted in favor of the other existing session; and SHOULD be aborted in favor of the other existing session;
otherwise otherwise,
2. Move to the S_KEYING_SENT state. Set DESTADDR, the far end 2. Move to the S_KEYING_SENT state. Set DESTADDR, the far-end
address for the session, to the address from which this RHello address for the session, to the address from which this RHello
was received. The Initiator chooses a new, unique receive was received. The initiator chooses a new, unique receive
session ID, not used by any other session, for the Responder to session ID, not used by any other session, for the responder to
use when sending packets to the Initiator. It computes a Session use when sending packets to the initiator. It computes a Session
Key Initiator Component appropriate to the responder's Key Initiator Component appropriate to the responder's
certificate according to the Cryptography Profile. Using this certificate according to the Cryptography Profile. Using this
data and the cookie from the RHello, the Initiator constructs and data and the cookie from the RHello, the initiator constructs and
signs an IIKeying chunk (Section 2.3.7). signs an IIKeying chunk (Section 2.3.7).
While the Initiator is in the S_KEYING_SENT state, it sends the While the initiator is in the S_KEYING_SENT state, it sends the
IIKeying to DESTADDR on a backoff schedule. The backoff SHOULD NOT IIKeying to DESTADDR on a backoff schedule. The backoff SHOULD NOT
be less than multiplicative with not less than 1.5 seconds added to be less than multiplicative, with not less than 1.5 seconds added to
the interval between each attempt. the interval between each attempt.
If the Initiator receives an RIKeying chunk (Section 2.3.8) in a If the initiator receives an RIKeying chunk (Section 2.3.8) in a
packet with this session's receive session identifier, AND this packet with this session's receive session identifier, AND this
session is in the S_KEYING_SENT state, AND the signature in the chunk session is in the S_KEYING_SENT state, AND the signature in the chunk
is authentic according to the far end's certificate (from the is authentic according to the far end's certificate (from the
RHello), AND the Session Key Responder Component successfully RHello), AND the Session Key Responder Component successfully
combines with the Session Key Initiator Component and the near and combines with the Session Key Initiator Component and the near and
far certificates to form the shared session keys and nonces according far certificates to form the shared session keys and nonces according
to the Cryptography Profile, then the session has opened to the Cryptography Profile, then the session has opened
successfully. The session moves to the S_OPEN state. The send successfully. The session moves to the S_OPEN state. The send
session identifier is set from the RIKeying. Packet encryption, session identifier is set from the RIKeying. Packet encryption,
decryption, and verification now use the newly computed shared decryption, and verification now use the newly computed shared
session keys, and the session nonces are available for application- session keys, and the session nonces are available for application-
layer cryptographic challenges. layer cryptographic challenges.
3.5.1.1.2. Responder 3.5.1.1.2. Responder
On receipt of an IHello chunk (Section 2.3.2) with an Endpoint On receipt of an IHello chunk (Section 2.3.2) with an Endpoint
Discriminator that selects its identity, an endpoint SHOULD construct Discriminator that selects its identity, an endpoint SHOULD construct
an RHello chunk (Section 2.3.4) and send it to the address from which an RHello chunk (Section 2.3.4) and send it to the address from which
the IHello was received. To avoid a potential resource exhaustion the IHello was received. To avoid a potential resource exhaustion
denial-of-service, the endpoint SHOULD NOT create any persistent denial of service, the endpoint SHOULD NOT create any persistent
state associated with the IHello. The endpoint MUST generate the state associated with the IHello. The endpoint MUST generate the
cookie for the RHello in such a way that it can be recognized as cookie for the RHello in such a way that it can be recognized as
authentic and valid when echoed in an IIKeying. The endpoint SHOULD authentic and valid when echoed in an IIKeying. The endpoint SHOULD
use the address from which the IHello was received as part of the use the address from which the IHello was received as part of the
cookie generation formula. Cookies SHOULD be valid only for a cookie generation formula. Cookies SHOULD be valid only for a
limited time; that lifetime SHOULD NOT be less than 95 seconds (the limited time; that lifetime SHOULD NOT be less than 95 seconds (the
recommended ultimate session open timeout). recommended ultimate session open timeout).
On receipt of an FIHello chunk (Section 2.3.3) from a Forwarder On receipt of an FIHello chunk (Section 2.3.3) from a Forwarder
(Section 3.5.1.5) where the Endpoint Discriminator selects its (Section 3.5.1.5) where the Endpoint Discriminator selects its
identity, an endpoint SHOULD do one of the following: identity, an endpoint SHOULD do one of the following:
1. Compute, construct and send an RHello as though the FIHello was 1. Compute, construct, and send an RHello as though the FIHello was
an IHello received from the indicated reply address; or an IHello received from the indicated reply address; or
2. Construct and send an Implied Redirect (Section 2.3.5) to the 2. Construct and send an Implied Redirect (Section 2.3.5) to the
FIHello's reply address; or FIHello's reply address; or
3. Ignore this FIHello. 3. Ignore this FIHello.
On receipt of an IIKeying chunk (Section 2.3.7), if the cookie is not On receipt of an IIKeying chunk (Section 2.3.7), if the cookie is not
authentic or if it has expired, ignore this IIKeying; otherwise, authentic or if it has expired, ignore this IIKeying; otherwise,
On receipt of an IIKeying chunk, if the cookie appears authentic but On receipt of an IIKeying chunk, if the cookie appears authentic but
does not match the address from which the IIKeying's packet was does not match the address from which the IIKeying's packet was
received, perform the special processing at Cookie Change received, perform the special processing at Cookie Change
(Section 3.5.1.2); otherwise, (Section 3.5.1.2); otherwise,
On receipt of an IIKeying with an authentic and valid cookie, if the On receipt of an IIKeying with an authentic and valid cookie, if the
certificate is authentic according to the Cryptography Profile, AND certificate is authentic according to the Cryptography Profile, AND
the signature in the chunk is authentic according to the far end's the signature in the chunk is authentic according to the far end's
certificate and the Cryptography Profile, AND the Session Key certificate and the Cryptography Profile, AND the Session Key
Initiator Component is acceptable, then: Initiator Component is acceptable, then:
skipping to change at page 54, line 31 skipping to change at page 56, line 47
to a session in the S_OPEN state, then: to a session in the S_OPEN state, then:
1. If the receiver was the Responder for the S_OPEN session and 1. If the receiver was the Responder for the S_OPEN session and
the session identifier, certificate, and Session Key the session identifier, certificate, and Session Key
Initiator Component are identical to those of the S_OPEN Initiator Component are identical to those of the S_OPEN
session, this IIKeying is a retransmission, so resend the session, this IIKeying is a retransmission, so resend the
S_OPEN session's RIKeying using the Default Session Key as S_OPEN session's RIKeying using the Default Session Key as
specified below; otherwise, specified below; otherwise,
2. If the certificate from this IIKeying does not override the 2. If the certificate from this IIKeying does not override the
certificate of the S_OPEN session: ignore this IIKeying; certificate of the S_OPEN session, ignore this IIKeying;
otherwise, otherwise,
3. The certificate from this IIKeying overrides the certificate 3. The certificate from this IIKeying overrides the certificate
of the S_OPEN session; this is a new opening session from the of the S_OPEN session; this is a new opening session from the
same identity and the existing S_OPEN session is stale. Move same identity, and the existing S_OPEN session is stale.
the existing S_OPEN session to S_CLOSED and abort all of its Move the existing S_OPEN session to S_CLOSED and abort all of
flows (signaling exceptions to the user), then continue its flows (signaling exceptions to the user), then continue
processing this IIKeying. processing this IIKeying.
Otherwise, Otherwise,
3. Compute a Session Key Responder Component and choose a new, 3. Compute a Session Key Responder Component and choose a new,
unique receive session ID not used by any other session for the unique receive session ID not used by any other session for the
Initiator to use when sending packets to the Responder. Using initiator to use when sending packets to the responder. Using
this data, construct and, with the Session Key Initiator this data, construct and, with the Session Key Initiator
Component, sign an RIKeying chunk (Section 2.3.8). Using the Component, sign an RIKeying chunk (Section 2.3.8). Using the
Session Key Initiator and Responder Components and the near and Session Key Initiator and Responder Components and the near and
far certificates, the Responder combines and computes the shared far certificates, the responder combines and computes the shared
session keys and nonces according to the Cryptography Profile. session keys and nonces according to the Cryptography Profile.
The Responder creates a new session in the S_OPEN state, with the The responder creates a new session in the S_OPEN state, with the
far endpoint address DESTADDR taken from the source address of far-endpoint address DESTADDR taken from the source address of
the packet containing the IIKeying and the send session the packet containing the IIKeying and the send session
identifier taken from the IIKeying. The Responder sends the identifier taken from the IIKeying. The responder sends the
RIKeying to the Initiator using the Default Session Key and the RIKeying to the initiator using the Default Session Key and the
requested send session identifier. Packet encryption, requested send session identifier. Packet encryption,
decryption, and verification of all future packets for this decryption, and verification of all future packets for this
session use the newly computed keys, and the session nonces are session use the newly computed keys, and the session nonces are
available for application-layer cryptographic challenges. available for application-layer cryptographic challenges.
3.5.1.2. Cookie Change 3.5.1.2. Cookie Change
In some circumstances, the Responder may generate an RHello cookie In some circumstances, the responder may generate an RHello cookie
for an Initiator's address that isn't the address the Initiator would for an initiator's address that isn't the address the initiator would
use when sending packets directly to the Responder. This can happen, use when sending packets directly to the responder. This can happen,
for example, when the Initiator has multiple local addresses, and for example, when the initiator has multiple local addresses and uses
uses one to reach a Forwarder (Section 3.5.1.5) but another to reach one address to reach a Forwarder (Section 3.5.1.5) but another to
the Responder. reach the responder.
Consider the following example: Consider the following example:
Initiator Forwarder Responder Initiator Forwarder Responder
| IHello | | | IHello | |
|(Src=Ix) | | |(Src=Ix) | |
|------------------------------->| | |------------------------------->| |
| | FIHello | | | FIHello |
| |(RA=Ix) | | |(RA=Ix) |
| |-------------------------------->| | |-------------------------------->|
| | | |
| RHello | | RHello |
| (Cookie:Ix)| | (Cookie:Ix)|
|<-----------------------------------------------------------------| |<-----------------------------------------------------------------|
| | | |
| IIKeying | | IIKeying |
|(Cookie:Ix,Src=Iy) | |(Cookie:Ix,Src=Iy) |
|----------------------------------------------------------------->| |----------------------------------------------------------------->|
| | | |
| RHello Cookie Change | | RHello Cookie Change |
| (Cookie:Ix,Cookie:Iy)| | (Cookie:Ix,Cookie:Iy)|
|<-----------------------------------------------------------------| |<-----------------------------------------------------------------|
| | | |
| IIKeying | | IIKeying |
|(Cookie:Iy) | |(Cookie:Iy) |
|----------------------------------------------------------------->| |----------------------------------------------------------------->|
| | | |
| RIKeying | | RIKeying |
|<-----------------------------------------------------------------| |<-----------------------------------------------------------------|
| | | |
|<======================== S E S S I O N =========================>| |<======================== S E S S I O N =========================>|
Figure 10: Handshake with Cookie Change Figure 10: Handshake with Cookie Change
Initiator has two network interfaces, a first preferred interface The initiator has two network interfaces: a first preferred interface
with address Ix = 192.0.2.100:50000, and a second with address Iy = with address Ix = 192.0.2.100:50000, and a second with address Iy =
198.51.100.101:50001. Responder has one interface with address Ry = 198.51.100.101:50001. The responder has one interface with address
198.51.100.200:51000, on the same network as Initiator's second Ry = 198.51.100.200:51000, on the same network as the initiator's
interface. Initiator uses its first interface to reach a Forwarder. second interface. The initiator uses its first interface to reach a
Forwarder observes Initiator's address of Ix and sends a Forwarded Forwarder. The Forwarder observes the initiator's address of Ix and
IHello (Section 2.3.3) to Responder. Responder treats this as if it sends a Forwarded IHello (Section 2.3.3) to the responder. The
was an IHello from Ix, calculates a corresponding cookie, and sends responder treats this as if it were an IHello from Ix, calculates a
an RHello to Ix. Initiator receives this RHello from Ry and selects corresponding cookie, and sends an RHello to Ix. The initiator
that address as the destination for the session. It then sends an receives this RHello from Ry and selects that address as the
IIKeying, copying the cookie from the RHello. However, since the destination for the session. It then sends an IIKeying, copying the
source of the RHello is Ry, on a network to which the Initiator is cookie from the RHello. However, since the source of the RHello is
directly connected, Initiator uses its second interface Iy to send Ry, on a network to which the initiator is directly connected, the
the IIKeying. Responder, on receiving the IIKeying, will compare the initiator uses its second interface Iy to send the IIKeying. The
cookie to the expected value based on the source address of the responder, on receiving the IIKeying, will compare the cookie to the
packet, and since the IIKeying source doesn't match the IHello source expected value based on the source address of the packet, and since
used to generate the cookie, Responder will reject the IIKeying. the IIKeying source doesn't match the IHello source used to generate
the cookie, the responder will reject the IIKeying.
If Responder determines that it generated the cookie in the IIKeying If the responder determines that it generated the cookie in the
but the cookie doesn't match the sender's address (for example, if IIKeying but the cookie doesn't match the sender's address (for
the cookie is in two parts, with a first part generated independently example, if the cookie is in two parts, with a first part generated
of the Initiator's address, and a second part dependent on the independently of the initiator's address and a second part dependent
address), Responder SHOULD generate a new cookie based on the address on the address), the responder SHOULD generate a new cookie based on
from which the IIKeying was received, and send an RHello Cookie the address from which the IIKeying was received and send an RHello
Change chunk (Section 2.3.6) to the source of the IIKeying, using the Cookie Change chunk (Section 2.3.6) to the source of the IIKeying,
session ID from the IIKeying and the Default Session Key. using the session ID from the IIKeying and the Default Session Key.
If Initiator receives an RHello Cookie Change chunk for a session in If the initiator receives an RHello Cookie Change chunk for a session
the S_KEYING_SENT state, AND the old cookie matches the one in the S_KEYING_SENT state, AND the old cookie matches the one
originally sent to the Responder, then: Initiator adopts the new originally sent to the responder, then the initiator adopts the new
cookie, constructs and signs a new IIKeying chunk, and sends the new cookie, constructs and signs a new IIKeying chunk, and sends the new
IIKeying to the Responder. Initiator SHOULD NOT change the cookie IIKeying to the responder. The initiator SHOULD NOT change the
for a session more than once. cookie for a session more than once.
3.5.1.3. Glare 3.5.1.3. Glare
Glare occurs when two endpoints attempt to initiate sessions to each Glare occurs when two endpoints attempt to initiate sessions to each
other concurrently. Glare is detected by receipt of a valid and other concurrently. Glare is detected by receipt of a valid and
authentic IIKeying from an endpoint address which is a destination authentic IIKeying from an endpoint address that is a destination for
for an opening session. Only one session is allowed between a pair an opening session. Only one session is allowed between a pair of
of endpoints. endpoints.
Glare is resolved by comparing the certificate in the received Glare is resolved by comparing the certificate in the received
IIKeying with the near end's certificate. The Cryptography Profile IIKeying with the near end's certificate. The Cryptography Profile
defines a certificate comparison function to determine the prevailing defines a certificate comparison function to determine the prevailing
endpoint when there is glare. endpoint when there is glare.
If the near end prevails, discard and ignore the received IIKeying. If the near end prevails, discard and ignore the received IIKeying.
The far end will abort its opening session on receipt of IIKeying The far end will abort its opening session on receipt of IIKeying
from the near end. from the near end.
Otherwise, the far end prevails: Otherwise, the far end prevails:
1. If the certificate in the IIKeying overrides the certificate 1. If the certificate in the IIKeying overrides the certificate
associated with the near opening session according to the associated with the near opening session according to the
Cryptography Profile, then: abort and destroy the near opening Cryptography Profile, then abort and destroy the near opening
session. Then, session. Then,
2. Continue with normal Responder IIKeying processing 2. Continue with normal Responder IIKeying processing
(Section 3.5.1.1.2). (Section 3.5.1.1.2).
3.5.1.4. Redirector 3.5.1.4. Redirector
+-----------+ +------------+ +-----------+ +-----------+ +------------+ +-----------+
| Initiator |---------->| Redirector | | Responder | | Initiator |---------->| Redirector | | Responder |
| |<----------| | | | | |<----------| | | |
| | +------------+ | | | | +------------+ | |
| |<=================================>| | | |<=================================>| |
+-----------+ +-----------+ +-----------+ +-----------+
Figure 11: Redirector Figure 11: Redirector
A Redirector acts like a name server for Endpoint Discriminators. An A Redirector acts like a name server for Endpoint Discriminators.
Initiator MAY use a Redirector to discover additional candidate An initiator MAY use a Redirector to discover additional candidate
endpoint addresses for a desired endpoint. endpoint addresses for a desired endpoint.
On receipt of an IHello chunk with an Endpoint Discriminator that On receipt of an IHello chunk with an Endpoint Discriminator that
does not select the Redirector's identity, the Redirector constructs does not select the Redirector's identity, the Redirector constructs
and sends a Responder Redirect chunk (Section 2.3.5) back to the and sends back to the initiator a Responder Redirect chunk
Initiator containing one or more additional candidate addresses for (Section 2.3.5) containing one or more additional candidate addresses
the indicated endpoint. for the indicated endpoint.
Initiator Redirector Responder Initiator Redirector Responder
| IHello | | | IHello | |
|------------------------------->| | |------------------------------->| |
| | | | | |
| Redirect | | | Redirect | |
|<-------------------------------| | |<-------------------------------| |
| | | |
| IHello | | IHello |
|----------------------------------------------------------------->| |----------------------------------------------------------------->|
| | | |
| RHello | | RHello |
|<-----------------------------------------------------------------| |<-----------------------------------------------------------------|
| | | |
| IIKeying | | IIKeying |
|----------------------------------------------------------------->| |----------------------------------------------------------------->|
| | | |
| RIKeying | | RIKeying |
|<-----------------------------------------------------------------| |<-----------------------------------------------------------------|
| | | |
|<======================== S E S S I O N =========================>| |<======================== S E S S I O N =========================>|
Figure 12: Handshake using a Redirector Figure 12: Handshake Using a Redirector
Deployment Design Note: Redirectors SHOULD NOT initiate new sessions Deployment Design Note: Redirectors SHOULD NOT initiate new sessions
to endpoints that might use the Redirector's address as a candidate to endpoints that might use the Redirector's address as a candidate
for another endpoint, since the far end might interpret the for another endpoint, since the far end might interpret the
Redirector's IIKeying as glare for the far end's initiation to the Redirector's IIKeying as glare for the far end's initiation to the
other endpoint. other endpoint.
3.5.1.5. Forwarder 3.5.1.5. Forwarder
+-----------+ +-----------+ +---+ +-----------+ +-----------+ +-----------+ +---+ +-----------+
| Initiator |---->| Forwarder |<===>| N |<===>| Responder | | Initiator |---->| Forwarder |<===>| N |<===>| Responder |
| | +-----------+ | A | | | | | +-----------+ | A | | |
| |<=====================>| T |<===>| | | |<=====================>| T |<===>| |
+-----------+ +---+ +-----------+ +-----------+ +---+ +-----------+
Figure 13: Forwarder Figure 13: Forwarder
A Responder might be behind a NAT or firewall that doesn't allow A responder might be behind a NAT or firewall that doesn't allow
inbound packets to reach the endpoint until it first sends an inbound packets to reach the endpoint until it first sends an
outbound packet for a particular far endpoint address. outbound packet for a particular far-endpoint address.
A Forwarder's endpoint address MAY be a candidate address for another A Forwarder's endpoint address MAY be a candidate address for another
endpoint. A Responder MAY use a Forwarder to receive FIHello chunks endpoint. A responder MAY use a Forwarder to receive FIHello chunks
sent on behalf of an Initiator. sent on behalf of an initiator.
On receipt of an IHello chunk with an Endpoint Discriminator that On receipt of an IHello chunk with an Endpoint Discriminator that
does not select the Forwarder's identity, if the Forwarder has an does not select the Forwarder's identity, if the Forwarder has an
S_OPEN session with an endpoint whose certificate matches the desired S_OPEN session with an endpoint whose certificate matches the desired
Endpoint Discriminator, the forwarder constructs and sends an FIHello Endpoint Discriminator, the Forwarder constructs and sends an FIHello
chunk (Section 2.3.3) to the selected endpoint over the S_OPEN chunk (Section 2.3.3) to the selected endpoint over the S_OPEN
session, using the Tag and Endpoint Discriminator from the IHello session, using the tag and Endpoint Discriminator from the IHello
chunk and the source address of the packet containing the IHello for chunk and the source address of the packet containing the IHello for
the corresponding fields of the FIHello. the corresponding fields of the FIHello.
On receipt of an FIHello chunk, a Responder might send an RHello or On receipt of an FIHello chunk, a responder might send an RHello or
Implied Redirect to the original source of the IHello Implied Redirect to the original source of the IHello
(Section 3.5.1.1.2), potentially allowing future packets to flow (Section 3.5.1.1.2), potentially allowing future packets to flow
directly between the Initiator and Responder through the NAT or directly between the initiator and responder through the NAT or
firewall. firewall.
Initiator Forwarder NAT Responder Initiator Forwarder NAT Responder
| IHello | | | | IHello | | |
|------------------------------->| | | |------------------------------->| | |
| | FIHello | | | | FIHello | |
| |--------------->|--------------->| | |--------------->|--------------->|
| | | | | |
| | RHello | | | RHello |
| :<---------------| | :<---------------|
|<------------------------------------------------: | |<------------------------------------------------: |
| : | | : |
| IIKeying : | | IIKeying : |
|-------------------------------------------------:--------------->| |-------------------------------------------------:--------------->|
| : | | : |
| : RIKeying | | : RIKeying |
| :<---------------| | :<---------------|
|<------------------------------------------------: | |<------------------------------------------------: |
| : | | : |
|<======================== S E S S I O N ========>:<==============>| |<======================== S E S S I O N ========>:<==============>|
Figure 14: Forwarder handshake where Responder sends an RHello Figure 14: Forwarder Handshake where Responder Sends an RHello
Initiator Forwarder NAT Responder Initiator Forwarder NAT Responder
| IHello | | | | IHello | | |
|------------------------------->| | | |------------------------------->| | |
| | FIHello | | | | FIHello | |
| |--------------->|--------------->| | |--------------->|--------------->|
| | | | | |
| | Redirect | | | Redirect |
| | (Implied,RD={})| | | (Implied,RD={})|
| :<---------------| | :<---------------|
|<------------------------------------------------: | |<------------------------------------------------: |
| : | | : |
| IHello : | | IHello : |
|------------------------------------------------>:--------------->| |------------------------------------------------>:--------------->|
| : | | : |
| : RHello | | : RHello |
| :<---------------| | :<---------------|
|<------------------------------------------------: | |<------------------------------------------------: |
| : | | : |
| IIKeying : | | IIKeying : |
|------------------------------------------------>:--------------->| |------------------------------------------------>:--------------->|
| : | | : |
| : RIKeying | | : RIKeying |
| :<---------------| | :<---------------|
|<------------------------------------------------: | |<------------------------------------------------: |
| : | | : |
|<======================== S E S S I O N ========>:<==============>| |<======================== S E S S I O N ========>:<==============>|
Figure 15: Forwarder handshake where Responder sends an Implied Figure 15: Forwarder Handshake where Responder Sends an
Redirect Implied Redirect
3.5.1.6. Redirector and Forwarder with NAT 3.5.1.6. Redirector and Forwarder with NAT
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
| I | | N | | I | | N | | R | | I | | N | | I | | N | | R |
| n |------>| A |------>| n | | A | | e | | n |------>| A |------>| n | | A | | e |
| i | | T | | t |<====>| T |<====>| s | | i | | T | | t |<====>| T |<====>| s |
| t |<------| |<------| r | | | | p | | t |<------| |<------| r | | | | p |
| i | | | | o | | | | o | | i | | | | o | | | | o |
| a | | | +---+ | | | n | | a | | | +---+ | | | n |
| t | | | | | | d | | t | | | | | | d |
| o |<=====>| |<================>| |<====>| e | | o |<=====>| |<================>| |<====>| e |
| r | | | | | | r | | r | | | | | | r |
+---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
Figure 16: Introduction service for Initiator and Responder behind Figure 16: Introduction Service for Initiator and Responder
NATs behind NATs
An Initiator and Responder might each be behind distinct NATs or An initiator and responder might each be behind distinct NATs or
firewalls that don't allow inbound packets to reach the respective firewalls that don't allow inbound packets to reach the respective
endpoints until each first sends an outbound packet for a particular endpoints until each first sends an outbound packet for a particular
far endpoint address. far-endpoint address.
An introduction service comprising Redirector and Forwarder functions An introduction service comprising Redirector and Forwarder functions
may facilitate direct communication between endpoints each behind a may facilitate direct communication between endpoints each behind
NAT. a NAT.
Responder is registered with the introduction service via an S_OPEN The responder is registered with the introduction service via an
session to it. The service observes and records Responder's public S_OPEN session to it. The service observes and records the
NAT address as the DESTADDR of the S_OPEN session. The service MAY responder's public NAT address as the DESTADDR of the S_OPEN session.
record other addresses for Responder, for example addresses Responder The service MAY record other addresses for the responder, for example
self-reports as being directly attached. addresses that the responder self-reports as being directly attached.
Initiator begins with an address of the introduction service as an The initiator begins with an address of the introduction service as
initial candidate. The Redirector portion of the service sends a an initial candidate. The Redirector portion of the service sends to
Responder Redirect to Initiator containing at least Responder's the initiator a Responder Redirect containing at least the
public NAT address as previously recorded. The Forwarder portion of responder's public NAT address as previously recorded. The Forwarder
the service sends a Forwarded IHello to Responder containing portion of the service sends to the responder a Forwarded IHello
Initiator's public NAT address as observed as the source of the containing the initiator's public NAT address as observed to be the
IHello. source of the IHello.
Responder sends an RHello to Initiator's public NAT address in The responder sends an RHello to the initiator's public NAT address
response to the FIHello. This will allow inbound packets to in response to the FIHello. This will allow inbound packets to the
Responder through its NAT from Initiator's public NAT address. responder through its NAT from the initiator's public NAT address.
Initiator sends an IHello to Responder's public NAT address in The initiator sends an IHello to the responder's public NAT address
response to the Responder Redirect. This will allow inbound packets in response to the Responder Redirect. This will allow inbound
to Initiator through its NAT from Responder's public NAT address. packets to the initiator through its NAT from the responder's public
NAT address.
With transit paths created in both NATs, normal session startup can With transit paths created in both NATs, normal session startup can
proceed. proceed.
Initiator NAT-I Redirector+Forwarder NAT-R Responder Initiator NAT-I Redirector+Forwarder NAT-R Responder
| | | | | | | | | |
| IHello | | | | | IHello | | | |
|(Dst=Intro) | | | | |(Dst=Intro) | | | |
|-------------->| | | | |-------------->| | | |
| |--------------->| | | | |--------------->| | |
| | | FIHello | | | | | FIHello | |
| | |(RA=NAT-I-Pub) | | | | |(RA=NAT-I-Pub) | |
| | |--------------->|--------------->| | | |--------------->|--------------->|
| | Redirect | | | | | Redirect | | |
| | (RD={NAT-R-Pub,| | | | | (RD={NAT-R-Pub,| | |
| | ...})| | | | | ...})| | |
|<--------------|<---------------| | | |<--------------|<---------------| | |
| | | RHello | | | | RHello |
| | | (Dst=NAT-I-Pub)| | | | (Dst=NAT-I-Pub)|
| | :<---------------| | | :<---------------|
| | (*) <--------------------------: | | | (*) <--------------------------: |
| IHello | : | | IHello | : |
|(Dst=NAT-R-Pub)| : | |(Dst=NAT-R-Pub)| : |
|-------------->: : | |-------------->: : |
| :-------------------------------->:--------------->| | :-------------------------------->:--------------->|
| : : | | : : |
| : : RHello | | : : RHello |
| : :<---------------| | : :<---------------|
|<--------------:<--------------------------------: | |<--------------:<--------------------------------: |
| : : | | : : |
| IIKeying : : | | IIKeying : : |
|-------------->: : | |-------------->: : |
| :-------------------------------->:--------------->| | :-------------------------------->:--------------->|
| : : | | : : |
| : : RIKeying | | : : RIKeying |
| : :<---------------| | : :<---------------|
|<--------------:<--------------------------------: | |<--------------:<--------------------------------: |
| : : | | : : |
|<=============>:<======== S E S S I O N ========>:<==============>| |<=============>:<======== S E S S I O N ========>:<==============>|
Figure 17: Handshake with Redirector and Forwarder Figure 17: Handshake with Redirector and Forwarder
At the point in Figure 17 marked (*), Responder's RHello from the At the point in Figure 17 marked (*), the responder's RHello from the
FIHello might arrive at Initiator's NAT before or after Initiator's FIHello might arrive at the initiator's NAT before or after the
IHello is sent outbound to Responder's public NAT address. If it initiator's IHello is sent outbound to the responder's public NAT
arrives before, it may be dropped by the NAT. If it arrives after, address. If it arrives before, it may be dropped by the NAT. If it
it will transit the NAT and trigger keying without waiting for arrives after, it will transit the NAT and trigger keying without
another round trip time. The timing of this race depends, among waiting for another round-trip time. The timing of this race
other factors, on the relative distances of Initiator and Responder depends, among other factors, on the relative distances of the
to each other and the introduction service. initiator and responder from each other and from the introduction
service.
3.5.1.7. Load Distribution and Fault Tolerance 3.5.1.7. Load Distribution and Fault Tolerance
+---+ IHello/RHello +-------------+ +---+ IHello/RHello +-------------+
| I |<------------------->| Responder 1 | | I |<------------------->| Responder 1 |
| n | +-------------+ | n | +-------------+
| i | SESSION +-------------+ | i | SESSION +-------------+
| t |<=========>| Responder 2 | | t |<=========>| Responder 2 |
| i | +-------------+ | i | +-------------+
| a | IHello... +----------------+ | a | IHello... +----------------+
| t |-------------------------> X | Dead Responder | | t |-------------------------> X | Dead Responder |
| o | +----------------+ | o | +----------------+
| r | IHello/RHello +-------------+ | r | IHello/RHello +-------------+
| |<---------------->| Responder N | | |<---------------->| Responder N |
+---+ +-------------+ +---+ +-------------+
Figure 18: Parallel Open to Multiple Endpoints Figure 18: Parallel Open to Multiple Endpoints
Section 3.2 allows more than one endpoint to be selected by one As specified in Section 3.2, more than one endpoint is allowed to be
Endpoint Discriminator. This will typically be the case for a set of selected by one Endpoint Discriminator. This will typically be the
servers, any of which could accommodate a connecting client. case for a set of servers, any of which could accommodate a
connecting client.
Section 3.5.1.1.1 allows an Initiator to use multiple candidate As specified in Section 3.5.1.1.1, an initiator is allowed to use
endpoint addresses when starting a session, and specifies that the multiple candidate endpoint addresses when starting a session, and
sender of the first acceptable RHello chunk to be received is the sender of the first acceptable RHello chunk to be received is
selected to complete the session, with later responses ignored. An selected to complete the session, with later responses ignored. An
Initiator can start with the multiple candidate endpoint addresses, initiator can start with the multiple candidate endpoint addresses,
or it may learn them during startup from one or more Redirectors or it may learn them during startup from one or more Redirectors
(Section 3.5.1.4). (Section 3.5.1.4).
Parallel open to multiple endpoints for the same Endpoint Parallel open to multiple endpoints for the same Endpoint
Discriminator combined with selection by earliest RHello can be used Discriminator, combined with selection by earliest RHello, can be
for load distribution and fault tolerance. The cost at each endpoint used for load distribution and fault tolerance. The cost at each
that is not selected is limited to receiving and processing an endpoint that is not selected is limited to receiving and processing
IHello, and generating and sending an RHello. an IHello, and generating and sending an RHello.
In one circumstance, multiple servers of similar processing and In one circumstance, multiple servers of similar processing and
networking capacity may be located in near proximity to each other, networking capacity may be located in near proximity to each other,
such as in a data center. In this circumstance, a less heavily such as in a data center. In this circumstance, a less heavily
loaded server can respond to an IHello more quickly than more heavily loaded server can respond to an IHello more quickly than more heavily
loaded servers, and will tend to be selected by a client. loaded servers and will tend to be selected by a client.
In another circumstance, multiple servers may be located in different In another circumstance, multiple servers may be located in different
physical locations, such as different data centers. In this physical locations, such as different data centers. In this
circumstance, a server that is located nearer (in terms of network circumstance, a server that is located nearer (in terms of network
distance) to the client can respond earlier than more distant distance) to the client can respond earlier than more distant servers
servers, and will tend to be selected by the client. and will tend to be selected by the client.
Multiple servers, in proximity or distant from one another, can form Multiple servers, in proximity or distant from one another, can form
a redundant pool of servers. A client can perform a parallel open to a redundant pool of servers. A client can perform a parallel open to
the multiple servers. In normal operation, the multiple servers will the multiple servers. In normal operation, the multiple servers will
all respond, and the client will select one of them as described all respond, and the client will select one of them as described
above. If one of the multiple servers fails, other servers in the above. If one of the multiple servers fails, other servers in the
pool can still respond to the client, allowing the client to pool can still respond to the client, allowing the client to succeed
successfully complete to an S_OPEN session with one of them. to an S_OPEN session with one of them.
3.5.2. Congestion Control 3.5.2. Congestion Control
An RTMFP MUST implement congestion control and avoidance algorithms An RTMFP MUST implement congestion control and avoidance algorithms
that are "TCP compatible", in accordance with Internet best current that are "TCP compatible", in accordance with Internet best current
practice [RFC2914]. The algorithms SHOULD NOT be more aggressive in practice [RFC2914]. The algorithms SHOULD NOT be more aggressive in
sending data than those described in TCP Congestion Control sending data than those described in "TCP Congestion Control"
[RFC5681], and MUST NOT be more aggressive in sending data than the [RFC5681] and MUST NOT be more aggressive in sending data than the
"slow start algorithm" described in RFC 5681 Section 3.1. "slow start algorithm" described in Section 3.1 of RFC 5681.
An endpoint maintains a transmission budget in the session An endpoint maintains a transmission budget in the session
information context of each S_OPEN session (Section 3.5), controlling information context of each S_OPEN session (Section 3.5), controlling
the rate at which the endpoint sends data into the network. the rate at which the endpoint sends data into the network.
For window-based congestion control and avoidance algorithms, the For window-based congestion control and avoidance algorithms, the
transmission budget is the congestion window, which is the amount of transmission budget is the congestion window, which is the amount of
user data that is allowed to be outstanding, or in flight, in the user data that is allowed to be outstanding, or in flight, in the
network. Transmission is allowed when S_OUTSTANDING_BYTES network. Transmission is allowed when S_OUTSTANDING_BYTES
(Section 3.5) is less than the congestion window (Section 3.6.2.3). (Section 3.5) is less than the congestion window (Section 3.6.2.3).
skipping to change at page 65, line 41 skipping to change at page 67, line 43
An endpoint avoids sending large bursts of data or packets into the An endpoint avoids sending large bursts of data or packets into the
network (Section 3.5.2.3). network (Section 3.5.2.3).
A sending endpoint increases and decreases its transmission budget in A sending endpoint increases and decreases its transmission budget in
response to acknowledgements (Section 3.6.2.4) and loss according to response to acknowledgements (Section 3.6.2.4) and loss according to
the congestion control and avoidance algorithms. Loss is detected by the congestion control and avoidance algorithms. Loss is detected by
negative acknowledgement (Section 3.6.2.5) and timeout negative acknowledgement (Section 3.6.2.5) and timeout
(Section 3.6.2.6). (Section 3.6.2.6).
Timeout is determined by the Effective Retransmission Timeout ERTO Timeout is determined by the Effective Retransmission Timeout (ERTO)
(Section 3.5.2.2). ERTO is measured using the Timestamp and (Section 3.5.2.2). The ERTO is measured using the Timestamp and
Timestamp Echo packet header fields (Section 2.2.4). Timestamp Echo packet header fields (Section 2.2.4).
A receiving endpoint acknowledges all received data (Section 3.6.3.4) A receiving endpoint acknowledges all received data (Section 3.6.3.4)
to enable the sender to measure receipt of data, or lack thereof. to enable the sender to measure receipt of data, or lack thereof.
A receiving endpoint may be receiving time critical (or real-time) A receiving endpoint may be receiving time critical (or real-time)
data from a first sender while receiving data from other senders. data from a first sender while receiving data from other senders.
The receiving endpoint can signal its other senders (Section 2.2.4) The receiving endpoint can signal its other senders (Section 2.2.4)
to cause them to decrease the aggressiveness of their congestion to cause them to decrease the aggressiveness of their congestion
control and avoidance algorithms, in order to yield network capacity control and avoidance algorithms, in order to yield network capacity
to the time critical data (Section 3.5.2.1). to the time critical data (Section 3.5.2.1).
3.5.2.1. Time Critical Reverse Notification 3.5.2.1. Time Critical Reverse Notification
A sender can increase its transmission budget at a rate compatible A sender can increase its transmission budget at a rate compatible
with (but not exceeding) the "slow start algorithm" specified in RFC with (but not exceeding) the "slow start algorithm" specified in
5681 (with which the transmission rate is doubled every round trip RFC 5681 (with which the transmission rate is doubled every round
when beginning or restarting transmission, until loss is detected). trip when beginning or restarting transmission, until loss is
However, a sender MUST behave as though the slow start threshold detected). However, a sender MUST behave as though the slow start
SSTHRESH is clamped to 0 (disabling the slow start algorithm's threshold SSTHRESH is clamped to 0 (disabling the slow start
exponential increase behavior) on a session where a Time Critical algorithm's exponential increase behavior) on a session where a Time
Reverse Notification (Section 2.2.4) indication has been received Critical Reverse Notification (Section 2.2.4) indication has been
from the far end within the last 800 milliseconds, unless the sender received from the far end within the last 800 milliseconds, unless
is itself currently sending time critical data to the far end. the sender is itself currently sending time critical data to the
far end.
During each round trip, a sender SHOULD NOT increase the transmission During each round trip, a sender SHOULD NOT increase the transmission
budget by more than 0.5% or by 384 bytes per round trip (whichever is budget by more than 0.5% or by 384 bytes per round trip (whichever is
greater) on a session where a Time Critical Reverse Notification greater) on a session where a Time Critical Reverse Notification
indication has been received from the far end within the last 800 indication has been received from the far end within the last 800
milliseconds, unless the sender is itself currently sending time milliseconds, unless the sender is itself currently sending time
critical data to the far end. critical data to the far end.
3.5.2.2. Retransmission Timeout 3.5.2.2. Retransmission Timeout
RTMFP uses the Effective Retransmission Timeout ERTO to detect when a RTMFP uses the ERTO to detect when a user data fragment has been lost
user data fragment has been lost in the network. The ERTO is in the network. The ERTO is typically calculated in a manner similar
typically calculated in a manner similar to that specified in to that specified in "Requirements for Internet Hosts - Communication
Requirements for Internet Hosts - Communication Layers [RFC1122], and Layers" [RFC1122] and is a function of round-trip time measurements
is a function of round trip time measurements and persistent timeout and persistent timeout behavior.
behavior.
The ERTO SHOULD be at least 250 milliseconds and SHOULD allow for the The ERTO SHOULD be at least 250 milliseconds and SHOULD allow for the
receiver to delay sending an acknowledgement for up to 200 receiver to delay sending an acknowledgement for up to 200
milliseconds (Section 3.6.3.4.4). The ERTO MUST NOT be less than the milliseconds (Section 3.6.3.4.4). The ERTO MUST NOT be less than the
round trip time. round-trip time.
To facilitate round trip time measurement, an endpoint MUST implement To facilitate round-trip time measurement, an endpoint MUST implement
the Timestamp Echo facility: the Timestamp Echo facility:
o On a session entering the S_OPEN state, initialize TS_RX_TIME to o On a session entering the S_OPEN state, initialize TS_RX_TIME to
negative infinity, and TS_RX and TS_ECHO_TX to have no value. negative infinity, and initialize TS_RX and TS_ECHO_TX to have no
value.
o On receipt of a packet in an S_OPEN session with the o On receipt of a packet in an S_OPEN session with the
timestampPresent (Section 2.2.4) flag set, if the timestamp field timestampPresent (Section 2.2.4) flag set, if the timestamp field
in the packet is different than TS_RX: set TS_RX to the value of in the packet is different than TS_RX, set TS_RX to the value of
the timestamp field in the packet, and set TS_RX_TIME to the the timestamp field in the packet, and set TS_RX_TIME to the
current time. current time.
o When sending a packet to the far end in an S_OPEN session: o When sending a packet to the far end in an S_OPEN session:
1. Calculate TS_RX_ELAPSED = current time - TS_RX_TIME. If 1. Calculate TS_RX_ELAPSED = current time - TS_RX_TIME. If
TS_RX_ELAPSED is more than 128 seconds, then set TS_RX and TS_RX_ELAPSED is more than 128 seconds, then set TS_RX and
TS_ECHO_TX to have no value and do not include a timestamp TS_ECHO_TX to have no value, and do not include a timestamp
echo; otherwise echo; otherwise,
2. Calculate TS_RX_ELAPSED_TICKS to be the number of whole 4 2. Calculate TS_RX_ELAPSED_TICKS to be the number of whole
millisecond periods in TS_RX_ELAPSED; then 4-millisecond periods in TS_RX_ELAPSED; then
3. Calculate TS_ECHO = (TS_RX + TS_RX_ELAPSED_TICKS) MODULO 3. Calculate TS_ECHO = (TS_RX + TS_RX_ELAPSED_TICKS) MODULO
65536; then 65536; then
4. If TS_ECHO is not equal to TS_ECHO_TX, then: set TS_ECHO_TX to 4. If TS_ECHO is not equal to TS_ECHO_TX, then set TS_ECHO_TX to
TS_ECHO, set the timestampEchoPresent flag, and set the TS_ECHO, set the timestampEchoPresent flag, and set the
timestampEcho field to TS_ECHO_TX. timestampEcho field to TS_ECHO_TX.
The remainder of this section describes an OPTIONAL method for The remainder of this section describes an OPTIONAL method for
calculating the Effective Retransmission Timeout ERTO. Real-time calculating the ERTO. Real-time applications and P2P mesh
applications and P2P mesh applications often require knowing the applications often require knowing the round-trip time and RTT
round trip time and RTT variance. This section additionally variance. This section additionally describes a method for measuring
describes a method for measuring the round trip time and RTT the round-trip time and RTT variance, and calculating a smoothed
variance, and calculating a smoothed round trip time. round-trip time.
Let the session information context contain additional variables: Let the session information context contain additional variables:
o TS_TX: the last timestamp sent to the far end, initialized to have o TS_TX: the last timestamp sent to the far end, initialized to have
no value; no value;
o TS_ECHO_RX: the last timestamp echo received from the far end, o TS_ECHO_RX: the last timestamp echo received from the far end,
initialized to have no value; initialized to have no value;
o SRTT: the smoothed round-trip time, initialized to have no value; o SRTT: the smoothed round-trip time, initialized to have no value;
o RTTVAR: the round-trip time variance, initialized to 0; o RTTVAR: the round-trip time variance, initialized to 0.
Initialize MRTO to 250 milliseconds. Initialize MRTO to 250 milliseconds.
Initialize ERTO to 3 seconds. Initialize ERTO to 3 seconds.
On sending a packet to the far end of an S_OPEN session, if the On sending a packet to the far end of an S_OPEN session, if the
current send timestamp is not equal to TS_TX, then: set TS_TX to the current send timestamp is not equal to TS_TX, then set TS_TX to the
current send timestamp, set the timestampPresent flag in the packet current send timestamp, set the timestampPresent flag in the packet
header, and set the timestamp field to TS_TX. header, and set the timestamp field to TS_TX.
On receipt of a packet from the far end of an S_OPEN session, if the On receipt of a packet from the far end of an S_OPEN session, if the
timestampEchoPresent flag is set in the packet header AND the timestampEchoPresent flag is set in the packet header, AND the
timestampEcho field is not equal to TS_ECHO_RX, then: timestampEcho field is not equal to TS_ECHO_RX, then:
1. Set TS_ECHO_RX to timestampEcho; 1. Set TS_ECHO_RX to timestampEcho;
2. Calculate RTT_TICKS = (current send timestamp - timestampEcho) 2. Calculate RTT_TICKS = (current send timestamp - timestampEcho)
MODULO 65536; MODULO 65536;
3. If RTT_TICKS is greater than 32767, the measurement is invalid, 3. If RTT_TICKS is greater than 32767, the measurement is invalid,
so discard this measurement; otherwise so discard this measurement; otherwise,
4. Calculate RTT = RTT_TICKS * 4 milliseconds; 4. Calculate RTT = RTT_TICKS * 4 milliseconds;
5. If SRTT has a value, then calculate new values of RTTVAR and 5. If SRTT has a value, then calculate new values of RTTVAR
SRTT: and SRTT:
1. RTT_DELTA = | SRTT - RTT |; 1. RTT_DELTA = | SRTT - RTT |;
2. RTTVAR = ((3 * RTTVAR) + RTT_DELTA) / 4; 2. RTTVAR = ((3 * RTTVAR) + RTT_DELTA) / 4;
3. SRTT = ((7 * SRTT) + RTT) / 8; 3. SRTT = ((7 * SRTT) + RTT) / 8.
6. If SRTT has no value, then set SRTT = RTT and RTTVAR = RTT / 2; 6. If SRTT has no value, then set SRTT = RTT and RTTVAR = RTT / 2;
7. Set MRTO = SRTT + 4 * RTTVAR + 200 milliseconds; 7. Set MRTO = SRTT + 4 * RTTVAR + 200 milliseconds;
8. Set ERTO to the greater of MRTO or 250 milliseconds. 8. Set ERTO to MRTO or 250 milliseconds, whichever is greater.
A retransmission timeout occurs when the most recently transmitted A retransmission timeout occurs when the most recently transmitted
user data fragment has remained outstanding in the network for ERTO. user data fragment has remained outstanding in the network for ERTO.
When this timeout occurs, increase ERTO on an exponential backoff When this timeout occurs, increase ERTO on an exponential backoff
with an ultimate backoff cap of 10 seconds: with an ultimate backoff cap of 10 seconds:
1. Calculate ERTO_BACKOFF = ERTO * 1.4142; 1. Calculate ERTO_BACKOFF = ERTO * 1.4142;
2. Calculate ERTO_CAPPED to be the lesser of ERTO_BACKOFF and 10 2. Calculate ERTO_CAPPED to be ERTO_BACKOFF or 10 seconds, whichever
seconds; is less;
3. Set ERTO to the greater of ERTO_CAPPED and MRTO. 3. Set ERTO to ERTO_CAPPED or MRTO, whichever is greater.
3.5.2.3. Burst Avoidance 3.5.2.3. Burst Avoidance
An application's sending patterns may cause the transmission budget An application's sending patterns may cause the transmission budget
to grow to a large value but, at times, for there to be a to grow to a large value, but at times its sending patterns will
comparatively small amount of data outstanding in the network. In result in a comparatively small amount of data outstanding in the
this circumstance, especially with a window-based congestion network. In this circumstance, especially with a window-based
avoidance algorithm, if the application then has a large amount of congestion avoidance algorithm, if the application then has a large
new data to send (for example, a new bulk data transfer), it could amount of new data to send (for example, a new bulk data transfer),
send data into the network all at once to fill the window. This kind it could send data into the network all at once to fill the window.
of transmission burst can jam interfaces, links, and buffers, and is This kind of transmission burst is undesirable, however, because it
undesirable. can jam interfaces, links, and buffers.
Accordingly, in any session, an endpoint SHOULD NOT send more than Accordingly, in any session, an endpoint SHOULD NOT send more than
six packets containing user data between receiving acknowledgements six packets containing user data between receiving any
or retransmission timeouts. acknowledgements or retransmission timeouts.
The following describes an OPTIONAL method to avoid bursting large The following describes an OPTIONAL method to avoid bursting large
numbers of packets into the network. numbers of packets into the network:
Let the session information context contain an additional variable Let the session information context contain an additional variable
DATA_PACKET_COUNT, initialized to 0. DATA_PACKET_COUNT, initialized to 0.
Transmission of a user data fragment on this session is not allowed Transmission of a user data fragment on this session is not allowed
if DATA_PACKET_COUNT is greater than or equal to 6, regardless of any if DATA_PACKET_COUNT is greater than or equal to 6, regardless of any
other allowance of the congestion control algorithm. other allowance of the congestion control algorithm.
On transmission of a packet containing at least one User Data chunk On transmission of a packet containing at least one User Data chunk
(Section 2.3.11), set DATA_PACKET_COUNT = DATA_PACKET_COUNT + 1. (Section 2.3.11), set DATA_PACKET_COUNT = DATA_PACKET_COUNT + 1.
On receipt of an acknowledgement chunk (Section 2.3.13, On receipt of an acknowledgement chunk (Sections 2.3.13 and 2.3.14),
Section 2.3.14), set DATA_PACKET_COUNT to 0. set DATA_PACKET_COUNT to 0.
On a retransmission timeout, set DATA_PACKET_COUNT to 0. On a retransmission timeout, set DATA_PACKET_COUNT to 0.
3.5.3. Address Mobility 3.5.3. Address Mobility
Sessions are demultiplexed with a 32 bit session ID, rather than by Sessions are demultiplexed with a 32-bit session ID, rather than by
endpoint address. This allows an endpoint's address to change during endpoint address. This allows an endpoint's address to change during
an S_OPEN session. This can happen, for example, when switching from an S_OPEN session. This can happen, for example, when switching from
a wireless to a wired network, or when moving from one wireless base a wireless to a wired network, or when moving from one wireless base
station to another, or when a NAT restarts. station to another, or when a NAT restarts.
If the near end receives a valid packet for an S_OPEN session from a If the near end receives a valid packet for an S_OPEN session from a
source address that doesn't match DESTADDR, the far end might have source address that doesn't match DESTADDR, the far end might have
changed addresses. The near end SHOULD verify that the far end is changed addresses. The near end SHOULD verify that the far end is
definitively at the new address before changing DESTADDR. A definitively at the new address before changing DESTADDR. A
suggested verification method is described in Section 3.5.4.2. suggested verification method is described in Section 3.5.4.2.
3.5.4. Ping 3.5.4. Ping
If an endpoint receives a Ping chunk (Section 2.3.9) in a session in If an endpoint receives a Ping chunk (Section 2.3.9) in a session in
the S_OPEN state, it SHOULD construct and send a Ping Reply chunk the S_OPEN state, it SHOULD construct and send a Ping Reply chunk
(Section 2.3.10) in response if possible, copying the message (Section 2.3.10) in response if possible, copying the message
unaltered. A Ping Reply response SHOULD be sent as quickly as unaltered. The Ping Reply SHOULD be sent as quickly as possible
possible following receipt of a Ping. The semantics of a Ping's following receipt of a Ping. The semantics of a Ping's message is
message is reserved for the sender; a receiver SHOULD NOT interpret reserved for the sender; a receiver SHOULD NOT interpret the Ping's
the Ping's message. message.
Endpoints can use the mechanism of the Ping chunk and the expected Endpoints can use the mechanism of the Ping chunk and the expected
Ping Reply for any purpose. This specification doesn't mandate any Ping Reply for any purpose. This specification doesn't mandate any
specific constraints on the format or semantics of a Ping message. A specific constraints on the format or semantics of a Ping message. A
Ping Reply MUST be sent only as a response to a Ping. Ping Reply MUST be sent only as a response to a Ping.
Receipt of a Ping Reply implies live bidirectional connectivity. Receipt of a Ping Reply implies live bidirectional connectivity.
This specification doesn't mandate any other semantics for a Ping This specification doesn't mandate any other semantics for a
Reply. Ping Reply.
3.5.4.1. Keepalive 3.5.4.1. Keepalive
An endpoint can use Ping to test for live bidirectional connectivity, An endpoint can use a Ping to test for live bidirectional
to test that the far end of a session is still S_OPEN, to keep NAT connectivity, to test that the far end of a session is still in the
translations alive, and to keep firewall holes open. S_OPEN state, to keep NAT translations alive, and to keep firewall
holes open.
An endpoint can use Ping to hasten detection by the far end of a near An endpoint can use a Ping to hasten detection of a near-end address
end address change. change by the far end.
An endpoint may declare a session to be defunct and dead after a An endpoint may declare a session to be defunct and dead after a
persistent failure by the far end to return Ping Replies in response persistent failure by the far end to return Ping Replies in response
to Pings. to Pings.
If used for these purposes, a Keepalive Ping SHOULD have an empty If used for these purposes, a Keepalive Ping SHOULD have an empty
message. message.
A Keepalive Ping SHOULD NOT be sent more often than once per ERTO. A Keepalive Ping SHOULD NOT be sent more often than once per ERTO.
If a corresponding Ping Reply is not received within ERTO of sending If a corresponding Ping Reply is not received within ERTO of sending
the Ping, ERTO SHOULD be increased according to Congestion Control the Ping, ERTO SHOULD be increased according to Section 3.5.2
(Section 3.5.2). ("Congestion Control").
3.5.4.2. Address Mobility 3.5.4.2. Address Mobility
This section describes an OPTIONAL but suggested method for This section describes an OPTIONAL but suggested method for
processing and verifying a far end address change. processing and verifying a far-end address change.
Let the session context contain additional variables MOB_TX_TS, Let the session context contain additional variables MOB_TX_TS,
MOB_RX_TS, and MOB_SECRET. MOB_TX_TS and MOB_RX_TS have initial MOB_RX_TS, and MOB_SECRET. MOB_TX_TS and MOB_RX_TS have initial
values of negative infinity. MOB_SECRET should be a values of negative infinity. MOB_SECRET should be a
cryptographically pseudorandom value not less than 128 bits in length cryptographically pseudorandom value not less than 128 bits in length
and known only to this end. and known only to this end.
On receipt of a packet for an S_OPEN session, after processing all On receipt of a packet for an S_OPEN session, after processing all
chunks in the packet: if the session is still S_OPEN, AND the source chunks in the packet: if the session is still in the S_OPEN state,
address of the packet does not match DESTADDR, AND MOB_TX_TS is at AND the source address of the packet does not match DESTADDR, AND
least one second in the past, then: MOB_TX_TS is at least one second in the past, then:
1. Set MOB_TX_TS to the current time; 1. Set MOB_TX_TS to the current time;
2. Construct a Ping message comprising: a marking to indicate (to 2. Construct a Ping message comprising the following: a marking to
this end when returned in a Ping Reply) that it is a mobility indicate (to this end when returned in a Ping Reply) that it is a
check (for example, the first byte being ASCII 'M' for mobility check (for example, the first byte being ASCII 'M' for
"Mobility"), a timestamp set to MOB_TX_TS, and a cryptographic "Mobility"), a timestamp set to MOB_TX_TS, and a cryptographic
hash over the preceding as well as the address from which the hash over the following: the preceding items, the address from
packet was received and MOB_SECRET; and which the packet was received, and MOB_SECRET; and
3. Send this Ping to the address from which the packet was received, 3. Send this Ping to the address from which the packet was received,
instead of DESTADDR. instead of DESTADDR.
On receipt of a Ping Reply in an S_OPEN session, if the Ping Reply's On receipt of a Ping Reply in an S_OPEN session, if the Ping Reply's
message satisfies all of these conditions: message satisfies all of these conditions:
o it has this end's expected marking to indicate it is a mobility o it has this end's expected marking to indicate that it is a
check, and mobility check, and
o the timestamp in the message is not more than 120 seconds in the o the timestamp in the message is not more than 120 seconds in the
past, and past, and
o the timestamp in the message is greater than MOB_RX_TS, and o the timestamp in the message is greater than MOB_RX_TS, and
o the cryptographic hash matches the expected value according to the o the cryptographic hash matches the expected value according to the
contents of the message plus the source address of the packet contents of the message plus the source address of the packet
containing this Ping Reply and MOB_SECRET, containing this Ping Reply and MOB_SECRET,
then: then:
1. Set MOB_RX_TS to the timestamp in the message; and 1. Set MOB_RX_TS to the timestamp in the message; and
2. Set DESTADDR to the source address of the packet containing this 2. Set DESTADDR to the source address of the packet containing this
Ping Reply. Ping Reply.
3.5.4.3. Path MTU Discovery 3.5.4.3. Path MTU Discovery
Packetization Layer Path MTU Discovery [RFC4821] describes a method "Packetization Layer Path MTU Discovery" [RFC4821] describes a method
for measuring the path MTU between communicating endpoints. for measuring the path MTU between communicating endpoints.
An RTMFP SHOULD perform path MTU discovery. An RTMFP SHOULD perform path MTU discovery.
The method of RFC 4821 can be adapted for use in RTMFP by sending a The method described in RFC 4821 can be adapted for use in RTMFP by
probe packet comprising one of the Padding chunk types (type 0x00 or sending a probe packet comprising one of the Padding chunk types
0xff) and a Ping. The Ping chunk SHOULD come after the Padding (type 0x00 or 0xff) and a Ping. The Ping chunk SHOULD come after the
chunk, to guard against a false positive response in case the probe Padding chunk, to guard against a false positive response in case the
packet is truncated. probe packet is truncated.
3.5.5. Close 3.5.5. Close
An endpoint may close a session at any time. Typically an endpoint An endpoint may close a session at any time. Typically, an endpoint
will close a session when there have been no open flows in either will close a session when there have been no open flows in either
direction for a time. In another circumstance, an endpoint may be direction for a time. In another circumstance, an endpoint may be
ceasing operation and will close all of its sessions even if they ceasing operation and will close all of its sessions even if they
have open flows. have open flows.
To close an S_OPEN session in a reliable and orderly fashion, an To close an S_OPEN session in a reliable and orderly fashion, an
endpoint moves the session to the S_NEARCLOSE state. endpoint moves the session to the S_NEARCLOSE state.
On a session transitioning from S_OPEN to S_NEARCLOSE and every 5 On a session transitioning from S_OPEN to S_NEARCLOSE and every
seconds thereafter while still in the S_NEARCLOSE state, send a 5 seconds thereafter while still in the S_NEARCLOSE state, send a
Session Close Request chunk (Section 2.3.17). Session Close Request chunk (Section 2.3.17).
A session that has been in the S_NEARCLOSE state for at least 90 A session that has been in the S_NEARCLOSE state for at least
seconds (allowing time to retransmit the Session Close Request 90 seconds (allowing time to retransmit the Session Close Request
multiple times) SHOULD move to the S_CLOSED state. multiple times) SHOULD move to the S_CLOSED state.
On a session transitioning from S_OPEN to the S_NEARCLOSE, On a session transitioning from S_OPEN to the S_NEARCLOSE,
S_FARCLOSE_LINGER or S_CLOSED state: immediately abort and terminate S_FARCLOSE_LINGER or S_CLOSED state, immediately abort and terminate
all open or closing flows. Flows only exist in S_OPEN sessions. all open or closing flows. Flows only exist in S_OPEN sessions.
To close an S_OPEN session abruptly, send a Session Close To close an S_OPEN session abruptly, send a Session Close
Acknowledgement chunk (Section 2.3.18), then move to the S_CLOSED Acknowledgement chunk (Section 2.3.18), then move to the S_CLOSED
state. state.
On receipt of a Session Close Request chunk for a session in the On receipt of a Session Close Request chunk for a session in the
S_OPEN, S_NEARCLOSE, or S_FARCLOSE_LINGER states: send a Session S_OPEN, S_NEARCLOSE, or S_FARCLOSE_LINGER states, send a Session
Close Acknowledgement chunk; then, if the session is in the S_OPEN Close Acknowledgement chunk; then, if the session is in the S_OPEN
state: move to the S_FARCLOSE_LINGER state. state, move to the S_FARCLOSE_LINGER state.
A session that has been in the S_FARCLOSE_LINGER state for at least A session that has been in the S_FARCLOSE_LINGER state for at least
19 seconds (allowing time to answer 3 retransmissions of a Session 19 seconds (allowing time to answer 3 retransmissions of a Session
Close Request) SHOULD move to the S_CLOSED state. Close Request) SHOULD move to the S_CLOSED state.
On receipt of a Session Close Acknowledgement chunk for a session in On receipt of a Session Close Acknowledgement chunk for a session in
the S_OPEN, S_NEARCLOSE, or S_FARCLOSE_LINGER states: move to the the S_OPEN, S_NEARCLOSE, or S_FARCLOSE_LINGER states, move to the
S_CLOSED state. S_CLOSED state.
3.6. Flows 3.6. Flows
A flow is a unidirectional communication channel in a session for A flow is a unidirectional communication channel in a session for
transporting a correlated series of user messages from a sender to a transporting a correlated series of user messages from a sender to a
receiver. Each end of a session may have zero or more sending flows receiver. Each end of a session may have zero or more sending flows
to the other end. Each sending flow at one end has a corresponding to the other end. Each sending flow at one end has a corresponding
receiving flow at the other end. receiving flow at the other end.
skipping to change at page 73, line 22 skipping to change at page 75, line 46
are no "well known" or reserved flow identifiers. are no "well known" or reserved flow identifiers.
Bidirectional flow association is indicated at flow startup with the Bidirectional flow association is indicated at flow startup with the
Return Flow Association option (Section 2.3.11.1.2). An endpoint can Return Flow Association option (Section 2.3.11.1.2). An endpoint can
indicate that a new sending flow is in return (or response) to a indicate that a new sending flow is in return (or response) to a
receiving flow from the other end. A sending flow MUST NOT indicate receiving flow from the other end. A sending flow MUST NOT indicate
more than one return association. A receiving flow can be specified more than one return association. A receiving flow can be specified
as the return association for any number of sending flows. The as the return association for any number of sending flows. The
return flow association, if any, is fixed for the lifetime of the return flow association, if any, is fixed for the lifetime of the
sending flow. Note: Closure of one flow in an association does not sending flow. Note: Closure of one flow in an association does not
automatically close other flows in the association except as automatically close other flows in the association, except as
specified in Section 3.6.3.1. specified in Section 3.6.3.1.
Flows are named with arbitrary user metadata. This specification Flows are named with arbitrary user metadata. This specification
doesn't mandate any particular encoding, syntax, or semantics for the doesn't mandate any particular encoding, syntax, or semantics for the
user metadata except for the encoded size (Section 2.3.11.1.1); the user metadata, except for the encoded size (Section 2.3.11.1.1); the
user metadata is entirely reserved for the application. The user user metadata is entirely reserved for the application. The user
metadata is fixed for the lifetime of the flow. metadata is fixed for the lifetime of the flow.
3.6.1.2. Messages and Sequencing 3.6.1.2. Messages and Sequencing
Flows provide message-oriented framing. Large messages are Flows provide message-oriented framing. Large messages are
fragmented for transport in the network. Receivers reassemble fragmented for transport in the network. Receivers reassemble
fragmented messages and only present complete messages to the user. fragmented messages and only present complete messages to the user.
A sender queues messages on a sending flow one after another. A A sender queues messages on a sending flow one after another. A
receiver can recover the original queuing order of the messages, even receiver can recover the original queuing order of the messages, even
when they are reordered in transit by the network or as a result of when they are reordered in transit by the network or as a result of
loss and retransmission, by means of the messages' fragment sequence loss and retransmission, by means of the messages' fragment sequence
numbers. Flows are the basic units of message sequencing; each flow numbers. Flows are the basic units of message sequencing; each flow
is sequenced independently of all other flows; inter-flow message is sequenced independently of all other flows; inter-flow message
arrival and delivery sequencing is not guaranteed. arrival and delivery sequencing are not guaranteed.
Independent flow sequencing allows a sender to prioritize the Independent flow sequencing allows a sender to prioritize the
transmission or retransmission of the messages of one flow over those transmission or retransmission of the messages of one flow over those
of other flows in a session, allocating capacity from the of other flows in a session, allocating capacity from the
transmission budget according to priority. RTMFP is designed for transmission budget according to priority. RTMFP is designed for
flows to be the basic unit of prioritization. In any flow, fragment flows to be the basic unit of prioritization. In any flow, fragment
sequence numbers are unique and monotonically increasing; that is, sequence numbers are unique and monotonically increasing; that is,
the fragment sequence numbers for any message MUST be greater than the fragment sequence numbers for any message MUST be greater than
the fragment sequence numbers of all messages previously queued in the fragment sequence numbers of all messages previously queued in
that flow. Receipt of fragments within a flow out of sequence number that flow. Receipt of fragments out of sequence number order within
order creates discontiguous gaps at the receiver, causing it to send a flow creates discontiguous gaps at the receiver, causing it to send
an acknowledgement for every packet and for the size of the encoded an acknowledgement for every packet and also causing the size of the
acknowledgements to grow. Therefore, for any flow, the sender SHOULD encoded acknowledgements to grow. Therefore, for any flow, the
send lower sequence numbers first. sender SHOULD send lower sequence numbers first.
A sender can abandon a queued message at any time, even if some A sender can abandon a queued message at any time, even if some
fragments of that message have been received by the other end. A fragments of that message have been received by the other end. A
receiver MUST be able to detect a gap in the flow when a message is receiver MUST be able to detect a gap in the flow when a message is
abandoned; therefore, each message SHOULD take at least one sequence abandoned; therefore, each message SHOULD take at least one sequence
number from the sequence space even if no fragments for that message number from the sequence space even if no fragments for that message
are ever sent. The sender will transmit the fragments of all are ever sent. The sender will transmit the fragments of all
messages not abandoned, and retransmit any lost fragments of all messages not abandoned, and retransmit any lost fragments of all
messages not abandoned, until all the fragments of all messages not messages not abandoned, until all the fragments of all messages not
abandoned are acknowledged by the receiver. A sender indicates a abandoned are acknowledged by the receiver. A sender indicates a
skipping to change at page 74, line 47 skipping to change at page 77, line 26
that point, the flow identifier alone is sufficient. that point, the flow identifier alone is sufficient.
Flow receivers SHOULD acknowledge all sequence numbers received for Flow receivers SHOULD acknowledge all sequence numbers received for
any flow, whether the flow is accepted or rejected. Flow receivers any flow, whether the flow is accepted or rejected. Flow receivers
MUST NOT acknowledge sequence numbers higher than the FSN that were MUST NOT acknowledge sequence numbers higher than the FSN that were
not received. Acknowledgements drive the congestion control and not received. Acknowledgements drive the congestion control and
avoidance algorithms and therefore must be accurate. avoidance algorithms and therefore must be accurate.
An endpoint can reject a receiving flow at any time in the flow's An endpoint can reject a receiving flow at any time in the flow's
lifetime. To reject the flow, the receiving endpoint sends a Flow lifetime. To reject the flow, the receiving endpoint sends a Flow
Exception chunk (Section 2.3.16) immediately preceding every Exception Report chunk (Section 2.3.16) immediately preceding every
acknowledgement chunk for the rejected receiving flow. acknowledgement chunk for the rejected receiving flow.
An endpoint may eventually conclude and close a sending flow. The An endpoint may eventually conclude and close a sending flow. The
last sequence number of the flow is marked with the Final flag. The last sequence number of the flow is marked with the Final flag. The
sending flow is complete when all sequence numbers of the flow, sending flow is complete when all sequence numbers of the flow,
including the final sequence number, have been cumulatively including the final sequence number, have been cumulatively
acknowledged by the receiver. The receiving flow is complete when acknowledged by the receiver. The receiving flow is complete when
every sequence number from the FSN to the final sequence number has every sequence number from the FSN to the final sequence number has
been received. The sending flow and corresponding receiving flow at been received. The sending flow and corresponding receiving flow at
the respective ends hold the flow identifier of a completed flow in the respective ends hold the flow identifier of a completed flow in
skipping to change at page 75, line 33 skipping to change at page 78, line 18
necessary to transfer that flow's messages to the other end. Each necessary to transfer that flow's messages to the other end. Each
sending flow context includes at least: sending flow context includes at least:
o F_FLOW_ID: this flow's identifier; o F_FLOW_ID: this flow's identifier;
o STARTUP_OPTIONS: the set of options to send to the receiver until o STARTUP_OPTIONS: the set of options to send to the receiver until
this flow is acknowledged, including the User's Per-Flow Metadata this flow is acknowledged, including the User's Per-Flow Metadata
and, if set, the Return Flow Association; and, if set, the Return Flow Association;
o SEND_QUEUE: the unacknowledged message fragments queued in this o SEND_QUEUE: the unacknowledged message fragments queued in this
flow, initially empty; each message fragment entry comprising: flow, initially empty; each message fragment entry comprising the
following:
* SEQUENCE_NUMBER: the sequence number of this fragment; * SEQUENCE_NUMBER: the sequence number of this fragment;
* DATA: this fragment's user data; * DATA: this fragment's user data;
* FRA: the fragment control value for this message fragment, * FRA: the fragment control value for this message fragment,
having one of the values enumerated for that purpose in User having one of the values enumerated for that purpose in
Data (Section 2.3.11); Section 2.3.11 ("User Data Chunk");
* ABANDONED: a boolean flag indicating whether this fragment has * ABANDONED: a boolean flag indicating whether this fragment has
been abandoned; been abandoned;
* SENT_ABANDONED: a boolean flag indicating whether this fragment * SENT_ABANDONED: a boolean flag indicating whether this fragment
was abandoned when sent; was abandoned when sent;
* EVER_SENT: a boolean flag indicating whether this fragment has * EVER_SENT: a boolean flag indicating whether this fragment has
been sent at least once, initially false; been sent at least once, initially false;
skipping to change at page 76, line 20 skipping to change at page 79, line 6
false; false;
* TRANSMIT_SIZE: the size, in bytes, of the encoded User Data * TRANSMIT_SIZE: the size, in bytes, of the encoded User Data
chunk (including the chunk header) for this fragment when it chunk (including the chunk header) for this fragment when it
was transmitted into the network. was transmitted into the network.
o F_OUTSTANDING_BYTES: the sum of the TRANSMIT_SIZE of each entry in o F_OUTSTANDING_BYTES: the sum of the TRANSMIT_SIZE of each entry in
SEND_QUEUE where entry.IN_FLIGHT is true; SEND_QUEUE where entry.IN_FLIGHT is true;
o RX_BUFFER_SIZE: the most recent available buffer advertisement o RX_BUFFER_SIZE: the most recent available buffer advertisement
from the other end (Section 2.3.13, Section 2.3.14), initially from the other end (Sections 2.3.13 and 2.3.14), initially
65536 bytes; 65536 bytes;
o NEXT_SN: the next sequence number to assign to a message fragment, o NEXT_SN: the next sequence number to assign to a message fragment,
initially 1; initially 1;
o F_FINAL_SN: the sequence number assigned to the final message o F_FINAL_SN: the sequence number assigned to the final message
fragment of the flow, initially having no value; fragment of the flow, initially having no value;
o EXCEPTION: a boolean flag indicating whether an exception has been o EXCEPTION: a boolean flag indicating whether an exception has been
reported by the receiver, initially false; reported by the receiver, initially false;
o The state, at any time being one of the following values: the open o The state, at any time being one of the following values: the open
state F_OPEN; the closing states F_CLOSING and F_COMPLETE_LINGER; state F_OPEN; the closing states F_CLOSING and F_COMPLETE_LINGER;
and the closed state F_CLOSED. and the closed state F_CLOSED.
Note: this diagram is only a summary of state transitions and their Note: The following diagram is only a summary of state transitions
causing events, and is not a complete operational specification. and their causing events, and is not a complete operational
specification.
+--------+
| F_OPEN |
+--------+
|CLOSE or
|rcv Flow Exception
|
v
+---------+
|F_CLOSING|
+---------+
|rcv Data Ack
| 0..F_FINAL_SN
v
+-----------------+
|F_COMPLETE_LINGER|
+-----------------+
| 130 seconds
v
+--------+ +--------+
|F_CLOSED| | F_OPEN |
+--------+ +--------+
|CLOSE or
|rcv Flow Exception
|
v
+---------+
|F_CLOSING|
+---------+
|rcv Data Ack
| 0..F_FINAL_SN
v
+-----------------+
|F_COMPLETE_LINGER|
+-----------------+
| 130 seconds
v
+--------+
|F_CLOSED|
+--------+
Figure 19: Sending flow state diagram Figure 19: Sending Flow State Diagram
3.6.2.1. Startup 3.6.2.1. Startup
The application opens a new sending flow to the other end in an The application opens a new sending flow to the other end in an
S_OPEN session. The implementation chooses a new flow ID that is not S_OPEN session. The implementation chooses a new flow ID that is not
assigned to any other sending flow in that session in the F_OPEN, assigned to any other sending flow in that session in the F_OPEN,
F_CLOSING, or F_COMPLETE_LINGER states. The flow starts in the F_CLOSING, or F_COMPLETE_LINGER states. The flow starts in the
F_OPEN state. The STARTUP_OPTIONS for the new flow is set with the F_OPEN state. The STARTUP_OPTIONS for the new flow is set with the
User's Per-Flow Metadata (Section 2.3.11.1.1). If this flow is in User's Per-Flow Metadata (Section 2.3.11.1.1). If this flow is in
return (or response) to a receiving flow from the other end, that return (or response) to a receiving flow from the other end, that
flow's ID is encoded in a Return Flow Association flow's ID is encoded in a Return Flow Association
(Section 2.3.11.1.2) option and added to STARTUP_OPTIONS. A new (Section 2.3.11.1.2) option and added to STARTUP_OPTIONS. A new
sending flow SHOULD NOT be opened in response to a receiving flow sending flow SHOULD NOT be opened in response to a receiving flow
from the other end that is not in the RF_OPEN state when the sending from the other end that is not in the RF_OPEN state when the sending
flow is opened. flow is opened.
At this point the flow exists in the sender, but not the receiver. At this point, the flow exists in the sender but not in the receiver.
The flow begins when user data fragments are transmitted to the The flow begins when user data fragments are transmitted to the
receiver. A sender can begin a flow in the absence of immediate user receiver. A sender can begin a flow in the absence of immediate user
data by sending a Forward Sequence Number Update (Section 3.6.2.7.1), data by sending a Forward Sequence Number Update (Section 3.6.2.7.1),
by queuing and transmitting a user data fragment that is already by queuing and transmitting a user data fragment that is already
abandoned. abandoned.
3.6.2.2. Queuing Data 3.6.2.2. Queuing Data
The application queues messages in an F_OPEN sending flow for The application queues messages in an F_OPEN sending flow for
transmission to the far end. The implementation divides each message transmission to the far end. The implementation divides each message
into one or more fragments for transmission in User Data chunks into one or more fragments for transmission in User Data chunks
(Section 2.3.11). Each fragment MUST be small enough so that, if (Section 2.3.11). Each fragment MUST be small enough so that, if
assembled into a Packet (Section 2.2.4) with a maximum-size common assembled into a packet (Section 2.2.4) with a maximum-size common
header, User Data chunk header, and, if not empty, this flow's header, User Data chunk header, and, if not empty, this flow's
STARTUP_OPTIONS, the Packet will not exceed the Path MTU STARTUP_OPTIONS, the packet will not exceed the path MTU
(Section 3.5.4.3). (Section 3.5.4.3).
For each fragment, create a fragment entry and set For each fragment, create a fragment entry and set
fragmentEntry.SEQUENCE_NUMBER to flow.NEXT_SN, and increment fragmentEntry.SEQUENCE_NUMBER to flow.NEXT_SN, and increment
flow.NEXT_SN by one. Set fragmentEntry.FRA according to the encoding flow.NEXT_SN by one. Set fragmentEntry.FRA according to the encoding
in User Data chunks: in User Data chunks:
0 : This fragment is a complete message. 0: This fragment is a complete message.
1 : This fragment is the first of a multi-fragment message. 1: This fragment is the first of a multi-fragment message.
2 : This fragment is the last of a multi-fragment message. 2: This fragment is the last of a multi-fragment message.
3 : This fragment is in the middle of a multi-fragment message. 3: This fragment is in the middle of a multi-fragment message.
Append fragmentEntry to flow.SEND_QUEUE. Append fragmentEntry to flow.SEND_QUEUE.
3.6.2.3. Sending Data 3.6.2.3. Sending Data
A sending flow is ready to transmit if the SEND_QUEUE contains at A sending flow is ready to transmit if the SEND_QUEUE contains at
least one entry that is eligible to send and if either RX_BUFFER_SIZE least one entry that is eligible to send, and if either
is greater than F_OUTSTANDING_BYTES or EXCEPTION is set to true. RX_BUFFER_SIZE is greater than F_OUTSTANDING_BYTES or EXCEPTION is
set to true.
A SEND_QUEUE entry is eligible to send if it is not IN_FLIGHT AND at A SEND_QUEUE entry is eligible to send if it is not IN_FLIGHT, AND at
least one of the following conditions holds: least one of the following conditions holds:
o The entry is not ABANDONED; or o The entry is not ABANDONED; or
o The entry is the first one in the SEND_QUEUE; or o The entry is the first one in the SEND_QUEUE; or
o The entry's SEQUENCE_NUMBER is equal to flow.F_FINAL_SN. o The entry's SEQUENCE_NUMBER is equal to flow.F_FINAL_SN.
If the session's transmission budget allows, a flow that is ready to If the session's transmission budget allows, a flow that is ready to
transmit is selected for transmission according to the transmit is selected for transmission according to the
implementation's prioritization scheme. The manner of flow implementation's prioritization scheme. The manner of flow
prioritization is not mandated by this specification. prioritization is not mandated by this specification.
Trim abandoned messages from the front of the queue and find the Trim abandoned messages from the front of the queue, and find the
Forward Sequence Number FSN: Forward Sequence Number (FSN):
1. While the SEND_QUEUE contains at least two entries, AND the first 1. While the SEND_QUEUE contains at least two entries, AND the first
entry is not IN_FLIGHT, AND the first entry is ABANDONED: remove entry is not IN_FLIGHT, AND the first entry is ABANDONED, remove
and discard the first entry from SEND_QUEUE; and discard the first entry from the SEND_QUEUE;
2. If the first entry in the SEND_QUEUE is not abandoned: set FSN to 2. If the first entry in the SEND_QUEUE is not abandoned, set FSN to
entry.SEQUENCE_NUMBER - 1; otherwise entry.SEQUENCE_NUMBER - 1; otherwise,
3. If the first entry in the SEND_QUEUE is IN_FLIGHT AND 3. If the first entry in the SEND_QUEUE is IN_FLIGHT, AND
entry.SENT_ABANDONED is false: set FSN to entry.SEQUENCE_NUMBER - entry.SENT_ABANDONED is false, set FSN to
1; otherwise entry.SEQUENCE_NUMBER - 1; otherwise,
4. The first entry in the SEND_QUEUE is abandoned and is either not 4. The first entry in the SEND_QUEUE is abandoned and either is not
IN_FLIGHT or was already abandoned when sent: set FSN to IN_FLIGHT or was already abandoned when sent; set FSN to
entry.SEQUENCE_NUMBER. entry.SEQUENCE_NUMBER.
The FSN MUST NOT be greater than any sequence number currently The FSN MUST NOT be greater than any sequence number currently
outstanding. The FSN MUST NOT be equal to any sequence number outstanding. The FSN MUST NOT be equal to any sequence number
currently outstanding that was not abandoned when sent. currently outstanding that was not abandoned when sent.
Assemble user data chunks for this flow into a packet to send to the Assemble user data chunks for this flow into a packet to send to the
receiver. While enough space remains in the packet and the flow is receiver. While enough space remains in the packet and the flow is
ready to transmit: ready to transmit:
1. Starting at the head of the SEND_QUEUE, find the first eligible 1. Starting at the head of the SEND_QUEUE, find the first eligible
fragment entry; fragment entry;
2. Encode entry into a User Data chunk (Section 2.3.11) or, if 2. Encode the entry into a User Data chunk (Section 2.3.11) or, if
possible (Section 3.6.2.3.2), a Next User Data chunk possible (Section 3.6.2.3.2), a Next User Data chunk
(Section 2.3.12); (Section 2.3.12);
3. If present, set chunk.flowID to flow.F_FLOW_ID; 3. If present, set chunk.flowID to flow.F_FLOW_ID;
4. If present, set chunk.sequenceNumber to entry.SEQUENCE_NUMBER; 4. If present, set chunk.sequenceNumber to entry.SEQUENCE_NUMBER;
5. If present, set chunk.fsnOffset to entry.SEQUENCE_NUMBER - FSN; 5. If present, set chunk.fsnOffset to entry.SEQUENCE_NUMBER - FSN;
6. Set chunk.fragmentControl to entry.FRA; 6. Set chunk.fragmentControl to entry.FRA;
7. Set chunk.abandon to entry.ABANDONED; 7. Set chunk.abandon to entry.ABANDONED;
8. If entry.SEQUENCE_NUMBER equals flow.F_FINAL_SN: set chunk.final 8. If entry.SEQUENCE_NUMBER equals flow.F_FINAL_SN, set chunk.final
to true; else set chunk.final to false; to true; else set chunk.final to false;
9. If any options are being sent with this chunk: set 9. If any options are being sent with this chunk, set
chunk.optionsPresent to true, assemble the options into the chunk.optionsPresent to true, assemble the options into the
chunk, and assemble a Marker to terminate the option list; chunk, and assemble a Marker to terminate the option list;
10. If entry.ABANDONED is true, set chunk.userData to empty; 10. If entry.ABANDONED is true, set chunk.userData to empty;
otherwise set chunk.userData to entry.DATA; otherwise, set chunk.userData to entry.DATA;
11. If adding the assembled chunk to the packet would cause the 11. If adding the assembled chunk to the packet would cause the
packet to exceed the path MTU: do not assemble this chunk into packet to exceed the path MTU, do not assemble this chunk into
the packet, enough space no longer remains in the packet, stop. the packet; enough space no longer remains in the packet; stop.
Otherwise, continue: Otherwise, continue:
12. Set entry.IN_FLIGHT to true; 12. Set entry.IN_FLIGHT to true;
13. Set entry.EVER_SENT to true; 13. Set entry.EVER_SENT to true;
14. Set entry.NAK_COUNT to 0; 14. Set entry.NAK_COUNT to 0;
15. Set entry.SENT_ABANDONED to entry.ABANDONED; 15. Set entry.SENT_ABANDONED to entry.ABANDONED;
skipping to change at page 80, line 48 skipping to change at page 83, line 29
3.6.2.3.2. Send Next Data 3.6.2.3.2. Send Next Data
The Next User Data chunk (Section 2.3.12) is a compact encoding for a The Next User Data chunk (Section 2.3.12) is a compact encoding for a
user message fragment when multiple contiguous fragments are user message fragment when multiple contiguous fragments are
assembled into one packet. Using this chunk where possible can assembled into one packet. Using this chunk where possible can
conserve space in a packet, potentially reducing transmission conserve space in a packet, potentially reducing transmission
overhead or allowing additional information to be sent in a packet. overhead or allowing additional information to be sent in a packet.
If, after assembling a user message fragment of a flow into a packet If, after assembling a user message fragment of a flow into a packet
(Section 3.6.2.3), the next eligible fragment to be selected for (Section 3.6.2.3), the next eligible fragment to be selected for
assembly into that packet belongs to the same flow AND its sequence assembly into that packet belongs to the same flow, AND its sequence
number is one greater than that of the fragment just assembled, it is number is one greater than that of the fragment just assembled, it is
RECOMMENDED that an implementation encode a Next User Data chunk RECOMMENDED that an implementation encode a Next User Data chunk
instead of a User Data chunk. instead of a User Data chunk.
The FIRST fragment of a flow assembled into a packet MUST be encoded The FIRST fragment of a flow assembled into a packet MUST be encoded
as a User Data chunk. as a User Data chunk.
3.6.2.4. Processing Acknowledgements 3.6.2.4. Processing Acknowledgements
A Data Acknowledgement Bitmap chunk (Section 2.3.13) or a Data A Data Acknowledgement Bitmap chunk (Section 2.3.13) or a Data
skipping to change at page 81, line 22 skipping to change at page 84, line 4
acknowledgement of receipt of one or more sequence numbers of a flow, acknowledgement of receipt of one or more sequence numbers of a flow,
as well as the receiver's current receive window advertisement. as well as the receiver's current receive window advertisement.
On receipt of an acknowledgement chunk for a sending flow: On receipt of an acknowledgement chunk for a sending flow:
1. Set PRE_ACK_OUTSTANDING_BYTES to flow.F_OUTSTANDING_BYTES; 1. Set PRE_ACK_OUTSTANDING_BYTES to flow.F_OUTSTANDING_BYTES;
2. Set flow.STARTUP_OPTIONS to empty; 2. Set flow.STARTUP_OPTIONS to empty;
3. Set flow.RX_BUFFER_SIZE to chunk.bufferBytesAvailable; 3. Set flow.RX_BUFFER_SIZE to chunk.bufferBytesAvailable;
4. For each sequence number encoded in the acknowledgement, if
4. For each sequence number encoded in the acknowledgement: if there there is an entry in flow.SEND_QUEUE with that sequence number
is an entry in flow.SEND_QUEUE with that sequence number and its and its IN_FLIGHT is true, then remove the entry from
IN_FLIGHT is true, then: remove entry from flow.SEND_QUEUE; and flow.SEND_QUEUE; and
5. Notify the congestion control and avoidance algorithms that 5. Notify the congestion control and avoidance algorithms that
PRE_ACK_OUTSTANDING_BYTES - flow.F_OUTSTANDING_BYTES were PRE_ACK_OUTSTANDING_BYTES - flow.F_OUTSTANDING_BYTES were
acknowledged. Note that Negative Acknowledgements acknowledged. Note that negative acknowledgements
(Section 3.6.2.5) affect "TCP friendly" congestion control. (Section 3.6.2.5) affect "TCP friendly" congestion control.
3.6.2.5. Negative Acknowledgement and Loss 3.6.2.5. Negative Acknowledgement and Loss
A negative acknowledgement is inferred for an outstanding fragment if A negative acknowledgement is inferred for an outstanding fragment if
an acknowledgement is received for any other fragments sent after it an acknowledgement is received for any other fragments sent after it
in the same session. in the same session.
An implementation SHOULD consider a fragment to be lost once that An implementation SHOULD consider a fragment to be lost once that
fragment receives three negative acknowledgements. A lost fragment fragment receives three negative acknowledgements. A lost fragment
skipping to change at page 82, line 23 skipping to change at page 85, line 4
On transmission of a message fragment into the network, set its On transmission of a message fragment into the network, set its
entry.TSN to session.NEXT_TSN, and increment session.NEXT_TSN. entry.TSN to session.NEXT_TSN, and increment session.NEXT_TSN.
On acknowledgement of an outstanding fragment, if its entry.TSN is On acknowledgement of an outstanding fragment, if its entry.TSN is
greater than session.MAX_TSN_ACK, set session.MAX_TSN_ACK to greater than session.MAX_TSN_ACK, set session.MAX_TSN_ACK to
entry.TSN. entry.TSN.
After processing all acknowledgements in a packet containing at least After processing all acknowledgements in a packet containing at least
one acknowledgement, then for each sending flow in that session, for one acknowledgement, then for each sending flow in that session, for
each entry in that flow's SEND_QUEUE, if entry.IN_FLIGHT is true and each entry in that flow's SEND_QUEUE, if entry.IN_FLIGHT is true and
entry.TSN is less than session.MAX_TSN_ACK: increment entry.NAK_COUNT entry.TSN is less than session.MAX_TSN_ACK, increment entry.NAK_COUNT
and notify the congestion control and avoidance algorithms that a and notify the congestion control and avoidance algorithms that a
negative acknowledgement was detected in this packet. negative acknowledgement was detected in this packet.
For each sending flow in that session, for each entry in that flow's For each sending flow in that session, for each entry in that flow's
SEND_QUEUE, if entry.IN_FLIGHT is true and entry.NAK_COUNT is at SEND_QUEUE, if entry.IN_FLIGHT is true and entry.NAK_COUNT is at
least 3, that fragment was lost in the network and is no longer least 3, that fragment was lost in the network and is no longer
considered to be in flight. Set entry.IN_FLIGHT to false. Notify considered to be in flight. Set entry.IN_FLIGHT to false. Notify
the congestion control and avoidance algorithms of the loss. the congestion control and avoidance algorithms of the loss.
3.6.2.6. Timeout 3.6.2.6. Timeout
A fragment is considered lost and no longer in flight in the network A fragment is considered lost and no longer in flight in the network
if it has remained outstanding for at least ERTO. if it has remained outstanding for at least ERTO.
The following describes an OPTIONAL method to manage transmission The following describes an OPTIONAL method to manage transmission
timeouts. This method REQUIRES that either Burst Avoidance timeouts. This method REQUIRES that either burst avoidance
(Section 3.5.2.3) is implemented, or that the implementation's (Section 3.5.2.3) is implemented or the implementation's congestion
congestion control and avoidance algorithms will eventually stop control and avoidance algorithms will eventually stop sending new
sending new fragments into the network if acknowledgements are fragments into the network if acknowledgements are persistently not
persistently not received. received.
Let the session information context contain an alarm TIMEOUT_ALARM, Let the session information context contain an alarm TIMEOUT_ALARM,
initially unset. initially unset.
On sending a packet containing at least one User Data chunk, set or On sending a packet containing at least one User Data chunk, set or
reset TIMEOUT_ALARM to fire in ERTO. reset TIMEOUT_ALARM to fire in ERTO.
On receiving a packet containing at least one acknowledgement, reset On receiving a packet containing at least one acknowledgement, reset
TIMEOUT_ALARM (if already set) to fire in ERTO. TIMEOUT_ALARM (if already set) to fire in ERTO.
When TIMEOUT_ALARM fires: When TIMEOUT_ALARM fires:
1. Set WAS_LOSS = false; 1. Set WAS_LOSS = false;
2. For each sending flow in the session, and for each entry in that 2. For each sending flow in the session, and for each entry in that
flow's SEND_QUEUE: flow's SEND_QUEUE:
1. If entry.IN_FLIGHT is true: set WAS_LOSS = true; and 1. If entry.IN_FLIGHT is true, set WAS_LOSS = true; and
2. Set entry.IN_FLIGHT to false. 2. Set entry.IN_FLIGHT to false.
3. If WAS_LOSS is true: perform ERTO backoff (Section 3.5.2.2); and 3. If WAS_LOSS is true, perform ERTO backoff (Section 3.5.2.2); and
4. Notify the congestion control and avoidance algorithms of the 4. Notify the congestion control and avoidance algorithms of the
timeout and, if WAS_LOSS is true, that there was loss. timeout and, if WAS_LOSS is true, that there was loss.
3.6.2.7. Abandoning Data 3.6.2.7. Abandoning Data
The application can abandon queued messages at any time and for any The application can abandon queued messages at any time and for any
reason. Example reasons include (but are not limited to): one or reason. Example reasons include (but are not limited to) the
more fragments of a message have remained in the SEND_QUEUE for following: one or more fragments of a message have remained in the
longer than a specified message lifetime; a fragment has been SEND_QUEUE for longer than a specified message lifetime; a fragment
retransmitted more than a specified retransmission limit; a prior has been retransmitted more than a specified retransmission limit; a
message on which this message depends (such as a key frame in a prior message on which this message depends (such as a key frame in a
prediction chain) was abandoned and not delivered. prediction chain) was abandoned and not delivered.
To abandon a message fragment, set its SEND_QUEUE entry's ABANDON To abandon a message fragment, set its SEND_QUEUE entry's ABANDON
flag to true. When abandoning a message fragment, abandon all flag to true. When abandoning a message fragment, abandon all
fragments of the message to which it belongs. fragments of the message to which it belongs.
An abandoned fragment MUST NOT be un-abandoned. An abandoned fragment MUST NOT be un-abandoned.
3.6.2.7.1. Forward Sequence Number Update 3.6.2.7.1. Forward Sequence Number Update
skipping to change at page 84, line 8 skipping to change at page 86, line 41
When the receiver has gaps in the received sequence number space and When the receiver has gaps in the received sequence number space and
no non-abandoned message fragments remain in the SEND_QUEUE, the no non-abandoned message fragments remain in the SEND_QUEUE, the
sender SHOULD transmit a Forward Sequence Number Update (FSN Update) sender SHOULD transmit a Forward Sequence Number Update (FSN Update)
comprising a User Data chunk marked abandoned, whose sequence number comprising a User Data chunk marked abandoned, whose sequence number
is the FSN and whose fsnOffset is 0. An FSN Update allows the is the FSN and whose fsnOffset is 0. An FSN Update allows the
receiver to skip gaps that will not be repaired and deliver received receiver to skip gaps that will not be repaired and deliver received
messages to the user. An FSN Update may be thought of as a messages to the user. An FSN Update may be thought of as a
transmission or retransmission of abandoned sequence numbers without transmission or retransmission of abandoned sequence numbers without
actually sending the data. actually sending the data.
The method described in Sending Data (Section 3.6.2.3) generates FSN The method described in Section 3.6.2.3 ("Sending Data") generates
Updates when appropriate. FSN Updates when appropriate.
3.6.2.8. Examples 3.6.2.8. Examples
Sender Sender
| : | :
1 |<--- Ack ID=2, seq:0-16 1 |<--- Ack ID=2, seq:0-16
2 |---> Data ID=2, seq#=25, fsnOff=9 (fsn=16) 2 |---> Data ID=2, seq#=25, fsnOff=9 (fsn=16)
3 |---> Data ID=2, seq#=26, fsnOff=10 (fsn=16) 3 |---> Data ID=2, seq#=26, fsnOff=10 (fsn=16)
4 |<--- Ack ID=2, seq:0-18 4 |<--- Ack ID=2, seq:0-18
5 |---> Data ID=2, seq#=27, fsnOff=9 (fsn=18) 5 |---> Data ID=2, seq#=27, fsnOff=9 (fsn=18)
6 |---> Data ID=2, seq#=28, fsnOff=10 (fsn=18) 6 |---> Data ID=2, seq#=28, fsnOff=10 (fsn=18)
| : | :
There are 9 sequence numbers in flight with delayed acknowledgements. There are 9 sequence numbers in flight with delayed acknowledgements.
Figure 20: Normal flow with no loss Figure 20: Normal Flow with No Loss
Sender Sender
| : | :
1 |<--- Ack ID=3, seq:0-30 1 |<--- Ack ID=3, seq:0-30
2 |---> Data ID=3, seq#=45, fsnOff=15 (fsn=30) 2 |---> Data ID=3, seq#=45, fsnOff=15 (fsn=30)
3 |<--- Ack ID=3, seq:0-30, 32 (nack 31:1) 3 |<--- Ack ID=3, seq:0-30, 32 (nack 31:1)
4 |---> Data ID=3, seq#=46, fsnOff=16 (fsn=30) 4 |---> Data ID=3, seq#=46, fsnOff=16 (fsn=30)
5 |<--- Ack ID=3, seq:0-30, 32, 34 (nack 31:2, 33:1) 5 |<--- Ack ID=3, seq:0-30, 32, 34 (nack 31:2, 33:1)
6 |<--- Ack ID=3, seq:0-30, 32, 34-35 (nack 31:3=lost, 33:2) 6 |<--- Ack ID=3, seq:0-30, 32, 34-35 (nack 31:3=lost, 33:2)
7 |---> Data ID=3, seq#=47, fsnOff=15 (fsn=32, abandon 31) 7 |---> Data ID=3, seq#=47, fsnOff=15 (fsn=32, abandon 31)
skipping to change at page 85, line 41 skipping to change at page 88, line 41
21 |<--- Ack ID=3, seq:0-59 21 |<--- Ack ID=3, seq:0-59
22 |<--- Ack ID=3, seq:0-59, 61 (nack 60:1) 22 |<--- Ack ID=3, seq:0-59, 61 (nack 60:1)
23 |<--- Ack ID=3, seq:0-59, 61-62 (nack 60:2) 23 |<--- Ack ID=3, seq:0-59, 61-62 (nack 60:2)
24 |<--- Ack ID=3, seq:0-59, 61-63 (nack 60:3=lost) 24 |<--- Ack ID=3, seq:0-59, 61-63 (nack 60:3=lost)
25 |---> Data ID=3, ABN=1, seq#=60, fsnOff=0 (fsn=60, abandon 60) 25 |---> Data ID=3, ABN=1, seq#=60, fsnOff=0 (fsn=60, abandon 60)
26 |<--- Ack ID=3, seq:0-59, 61-64 26 |<--- Ack ID=3, seq:0-59, 61-64
| : | :
27 |<--- Ack ID=3, seq:0-64 27 |<--- Ack ID=3, seq:0-64
Flow with sequence numbers 31, 33, and 60 lost in transit, and a Flow with sequence numbers 31, 33, and 60 lost in transit, and a
pause at 64. 33 is retransmitted, 31 and 60 are abandoned. Note line pause at 64. 33 is retransmitted; 31 and 60 are abandoned. Note
25 is a Forward Sequence Number Update (Section 3.6.2.7.1). that line 25 is a Forward Sequence Number Update (Section 3.6.2.7.1).
Figure 21: Flow with loss Figure 21: Flow with Loss
3.6.2.9. Flow Control 3.6.2.9. Flow Control
The flow receiver advertises the amount of new data it's willing to The flow receiver advertises the amount of new data it's willing to
accept from the flow sender with the bufferBytesAvailable derived accept from the flow sender with the bufferBytesAvailable derived
field of an acknowledgement (Section 2.3.13, Section 2.3.14). field of an acknowledgement (Sections 2.3.13 and 2.3.14).
The flow sender MUST NOT send new data into the network if The flow sender MUST NOT send new data into the network if
flow.F_OUTSTANDING_BYTES is greater than or equal to the most flow.F_OUTSTANDING_BYTES is greater than or equal to the most
recently received buffer advertisement, unless flow.EXCEPTION is true recently received buffer advertisement, unless flow.EXCEPTION is true
(Section 3.6.2.3). (Section 3.6.2.3).
3.6.2.9.1. Buffer Probe 3.6.2.9.1. Buffer Probe
The flow sender is suspended if the most recently received buffer The flow sender is suspended if the most recently received buffer
advertisement is zero and the flow hasn't been rejected by the advertisement is zero and the flow hasn't been rejected by the
receiver; that is, while RX_BUFFER_SIZE is zero AND EXCEPTION is receiver -- that is, while RX_BUFFER_SIZE is zero AND EXCEPTION is
false. To guard against potentially lost acknowledgements that might false. To guard against potentially lost acknowledgements that might
reopen the receive window, a suspended flow sender SHOULD send a reopen the receive window, a suspended flow sender SHOULD send a
packet comprising a Buffer Probe chunk (Section 2.3.15) for this flow packet comprising a Buffer Probe chunk (Section 2.3.15) for this flow
from time to time. from time to time.
If the receive window advertisement transitions from non-zero to If the receive window advertisement transitions from non-zero to
zero, the flow sender MAY send a Buffer Probe immediately and SHOULD zero, the flow sender MAY send a Buffer Probe immediately and SHOULD
send a probe within one second. send a probe within one second.
The initial period between Buffer Probes SHOULD be at least one The initial period between Buffer Probes SHOULD be at least
second or ERTO, whichever is greater. The period between probes one second or ERTO, whichever is greater. The period between probes
SHOULD increase over time, but the period between probes SHOULD NOT SHOULD increase over time, but the period between probes SHOULD NOT
be more than one minute or ERTO, whichever is greater. be more than one minute or ERTO, whichever is greater.
The flow sender SHOULD stop sending Buffer Probes if it is no longer The flow sender SHOULD stop sending Buffer Probes if it is no longer
suspended. suspended.
3.6.2.10. Exception 3.6.2.10. Exception
The flow receiver can reject the flow at any time and for any reason. The flow receiver can reject the flow at any time and for any reason.
The flow receiver sends a Flow Exception Report (Section 2.3.16) when The flow receiver sends a Flow Exception Report (Section 2.3.16) when
it has rejected a flow. it has rejected a flow.
On receiving a Flow Exception Report for a sending flow: On receiving a Flow Exception Report for a sending flow:
1. If the flow is F_OPEN, close the flow (Section 3.6.2.11) and 1. If the flow is F_OPEN, close the flow (Section 3.6.2.11) and
notify the user that the far end reported an exception with the notify the user that the far end reported an exception with the
encoded exception code; encoded exception code;
2. Set the EXCEPTION flag to true; and 2. Set the EXCEPTION flag to true; and
3. For each entry in SEND_QUEUE: set entry.ABANDONED = true. 3. For each entry in SEND_QUEUE, set entry.ABANDONED = true.
3.6.2.11. Close 3.6.2.11. Close
A sending flow is closed by the user or as a result of an exception. A sending flow is closed by the user or as a result of an exception.
To close an F_OPEN flow: To close an F_OPEN flow:
1. Move to the F_CLOSING state; 1. Move to the F_CLOSING state;
2. If the SEND_QUEUE is not empty, AND the tail entry of the 2. If the SEND_QUEUE is not empty, AND the tail entry of the
SEND_QUEUE has a sequence number of NEXT_SN - 1, AND the tail SEND_QUEUE has a sequence number of NEXT_SN - 1, AND the
entry.EVER_SENT is false: set F_FINAL_SN to tail entry.EVER_SENT is false, set F_FINAL_SN to
entry.SEQUENCE_NUMBER; else entry.SEQUENCE_NUMBER; else
3. The SEND_QUEUE is empty, OR the tail entry does not have a 3. The SEND_QUEUE is empty, OR the tail entry does not have a
sequence number of NEXT_SN - 1, OR the tail entry.EVER_SENT is sequence number of NEXT_SN - 1, OR the tail entry.EVER_SENT is
true: enqueue a new SEND_QUEUE entry with entry.SEQUENCE_NUMBER = true: enqueue a new SEND_QUEUE entry with entry.SEQUENCE_NUMBER =
flow.NEXT_SN, entry.FRA = 0, and entry.ABANDONED = true, and set flow.NEXT_SN, entry.FRA = 0, and entry.ABANDONED = true, and set
flow.F_FINAL_SN to entry.SEQUENCE_NUMBER. flow.F_FINAL_SN to entry.SEQUENCE_NUMBER.
An F_CLOSING sending flow is complete when its SEND_QUEUE transitions An F_CLOSING sending flow is complete when its SEND_QUEUE transitions
to empty, indicating that all sequence numbers including the FINAL_SN to empty, indicating that all sequence numbers, including the
have been acknowledged by the other end. FINAL_SN, have been acknowledged by the other end.
When an F_CLOSING sending flow becomes complete, move to the When an F_CLOSING sending flow becomes complete, move to the
F_COMPLETE_LINGER state. F_COMPLETE_LINGER state.
A sending flow MUST remain in the F_COMPLETE_LINGER state for at A sending flow MUST remain in the F_COMPLETE_LINGER state for at
least 130 seconds. After at least 130 seconds, move to the F_CLOSED least 130 seconds. After at least 130 seconds, move to the F_CLOSED
state. The sending flow is now closed, its resources can be state. The sending flow is now closed, its resources can be
reclaimed, and its F_FLOW_ID MAY be used for a new sending flow. reclaimed, and its F_FLOW_ID MAY be used for a new sending flow.
3.6.3. Receiver 3.6.3. Receiver
skipping to change at page 87, line 48 skipping to change at page 91, line 7
o SEQUENCE_SET: the set of all fragment sequence numbers seen in o SEQUENCE_SET: the set of all fragment sequence numbers seen in
this receiving flow, whether received or abandoned, initially this receiving flow, whether received or abandoned, initially
empty; empty;
o RF_FINAL_SN: the final fragment sequence number of the flow, o RF_FINAL_SN: the final fragment sequence number of the flow,
initially having no value; initially having no value;
o RECV_BUFFER: the message fragments waiting to be delivered to the o RECV_BUFFER: the message fragments waiting to be delivered to the
user, sorted by sequence number in ascending order, initially user, sorted by sequence number in ascending order, initially
empty; each message fragment entry comprising: empty; each message fragment entry comprising the following:
* SEQUENCE_NUMBER: the sequence number of this fragment; * SEQUENCE_NUMBER: the sequence number of this fragment;
* DATA: this fragment's user data; and * DATA: this fragment's user data; and
* FRA: the fragment control value for this message fragment, * FRA: the fragment control value for this message fragment,
having one of the values enumerated for that purpose in User having one of the values enumerated for that purpose in
Data (Section 2.3.11). Section 2.3.11 ("User Data Chunk").
o BUFFERED_SIZE: the sum of the lengths of each fragment in o BUFFERED_SIZE: the sum of the lengths of each fragment in
RECV_BUFFER plus any additional storage overhead for the fragments RECV_BUFFER plus any additional storage overhead for the fragments
incurred by the implementation, in bytes; incurred by the implementation, in bytes;
o BUFFER_CAPACITY: the desired maximum size for the receive buffer, o BUFFER_CAPACITY: the desired maximum size for the receive buffer,
in bytes; in bytes;
o PREV_RWND: the most recent receive window advertisement sent in an o PREV_RWND: the most recent receive window advertisement sent in an
acknowledgement, in 1024-byte blocks, initially having no value; acknowledgement, in 1024-byte blocks, initially having no value;
skipping to change at page 89, line 5 skipping to change at page 92, line 5
o SHOULD_ACK: whether or not an acknowledgement should be sent for o SHOULD_ACK: whether or not an acknowledgement should be sent for
this flow, initially false; this flow, initially false;
o EXCEPTION_CODE: the exception code to report to the sender when o EXCEPTION_CODE: the exception code to report to the sender when
the flow has been rejected, initially 0; the flow has been rejected, initially 0;
o The state, at any time being one of the following values: the open o The state, at any time being one of the following values: the open
state RF_OPEN; the closing states RF_REJECTED and state RF_OPEN; the closing states RF_REJECTED and
RF_COMPLETE_LINGER; and the closed state RF_CLOSED. RF_COMPLETE_LINGER; and the closed state RF_CLOSED.
Note: this diagram is only a summary of state transitions and their Note: The following diagram is only a summary of state transitions
causing events, and is not a complete operational specification. and their causing events, and is not a complete operational
specification.
+-+ +-+
|X| |X|
+-+ +-+
|rcv User Data for |rcv User Data for
| no existing flow | no existing flow
v v
+---------+ +---------+
| RF_OPEN | | RF_OPEN |
+---------+ +---------+
rcv all sequence numbers| |user reject, rcv all sequence numbers| |user reject,
0..RF_FINAL_SN | |rcv bad option, 0..RF_FINAL_SN | |rcv bad option,
| |no metadata at open, | |no metadata at open,
| |association specified | |association specified
| | but not F_OPEN at open | | but not F_OPEN at open
+---+ | +---+ |
| v | v
| +-----------+ | +-----------+
| |RF_REJECTED| | |RF_REJECTED|
| +-----------+ | +-----------+
| |rcv all sequence numbers | |rcv all sequence numbers
| | 0..RF_FINAL_SN | | 0..RF_FINAL_SN
v v v v
+------------------+ +------------------+
|RF_COMPLETE_LINGER| |RF_COMPLETE_LINGER|
+------------------+ +------------------+
| 120 seconds | 120 seconds
v v
+---------+ +---------+
|RF_CLOSED| |RF_CLOSED|
+---------+ +---------+
Figure 22: Receiving flow state diagram Figure 22: Receiving Flow State Diagram
3.6.3.1. Startup 3.6.3.1. Startup
A new receiving flow starts on receipt of a User Data chunk A new receiving flow starts on receipt of a User Data chunk
(Section 2.3.11) encoding a flow ID not belonging to any other (Section 2.3.11) encoding a flow ID not belonging to any other
receiving flow in the same session in the RF_OPEN, RF_REJECTED, or receiving flow in the same session in the RF_OPEN, RF_REJECTED, or
RF_COMPLETE_LINGER states. RF_COMPLETE_LINGER states.
On receipt of such a User Data chunk: On receipt of such a User Data chunk:
skipping to change at page 90, line 23 skipping to change at page 93, line 35
4. If the opening User Data chunk encodes a Return Flow Association 4. If the opening User Data chunk encodes a Return Flow Association
option (Section 2.3.11.1.2), set ASSOCIATED_FLOWID to option (Section 2.3.11.1.2), set ASSOCIATED_FLOWID to
option.flowID; option.flowID;
5. If METADATA has no value, the receiver MUST reject the flow 5. If METADATA has no value, the receiver MUST reject the flow
(Section 3.6.3.7), moving it to the RF_REJECTED state; (Section 3.6.3.7), moving it to the RF_REJECTED state;
6. If ASSOCIATED_FLOWID has a value, then if there is no sending 6. If ASSOCIATED_FLOWID has a value, then if there is no sending
flow in the same session with a flow ID of ASSOCIATED_FLOWID, flow in the same session with a flow ID of ASSOCIATED_FLOWID,
the receiver MUST reject the flow, moving it to the RF_REJECTED the receiver MUST reject the flow, moving it to the RF_REJECTED
state; otherwise set ASSOCIATION to the indicated sending flow; state; otherwise, set ASSOCIATION to the indicated sending flow;
7. If ASSOCIATION indicates a sending flow AND that sending flow's 7. If ASSOCIATION indicates a sending flow, AND that sending flow's
state is not F_OPEN, the receiver MUST reject this receiving state is not F_OPEN, the receiver MUST reject this receiving
flow, moving it to the RF_REJECTED state; flow, moving it to the RF_REJECTED state;
8. If the opening User Data chunk encodes any unrecognized option 8. If the opening User Data chunk encodes any unrecognized option
with a type code less than 8192 (Section 2.3.11.1), the receiver with a type code less than 8192 (Section 2.3.11.1), the receiver
MUST reject the flow, moving it to the RF_REJECTED state; MUST reject the flow, moving it to the RF_REJECTED state;
9. If this new receiving flow is still RF_OPEN, then: notify the 9. If this new receiving flow is still RF_OPEN, then notify the
user that a new receiving flow has opened, including the user that a new receiving flow has opened, including the
METADATA and, if present, the ASSOCIATION, and set METADATA and, if present, the ASSOCIATION, and set
flow.BUFFER_CAPACITY according to the user; flow.BUFFER_CAPACITY according to the user;
10. Perform the normal data processing (Section 3.6.3.2) for the 10. Perform the normal data processing (Section 3.6.3.2) for the
opening User Data chunk; and opening User Data chunk; and
11. Set this session's ACK_NOW to true. 11. Set this session's ACK_NOW to true.
3.6.3.2. Receiving Data 3.6.3.2. Receiving Data
A User Data chunk (Section 2.3.11) or a Next User Data chunk A User Data chunk (Section 2.3.11) or a Next User Data chunk
(Section 2.3.12) encodes one fragment of a user data message of a (Section 2.3.12) encodes one fragment of a user data message of a
flow, as well as the flow's Forward Sequence Number and potentially flow, as well as the flow's Forward Sequence Number and potentially
optional parameters (Section 2.3.11.1). optional parameters (Section 2.3.11.1).
On receipt of a User Data or Next User Data chunk: On receipt of a User Data or Next User Data chunk:
1. If chunk.flowID doesn't indicate an existing receiving flow in 1. If chunk.flowID doesn't indicate an existing receiving flow in
the same session in the RF_OPEN, RF_REJECTED, or the same session in the RF_OPEN, RF_REJECTED, or
RF_COMPLETE_LINGER state, perform the steps at Startup RF_COMPLETE_LINGER state, perform the steps of Section 3.6.3.1
(Section 3.6.3.1) to start a new receiving flow; ("Startup") to start a new receiving flow;
2. Retrieve the receiving flow context for the flow indicated by 2. Retrieve the receiving flow context for the flow indicated by
chunk.flowID; chunk.flowID;
3. Set flow.SHOULD_ACK to true; 3. Set flow.SHOULD_ACK to true;
4. If the flow is RF_OPEN AND the chunk encodes any unrecognized 4. If the flow is RF_OPEN, AND the chunk encodes any unrecognized
option with a type code less than 8192 (Section 2.3.11.1), the option with a type code less than 8192 (Section 2.3.11.1), the
flow MUST be rejected: notify the user of an exception, and flow MUST be rejected: notify the user of an exception, and
reject the flow (Section 3.6.3.7), moving it to the RF_REJECTED reject the flow (Section 3.6.3.7), moving it to the RF_REJECTED
state; state;
5. If the flow is not in the RF_OPEN state: set session.ACK_NOW to 5. If the flow is not in the RF_OPEN state, set session.ACK_NOW
true; to true;
6. If flow.PREV_RWND has a value and that value is less than 2 6. If flow.PREV_RWND has a value and that value is less than
blocks, set session.ACK_NOW to true; 2 blocks, set session.ACK_NOW to true;
7. If chunk.abandon is true: set session.ACK_NOW to true; 7. If chunk.abandon is true, set session.ACK_NOW to true;
8. If flow.SEQUENCE_SET has any gaps (that is, if it doesn't 8. If flow.SEQUENCE_SET has any gaps (that is, if it doesn't
contain every sequence number from 0 through and including the contain every sequence number from 0 through and including the
highest sequence number in the set), set session.ACK_NOW to highest sequence number in the set), set session.ACK_NOW
true; to true;
9. If flow.SEQUENCE_SET contains chunk.sequenceNumber, then this 9. If flow.SEQUENCE_SET contains chunk.sequenceNumber, then this
chunk is a duplicate: set session.ACK_NOW to true; chunk is a duplicate: set session.ACK_NOW to true;
10. If flow.SEQUENCE_SET doesn't contain chunk.sequenceNumber, AND 10. If flow.SEQUENCE_SET doesn't contain chunk.sequenceNumber, AND
chunk.final is true, AND flow.RF_FINAL_SN has no value, then: chunk.final is true, AND flow.RF_FINAL_SN has no value, then set
set flow.RF_FINAL_SN to chunk.sequenceNumber, and set flow.RF_FINAL_SN to chunk.sequenceNumber, and set
session.ACK_NOW to true; session.ACK_NOW to true;
11. If the flow is in the RF_OPEN state, AND flow.SEQUENCE_SET 11. If the flow is in the RF_OPEN state, AND flow.SEQUENCE_SET
doesn't contain chunk.sequenceNumber, AND chunk.abandon is doesn't contain chunk.sequenceNumber, AND chunk.abandon is
false, then: create a new RECV_BUFFER entry for this chunk's false, then create a new RECV_BUFFER entry for this chunk's data
data and set entry.SEQUENCE_NUMBER to chunk.sequenceNumber, and set entry.SEQUENCE_NUMBER to chunk.sequenceNumber,
entry.DATA to chunk.userData, and entry.FRA to entry.DATA to chunk.userData, and entry.FRA to
chunk.fragmentControl, and insert this new entry into chunk.fragmentControl, and insert this new entry into
flow.RECV_BUFFER; flow.RECV_BUFFER;
12. Add to flow.SEQUENCE_SET the range of sequence numbers from 0 12. Add to flow.SEQUENCE_SET the range of sequence numbers from 0
through and including the chunk.forwardSequenceNumber derived through and including the chunk.forwardSequenceNumber derived
field; field;
13. Add chunk.sequenceNumber to flow.SEQUENCE_SET; 13. Add chunk.sequenceNumber to flow.SEQUENCE_SET;
14. If flow.SEQUENCE_SET now has any gaps, set session.ACK_NOW to 14. If flow.SEQUENCE_SET now has any gaps, set session.ACK_NOW
true; to true;
15. If session.ACK_NOW is false and session.DELACK_ALARM is not set: 15. If session.ACK_NOW is false and session.DELACK_ALARM is not set,
set session.DELACK_ALARM to fire in 200 milliseconds; and set session.DELACK_ALARM to fire in 200 milliseconds; and
16. Attempt delivery of completed messages in this flow's 16. Attempt delivery of completed messages in this flow's
RECV_BUFFER to the user (Section 3.6.3.3). RECV_BUFFER to the user (Section 3.6.3.3).
After processing all chunks in a packet containing at least one User After processing all chunks in a packet containing at least one User
Data chunk, increment session.RX_DATA_PACKETS by one. If Data chunk, increment session.RX_DATA_PACKETS by one. If
session.RX_DATA_PACKETS is at least two, set session.ACK_NOW to true. session.RX_DATA_PACKETS is at least two, set session.ACK_NOW to true.
A receiving flow that is not in the RF_CLOSED state is ready to send A receiving flow that is not in the RF_CLOSED state is ready to send
skipping to change at page 92, line 32 skipping to change at page 95, line 49
for receiving flows that are ready are sent either opportunistically for receiving flows that are ready are sent either opportunistically
by piggybacking on a packet that's already sending user data or an by piggybacking on a packet that's already sending user data or an
acknowledgement (Section 3.6.3.4.6), or when the session's ACK_NOW acknowledgement (Section 3.6.3.4.6), or when the session's ACK_NOW
flag is set (Section 3.6.3.4.5). flag is set (Section 3.6.3.4.5).
3.6.3.3. Buffering and Delivering Data 3.6.3.3. Buffering and Delivering Data
A receiving flow's information context contains a RECV_BUFFER for A receiving flow's information context contains a RECV_BUFFER for
reordering, reassembling, and holding the user data messages of the reordering, reassembling, and holding the user data messages of the
flow. Only complete messages are delivered to the user; an flow. Only complete messages are delivered to the user; an
implementation MUST NOT deliver partially received messages except by implementation MUST NOT deliver partially received messages, except
special arrangement with the user. by special arrangement with the user.
Let the Cumulative Acknowledgement Sequence Number CSN be the highest Let the Cumulative Acknowledgement Sequence Number (CSN) be the
number in the contiguous range of numbers in SEQUENCE_SET starting highest number in the contiguous range of numbers in SEQUENCE_SET
with 0. For example, if SEQUENCE_SET contains {0, 1, 2, 3, 5, 6}, starting with 0. For example, if SEQUENCE_SET contains {0, 1, 2, 3,
the contiguous range starting with 0 is 0..3, so the CSN is 3. 5, 6}, the contiguous range starting with 0 is 0..3, so the CSN is 3.
A message is complete if all of its fragments are present in the A message is complete if all of its fragments are present in the
RECV_BUFFER. The fragments of one message have contiguous sequence RECV_BUFFER. The fragments of one message have contiguous sequence
numbers. A message can either be a single fragment, whose fragment numbers. A message can be either a single fragment, whose fragment
control value is 0-whole, or can be two or more fragments where the control value is 0-whole, or two or more fragments where the first's
first's fragment control value is 1-begin, followed by zero or more fragment control value is 1-begin, followed by zero or more fragments
fragments with control value 3-middle, and terminated by a last with control value 3-middle, and terminated by a last fragment with
fragment with control value 2-end. control value 2-end.
An incomplete message segment is a contiguous sequence of one or more An incomplete message segment is a contiguous sequence of one or more
fragments that do not form a complete message; that is, a 1-begin fragments that do not form a complete message -- that is, a 1-begin
followed by zero or more 3-middle fragments but with no 2-end, or followed by zero or more 3-middle fragments but with no 2-end, or
zero or more 3-middle fragments followed by a 2-end but with no zero or more 3-middle fragments followed by a 2-end but with no
1-begin, or one or more 3-middle fragments with neither a 1-begin nor 1-begin, or one or more 3-middle fragments with neither a 1-begin nor
a 2-end. a 2-end.
Incomplete message segments can either be in progress or abandoned. Incomplete message segments can either be in progress or abandoned.
An incomplete segment is abandoned in the following cases: An incomplete segment is abandoned in the following cases:
o The sequence number of the segment's first fragment is less than o The sequence number of the segment's first fragment is less than
or equal to the CSN AND that fragment's control value is not or equal to the CSN, AND that fragment's control value is not
1-begin; or 1-begin; or
o The sequence number of the segment's last fragment is less than o The sequence number of the segment's last fragment is less than
the CSN. the CSN.
Abandoned message segments will never be completed, so they SHOULD be Abandoned message segments will never be completed, so they SHOULD be
removed from the RECV_BUFFER to make room in the advertised receive removed from the RECV_BUFFER to make room in the advertised receive
window and the receiver's memory for messages that can be completed. window and the receiver's memory for messages that can be completed.
The user can suspend delivery of a flow's messages. A suspended The user can suspend delivery of a flow's messages. A suspended
receiving flow holds completed messages in its RECV_BUFFER until the receiving flow holds completed messages in its RECV_BUFFER until the
user resumes delivery. A suspended flow can cause the receive window user resumes delivery. A suspended flow can cause the receive window
advertisement to go to zero even when the BUFFER_CAPACITY is non- advertisement to go to zero even when the BUFFER_CAPACITY is
zero; this is described in detail in Flow Control (Section 3.6.3.5). non-zero; this is described in detail in Section 3.6.3.5
("Flow Control").
When the receiving flow is not suspended, the original queuing order When the receiving flow is not suspended, the original queuing order
of the messages is recovered by delivering, in ascending sequence of the messages is recovered by delivering, in ascending sequence
number order, complete messages in the RECV_BUFFER whose sequence number order, complete messages in the RECV_BUFFER whose sequence
numbers are less than or equal to the CSN. numbers are less than or equal to the CSN.
The following describes a method for discarding abandoned message The following describes a method for discarding abandoned message
segments and delivering complete messages in original queueing order segments and delivering complete messages in original queuing order
when the receiving flow is not suspended. when the receiving flow is not suspended.
While the first fragment entry in the RECV_BUFFER has a sequence While the first fragment entry in the RECV_BUFFER has a sequence
number less than or equal to CSN and delivery is still possible: number less than or equal to the CSN and delivery is still possible:
1. If entry.FRA is 0-whole: deliver entry.DATA to the user, and 1. If entry.FRA is 0-whole, deliver entry.DATA to the user, and
remove this entry from RECV_BUFFER; otherwise, remove this entry from RECV_BUFFER; otherwise,
2. If entry.FRA is 2-end or 3-middle: this entry belongs to an 2. If entry.FRA is 2-end or 3-middle, this entry belongs to an
abandoned segment, so remove and discard this entry from abandoned segment, so remove and discard this entry from
RECV_BUFFER; otherwise, RECV_BUFFER; otherwise,
3. Entry.FRA is 1-begin. Let LAST_ENTRY be the last RECV_BUFFER 3. Entry.FRA is 1-begin. Let LAST_ENTRY be the last RECV_BUFFER
entry that is part of this message segment (LAST_ENTRY can be entry that is part of this message segment (LAST_ENTRY can be
entry if the segment has only one fragment so far). Then: entry if the segment has only one fragment so far). Then:
1. If LAST_ENTRY.FRA is 2-end: this segment is a complete 1. If LAST_ENTRY.FRA is 2-end, this segment is a complete
message, so concatenate the DATA fields of each fragment message, so concatenate the DATA fields of each fragment
entry of this segment in ascending sequence number order and entry of this segment in ascending sequence number order and
deliver the complete message to the user, then remove the deliver the complete message to the user, then remove the
entries for this complete message from RECV_BUFFER; entries for this complete message from RECV_BUFFER;
otherwise, otherwise,
2. If LAST_ENTRY.SEQUENCE_NUMBER is less than CSN: this segment 2. If LAST_ENTRY.SEQUENCE_NUMBER is less than CSN, this segment
is incomplete and abandoned, so remove and discard the is incomplete and abandoned, so remove and discard the
entries for this segment from RECV_BUFFER; otherwise, entries for this segment from RECV_BUFFER; otherwise,
3. LAST_ENTRY.SEQUENCE_NUMBER is equal to CSN and LAST_ENTRY.FRA 3. LAST_ENTRY.SEQUENCE_NUMBER is equal to CSN and LAST_ENTRY.FRA
is not 2-end: this segment is incomplete but still in is not 2-end: this segment is incomplete but still in
progress. Ordered delivery is no longer possible until at progress. Ordered delivery is no longer possible until at
least one more fragment is received. Stop. least one more fragment is received. Stop.
If flow.RF_FINAL_SN has a value and is equal to CSN, AND RECV_BUFFER If flow.RF_FINAL_SN has a value and is equal to the CSN, AND
is empty: all complete messages have been delivered to the user, so RECV_BUFFER is empty, all complete messages have been delivered to
notify the user that the flow is complete. the user, so notify the user that the flow is complete.
3.6.3.4. Acknowledging Data 3.6.3.4. Acknowledging Data
A flow receiver SHOULD acknowledge all user data fragment sequence A flow receiver SHOULD acknowledge all user data fragment sequence
numbers seen in that flow. Acknowledgements drive the sender's numbers seen in that flow. Acknowledgements drive the sender's
congestion control and avoidance algorithms, clear data from the congestion control and avoidance algorithms, clear data from the
sender's buffers, and in some sender implementations clock new data sender's buffers, and in some sender implementations clock new data
into the network, and therefore must be accurate and timely. into the network; therefore, the acknowledgements must be accurate
and timely.
3.6.3.4.1. Timing 3.6.3.4.1. Timing
For similar reasons as discussed in RFC 1122 Section 4.2.3.2 For reasons similar to those discussed in Section 4.2.3.2 of RFC 1122
[RFC1122], it is advantageous to delay sending acknowledgements for a [RFC1122], it is advantageous to delay sending acknowledgements for a
short time so that multiple data fragments can be acknowledged in a short time, so that multiple data fragments can be acknowledged in a
single transmission. However, it is also advantageous for a sender single transmission. However, it is also advantageous for a sender
to receive timely notification about the receiver's disposition of to receive timely notification about the receiver's disposition of
the flow, particularly in unusual or exceptional circumstances, so the flow, particularly in unusual or exceptional circumstances, so
that the circumstances can be addressed if possible. that the circumstances can be addressed if possible.
Therefore, a flow receiver SHOULD send an acknowledgement for a flow Therefore, a flow receiver SHOULD send an acknowledgement for a flow
as soon as is practical in any of the following circumstances: as soon as is practical in any of the following circumstances:
o On receipt of a User Data chunk that starts a new flow; o On receipt of a User Data chunk that starts a new flow;
skipping to change at page 95, line 24 skipping to change at page 98, line 48
o On receipt of a User Data or Next User Data chunk for the flow if, o On receipt of a User Data or Next User Data chunk for the flow if,
after processing the chunk, the flow's BUFFER_CAPACITY is not at after processing the chunk, the flow's BUFFER_CAPACITY is not at
least 1024 bytes greater than BUFFERED_SIZE; least 1024 bytes greater than BUFFERED_SIZE;
o On receipt of a User Data or Next User Data chunk for any sequence o On receipt of a User Data or Next User Data chunk for any sequence
number that was already seen (that is, on receipt of a duplicate); number that was already seen (that is, on receipt of a duplicate);
o On the first receipt of the final sequence number of the flow; o On the first receipt of the final sequence number of the flow;
o On receipt of two packets in the session containing user data for o On receipt of two packets in the session that contain user data
any flows since an acknowledgement was last sent; the new for any flows since an acknowledgement was last sent, the new
acknowledgements being for the flows having any User Data chunks acknowledgements being for the flows having any User Data chunks
in the received packets (that is, for every second packet in the received packets (that is, for every second packet
containing user data); containing user data);
o After receipt of a User Data chunk for the flow, if an o After receipt of a User Data chunk for the flow, if an
acknowledgement for any other flow is being sent (that is, acknowledgement for any other flow is being sent (that is,
consolidate acknowledgements); consolidate acknowledgements);
o After receipt of a User Data chunk for the flow, if any user data o After receipt of a User Data chunk for the flow, if any user data
for a sending flow is being sent in a packet and if there is space for a sending flow is being sent in a packet and if there is space
skipping to change at page 95, line 47 skipping to change at page 99, line 22
acknowledgement with user data if possible); acknowledgement with user data if possible);
o No longer than 200 milliseconds after receipt of a User Data chunk o No longer than 200 milliseconds after receipt of a User Data chunk
for the flow. for the flow.
3.6.3.4.2. Size and Truncation 3.6.3.4.2. Size and Truncation
Including an encoded acknowledgement in a packet might cause the Including an encoded acknowledgement in a packet might cause the
packet to exceed the path MTU. In that case: packet to exceed the path MTU. In that case:
o If the packet is being sent primarily to send an acknowledgement o If the packet is being sent primarily to send an acknowledgement,
AND this is the first acknowledgement in the packet, truncate the AND this is the first acknowledgement in the packet, truncate the
acknowledgement so that the packet does not exceed the path MTU; acknowledgement so that the packet does not exceed the path MTU;
otherwise otherwise,
o The acknowledgement is being piggybacked in a packet with user o The acknowledgement is being piggybacked in a packet with user
data or with an acknowledgement for another flow: do not include data or with an acknowledgement for another flow: do not include
this acknowledgement in the packet, and send it later. this acknowledgement in the packet, and send it later.
3.6.3.4.3. Constructing 3.6.3.4.3. Constructing
The Data Acknowledgement Bitmap chunk (Section 2.3.13) and Data The Data Acknowledgement Bitmap chunk (Section 2.3.13) and Data
Acknowledgement Ranges chunk (Section 2.3.14) encode a receiving Acknowledgement Ranges chunk (Section 2.3.14) encode a receiving
flow's SEQUENCE_SET and its receive window advertisement. The two flow's SEQUENCE_SET and its receive window advertisement. The two
skipping to change at page 96, line 25 skipping to change at page 99, line 47
whichever provides the most compact encoding of the SEQUENCE_SET. whichever provides the most compact encoding of the SEQUENCE_SET.
When assembling an acknowledgement for a receiving flow: When assembling an acknowledgement for a receiving flow:
1. If the flow's state is RF_REJECTED, first assemble a Flow 1. If the flow's state is RF_REJECTED, first assemble a Flow
Exception Report chunk (Section 2.3.16) for flow.flowID; Exception Report chunk (Section 2.3.16) for flow.flowID;
2. Choose the acknowledgement chunk type that most compactly encodes 2. Choose the acknowledgement chunk type that most compactly encodes
flow.SEQUENCE_SET; flow.SEQUENCE_SET;
3. Use the method described in Flow Control (Section 3.6.3.5) to 3. Use the method described in Section 3.6.3.5 ("Flow Control") to
determine the value for the acknowledgement chunk's determine the value for the acknowledgement chunk's
bufferBlocksAvailable field; bufferBlocksAvailable field.
3.6.3.4.4. Delayed Acknowledgement 3.6.3.4.4. Delayed Acknowledgement
As discussed in Acknowledging Data (Section 3.6.3.4.1), a flow As discussed in Section 3.6.3.4.1 ("Timing"), a flow receiver can
receiver can delay sending an acknowledgement for up to 200 delay sending an acknowledgement for up to 200 milliseconds after
milliseconds after receiving user data. The method described in receiving user data. The method described in Section 3.6.3.2
Receiving Data (Section 3.6.3.2) sets the session's DELACK_ALARM. ("Receiving Data") sets the session's DELACK_ALARM.
When DELACK_ALARM fires: set ACK_NOW to true. When DELACK_ALARM fires, set ACK_NOW to true.
3.6.3.4.5. Obligatory Acknowledgement 3.6.3.4.5. Obligatory Acknowledgement
One or more acknowledgements should be sent as soon as is practical One or more acknowledgements should be sent as soon as is practical
when the session's ACK_NOW flag is set. While the ACK_NOW flag is when the session's ACK_NOW flag is set. While the ACK_NOW flag
set: is set:
1. Choose a receiving flow that is ready to send an acknowledgement; 1. Choose a receiving flow that is ready to send an acknowledgement;
2. If there is no such flow: there is no work to do, set ACK_NOW to 2. If there is no such flow, there is no work to do, set ACK_NOW to
false, set RX_DATA_PACKETS to 0, clear the DELACK_ALARM, and false, set RX_DATA_PACKETS to 0, clear the DELACK_ALARM, and
stop; otherwise stop; otherwise,
3. Start a new packet; 3. Start a new packet;
4. Assemble an acknowledgement for the flow and include it in the 4. Assemble an acknowledgement for the flow and include it in the
packet, truncating it if necessary so that the packet doesn't packet, truncating it if necessary so that the packet doesn't
exceed the path MTU; exceed the path MTU;
5. Set flow.SHOULD_ACK to false; 5. Set flow.SHOULD_ACK to false;
6. Set flow.PREV_RWND to the bufferBlocksAvailable field of the 6. Set flow.PREV_RWND to the bufferBlocksAvailable field of the
included acknowledgement chunk; included acknowledgement chunk;
7. Attempt to piggyback acknowledgements for any other flows that 7. Attempt to piggyback acknowledgements for any other flows that
skipping to change at page 97, line 26 skipping to change at page 101, line 6
8. Send the packet. 8. Send the packet.
3.6.3.4.6. Opportunistic Acknowledgement 3.6.3.4.6. Opportunistic Acknowledgement
When sending a packet with user data or an acknowledgement, any other When sending a packet with user data or an acknowledgement, any other
receiving flows that are ready to send an acknowledgement should receiving flows that are ready to send an acknowledgement should
include their acknowledgements in the packet if possible. include their acknowledgements in the packet if possible.
To piggyback acknowledgements in a packet that is already being sent, To piggyback acknowledgements in a packet that is already being sent,
where the packet contains user data or an acknowledgement: While where the packet contains user data or an acknowledgement, while
there is at least one receiving flow that is ready to send an there is at least one receiving flow that is ready to send an
acknowledgement: acknowledgement:
1. Assemble an acknowledgement for the flow; 1. Assemble an acknowledgement for the flow;
2. If the acknowledgement cannot be included in the packet without 2. If the acknowledgement cannot be included in the packet without
exceeding the path MTU: the packet is full, stop; otherwise exceeding the path MTU, the packet is full; stop. Otherwise,
3. Include the acknowledgement in the packet; 3. Include the acknowledgement in the packet;
4. Set flow.SHOULD_ACK to false; 4. Set flow.SHOULD_ACK to false;
5. Set flow.PREV_RWND to the bufferBlocksAvailable field of the 5. Set flow.PREV_RWND to the bufferBlocksAvailable field of the
included acknowledgement chunk; and included acknowledgement chunk; and
6. If there are no longer any receiving flows in the session that 6. If there are no longer any receiving flows in the session that
are ready to send an acknowledgement: set session.ACK_NOW to are ready to send an acknowledgement, set session.ACK_NOW to
false, set session.RX_DATA_PACKETS to 0, and clear false, set session.RX_DATA_PACKETS to 0, and clear
session.DELACK_ALARM. session.DELACK_ALARM.
3.6.3.4.7. Example 3.6.3.4.7. Example
Figure 23 shows an example flow with sequence numbers 31 and 33 lost
in transit; 31 is abandoned, and 33 is retransmitted.
Receiver Receiver
1 |<--- Data ID=3, seq#=29, fsnOff=11 (fsn=18) 1 |<--- Data ID=3, seq#=29, fsnOff=11 (fsn=18)
2 |<--- Data ID=3, seq#=30, fsnOff=12 (fsn=18) 2 |<--- Data ID=3, seq#=30, fsnOff=12 (fsn=18)
3 |---> Ack ID=3, seq:0-30 3 |---> Ack ID=3, seq:0-30
4 |<--- Data ID=3, seq#=32, fsnOff=12 (fsn=20) 4 |<--- Data ID=3, seq#=32, fsnOff=12 (fsn=20)
5 |---> Ack ID=3, seq:0-30, 32 5 |---> Ack ID=3, seq:0-30, 32
6 |<--- Data ID=3, seq#=34, fsnOff=12 (fsn=22) 6 |<--- Data ID=3, seq#=34, fsnOff=12 (fsn=22)
7 |---> Ack ID=3, seq:0-30, 32, 34 7 |---> Ack ID=3, seq:0-30, 32, 34
| : | :
8 |<--- Data ID=3, seq#=46, fsnOff=16 (fsn=30) 8 |<--- Data ID=3, seq#=46, fsnOff=16 (fsn=30)
9 |---> Ack ID=3, seq:0-30, 32, 34-46 9 |---> Ack ID=3, seq:0-30, 32, 34-46
10 |<--- Data ID=3, seq#=47, fsnOff=15 (fsn=32) 10 |<--- Data ID=3, seq#=47, fsnOff=15 (fsn=32)
11 |---> Ack ID=3, seq:0-32, 34-47 11 |---> Ack ID=3, seq:0-32, 34-47
12 |<--- Data ID=3, seq#=33, fsnOff=1 (fsn=32) 12 |<--- Data ID=3, seq#=33, fsnOff=1 (fsn=32)
13 |---> Ack ID=3, seq#=0-47 13 |---> Ack ID=3, seq#=0-47
14 |<--- Data ID=3, seq#=48, fsnOff=16 (fsn=32) 14 |<--- Data ID=3, seq#=48, fsnOff=16 (fsn=32)
15 |<--- Data ID=3, seq#=49, fsnOff=17 (fsn=32) 15 |<--- Data ID=3, seq#=49, fsnOff=17 (fsn=32)
16 |---> Ack ID=3, seq#=0-49 16 |---> Ack ID=3, seq#=0-49
| : | :
Flow with sequence numbers 31 and 33 lost in transit, 31 abandoned Figure 23: Flow Example with Loss
and 33 retransmitted.
Figure 23
3.6.3.5. Flow Control 3.6.3.5. Flow Control
The flow receiver maintains a buffer for reassembling and reordering The flow receiver maintains a buffer for reassembling and reordering
messages for delivery to the user (Section 3.6.3.3). The messages for delivery to the user (Section 3.6.3.3). The
implementation and the user may wish to limit the amount of resources implementation and the user may wish to limit the amount of resources
(including buffer memory) that a flow is allowed to use. (including buffer memory) that a flow is allowed to use.
RTMFP provides a means for each receiving flow to govern the amount RTMFP provides a means for each receiving flow to govern the amount
of data sent by the sender, by way of the bufferBytesAvailable of data sent by the sender, by way of the bufferBytesAvailable
derived field of acknowledgement chunks (Section 2.3.13, derived field of acknowledgement chunks (Sections 2.3.13 and 2.3.14).
Section 2.3.14). This derived field indicates the amount of data This derived field indicates the amount of data that the sender is
that the sender is allowed to have outstanding in the network, until allowed to have outstanding in the network, until instructed
instructed otherwise. This amount is also called the receive window. otherwise. This amount is also called the receive window.
The flow receiver can suspend the sender by advertising a closed The flow receiver can suspend the sender by advertising a closed
(zero length) receive window. (zero length) receive window.
The user can suspend delivery of messages from the receiving flow The user can suspend delivery of messages from the receiving flow
(Section 3.6.3.3). This can cause the receive buffer to fill. (Section 3.6.3.3). This can cause the receive buffer to fill.
In order for progress to be made on completing a fragmented message In order for progress to be made on completing a fragmented message
or repairing a gap for sequenced delivery in a flow, the flow or repairing a gap for sequenced delivery in a flow, the flow
receiver MUST advertise at least one buffer block in an receiver MUST advertise at least one buffer block in an
acknowledgement if it is not suspended, even if the amount of data in acknowledgement if it is not suspended, even if the amount of data in
the buffer exceeds the buffer capacity, unless the buffer capacity is the buffer exceeds the buffer capacity, unless the buffer capacity is
0. Otherwise, deadlock can occur, as the receive buffer will stay 0. Otherwise, deadlock can occur, as the receive buffer will stay
full and won't drain because of a gap or incomplete message, and the full and won't drain because of a gap or incomplete message, and the
gap or incomplete message can't be repaired or completed because the gap or incomplete message can't be repaired or completed because the
sender is suspended. sender is suspended.
The receive window is advertised in units of 1024-byte blocks. For The receive window is advertised in units of 1024-byte blocks. For
example, advertisements for 1 byte, 1023 bytes, and 1024 bytes each example, advertisements for 1 byte, 1023 bytes, and 1024 bytes each
require one block. An advertisement for 1025 bytes requires two require one block. An advertisement for 1025 bytes requires
blocks. two blocks.
The following describes the RECOMMENDED method of calculating the The following describes the RECOMMENDED method of calculating the
bufferBlocksAvailable field of an acknowledgement chunk for a bufferBlocksAvailable field of an acknowledgement chunk for a
receiving flow: receiving flow:
1. If BUFFERED_SIZE is greater than or equal to BUFFER_CAPACITY: set 1. If BUFFERED_SIZE is greater than or equal to BUFFER_CAPACITY, set
ADVERTISE_BYTES to 0; ADVERTISE_BYTES to 0;
2. If BUFFERED_SIZE is less than BUFFER_CAPACITY: set 2. If BUFFERED_SIZE is less than BUFFER_CAPACITY, set
ADVERTISE_BYTES to BUFFER_CAPACITY - BUFFERED_SIZE; ADVERTISE_BYTES to BUFFER_CAPACITY - BUFFERED_SIZE;
3. Set ADVERTISE_BLOCKS to CEIL(ADVERTISE_BYTES / 1024); 3. Set ADVERTISE_BLOCKS to CEIL(ADVERTISE_BYTES / 1024);
4. If ADVERTISE_BLOCKS is 0, AND BUFFER_CAPACITY is greater than 0, 4. If ADVERTISE_BLOCKS is 0, AND BUFFER_CAPACITY is greater than 0,
AND delivery to the user is not suspended: set ADVERTISE_BLOCKS AND delivery to the user is not suspended, set ADVERTISE_BLOCKS
to 1; and to 1; and
5. Set the acknowledgement's bufferBlocksAvailable field to 5. Set the acknowledgement's bufferBlocksAvailable field to
ADVERTISE_BLOCKS. ADVERTISE_BLOCKS.
3.6.3.6. Receiving a Buffer Probe 3.6.3.6. Receiving a Buffer Probe
A Buffer Probe chunk (Section 2.3.15) is sent by the flow sender A Buffer Probe chunk (Section 2.3.15) is sent by the flow sender
(Section 3.6.2.9.1) to request the current receive window (Section 3.6.2.9.1) to request the current receive window
advertisement (in the form of an acknowledgement) from the flow advertisement (in the form of an acknowledgement) from the flow
receiver. receiver.
On receipt of a Buffer Probe chunk: On receipt of a Buffer Probe chunk:
1. If chunk.flowID doesn't belong to a receiving flow in the same 1. If chunk.flowID doesn't belong to a receiving flow in the same
session in the RF_OPEN, RF_REJECTED, or RF_COMPLETE_LINGER state: session in the RF_OPEN, RF_REJECTED, or RF_COMPLETE_LINGER state,
ignore this Buffer Probe; otherwise, ignore this Buffer Probe; otherwise,
2. Retrieve the receiving flow context for the flow indicated by 2. Retrieve the receiving flow context for the flow indicated by
chunk.flowID; then chunk.flowID; then
3. Set flow.SHOULD_ACK to true; and 3. Set flow.SHOULD_ACK to true; and
4. Set session.ACK_NOW to true. 4. Set session.ACK_NOW to true.
3.6.3.7. Rejecting a Flow 3.6.3.7. Rejecting a Flow
A receiver can reject an RF_OPEN flow at any time and for any reason. A receiver can reject an RF_OPEN flow at any time and for any reason.
To reject a receiving flow in the RF_OPEN state: To reject a receiving flow in the RF_OPEN state:
1. Move to the RF_REJECTED state; 1. Move to the RF_REJECTED state;
2. Discard all entries in flow.RECV_BUFFER, as they are no longer 2. Discard all entries in flow.RECV_BUFFER, as they are no longer
relevant; relevant;
3. If the user rejected the flow, set flow.EXCEPTION_CODE to the 3. If the user rejected the flow, set flow.EXCEPTION_CODE to the
exception code indicated by the user; otherwise the flow was exception code indicated by the user; otherwise, the flow was
rejected automatically by the implementation, so the exception rejected automatically by the implementation, so the exception
code is 0; code is 0;
4. Set flow.SHOULD_ACK to true; and 4. Set flow.SHOULD_ACK to true; and
5. Set session.ACK_NOW to true. 5. Set session.ACK_NOW to true.
The receiver indicates that it has rejected a flow by sending a Flow The receiver indicates that it has rejected a flow by sending a Flow
Exception Report chunk (Section 2.3.16) with every acknowledgement Exception Report chunk (Section 2.3.16) with every acknowledgement
(Section 3.6.3.4.3) for a flow in the RF_REJECTED state. (Section 3.6.3.4.3) for a flow in the RF_REJECTED state.
3.6.3.8. Close 3.6.3.8. Close
A receiving flow is complete when every sequence number from 0 A receiving flow is complete when every sequence number from 0
through and including the final sequence number has been received; through and including the final sequence number has been received --
that is, when flow.RF_FINAL_SN has a value and flow.SEQUENCE_SET that is, when flow.RF_FINAL_SN has a value and flow.SEQUENCE_SET
contains every sequence number from 0 through flow.RF_FINAL_SN, contains every sequence number from 0 through flow.RF_FINAL_SN,
inclusive. inclusive.
When an RF_OPEN or RF_REJECTED receiving flow becomes complete, move When an RF_OPEN or RF_REJECTED receiving flow becomes complete, move
to the RF_COMPLETE_LINGER state, set flow.SHOULD_ACK to true, and set to the RF_COMPLETE_LINGER state, set flow.SHOULD_ACK to true, and set
session.ACK_NOW to true. session.ACK_NOW to true.
A receiving flow SHOULD remain in the RF_COMPLETE_LINGER state for A receiving flow SHOULD remain in the RF_COMPLETE_LINGER state for
120 seconds. After 120 seconds, move to the RF_CLOSED state. The 120 seconds. After 120 seconds, move to the RF_CLOSED state. The
receiving flow is now closed, and its resources can be reclaimed once receiving flow is now closed, and its resources can be reclaimed once
all complete messages in flow.RECV_BUFFER have been delivered to the all complete messages in flow.RECV_BUFFER have been delivered to the
user (Section 3.6.3.3). The same flow ID might be used for a new user (Section 3.6.3.3). The same flow ID might be used for a new
flow by the sender after this point. flow by the sender after this point.
Discussion: The flow sender detects that the flow is complete on Discussion: The flow sender detects that the flow is complete on
receiving an acknowledgement of all fragment sequence numbers of the receiving an acknowledgement of all fragment sequence numbers of the
flow. This can't happen until after the receiver has detected that flow. This can't happen until after the receiver has detected that
the flow is complete and acknowledged all of the sequence numbers. the flow is complete and acknowledged all of the sequence numbers.
The receiver's RF_COMPLETE_LINGER period is two minutes (one Maximum The receiver's RF_COMPLETE_LINGER period is two minutes (one Maximum
Segment Lifetime (MSL)), which allows any in flight packets to drain Segment Lifetime (MSL)); this period allows any in-flight packets to
from the network without being misidentified, and gives the sender an drain from the network without being misidentified and gives the
opportunity to retransmit any sequence numbers if the completing sender an opportunity to retransmit any sequence numbers if the
acknowledgement is lost. The sender's F_COMPLETE_LINGER period is at completing acknowledgement is lost. The sender's F_COMPLETE_LINGER
least two minutes plus 10 seconds, and doesn't begin until the period is at least two minutes plus 10 seconds and doesn't begin
completing acknowledgement is received; therefore, the same flow until the completing acknowledgement is received; therefore, the same
identifier won't be re-used by the flow sender for a new sending flow flow identifier won't be reused by the flow sender for a new sending
for at least 10 seconds after the flow receiver has closed the flow for at least 10 seconds after the flow receiver has closed the
receiving flow context. This ensures correct operation independent receiving flow context. This ensures correct operation independent
of network delay and even when the sender's clock runs up to 8 of network delay, even when the sender's clock runs up to 8 percent
percent faster than the receiver's. faster than the receiver's.
4. IANA Considerations 4. IANA Considerations
This memo specifies chunk type code values (Section 2.3) and User This memo specifies chunk type code values (Section 2.3) and User
Data option type code values (Section 2.3.11.1). These type code Data option type code values (Section 2.3.11.1). These type code
values are assigned and maintained by Adobe. Therefore, this memo values are assigned and maintained by Adobe. Therefore, this memo
has no IANA actions. has no IANA actions.
5. Security Considerations 5. Security Considerations
skipping to change at page 101, line 39 skipping to change at page 105, line 18
a confidential and authenticated session between endpoints. A a confidential and authenticated session between endpoints. A
Cryptography Profile, not specified herein, defines the cryptographic Cryptography Profile, not specified herein, defines the cryptographic
algorithms, data formats, and semantics as used within this algorithms, data formats, and semantics as used within this
framework. Designing a Cryptography Profile to ensure that framework. Designing a Cryptography Profile to ensure that
communications are protected to the degree required by the communications are protected to the degree required by the
application-specific threat model is outside the scope of this application-specific threat model is outside the scope of this
specification. specification.
A block cipher in CBC mode is RECOMMENDED for packet encryption A block cipher in CBC mode is RECOMMENDED for packet encryption
(Section 2.2.3). An attacker can predict the values of some fields (Section 2.2.3). An attacker can predict the values of some fields
from one plain RTMFP packet to the next, or predict that some fields from one plain RTMFP packet to the next or predict that some fields
may be the same from one packet to the next. This SHOULD be may be the same from one packet to the next. This SHOULD be
considered in choosing and implementing a packet encryption cipher considered in choosing and implementing a packet encryption cipher
and mode. and mode.
The well-known Default Session Key of a Cryptography Profile serves The well-known Default Session Key of a Cryptography Profile serves
multiple purposes, including: to scramble session startup packets to multiple purposes, including the scrambling of session startup
protect interior fields from undesirable modification by middleboxes packets to protect interior fields from undesirable modification by
such as NATs; to increase the effort required for casual passive middleboxes such as NATs, increasing the effort required for casual
observation of startup packets; to allow for different applications passive observation of startup packets, and allowing different
of RTMFP using different Default Session Keys to (intentionally or applications of RTMFP using different Default Session Keys to
not) share network transport addresses without interference. The (intentionally or not) share network transport addresses without
Default Session Key, being well-known, MUST NOT be construed to interference. The Default Session Key, being well known, MUST NOT be
contribute to the security of session startup; session startup is construed to contribute to the security of session startup; session
essentially in the clear. startup is essentially in the clear.
Section 3.5.4.2 describes an OPTIONAL method for processing a change Section 3.5.4.2 describes an OPTIONAL method for processing a change
of network address of a communicating peer. Securely processing of network address of a communicating peer. Securely processing
address mobility using that or any substantially similar method address mobility using that method, or any substantially similar
REQUIRES at least that the Packet Encryption function of the method, REQUIRES at least that the packet encryption function of the
Cryptography Profile (Section 2.2.3) employs a cryptographic Cryptography Profile (Section 2.2.3) employs a cryptographic
verification mechanism comprising secret information known only to verification mechanism comprising secret information known only to
the two endpoints. Without this constraint, that or any the two endpoints. Without this constraint, that method, or any
substantially similar method becomes "session hijacking support". substantially similar method, becomes "session hijacking support".
Flows and packet fragmentation imply semantics that could cause Flows and packet fragmentation imply semantics that could cause
unbounded resource utilization in receivers, causing a denial of unbounded resource utilization in receivers, causing a denial of
service. Implementations SHOULD guard against unbounded or excessive service. Implementations SHOULD guard against unbounded or excessive
resource use, and abort sessions that appear abusive. resource use and abort sessions that appear abusive.
A rogue but popular Redirector (Section 3.5.1.4) could direct session A rogue but popular Redirector (Section 3.5.1.4) could direct session
Initiators to flood a victim address or network with Initiator Hello initiators to flood a victim address or network with Initiator Hello
packets, potentially causing a denial of service. packets, potentially causing a denial of service.
An attacker that can passively observe an IHello and that possesses a An attacker that can passively observe an IHello and that possesses a
certificate matching the Endpoint Discriminator (without having to certificate matching the Endpoint Discriminator (without having to
know the private key, if any, associated with it) can deny the know the private key, if any, associated with it) can deny the
Initiator access to the desired Responder by sending an RHello before initiator access to the desired responder by sending an RHello before
the desired Responder does, since only the first received RHello is the desired responder does, since only the first received RHello is
selected by the Initiator. The attacker needn't forge the desired selected by the initiator. The attacker needn't forge the desired
Responder's source address, since the RHello is selected based on the responder's source address, since the RHello is selected based on the
tag echo and not the packet's source address. This can simplify the tag echo and not the packet's source address. This can simplify the
attack in some network or host configurations. attack in some network or host configurations.
An attacker that can passively observe and record the packets of an An attacker that can passively observe and record the packets of an
established session can use traffic analysis techniques to infer the established session can use traffic analysis techniques to infer the
start and completion of flows without decrypting the packets. The start and completion of flows without decrypting the packets. The
User Data fragments of flows have unique sequence numbers, so flows User Data fragments of flows have unique sequence numbers, so flows
are immune to replay while they are open. However, once a flow has are immune to replay while they are open. However, once a flow has
completed and the linger period has concluded, the attacker could completed and the linger period has concluded, the attacker could
replay the recorded packets, opening a new flow in the receiver and replay the recorded packets, opening a new flow in the receiver and
</