Tech-invite3GPPspaceIETFspace
959493929190898887868584838281807978777675747372717069686766656463626160595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100
in Index   Prev   Next

RFC 7016

Adobe's Secure Real-Time Media Flow Protocol

Pages: 113
Informational
Part 2 of 4 – Pages 13 to 44
First   Prev   Next

Top   ToC   RFC7016 - Page 13   prevText

2.2. Network Layer

2.2.1. Encapsulation

RTMFP Multiplex packets are usually carried in UDP [RFC0768] datagrams so that they may transit commonly deployed NATs and firewalls, and so that RTMFP may be implemented on commonly deployed operating systems without special privileges or permissions. RTMFP Multiplex packets MAY be carried by any suitable datagram transport or encapsulation where endpoints are addressed by an Internet socket address (that is, an IPv4 or IPv6 address and a 16-bit port number). The choice of port numbers is not mandated by this specification. Higher protocol layers or the application define the port numbers used.

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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Scrambled Session ID (SSID) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | e first32[0] | |- - - - - - n - - - - - - - - - - - - - - - - - - - - - - - -| | c first32[1] | +- - - - - - r - - - - - - - - - - - - - - - - - - - - - - - -+ | y | | pted packet | +---------------------------------------------------------------/ struct multiplex_t { uint32_t scrambledSessionID; // "SSID" union { uint32_t first32[2]; // see note uint8_t encryptedPacket[remainder()]; } :(encapsulation.length - 4)*8; // if encryptedPacket is less than 8 bytes long, treat it // as if it were end-padded with 0s for the following: sessionID = scrambledSessionID XOR first32[0] XOR first32[1]; } :encapsulation.length*8;
Top   ToC   RFC7016 - Page 14
   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
   the first two 32-bit words of the encrypted packet.

   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
   (Sections 2.3.7 and 2.3.8).  The session ID identifies the session to
   which this packet belongs and the decryption key to be used to
   decrypt the encrypted packet.

   Note: Session ID 0 (prior to scrambling) denotes the startup pseudo-
   session and implies the Default Session Key.

   Note: If the encrypted packet is less than 8 bytes long, then for the
   scrambling operation, perform the exclusive-or as though the
   encrypted packet were end-padded with enough 0-bytes to bring its
   length to 8.

2.2.3. Encryption

RTMFP packets are encrypted according to a Cryptography Profile. This specification doesn't define a Cryptography Profile or mandate a particular choice of cryptography. The application defines the cryptographic syntax and algorithms. Packet encryption is RECOMMENDED to be a block cipher operating in Cipher Block Chaining [CBC] or similar mode. Encrypted packets MUST be decipherable without inter-packet dependency, since packets may be lost, duplicated, or reordered in the network. The packet encryption layer is responsible for data integrity and authenticity of packets, for example by means of a checksum or cryptographic message authentication code. To mitigate replay attacks, data integrity SHOULD comprise duplicate packet detection, for example by means of a session-wide packet sequence number. The packet encryption layer SHALL discard a received packet that does not pass integrity or authenticity tests. Note that the structures described below are of plain, unencrypted packets. Encrypted packets MUST be decrypted according to the Session Key associated with the Multiplex Session ID before being interpreted according to this specification. The Cryptography Profile defines a well-known Default Session Key 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 the Default Session Key. The Default Session Key is also used with
Top   ToC   RFC7016 - Page 15
   non-zero session IDs during the latter phases of session startup
   (Sections 2.3.6 and 2.3.8).  See Security Considerations (Section 5)
   for more about the Default Session Key.

2.2.4. Packet

An (unencrypted, plain) RTMFP packet consists of a variable sized common header, zero or more chunks, and padding. Padding can be inserted by the encryption layer of the sender to meet cipher block size constraints and is ignored by the receiver. A sender's 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 for the cipher. Alternatively, the Cryptography Profile MAY define its own framing and padding scheme, if needed, such that decrypted packets are compatible with the syntax defined in this section.
Top   ToC   RFC7016 - Page 16
    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 |
   |C|C| s |S|S| O |
   | |R| v | |E| D |
   +-+-+-+-+-+-+-+-+
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   |        if(TS) timestamp       |     if(TSE) timestampEcho     |
   +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                             Chunk                             |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
                                   :
                                   :
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                             Chunk                             |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                            padding                            |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct packet_t
   {
       bool_t  timeCritical         :1; // "TC"
       bool_t  timeCriticalReverse  :1; // "TCR"
       uintn_t reserved             :2; // "rsv"
       bool_t  timestampPresent     :1; // "TS"
       bool_t  timestampEchoPresent :1; // "TSE"
       uintn_t mode                 :2; // "MOD"
       if(0 != mode)
       {
           if(timestampPresent)
               uint16_t timestamp;
           if(timestampEchoPresent)
               uint16_t timestampEcho;
           while(remainder() > 2)
           {
               uint8_t  chunkType;
               uint16_t chunkLength;
               if(remainder() < chunkLength)
                   break;
               uint8_t  chunkPayload[chunkLength];
           } // chunks
           uint8_t padding[remainder()];
       }
   } :plainPacket.length*8;
Top   ToC   RFC7016 - Page 17
   timeCritical:  Time Critical Forward Notification.  If set, indicates
      that this packet contains real-time user data.

   timeCriticalReverse:  Time Critical Reverse Notification.  If set,
      indicates that the sender is currently receiving packets on other
      sessions that have the timeCritical flag set.

   timestampPresent:  If set, indicates that the timestamp field is
      present.  If clear, there is no timestamp field.

   timestampEchoPresent:  If set, indicates that the timestamp echo
      field is present.  If clear, there is no timestamp echo field.

   mode:  The mode of this packet.  See below for additional discussion
      of packet modes.  Possible values are:

      0:    Forbidden value

      1:    Initiator Mark

      2:    Responder Mark

      3:    Startup

   timestamp:  If the timestampPresent flag is set, this field is
      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
      MAY have its origin at any time in the past.

   timestampEcho:  If the timestampEchoPresent flag is set, this field
      is present and contains the sender's estimate of what the
      timestamp field of a packet received from the other end would be
      at the time this packet was transmitted, using the method
      described in Section 3.5.2.2.

   chunks:  Zero or more chunks follow the header.  It is RECOMMENDED
      that a packet contain at least one chunk.

   padding:  Zero or more bytes of padding follow the chunks.  The
      following conditions indicate padding:

      *  Fewer than three bytes (the size of a chunk header) remain in
         the packet.

      *  The chunkLength field of what would be the current chunk header
         indicates that the hypothetical chunk payload wouldn't fit in
         the remaining bytes of the packet.
Top   ToC   RFC7016 - Page 18
   Packet mode 0 is not allowed.  Packets marked with this mode are
   invalid and MUST be discarded.

   The original initiator of a session MUST mark all non-startup packets
   it sends in that session with packet mode 1 ("Initiator Mark").  It
   SHOULD ignore any packet received in that session with packet mode 1.

   The original responder of a session MUST mark all non-startup packets
   it sends in that session with packet mode 2 ("Responder Mark").  It
   SHOULD ignore any packet received in that session with packet mode 2.

   Packet mode 3 is for session startup.  Session startup chunks are
   only allowed in packets with this mode.

   Chunks that are not for session startup are only allowed in packets
   with modes 1 or 2.

2.3. Chunks

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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | chunkType | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | chunkPayload (chunkLength bytes, may be zero) | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct chunk_t { uint8_t chunkType; uint16_t chunkLength; uint8_t chunkPayload[chunkLength]; } :variable*8; chunkType: The chunk type code. chunkLength: The size, in bytes, of the chunk payload. chunkPayload: The type-specific payload of this chunk, chunkLength bytes in length (may be empty).
Top   ToC   RFC7016 - Page 19
   Defined chunk types are enumerated here in the order they might be
   encountered in the course of a typical session.  The following chunk
   type codes are defined:

   0x7f:  Packet Fragment (Section 2.3.1)

   0x30:  Initiator Hello (Section 2.3.2)

   0x0f:  Forwarded Initiator Hello (Section 2.3.3)

   0x70:  Responder Hello (Section 2.3.4)

   0x71:  Responder Redirect (Section 2.3.5)

   0x79:  RHello Cookie Change (Section 2.3.6)

   0x38:  Initiator Initial Keying (Section 2.3.7)

   0x78:  Responder Initial Keying (Section 2.3.8)

   0x01:  Ping (Section 2.3.9)

   0x41:  Ping Reply (Section 2.3.10)

   0x10:  User Data (Section 2.3.11)

   0x11:  Next User Data (Section 2.3.12)

   0x50:  Data Acknowledgement Bitmap (Section 2.3.13)

   0x51:  Data Acknowledgement Ranges (Section 2.3.14)

   0x18:  Buffer Probe (Section 2.3.15)

   0x5e:  Flow Exception Report (Section 2.3.16)

   0x0c:  Session Close Request (Section 2.3.17)

   0x4c:  Session Close Acknowledgement (Section 2.3.18)

   0x00:  Ignore/Padding

   0xff:  Ignore/Padding

   A receiver MUST ignore a chunk having an unrecognized chunk type
   code.  A receiver MUST ignore a chunk appearing in a packet having a
   mode inappropriate to that chunk type.
Top   ToC   RFC7016 - Page 20
   Unless specified otherwise, if a chunk has a syntax or processing
   error (for example, the chunk's payload field is not long enough to
   contain the specified syntax elements), the chunk SHALL be ignored as
   though it was not present in the packet, and parsing and processing
   SHALL commence with the next chunk in the packet, if any.

2.3.1. Packet Fragment Chunk

This chunk is used to divide a plain RTMFP packet (Section 2.2.4) that is unavoidably larger than the path MTU (such as session startup packets containing Responder Hello (Section 2.3.4) or Initiator Initial Keying (Section 2.3.7) chunks with large certificates) into segments that do not exceed the path MTU, and to allow the segments to be sent through the network at a moderated rate to avoid jamming interfaces, links, or paths. 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x7f | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-------------/-+-------------/-+ |M| reserved | packetID \ | fragmentNum \ | +-+-+-+-+-+-+-+-+-------------/-+-------------/-+ +---------------------------------------------------------------+ | packetFragment | +---------------------------------------------------------------/ struct fragmentChunkPayload_t { bool_t moreFragments :1; // M uintn_t reserved :7; vlu_t packetID :variable*8; vlu_t fragmentNum :variable*8; uint8_t packetFragment[remainder()]; } :chunkLength*8; moreFragments: If set, the indicated packet comprises additional fragments. If clear, this fragment is the final fragment of the packet. reserved: Reserved for future use. packetID: VLU, the identifier of this segmented packet. All fragments of the same packet have the same packetID. fragmentNum: VLU, the index of this fragment of the indicated packet. The first fragment of the packet MUST be index 0. Fragments are numbered consecutively.
Top   ToC   RFC7016 - Page 21
   packetFragment:  The bytes of the indicated segment of the indicated
      original plain RTMFP packet.  A packetFragment MUST NOT be empty.

   The use of this mechanism is detailed in Section 3.4.

2.3.2. Initiator Hello Chunk (IHello)

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 Session ID 0, encrypted 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x30 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | epdLength \ | endpointDiscriminator (epdLength bytes) | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | tag | +---------------------------------------------------------------/ struct ihelloChunkPayload_t { vlu_t epdLength :variable*8; uint8_t endpointDiscriminator[epdLength]; uint8_t tag[remainder()]; } :chunkLength*8; epdLength: VLU, the length of the following endpointDiscriminator field in bytes. endpointDiscriminator: The Endpoint Discriminator for the identity with which the initiator wants to communicate. tag: Initiator-provided data to be returned in a Responder Hello's tagEcho field. The tag/tagEcho is used to match Responder Hellos to the initiator's session startup state independent of the responder's address. The use of IHello is detailed in Section 3.5.1.
Top   ToC   RFC7016 - Page 22

2.3.3. Forwarded Initiator Hello Chunk (FIHello)

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 1 or 2. A receiver MAY treat this chunk as though it was an Initiator Hello received directly from replyAddress. Alternatively, if the receiver is selected by the Endpoint Discriminator, it MAY 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0f | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | epdLength \ | endpointDiscriminator (epdLength bytes) | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | replyAddress | +---------------------------------------------------------------/ +---------------------------------------------------------------+ | tag | +---------------------------------------------------------------/ struct fihelloChunkPayload_t { vlu_t epdLength :variable*8; uint8_t endpointDiscriminator[epdLength]; address_t replyAddress :variable*8; uint8_t tag[remainder()]; } :chunkLength*8; epdLength: VLU, the length of the following endpointDiscriminator field in bytes. endpointDiscriminator: The Endpoint Discriminator for the identity with which the original initiator wants to communicate, copied from the original Initiator Hello. replyAddress: Address format (Section 2.1.5), the address that the forwarding node derived from the received Initiator Hello, to which the receiver should respond. tag: Copied from the original Initiator Hello. The use of FIHello is detailed in Section 3.5.1.5.
Top   ToC   RFC7016 - Page 23

2.3.4. Responder Hello Chunk (RHello)

This chunk is sent by a responder in response to an Initiator Hello or Forwarded Initiator Hello if the Endpoint Discriminator indicates the responder's identity. This chunk is only allowed in a packet with Session ID 0, encrypted 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x70 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | tagLength \ | tagEcho (tagLength bytes) | +-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------+ | cookieLength\ | cookie (cookieLength bytes) | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | responderCertificate | +---------------------------------------------------------------/ struct rhelloChunkPayload_t { vlu_t tagLength :variable*8; uint8_t tagEcho[tagLength]; vlu_t cookieLength :variable*8; uint8_t cookie[cookieLength]; uint8_t responderCertificate[remainder()]; } :chunkLength*8; tagLength: VLU, the length of the following tagEcho field in bytes. tagEcho: The tag from the Initiator Hello, unaltered. cookieLength: VLU, the length of the following cookie field in bytes. cookie: Responder-created state data to authenticate a future Initiator Initial Keying message (in order to prevent denial-of- service attacks). responderCertificate: The responder's cryptographic credentials.
Top   ToC   RFC7016 - Page 24
   Note: This specification doesn't mandate a specific choice of
   certificate format.  The Cryptography Profile determines the syntax,
   algorithms, and interpretation of the responderCertificate.

   The use of RHello is detailed in Section 3.5.1.

2.3.5. Responder Redirect Chunk (Redirect)

This chunk is sent in response to an Initiator Hello or Forwarded Initiator Hello to indicate that the requested endpoint can be reached at one or more of the indicated addresses. A receiver can add none, some, or all of the indicated addresses to the set of addresses to which it is sending Initiator Hello messages for the opening session associated with tagEcho. This chunk is only allowed in a packet with Session ID 0, encrypted with the Default Session Key, and having packet mode 3 (Startup).
Top   ToC   RFC7016 - Page 25
    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          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   +-------------/-+-----------------------------------------------+
   |  tagLength  \ |            tagEcho (tagLength bytes)          |
   +-------------/-+-----------------------------------------------/
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                     redirectDestination 1                     |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
                                   :
                                   :
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
   |                     redirectDestination N                     |
   +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/

   struct responderRedirectChunkPayload_t
   {
       vlu_t   tagLength :variable*8;
       uint8_t tagEcho[tagLength];
       addressCount = 0;
       while(remainder() > 0)
       {
           address_t redirectDestination :variable*8;
           addressCount++;
       }
       if(0 == addressCount)
           redirectDestination = packetSourceAddress();
   } :chunkLength*8;

   tagLength:  VLU, the length of the following tagEcho field in bytes.

   tagEcho:  The tag from the Initiator Hello, unaltered.

   redirectDestination:  (Zero or more) Address format (Section 2.1.5)
      addresses to add to the opening set for the indicated session.

   If this chunk lists zero redirectDestination addresses, then this is
   an Implied Redirect, and the indicated address is the address from
   which the packet containing this chunk was received.

   The use of Redirect is detailed in Sections 3.5.1.1.1, 3.5.1.1.2,
   and 3.5.1.4.
Top   ToC   RFC7016 - Page 26

2.3.6. RHello Cookie Change Chunk

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 been created by the responder but the cookie is incorrect (for example, it includes a hash of the initiator's address, but the initiator's address is different than the one that elicited the Responder Hello containing the original cookie). This chunk is only allowed in a packet encrypted with the Default Session Key and having packet mode 3, and with the session ID indicated in the initiatorSessionID field of the Initiator Initial 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x79 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | oldCookieLen\ | oldCookie (oldCookieLen bytes) | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | newCookie | +---------------------------------------------------------------/ struct rhelloCookieChangeChunkPayload_t { vlu_t oldCookieLen :variable*8; uint8_t oldCookie[oldCookieLen]; uint8_t newCookie[remainder()]; } :chunkLength*8; oldCookieLen: VLU, the length of the following oldCookie field in bytes. oldCookie: The cookie that was sent in a previous Responder Hello and Initiator Initial Keying. newCookie: The new cookie that the responder would like sent (and signed) in a replacement Initiator Initial Keying. The old and new cookies need not have the same lengths. On receipt of this chunk, the initiator SHOULD compute, sign, and 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.
Top   ToC   RFC7016 - Page 27

2.3.7. Initiator Initial Keying Chunk (IIKeying)

This chunk is sent by an initiator to establish a session with a responder. The initiator MUST have obtained a valid cookie to use with the responder, typically by receiving a Responder Hello from it. This chunk is only allowed in a packet with Session ID 0, encrypted 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x38 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | initiatorSessionID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | cookieLength\ | cookieEcho | +-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------+ | certLength \ | initiatorCertificate | +-------------/-+-----------------------------------------------/ +-------------/-+-----------------------------------------------+ | skicLength \ | sessionKeyInitiatorComponent | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | signature | +---------------------------------------------------------------/ struct iikeyingChunkPayload_t { struct { uint32_t initiatorSessionID; vlu_t cookieLength :variable*8; uint8_t cookieEcho[cookieLength]; vlu_t certLength :variable*8; uint8_t initiatorCertificate[certLength]; vlu_t skicLength :variable*8; uint8_t sessionKeyInitiatorComponent[skicLength]; } initiatorSignedParameters :variable*8; uint8_t signature[remainder()]; } :chunkLength*8; initiatorSessionID: The session ID to be used by the responder when sending packets to the initiator.
Top   ToC   RFC7016 - Page 28
   cookieLength:  VLU, the length of the following cookieEcho field
      in bytes.

   cookieEcho:  The cookie from the Responder Hello, unaltered.

   certLength:  VLU, the length of the following initiatorCertificate
      field in bytes.

   initiatorCertificate:  The initiator's identity credentials.

   skicLength:  VLU, the length of the following
      sessionKeyInitiatorComponent field in bytes.

   sessionKeyInitiatorComponent:  The initiator's portion of the session
      key negotiation according to the Cryptography Profile.

   initiatorSignedParameters:  The payload portion of this chunk up to
      the signature field.

   signature:  The initiator's digital signature of the
      initiatorSignedParameters according to the Cryptography Profile.

   Note: This specification doesn't mandate a specific choice of
   cryptography.  The Cryptography Profile determines the syntax,
   algorithms, and interpretation of the initiatorCertificate,
   responderCertificate, sessionKeyInitiatorComponent,
   sessionKeyResponderComponent, and signature, and how the
   sessionKeyInitiatorComponent and sessionKeyResponderComponent are
   combined to derive the session keys.

   The use of IIKeying is detailed in Section 3.5.1.
Top   ToC   RFC7016 - Page 29

2.3.8. Responder Initial Keying Chunk (RIKeying)

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 allowed in a packet encrypted with the Default Session Key, having packet mode 3 (Startup), and sent to the initiator with the session ID specified by the initiatorSessionID field from the 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x78 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | responderSessionID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-----------------------------------------------+ | skrcLength \ | sessionKeyResponderComponent | +-------------/-+-----------------------------------------------/ +---------------------------------------------------------------+ | signature | +---------------------------------------------------------------/ struct rikeyingChunkPayload_t { struct { uint32_t responderSessionID; vlu_t skrcLength :variable*8; uint8_t sessionKeyResponderComponent[skrcLength]; } responderSignedParametersPortion :variable*8; uint8_t signature[remainder()]; } :chunkLength*8; struct { responderSignedParametersPortion; sessionKeyInitiatorComponent; } responderSignedParameters; responderSessionID: The session ID to be used by the initiator when sending packets to the responder. skrcLength: VLU, the length of the following sessionKeyResponderComponent field in bytes. sessionKeyResponderComponent: The responder's portion of the session key negotiation according to the Cryptography Profile.
Top   ToC   RFC7016 - Page 30
   responderSignedParametersPortion:  The payload portion of this chunk
      up to the signature field.

   signature:  The responder's digital signature of the
      responderSignedParameters (see below) according to the
      Cryptography Profile.

   responderSignedParameters:  The concatenation of the
      responderSignedParametersPortion (the payload portion of this
      chunk up to the signature field) and the
      sessionKeyInitiatorComponent from the Initiator Initial Keying to
      which this chunk is a response.

   Note: This specification doesn't mandate a specific choice of
   cryptography.  The Cryptography Profile determines the syntax,
   algorithms, and interpretation of the initiatorCertificate,
   responderCertificate, sessionKeyInitiatorComponent,
   sessionKeyResponderComponent, and signature, and how the
   sessionKeyInitiatorComponent and sessionKeyResponderComponent are
   combined to derive the session keys.

   Once the responder has computed the sessionKeyResponderComponent, it
   has all of the information and state necessary for an established
   session with the initiator.  Once the responder has sent this chunk
   to the initiator, the session is established and ready to carry flows
   of user data.

   Once the initiator receives, verifies, and processes this chunk, it
   has all of the information and state necessary for an established
   session with the responder.  The session is established and ready to
   carry flows of user data.

   The use of RIKeying is detailed in Section 3.5.1.
Top   ToC   RFC7016 - Page 31

2.3.9. Ping Chunk

This chunk is sent in order to elicit a Ping Reply from the receiver. It is only allowed in a packet belonging to an established 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x01 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | message | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct pingChunkPayload_t { uint8_t message[chunkLength]; } :chunkLength*8; message: The (potentially empty) message that is expected to be returned by the other end of the session in a Ping Reply. The receiver of this chunk SHOULD reply as immediately as is practical with a Ping Reply. Ping and the expected Ping Reply are typically used for session keepalive, endpoint address change verification, and path MTU discovery. See Section 3.5.4 for details.
Top   ToC   RFC7016 - Page 32

2.3.10. Ping Reply Chunk

This chunk is sent in response to a Ping chunk. It is only allowed in a packet belonging to an established 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x41 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | messageEcho | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct pingReplyChunkPayload_t { uint8_t messageEcho[chunkLength]; } :chunkLength*8; messageEcho: The message from the Ping to which this is a response, unaltered.
Top   ToC   RFC7016 - Page 33

2.3.11. User Data Chunk

This chunk is the basic unit of transmission for the user messages of a flow. A user message comprises one or more fragments. Each 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 established 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x10 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |O|r| F | r |A|F| |P|s| R | s |B|I| |T|v| A | v |N|N| +-+-+-+-+-+-+-+-+ +-------------/-+-------------/-+-------------/-+ | flowID \ | seq# \ | fsnOffset \ | +-------------/-+-------------/-+-------------/-+ +~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+ | L \ T \ V |... options ...| L \ T \ V | 0 \ | \~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | userData | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct userDataChunkPayload_t { bool_t optionsPresent :1; // "OPT" uintn_t reserved1 :1; // "rsv" uintn_t fragmentControl :2; // "FRA" // 0=whole, 1=begin, 2=end, 3=middle uintn_t reserved2 :2; // "rsv" bool_t abandon :1; // "ABN" bool_t final :1; // "FIN" vlu_t flowID :variable*8; vlu_t sequenceNumber :variable*8; // "seq#" vlu_t fsnOffset :variable*8; forwardSequenceNumber = sequenceNumber - fsnOffset; if(optionsPresent) optionList_t options :variable*8; uint8_t userData[remainder()]; } :chunkLength*8; optionsPresent: If set, indicates the presence of an option list before the user data. If clear, there is no option list in this chunk.
Top   ToC   RFC7016 - Page 34
   fragmentControl:  Indicates how this fragment is assembled,
      potentially with others, into a complete user message.  Possible
      values:

      0:    This fragment is a complete message.

      1:    This fragment is the first 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.

      A single-fragment user message has a fragment control of
      "0-whole".  When a message has more than one fragment, the first
      fragment has a fragment control of "1-begin", then zero or more
      "3-middle" fragments, and finally a "2-end" fragment.  The
      sequence numbers of a multi-fragment message MUST be contiguous.

   abandon:  If set, this sequence number has been abandoned by the
      sender.  The userData, if any, MUST be ignored.

   final:  If set, this is the last sequence number of the flow.

   flowID:  VLU, the flow identifier.

   sequenceNumber:  VLU, the sequence number of this fragment.
      Fragments are assigned contiguous increasing sequence numbers in a
      flow.  The first sequence number of a flow SHOULD be 1.  The first
      sequence number of a flow MUST be greater than zero.  Sequence
      numbers are unbounded and do not wrap.

   fsnOffset:  VLU, the difference between the sequence number and the
      Forward Sequence Number.  This field MUST NOT be zero if the
      abandon flag is not set.  This field MUST NOT be greater than
      sequenceNumber.

   forwardSequenceNumber:  The flow sender will not send (or resend) any
      fragment with a sequence number less than or equal to the Forward
      Sequence Number.

   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
      for defined options.

   userData:  The actual user data for this fragment.

   The use of User Data is detailed in Section 3.6.2.
Top   ToC   RFC7016 - Page 35
2.3.11.1. Options for User Data
This section lists options that may appear in User Data option lists. A conforming implementation MUST support the options in this section. 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 receiver MUST ignore any flow option that is not understood if the option type is 8192 or greater. The following option type codes are defined for User Data: 0x00: User's Per-Flow Metadata (Section 2.3.11.1.1) 0x0a: Return Flow Association (Section 2.3.11.1.2)
2.3.11.1.1. User's Per-Flow Metadata
This option conveys the user's per-flow metadata for the flow to which it's attached. +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | length \ | 0x00 \ | userMetadata | +-------------/-+-------------/-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct userMetadataOptionValue_t { uint8_t userMetadata[remainder()]; } :remainder()*8; The user associates application-defined metadata with each flow. The metadata does not change over the life of the flow. Every flow MUST have metadata. A flow sender MUST send this option with the first User Data chunk for this flow in each packet 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 packet. A flow sender SHOULD NOT send this option for a flow once the flow has been acknowledged. This specification doesn't mandate the encoding, syntax, or interpretation of the user's per-flow metadata; this is determined by the application. The userMetadata SHOULD NOT exceed 512 bytes. The userMetadata MAY be 0 bytes in length.
Top   ToC   RFC7016 - Page 36
2.3.11.1.2. Return Flow Association
A new flow can be considered to be in return (or response) to a flow sent by the other endpoint. This option encodes the receive flow identifier to which this new sending flow is a response. +-------------/-+-------------/-+-------------/-+ | length \ | 0x0a \ | flowID \ | +-------------/-+-------------/-+-------------/-+ struct returnFlowAssociationOptionValue_t { vlu_t flowID :variable*8; } :variable*8; Consider endpoints A and B. Endpoint A begins a flow with identifier 5 to endpoint B. A is the flow sender for A's flowID=5, and B is the flow receiver for A's flowID=5. B begins a return flow with identifier 7 to A in response to A's flowID=5. B is the flow sender for B's flowID=7, and A is the flow receiver for B's flowID=7. B sends this option with flowID set to 5 to indicate that B's 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 option with the first User Data chunk for this flow in each packet 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 packet. A flow sender SHOULD NOT send this option for a flow once the flow has been acknowledged. A flow MUST NOT indicate more than one return association. A flow MUST indicate its return association, if any, upon its first transmission of a User Data chunk. A return association can't be added to a sending flow after it begins. A flow receiver MUST reject a new receiving flow having a return flow association that does not indicate an F_OPEN sending flow.
Top   ToC   RFC7016 - Page 37

2.3.12. Next User Data Chunk

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 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x11 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ |O|r| F | r |A|F| |P|s| R | s |B|I| |T|v| A | v |N|N| +-+-+-+-+-+-+-+-+ +~~~/~~~/~~~~~~~+ +~~~/~~~/~~~~~~~+-------------/-+ | L \ T \ V |... options ...| L \ T \ V | 0 \ | \~~~/~~~/~~~~~~~+ [if(OPT)] +~~~/~~~/~~~~~~~+-------------/-/ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | userData | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/ struct nextUserDataChunkPayload_t { bool_t optionsPresent :1; // "OPT" uintn_t reserved1 :1; // "rsv" uintn_t fragmentControl :2; // "FRA" // 0=whole, 1=begin, 2=end, 3=middle uintn_t reserved2 :2; // "rsv" bool_t abandon :1; // "ABN" bool_t final :1; // "FIN" if(optionsPresent) optionList_t options :variable*8; uint8_t userData[remainder()]; } :chunkLength*8; 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 packet, having the same Forward Sequence Number, and having the next sequence number. The optionsPresent, fragmentControl, abandon, and final flags, and the options (if present), have the same interpretation as for the User Data chunk.
Top   ToC   RFC7016 - Page 38
               ...
               ----------+------------------------------------
               10 00 07  | User Data chunk, length=7
               00        | OPT=0, FRA=0 "whole", ABN=0, FIN=0
               02 05 03  | flowID=2, seq#=5, fsn=(5-3)=2
               00 01 02  | data 3 bytes: 00, 01, 02
               ----------+------------------------------------
               11 00 04  | Next User Data chunk,length=4
               00        | OPT=0, FRA=0 "whole", ABN=0, FIN=0
                         | flowID=2, seq#=6, fsn=2
               03 04 05  | data 3 bytes: 03, 04, 05
               ----------+------------------------------------
               11 00 04  | Next User Data chunk, length=4
               00        | OPT=0, FRA=0 "whole", ABN=0, FIN=0
                         | flowID=2, seq#=7, fsn=2
               06 07 08  | data 3 bytes: 06, 07, 08
               ----------+------------------------------------

     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.
Top   ToC   RFC7016 - Page 39

2.3.13. Data Acknowledgement Bitmap Chunk (Bitmap Ack)

This chunk is sent by the flow receiver to indicate to the flow sender the User Data fragment sequence numbers that have been received for one flow. It is only allowed in a packet belonging to an established session and having packet mode 1 or 2. 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 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x50 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-------------/-+-------------/-+ | flowID \ | bufAvail \ | cumAck \ | +-------------/-+-------------/-+-------------/-+ +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ |C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C|C| |+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+|+| |9|8|7|6|5|4|3|2|1|1|1|1|1|1|1|1|2|2|2|2|2|2|1|1| .... | | | | | | | | |7|6|5|4|3|2|1|0|5|4|3|2|1|0|9|8| +~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+~+ struct dataAckBitmapChunkPayload_t { vlu_t flowID :variable*8; vlu_t bufferBlocksAvailable :variable*8; // "bufAvail" vlu_t cumulativeAck :variable*8; // "cumAck" bufferBytesAvailable = bufferBlocksAvailable * 1024; acknowledge(0 through cumulativeAck); ackCursor = cumulativeAck + 1; while(remainder() > 0) { for(bitPosition = 8; bitPosition > 0; bitPosition--) { bool_t bit :1; if(bit) acknowledge(ackCursor + bitPosition); } ackCursor += 8; } } :chunkLength*8;
Top   ToC   RFC7016 - Page 40
   flowID:  VLU, the flow identifier.

   bufferBlocksAvailable:  VLU, the number of 1024-byte blocks of User
      Data that the receiver is currently able to accept.
      Section 3.6.3.5 describes how to calculate this value.

   cumulativeAck:  VLU, the acknowledgement of every fragment sequence
      number in this flow that is less than or equal to this value.
      This MUST NOT be less than the highest Forward Sequence Number
      received in this flow.

   bit field:  A sequence of zero or more bytes representing a bit field
      of received fragment sequence numbers after the cumulative
      acknowledgement, least significant bit first.  A set bit indicates
      receipt of a sequence number.  A clear bit indicates that sequence
      number was not received.  The least significant bit of the first
      byte is the second sequence number following the cumulative
      acknowledgement, the next bit is the third sequence number
      following, and so on.

      Figure 4 shows an example Bitmap Ack indicating acknowledgement of
      fragment sequence numbers 0 through 16, 18, 21 through 24, 27,
      and 28.

         50 00 05  | Bitmap Ack, length=5 bytes
         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: Example Bitmap Ack
Top   ToC   RFC7016 - Page 41

2.3.14. Data Acknowledgement Ranges Chunk (Range Ack)

This chunk is sent by the flow receiver to indicate to the flow sender the User Data fragment sequence numbers that have been received for one flow. It is only allowed in a packet belonging to an established session and having packet mode 1 or 2. 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 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x51 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-------------/-+-------------/-+ | flowID \ | bufAvail \ | cumAck \ | +-------------/-+-------------/-+-------------/-+ +~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+ | #holes-1 \ | #recv-1 \ | +~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+ : : +~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+ | #holes-1 \ | #recv-1 \ | +~~~~~~~~~~~~~/~+~~~~~~~~~~~~~/~+ struct dataAckRangesChunkPayload_t { vlu_t flowID :variable*8; vlu_t bufferBlocksAvailable :variable*8; // "bufAvail" vlu_t cumulativeAck :variable*8; // "cumAck" bufferBytesAvailable = bufferBlocksAvailable * 1024; acknowledge(0 through cumulativeAck); ackCursor = cumulativeAck; while(remainder() > 0) { vlu_t holesMinusOne :variable*8; // "#holes-1" vlu_t receivedMinusOne :variable*8; // "#recv-1" ackCursor++; rangeFrom = ackCursor + holesMinusOne + 1; rangeTo = rangeFrom + receivedMinusOne; acknowledge(rangeFrom through rangeTo); ackCursor = rangeTo; } } :chunkLength*8;
Top   ToC   RFC7016 - Page 42
   flowID:  VLU, the flow identifier.

   bufferBlocksAvailable:  VLU, the number of 1024-byte blocks of User
      Data that the receiver is currently able to accept.
      Section 3.6.3.5 describes how to calculate this value.

   cumulativeAck:  VLU, the acknowledgement of every fragment sequence
      number in this flow that is less than or equal to this value.
      This MUST NOT be less than the highest Forward Sequence Number
      received in this flow.

   holesMinusOne / receivedMinusOne:  Zero or more acknowledgement
      ranges, run-length encoded.  Runs are encoded as zero or more
      pairs of VLUs indicating the number (minus one) of missing
      sequence numbers followed by the number (minus one) of received
      sequence numbers, starting at the cumulative acknowledgement.
      NOTE: If a parser syntax error is encountered here (that is, if
      the chunk is truncated such that not enough bytes remain to
      completely encode both VLUs of the acknowledgement range), then
      treat and process this chunk as though it was properly formed up
      to the last completely encoded range.

      Figure 5 shows an example Range Ack indicating acknowledgement of
      fragment sequence numbers 0 through 16, 18, 21, 22, 23, and 24.

      51 00 07  | Range Ack, length=7
      05 7f 10  | flowID=5, bufAvail=127*1024 bytes, cumAck=0..16
      00 00     | holes=1, received=1 -- missing 17, received 18
      01 03     | holes=2, received=4 -- missing 19..20, received 21..24

                        Figure 5: Example Range Ack

      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
Top   ToC   RFC7016 - Page 43

2.3.15. Buffer Probe Chunk

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 a flow. It is only allowed in a packet belonging to an established 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x18 | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+ | flowID \ | +-------------/-+ struct bufferProbeChunkPayload_t { vlu_t flowID :variable*8; } :chunkLength*8; flowID: VLU, the flow identifier. The receiver of this chunk SHOULD reply as immediately as is practical with a Data Acknowledgement.

2.3.16. Flow Exception Report Chunk

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 sender to close the flow. This chunk SHOULD precede every Data Acknowledgement chunk for the same flow in this condition. This chunk is only allowed in a packet belonging to an established 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x5e | chunkLength | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +-------------/-+-------------/-+ | flowID \ | exception \ | +-------------/-+-------------/-+ struct flowExceptionReportChunkPayload_t { vlu_t flowID :variable*8; vlu_t exception :variable*8; } :chunkLength*8;
Top   ToC   RFC7016 - Page 44
   flowID:  VLU, the flow identifier.

   exception:  VLU, the application-defined exception code being
      reported.

   A receiving RTMFP might reject a flow automatically, for example if
   it is missing metadata, or if an invalid return association is
   specified.  In circumstances where an RTMFP rejects a flow
   automatically, the exception code MUST be 0.  The application can
   specify any exception code, including 0, when rejecting a flow.  All
   non-zero exception codes are reserved for the application.

2.3.17. Session Close Request Chunk (Close)

This chunk is sent to cleanly terminate a session. It is only allowed in a packet belonging to an established or closing 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x0c | 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ This chunk has no payload. The use of Close is detailed in Section 3.5.5.

2.3.18. Session Close Acknowledgement Chunk (Close Ack)

This chunk is sent in response to a Session Close Request to indicate that the sender has terminated the session. It is only allowed in a packet belonging to an established or closing 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 0x4c | 0 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ This chunk has no payload. The use of Close Ack is detailed in Section 3.5.5.


(next page on part 3)

Next Section