Adobe's Secure Real-Time Media Flow Protocol
draft-thornburgh-adobe-rtmfp-06
The information below is for an old version of the document.
Document | Type |
This is an older version of an Internet-Draft that was ultimately published as RFC 7016.
|
|
---|---|---|---|
Author | Michael C. Thornburgh | ||
Last updated | 2013-04-15 | ||
RFC stream | Internet Engineering Task Force (IETF) | ||
Formats | |||
Reviews |
GENART Telechat review
(of
-09)
by Ben Campbell
Almost ready
GENART Last Call review
(of
-07)
by Ben Campbell
Almost ready
SECDIR Last Call review
(of
-07)
by Hilarie Orman
Serious Issues
|
||
Additional resources | |||
Stream | WG state | (None) | |
Document shepherd | (None) | ||
IESG | IESG state | Became RFC 7016 (Informational) | |
Consensus boilerplate | Unknown | ||
Telechat date | (None) | ||
Responsible AD | Martin Stiemerling | ||
Send notices to | mthornbu@adobe.com, draft-thornburgh-adobe-rtmfp@tools.ietf.org |
draft-thornburgh-adobe-rtmfp-06
Thornburgh Expires October 17, 2013 [Page 84] Internet-Draft Adobe RTMFP April 2013 * FRA: the fragment control value for this message fragment, having one of the values enumerated for that purpose in User Data (Section 2.3.11). o BUFFERED_SIZE: the sum of the lengths of each fragment in RECV_BUFFER plus any additional storage overhead for the fragments incurred by the implementation, in bytes; o BUFFER_CAPACITY: the desired maximum size for the receive buffer, in bytes; o PREV_RWND: the most recent receive window advertisement sent in an acknowledgement, in 1024-byte blocks, initially having no value; o SHOULD_ACK: whether or not an acknowledgement should be sent for this flow, initially false; o EXCEPTION_CODE: the exception code to report to the sender when the flow has been rejected, initially 0; o The state, at any time being one of the following values: the open state RF_OPEN; the closing states RF_REJECTED and RF_COMPLETE_LINGER; and the closed state RF_CLOSED. Thornburgh Expires October 17, 2013 [Page 85] Internet-Draft Adobe RTMFP April 2013 Note: this diagram is only a summary of state transitions and their causing events, and is not a complete operational specification. +-+ |X| +-+ |rcv User Data for | no existing flow v +---------+ | RF_OPEN | +---------+ rcv all sequence numbers| |user reject, 0..RF_FINAL_SN | |rcv bad option, | |no metadata at open, | |association specified | | but not F_OPEN at open +---+ | | v | +-----------+ | |RF_REJECTED| | +-----------+ | |rcv all sequence numbers | | 0..RF_FINAL_SN v v +------------------+ |RF_COMPLETE_LINGER| +------------------+ | 120 seconds v +---------+ |RF_CLOSED| +---------+ Figure 21: Receiving flow state diagram 3.6.3.1. Startup 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 receiving flow in the same session in the RF_OPEN, RF_REJECTED, or RF_COMPLETE_LINGER states. On receipt of such a User Data chunk: 1. Set temporary variables METADATA, ASSOCIATED_FLOWID, and ASSOCIATION to each have no value; Thornburgh Expires October 17, 2013 [Page 86] Internet-Draft Adobe RTMFP April 2013 2. Create a new receiving flow context in this session, setting its RF_FLOW_ID to the flow ID encoded in the opening User Data chunk, and set to the RF_OPEN state; 3. If the opening User Data chunk encodes a User's Per-Flow Metadata option (Section 2.3.11.1.1), set METADATA to option.userMetadata; 4. If the opening User Data chunk encodes a Return Flow Association option (Section 2.3.11.1.2), set ASSOCIATED_FLOWID to option.flowID; 5. If METADATA has no value, the receiver MUST reject the flow (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 flow in the same session with a flow ID of ASSOCIATED_FLOWID, the receiver MUST reject the flow, moving it to the RF_REJECTED state; otherwise set ASSOCIATION to the indicated sending flow; 7. If ASSOCIATION indicates a sending flow AND that sending flow's state is not F_OPEN, the receiver MUST reject this receiving flow, moving it to the RF_REJECTED state; 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 MUST reject the flow, moving it to the RF_REJECTED state; 9. If this new receiving flow is still RF_OPEN, then: notify the user that a new receiving flow has opened, including the METADATA and, if present, the ASSOCIATION, and set flow.BUFFER_CAPACITY according to the user; 10. Perform the normal data processing (Section 3.6.3.2) for the opening User Data chunk; and 11. Set this session's ACK_NOW to true. 3.6.3.2. Receiving Data 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 flow, as well as the flow's Forward Sequence Number and potentially optional parameters (Section 2.3.11.1). On receipt of a User Data or Next User Data chunk: Thornburgh Expires October 17, 2013 [Page 87] Internet-Draft Adobe RTMFP April 2013 1. If chunk.flowID doesn't indicate an existing receiving flow in the same session in the RF_OPEN, RF_REJECTED, or RF_COMPLETE_LINGER state, perform the steps at Startup (Section 3.6.3.1) to start a new receiving flow; 2. Retrieve the receiving flow context for the flow indicated by chunk.flowID; 3. Set flow.SHOULD_ACK to true; 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 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 state; 5. If the flow is not in the RF_OPEN state: set session.ACK_NOW to true; 6. If flow.PREV_RWND has a value and that value is less than 2 blocks, 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 contain every sequence number from 0 through and including the highest sequence number in the set), set session.ACK_NOW to true; 9. If flow.SEQUENCE_SET contains chunk.sequenceNumber, then this chunk is a duplicate: set session.ACK_NOW to true; 10. If flow.SEQUENCE_SET doesn't contain chunk.sequenceNumber, AND chunk.final is true, AND flow.RF_FINAL_SN has no value, then: set flow.RF_FINAL_SN to chunk.sequenceNumber, and set session.ACK_NOW to true; 11. If the flow is in the RF_OPEN state, AND flow.SEQUENCE_SET doesn't contain chunk.sequenceNumber, AND chunk.abandon is false, then: create a new RECV_BUFFER entry for this chunk's data and set entry.SEQUENCE_NUMBER to chunk.sequenceNumber, entry.DATA to chunk.userData, and entry.FRA to chunk.fragmentControl, and insert this new entry into flow.RECV_BUFFER; 12. Add to flow.SEQUENCE_SET the range of sequence numbers from 0 through and including the chunk.forwardSequenceNumber derived field; Thornburgh Expires October 17, 2013 [Page 88] Internet-Draft Adobe RTMFP April 2013 13. Add chunk.sequenceNumber to flow.SEQUENCE_SET; 14. If flow.SEQUENCE_SET now has any gaps, set session.ACK_NOW to true; 15. If session.ACK_NOW is false and session.DELACK_ALARM is not set: set session.DELACK_ALARM to fire in 200 milliseconds; and 16. Attempt delivery of completed messages in this flow's RECV_BUFFER to the user (Section 3.6.3.3). After processing all chunks in a packet containing at least one User Data chunk, increment session.RX_DATA_PACKETS by one. If 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 an acknowledgement if its SHOULD_ACK flag is set. Acknowledgements for receiving flows that are ready are sent either opportunistically 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 flag is set (Section 3.6.3.4.5). 3.6.3.3. Buffering and Delivering Data A receiving flow's information context contains a RECV_BUFFER for reordering, reassembling, and holding the user data messages of the flow. Only complete messages are delivered to the user; an implementation MUST NOT deliver partially received messages except by special arrangement with the user. Let the Cumulative Acknowledgement Sequence Number CSN be the highest number in the contiguous range of numbers in SEQUENCE_SET starting with 0. For example, if SEQUENCE_SET contains {0, 1, 2, 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 RECV_BUFFER. The fragments of one message have contiguous sequence numbers. A message can either be a single fragment, whose fragment control value is 0-whole, or can be two or more fragments where the first's fragment control value is 1-begin, followed by zero or more fragments with control value 3-middle, and terminated by a last fragment with control value 2-end. 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 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 1-begin, or one or more 3-middle fragments with neither a 1-begin nor Thornburgh Expires October 17, 2013 [Page 89] Internet-Draft Adobe RTMFP April 2013 a 2-end. Incomplete message segments can either be in progress or abandoned. An incomplete segment is abandoned in the following cases: 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 1-begin; or o The sequence number of the segment's last fragment is less than the CSN. Abandoned message segments will never be completed, so they SHOULD be removed from the RECV_BUFFER to make room in the advertised receive window and the receiver's memory for messages that can be completed. The user can suspend delivery of a flow's messages. A suspended receiving flow holds completed messages in its RECV_BUFFER until the user resumes delivery. A suspended flow can cause the receive window advertisement to go to zero even when the BUFFER_CAPACITY is non- zero; this is described in detail in Flow Control (Section 3.6.3.5). When the receiving flow is not suspended, the original queuing order of the messages is recovered by delivering, in ascending sequence number order, complete messages in the RECV_BUFFER whose sequence numbers are less than or equal to the CSN. The following describes a method for discarding abandoned message segments and delivering complete messages in original queueing order when the receiving flow is not suspended. While the first fragment entry in the RECV_BUFFER has a sequence number less than or equal to CSN and delivery is still possible: 1. If entry.FRA is 0-whole: deliver entry.DATA to the user, and remove this entry from RECV_BUFFER; otherwise, 2. If entry.FRA is 2-end or 3-middle: this entry belongs to an abandoned segment, so remove and discard this entry from RECV_BUFFER; otherwise, 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 if the segment has only one fragment so far). Then: 1. If LAST_ENTRY.FRA is 2-end: this segment is a complete message, so concatenate the DATA fields of each fragment entry of this segment in ascending sequence number order and Thornburgh Expires October 17, 2013 [Page 90] Internet-Draft Adobe RTMFP April 2013 deliver the complete message to the user, then remove the entries for this complete message from RECV_BUFFER; otherwise, 2. If LAST_ENTRY.SEQUENCE_NUMBER is less than CSN: this segment is incomplete and abandoned, so remove and discard the entries for this segment from RECV_BUFFER; otherwise, 3. LAST_ENTRY.SEQUENCE_NUMBER is equal to CSN and LAST_ENTRY.FRA is not 2-end: this segment is incomplete but still in progress. Ordered delivery is no longer possible until at least one more fragment is received. Stop. If flow.RF_FINAL_SN has a value and is equal to CSN, AND RECV_BUFFER is empty: all complete messages have been delivered to the user, so notify the user that the flow is complete. 3.6.3.4. Acknowledging Data A flow receiver SHOULD acknowledge all user data sequence numbers seen in that flow. Acknowledgements drive the sender's congestion control and avoidance algorithms, clear data from the sender's buffers, and in some sender implementations clock new data into the network, and therefore must be accurate and timely. 3.6.3.4.1. Timing For similar reasons as discussed in RFC 1122 Section 4.2.3.2 [RFC1122], it is advantageous to delay sending acknowledgements for a short time so that multiple data fragments can be acknowledged in a single transmission. However, it is also advantageous for a sender to receive timely notification about the receiver's disposition of the flow, particularly in unusual or exceptional circumstances, so that the circumstances can be addressed if possible. Therefore, a flow receiver SHOULD send an acknowledgement for a flow 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 or Next User Data chunk if the flow is not in the RF_OPEN state; o On receipt of a User Data chunk where, before processing the chunk, the SEQUENCE_SET of the indicated flow does not contain every sequence number between 0 and the highest sequence number in the set (that is, if there was a sequence number gap before processing the chunk); Thornburgh Expires October 17, 2013 [Page 91] Internet-Draft Adobe RTMFP April 2013 o On receipt of a User Data chunk where, after processing the chunk, the flow's SEQUENCE_SET does not contain every sequence number between 0 and the highest sequence number in the set (that is, if this chunk causes a sequence number gap); o On receipt of a Buffer Probe for the flow; o On receipt of a User Data chunk if the last acknowledgement sent for the flow indicated fewer than two bufferBlocksAvailable; 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 least 1024 bytes greater than BUFFERED_SIZE; 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); 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 any flows since an acknowledgement was last sent; the new acknowledgements being for the flows having any User Data chunks in the received packets (that is, for every second packet containing user data); o After receipt of a User Data chunk for the flow, if an acknowledgement for any other flow is being sent (that is, consolidate acknowledgements); 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 available in the same packet (that is, attempt to piggyback an acknowledgement with user data if possible); o No longer than 200 milliseconds after receipt of a User Data chunk for the flow. 3.6.3.4.2. Size and Truncation Including an encoded acknowledgement in a packet might cause the packet to exceed the path MTU. In that case: o If the packet is being sent primarily to send an acknowledgement AND this is the first acknowledgement in the packet, truncate the acknowledgement so that the packet does not exceed the path MTU; otherwise Thornburgh Expires October 17, 2013 [Page 92] Internet-Draft Adobe RTMFP April 2013 o The acknowledgement is being piggybacked in a packet with user data or with an acknowledgement for another flow: do not include this acknowledgement in the packet, and send it later. 3.6.3.4.3. Constructing The Data Acknowledgement Bitmap chunk (Section 2.3.13) and Data Acknowledgement Ranges chunk (Section 2.3.14) encode a receiving flow's SEQUENCE_SET and its receive window advertisement. The two chunks are semantically equivalent; implementations SHOULD send whichever provides the most compact encoding of the SEQUENCE_SET. When assembling an acknowledgement for a receiving flow: 1. If the flow's state is RF_REJECTED, first assemble a Flow Exception Report chunk (Section 2.3.16) for flow.flowID; 2. Choose the acknowledgement chunk type that most compactly encodes flow.SEQUENCE_SET; 3. Use the method described in Flow Control (Section 3.6.3.5) to determine the value for the acknowledgement chunk's bufferBlocksAvailable field; 3.6.3.4.4. Delayed Acknowledgement As discussed in Acknowledging Data (Section 3.6.3.4.1), a flow receiver can delay sending an acknowledgement for up to 200 milliseconds after receiving user data. The method described in Receiving Data (Section 3.6.3.2) sets the session's DELACK_ALARM. When DELACK_ALARM fires: set ACK_NOW to true. 3.6.3.4.5. Obligatory Acknowledgement One or more acknowledgements should be sent as soon as is practical when the session's ACK_NOW flag is set. When the ACK_NOW flag is set: 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 false, set RX_DATA_PACKETS to 0, clear the DELACK_ALARM, and stop; otherwise 3. Start a new packet; Thornburgh Expires October 17, 2013 [Page 93] Internet-Draft Adobe RTMFP April 2013 4. Assemble an acknowledgement for the flow and include it in the packet, truncating it if necessary so that the packet doesn't exceed the path MTU; 5. Set flow.SHOULD_ACK to false; 6. Set flow.PREV_RWND to the bufferBlocksAvailable field of the included acknowledgement chunk; 7. Attempt to piggyback acknowledgements for any other flows that are ready to send an acknowledgement into the packet, as described below; and 8. Send the packet. 3.6.3.4.6. Opportunistic Acknowledgement When sending a packet with user data or an acknowledgement, any other receiving flows that are ready to send an acknowledgement should include their acknowledgements in the packet if possible. To piggyback acknowledgements in a packet that is already being sent, where the packet contains user data or an acknowledgement: While there is at least one receiving flow that is ready to send an acknowledgement: 1. Assemble an acknowledgement for the flow; 2. If the acknowledgement cannot be included in the packet without exceeding the path MTU: the packet is full, stop; otherwise 3. Include the acknowledgement in the packet; 4. Set flow.SHOULD_ACK to false; 5. Set flow.PREV_RWND to the bufferBlocksAvailable field of the included acknowledgement chunk; and 6. If there are no longer any receiving flows in the session that are ready to send an acknowledgement: set session.ACK_NOW to false, set session.RX_DATA_PACKETS to 0, and clear session.DELACK_ALARM. 3.6.3.4.7. Example Thornburgh Expires October 17, 2013 [Page 94] Internet-Draft Adobe RTMFP April 2013 Receiver 1 |<--- Data ID=3, seq#=29, fsnOff=11 (fsn=18) 2 |<--- Data ID=3, seq#=30, fsnOff=12 (fsn=18) 3 |---> Ack ID=3, seq:0-30 4 |<--- Data ID=3, seq#=32, fsnOff=12 (fsn=20) 5 |---> Ack ID=3, seq:0-30, 32 6 |<--- Data ID=3, seq#=34, fsnOff=12 (fsn=22) 7 |---> Ack ID=3, seq:0-30, 32, 34 | : 8 |<--- Data ID=3, seq#=46, fsnOff=16 (fsn=30) 9 |---> Ack ID=3, seq:0-30, 32, 34-46 10 |<--- Data ID=3, seq#=47, fsnOff=15 (fsn=32) 11 |---> Ack ID=3, seq:0-32, 34-47 12 |<--- Data ID=3, seq#=33, fsnOff=1 (fsn=32) 13 |---> Ack ID=3, seq#=0-47 14 |<--- Data ID=3, seq#=48, fsnOff=16 (fsn=32) 15 |<--- Data ID=3, seq#=49, fsnOff=17 (fsn=32) 16 |---> Ack ID=3, seq#=0-49 | : Flow with sequence numbers 31 and 33 lost in transit, 31 abandoned and 33 retransmitted. Figure 22 3.6.3.5. Flow Control The flow receiver maintains a buffer for reassembling and reordering messages for delivery to the user (Section 3.6.3.3). The implementation and the user may wish to limit the amount of resources (including buffer memory) that a flow is allowed to use. RTMFP provides a means for each receiving flow to govern the amount of data sent by the sender, by way of the bufferBytesAvailable derived field of acknowledgement chunks (Section 2.3.13, Section 2.3.14). This derived field indicates the amount of data that the sender is allowed to have outstanding in the network, until instructed otherwise. This amount is also called the receive window. The flow receiver can suspend the sender by advertising a closed (zero length) receive window. The user can suspend delivery of messages from the receiving flow (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 or repairing a gap for sequenced delivery in a flow, the flow receiver MUST advertise at least one buffer block in an Thornburgh Expires October 17, 2013 [Page 95] Internet-Draft Adobe RTMFP April 2013 acknowledgement if it is not suspended, even if the amount of data in the buffer exceeds the buffer capacity, unless the buffer capacity is 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 gap or incomplete message can't be repaired or completed because the sender is suspended. The receive window is advertised in units of 1024-byte blocks. For example, advertisements for 1 byte, 1023 bytes, and 1024 bytes each require one block. An advertisement for 1025 bytes requires two blocks. The following describes the RECOMMENDED method of calculating the bufferBlocksAvailable field of an acknowledgement chunk for a receiving flow: 1. If BUFFERED_SIZE is greater than or equal to BUFFER_CAPACITY: set ADVERTISE_BYTES to 0; 2. If BUFFERED_SIZE is less than BUFFER_CAPACITY: set ADVERTISE_BYTES to BUFFER_CAPACITY - BUFFERED_SIZE; 3. Set ADVERTISE_BLOCKS to CEIL(ADVERTISE_BYTES / 1024); 4. If ADVERTISE_BLOCKS is 0, AND BUFFER_CAPACITY is greater than 0, AND delivery to the user is not suspended: set ADVERTISE_BLOCKS to 1; and 5. Set the acknowledgement's bufferBlocksAvailable field to ADVERTISE_BLOCKS. 3.6.3.6. Receiving a Buffer Probe 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 advertisement (in the form of an acknowledgement) from the flow receiver. On receipt of a Buffer Probe chunk: 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: ignore this Buffer Probe; otherwise, 2. Retrieve the receiving flow context for the flow indicated by chunk.flowID; then Thornburgh Expires October 17, 2013 [Page 96] Internet-Draft Adobe RTMFP April 2013 3. Set flow.SHOULD_ACK to true; and 4. Set session.ACK_NOW to true. 3.6.3.7. Rejecting a Flow 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: 1. Move to the RF_REJECTED state; 2. Discard all entries in flow.RECV_BUFFER, as they are no longer relevant; 3. If the user rejected the flow, set flow.EXCEPTION_CODE to the exception code indicated by the user; otherwise the flow was rejected automatically by the implementation, so the exception code is 0; 4. Set flow.SHOULD_ACK to true; and 5. Set session.ACK_NOW to true. The receiver indicates that it has rejected a flow by sending a Flow Exception Report chunk (Section 2.3.16) with every acknowledgement (Section 3.6.3.4.3) for a flow in the RF_REJECTED state. 3.6.3.8. Close A receiving flow is complete when every sequence number from 0 through and including the final sequence number has been received; 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, inclusive. 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 session.ACK_NOW to true. A receiving flow SHOULD remain in the RF_COMPLETE_LINGER state for 120 seconds. After 120 seconds, move to the RF_CLOSED state. The receiving flow is now closed, and its resources can be reclaimed once 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 flow by the sender after this point. Discussion: The flow sender detects that the flow is complete on receiving an acknowledgement of all sequence numbers of the flow. Thornburgh Expires October 17, 2013 [Page 97] Internet-Draft Adobe RTMFP April 2013 This can't happen until after the receiver has detected that the flow is complete and acknowledged all of the sequence numbers. The receiver's RF_COMPLETE_LINGER period is two minutes (one Maximum Segment Lifetime (MSL)), which allows any in-flight packets to drain from the network without being misidentified, and gives the sender an opportunity to retransmit any sequence numbers if the completing acknowledgement is lost. The sender's F_COMPLETE_LINGER period is at least two minutes plus 10 seconds, and doesn't begin until the completing acknowledgement is received; therefore, the same flow identifier won't be re-used by the flow sender for a new sending flow for at least 10 seconds after the flow receiver has closed the receiving flow context. This ensures correct operation independent of network delay and even when the sender's clock runs up to 8 percent faster than the receiver's. 4. IANA Considerations 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 values are assigned and maintained by Adobe. Therefore, this memo has no IANA actions. 5. Security Considerations This memo specifies a general framework that can be used to establish a confidential and authenticated session between endpoints. A Cryptography Profile, not specified herein, defines the cryptographic algorithms, data formats, and semantics as used within this framework. Designing a Cryptography Profile to ensure that communications are protected to the degree required by the application-specific threat model is outside the scope of this specification. The well-known Default Session Key of a Cryptography Profile serves multiple purposes, including: to scramble session startup packets to protect interior fields from undesirable modification by middleboxes such as NATs; to increase the effort required for casual passive observation of startup packets; to allow for different applications of RTMFP using different Default Session Keys to (intentionally or not) share network transport addresses without interference. The Default Session Key, being well-known, MUST NOT be construed to contribute to the security of session startup; session startup is essentially in the clear. Section 3.5.4.2 describes an OPTIONAL method for processing a change of network address of a communicating peer. Securely processing Thornburgh Expires October 17, 2013 [Page 98] Internet-Draft Adobe RTMFP April 2013 address mobility using that or any substantially similar method REQUIRES at least that the Packet Encryption function of the Cryptography Profile (Section 2.2.3) employs a cryptographic verification mechanism comprising secret information known only to the two endpoints. Without this constraint, that or any substantially similar method becomes "session hijacking support". Flows and packet fragmentation imply semantics that could cause unbounded resource utilization in receivers, causing a denial of service. Implementations SHOULD guard against unbounded or excessive resource use, and abort sessions that appear abusive. A rogue but popular Redirector (Section 3.5.1.4) could direct session Initiators to flood a victim address or network with Initiator Hello packets, potentially causing a denial of service. An attacker that can passively observe an IHello and that possesses a certificate matching the Endpoint Discriminator (without having to know the private key, if any, associated with it) can deny the Initiator access to the desired Responder by sending an RHello before the desired Responder does, since only the first received RHello is selected by the Initiator. The attacker needn't forge the desired 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 attack in some network or host configurations. 6. Acknowledgements Special thanks go to Matthew Kaufman for his contributions to the creation and design of RTMFP. Thanks to Wesley Eddy, Philipp Hancke, Bela Lubkin, and Martin Stiemerling for their detailed reviews of this memo. 7. References 7.1. Normative References [RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, August 1980. [RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791, September 1981. [RFC1122] Braden, R., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, October 1989. Thornburgh Expires October 17, 2013 [Page 99] Internet-Draft Adobe RTMFP April 2013 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998. [RFC2914] Floyd, S., "Congestion Control Principles", BCP 41, RFC 2914, September 2000. [RFC4821] Mathis, M. and J. Heffner, "Packetization Layer Path MTU Discovery", RFC 4821, March 2007. [RFC5681] Allman, M., Paxson, V., and E. Blanton, "TCP Congestion Control", RFC 5681, September 2009. 7.2. Informative References [RFC5389] Rosenberg, J., Mahy, R., Matthews, P., and D. Wing, "Session Traversal Utilities for NAT (STUN)", RFC 5389, October 2008. [ScalableTCP] Kelly, T., "Scalable TCP: Improving Performance in Highspeed Wide Area Networks", December 2002, <http:// datatag.web.cern.ch/datatag/papers/pfldnet2003-ctk.pdf>. Appendix A. Example Congestion Control Algorithm Section 3.5.2 mandates that an RTMFP use TCP-compatible congestion control, but allows flexibility in exact implementation within certain limits. This section describes an experimental window-based congestion control algorithm that is appropriate for real-time and bulk data transport in RTMFP. The algorithm includes slow-start and congestion avoidance phases including modified increase and decrease parameters. These parameters are further adjusted according to whether real-time data is being sent and whether time-critical reverse notifications are received. A.1. Discussion RFC 5681 defines the standard window-based congestion control algorithms for TCP. These algorithms are appropriate for delay- insensitive bulk data transport, but have undesirable behaviors for delay- and loss-sensitive applications. Among the undesirable behaviors are the cutting of the congestion window in half during a loss event, and the rapidity of the slow start algorithm's exponential growth. Cutting the congestion window in half requires a Thornburgh Expires October 17, 2013 [Page 100] Internet-Draft Adobe RTMFP April 2013 large channel headroom to support a real-time application, and can cause a large amount of jitter from sender-side buffering. Doubling the congestion window during the slow-start phase can lead to the congestion window temporarily growing to twice the size it should be, causing a period of excessive loss in the path. We found that a number of deployed TCP implementations use the method of equation 3 from RFC 5681 Section 3.1, which, when combined with the recommended behavior of acknowledging every other packet, causes the congestion window to grow at approximately half the rate as the recommended method specifies. In order to compete fairly with these deployed TCPs, we choose 768 bytes per round trip as the increment during the normal congestion avoidance phase, which is approximately half of the typical maximum segment size of 1500 bytes while also being easily subdivided. The sender may be sending real-time data to the far end. When sending real-time data, a smoother response to congestion is desired while still competing with reasonable fairness to other flows in the Internet. In order to scale the sending rate quickly, the slow start algorithm is desired, but slow start's normal rate of increase can cause excessive loss in the last round trip. Accordingly, slow start's exponential increase rate is adjusted to double every approximately 3 round trips instead of every round trip. The multiplicative decrease cuts the congestion window by one eighth on loss to maintain a smoother sending rate. The additive increase is done at half the normal rate (incrementing at 384 bytes per round trip), both to compensate for the less aggressive loss response and to probe the path capacity more gently. The far end may report that it is receiving real-time data from other peers, or the sender may be sending real-time data to other far ends. In these circumstances (if not sending real-time data to this far end) it is desirable to respond differently than the standard TCP algorithms specify, both to yield capacity to the real-time flows and to avoid excessive losses while probing the path capacity. Slow start's exponential increase is disabled and the additive increase is done at half the normal rate (incrementing at 384 bytes per round trip). Multiplicative decrease is left at cutting by half to yield to other flows. Since real-time messages may be small, and sent regularly, it is advantageous to spread congestion window increases out across the round-trip time instead of doing them all at once. We divide the round-trip into 16 segments with an additive increase of a useful size (48 bytes) per segment. Scalable TCP [ScalableTCP] describes experimental methods of Thornburgh Expires October 17, 2013 [Page 101] Internet-Draft Adobe RTMFP April 2013 modifying the additive increase and multiplicative decrease of the congestion window in large delay-bandwidth scenarios. The congestion window is increased by 1% each round trip and decreased by one eighth on loss in the congestion avoidance phase in certain circumstances (specifically, when a 1% increase is larger than the normal additive- increase amount). Those methods are adapted here. The scalable increase amount is 48 bytes for every 4800 bytes acknowledged, to spread the increase out over the round-trip. The congestion window is decreased by one eighth on loss when it is at least 67200 bytes per round trip, which is seven eighths of 76800 (the point at which 1% is greater than 768 bytes per round trip). When sending real-time data to the far end, the scalable increase is 1% or 384 bytes per round trip, whichever is greater. Otherwise, when notified that the far end is receiving real-time data from other peers, the scaled increase is adjusted to 0.5% or 384 bytes per round trip, whichever is greater. A.2. Algorithm Let SMSS denote the Sender Maximum Segment Size [RFC5681], for example 1460 bytes. Let CWND_INIT denote the Initial Congestion Window (IW) according to RFC 5681 Section 3.1, for example 4380 bytes. Let CWND_TIMEDOUT denote the congestion window after a timeout indicating lost data, being 1*SMSS (for example 1460 bytes). Let the session information context contain additional variables: o CWND: the Congestion Window, initialized to CWND_INIT; o SSTHRESH: the Slow Start Threshold, initialized to positive infinity; o ACKED_BYTES_ACCUMULATOR: a count of acknowledged bytes, initialized to 0; o ACKED_BYTES_THIS_PACKET: a count of acknowledged bytes observed in the current packet; o PRE_ACK_OUTSTANDING: the number of bytes outstanding in the network before processing any acknowledgements in the current packet; o ANY_LOSS: an indication to whether any loss has been detected in the current packet; o ANY_NAKS: an indication to whether any negative acknowledgements have been detected in the current packet; Thornburgh Expires October 17, 2013 [Page 102] Internet-Draft Adobe RTMFP April 2013 o ANY_ACKS: an indication to whether any acknowledgement chunks have been received in the current packet; Let FASTGROW_ALLOWED indicate whether the congestion window is allowed to grow at the normal rate versus a slower rate, being FALSE if a Time Critical Reverse Notification has been received on this session within the last 800 milliseconds (Section 2.2.4, Section 3.5.2.1) or if a Time Critical Forward Notification has been sent on ANY session in the last 800 milliseconds, and otherwise being TRUE. Let TC_SENT indicate whether a Time Critical Forward Notification has been sent on this session within the last 800 milliseconds. Implement the method of Section 3.6.2.6 to manage transmission timeouts, including setting the TIMEOUT_ALARM. On being notified that the TIMEOUT_ALARM has fired, perform the function in Figure 23: on TimeoutNotification(WAS_LOSS): set SSTHRESH to MAX(SSTHRESH, CWND * 3/4). set ACKED_BYTES_ACCUMULATOR to 0. if WAS_LOSS is TRUE: set CWND to CWND_TIMEDOUT. else: set CWND to CWND_INIT. Figure 23: Pseudocode for handling a timeout notification Before processing each received packet in this session: 1. Set ANY_LOSS to FALSE; 2. Set ANY_NAKS to FALSE; 3. Set ACKED_BYTES_THIS_PACKET to 0; and 4. Set PRE_ACK_OUTSTANDING to S_OUTSTANDING_BYTES. On notification of loss (Section 3.6.2.5): set ANY_LOSS to TRUE. On notification of negative acknowledgement (Section 3.6.2.5): set ANY_NAKS to TRUE. On notification of acknowledgement of data (Section 3.6.2.4): set ANY_ACKS to TRUE, and add the count of acknowledged bytes to ACKED_BYTES_THIS_PACKET. Thornburgh Expires October 17, 2013 [Page 103] Internet-Draft Adobe RTMFP April 2013 After processing all chunks in each received packet for this session, perform the function in Figure 24: if ANY_LOSS is TRUE: if (TC_SENT is TRUE) OR (PRE_ACK_OUTSTANDING > 67200 AND \ FASTGROW_ALLOWED is TRUE): set SSTHRESH to MAX(PRE_ACK_OUTSTANDING * 7/8, CWND_INIT). else: set SSHTRESH to MAX(PRE_ACK_OUTSTANDING * 1/2, CWND_INIT). set CWND to SSTHRESH. set ACKED_BYTES_ACCUMULATOR to 0. else if (ANY_ACKS is TRUE) AND (ANY_NAKS is FALSE) AND \ (PRE_ACK_OUTSTANDING >= CWND): set var INCREASE to 0. var AITHRESH. if FASTGROW_ALLOWED is TRUE: if CWND < SSTHRESH: set INCREASE to ACKED_BYTES_THIS_PACKET. else: add ACKED_BYTES_THIS_PACKET to ACKED_BYTES_ACCUMULATOR. set AITHRESH to MIN(MAX(CWND / 16, 64), 4800). while ACKED_BYTES_ACCUMULATOR >= AITHRESH: subtract AITHRESH from ACKED_BYTES_ACCUMULATOR. add 48 to INCREASE. else FASTGROW_ALLOWED is FALSE: if CWND < SSTHRESH AND TC_SENT is TRUE: set INCREASE to CEIL(ACKED_BYTES_THIS_PACKET / 4). else: var AITHRESH_CAP. if TC_SENT is TRUE: set AITHRESH_CAP to 2400. else: set AITHRESH_CAP to 4800. add ACKED_BYTES_THIS_PACKET to ACKED_BYTES_ACCUMULATOR. set AITHRESH to MIN(MAX(CWND / 16, 64), AITHRESH_CAP). while ACKED_BYTES_ACCUMULATOR >= AITHRESH: subtract AITHRESH from ACKED_BYTES_ACCUMULATOR. add 24 to INCREASE. set CWND to MAX(CWND + MIN(INCREASE, SMSS), CWND_INIT). Figure 24: Pseudocode for congestion window adjustment after processing a packet Thornburgh Expires October 17, 2013 [Page 104] Internet-Draft Adobe RTMFP April 2013 Author's Address Michael C. Thornburgh Adobe Systems Incorporated 345 Park Avenue San Jose, CA 95110-2704 US Phone: +1 408 536 6000 Email: mthornbu@adobe.com URI: http://www.adobe.com/ Thornburgh Expires October 17, 2013 [Page 105]