Constrained Application Protocol (CoAP) Block-Wise Transfer Options Supporting Robust Transmission
Extracted elements (29)
Q-Block options were introduced to fill a gap in RFC 7959: block-wise transfers using Non-confirmable messages where an entire body can be sent without requiring intermediate acknowledgments. The primary target is DDoS mitigation signaling (DOTS, RFC 9132) where 'flooded pipe' conditions make CON-based lock-stepping impractical.
The default value of MAX_PAYLOADS is 10, chosen for reasons similar to RFC 6928's initial window size recommendation, balancing throughput with congestion risk given the primary DOTS use case.
Q-Block1 and Q-Block2 options are not a replacement for Block1 and Block2. If a peer does not support Q-Block options, transmissions fall back to using Block1 and Block2. Mixing Q-Block and Block options (CON vs NON, stateless access, multicast) is not supported.
There is little benefit to using Q-Block options over reliable transports (RFC 8323, e.g., CoAP over TCP/TLS/WebSockets) since CON/NON distinctions do not apply. Using Q-Block1/2 with NoSec mode is NOT RECOMMENDED because the source endpoint cannot be trusted and intermediaries may manipulate unprotected Outer options.
A 4.00 (Bad Request) MUST be returned if a request includes a Q-Block1 option but omits either the Request-Tag option or the Size1 option.
A CoAP endpoint (or proxy) MUST support either both or neither of the Q-Block1 and Q-Block2 options; partial support is not allowed.
After transmitting every MAX_PAYLOADS_SET of a single body, a delay of NON_TIMEOUT_RANDOM MUST be introduced before sending the next set, unless a 'Continue' is received from the peer for the current set, in which case the next set MAY start immediately.
If Q-Block1 or Q-Block2 options are included as OSCORE Inner options, the Block1 or Block2 options MUST NOT also be included as Inner options, and there MUST NOT be a mix of Q-Block and Block Outer options. Messages violating this MUST be rejected with 4.02 (Bad Option).
Servers MUST ignore multicast requests that contain the Q-Block2 option; the Block2 option may be used for multicast as specified in RFC 7959.
The Size1 option MUST be used with Q-Block1 in all request payloads preserving the same value; the Size2 option MUST be used with Q-Block2 in all response payloads preserving the same value. Both must exactly represent the body size so missing data can be determined.
The transmission of all blocks of a single body over an unreliable transport MUST either all be Confirmable or all be Non-confirmable; mixing CON and NON within a single Q-Block exchange is not permitted.
To indicate support for Q-Block2 responses, the CoAP client MUST include the Q-Block2 option in a GET/FETCH or the Q-Block1 option in a PUT/POST so the server knows to use Q-Block2 for large response bodies instead of falling back to Block2.
To reliably detect whether a peer supports Q-Block options, clients MUST use a Confirmable message for the capability probe, since NON messages with unrecognized critical options may be silently ignored rather than rejected.
When using the Q-Block1 option, the client MUST include a Request-Tag option (RFC 9175) with the same value for all payloads of a given body, and MUST ensure the Request-Tag is unique for every distinct body transmitted.
For Q-Block1 and Q-Block2, the Observe option value MUST be the same for all payloads of the same body (including retransmitted missing payloads). This differs from Block2 where Observe appears only in the first block. Missing-block requests and responses MUST NOT include the Observe option.
For Q-Block2, the server MUST ensure all payloads for the same body share the same ETag value, and MUST NOT reuse the same ETag for different resource representations. If the ETag changes mid-transfer, the client should discard the partial old-ETag body and may re-request from block 0.
MAX_PAYLOADS is the maximum number of payloads that can be transmitted at any one time (default 10). Both CoAP endpoints MUST have the same value and it MAY be negotiated via a higher-level protocol. MAX_PAYLOADS_SET is the corresponding set of block numbers whose block number divided by MAX_PAYLOADS yields the same integer result.
Seven new congestion control parameters are introduced for NON transmission: MAX_PAYLOADS (10), NON_TIMEOUT (2 s), NON_TIMEOUT_RANDOM (2–3 s), NON_RECEIVE_TIMEOUT (4 s), NON_MAX_RETRANSMIT (4), NON_PROBING_WAIT (247–248 s), and NON_PARTIAL_TIMEOUT (247 s).
The 4.08 (Request Entity Incomplete) response with content type 'application/missing-blocks+cbor-seq' carries a CBOR Sequence of unique unsigned integers identifying the missing block numbers. The Content-Format option MUST be set to this type and the blocks MUST be listed in ascending order without duplicates.
The 'Continue' Q-Block2 request has M bit set with 'NUM modulo MAX_PAYLOADS' equal to zero (and NUM non-zero). It confirms that the previous MAX_PAYLOADS_SET was fully received and instructs the server to continue sending the next set without waiting for the NON_TIMEOUT_RANDOM delay.
The Q-Block1 option (number 19) and Q-Block2 option (number 31) are CoAP block-wise transfer options designed for Non-confirmable (NON) messages. Q-Block1 pertains to request payloads; Q-Block2 pertains to response payloads. Both are Critical and UnSafe; Q-Block2 is also Repeatable.
IANA has added Q-Block1 (number 19) and Q-Block2 (number 31) to the 'CoAP Option Numbers' subregistry within the 'Constrained RESTful Environments (CoRE) Parameters' registry.
IANA has registered media type 'application/missing-blocks+cbor-seq' in the 'Media Types' registry and assigned CoAP Content-Format ID 272 in the 'CoAP Content-Formats' registry for reporting missing blocks in Q-Block1 transfers.
An intermediary node can modify unprotected Outer Q-Block1/Q-Block2 options to cause a transfer to fail or to force re-requesting all blocks by setting the M bit, enabling amplification attacks. Using OSCORE does not fully protect against this because Outer options remain visible to proxies. It is NOT RECOMMENDED to use NoSec mode with Q-Block options.
If a Q-Block2 request includes multiple overlapping options (e.g., M bit set and unset for the same block), the server MUST only send back one instance of that block to prevent amplification attacks.
For Q-Block1 server-side recovery: server waits NON_RECEIVE_TIMEOUT (exponentially scaled) after the last received payload or after sending 2.31 (Continue), then sends 4.08 listing missing blocks. After NON_MAX_RETRANSMIT retries without response, server discards the partial body and stops requesting missing payloads.
For Q-Block2 missing block recovery: client waits NON_RECEIVE_TIMEOUT after last received payload, then requests missing blocks via GET/FETCH with one or more Q-Block2 options. Each re-request doubles the wait (Time-to-Wait = NON_RECEIVE_TIMEOUT * 2^(Re-Request-Count − 1)). After NON_MAX_RETRANSMIT failures, client discards the partial body.
Q-Block1 (option number 19) and Q-Block2 (option number 31) are encoded as unsigned integers of 0–3 bytes with no default value. The structure mirrors the Block1/Block2 option from RFC 7959, comprising a block number (NUM), a More bit (M), and a size exponent (SZX).
The missing-blocks payload is a CBOR Sequence (RFC 8742) of one or more CBOR unsigned integers representing missing block numbers. CDDL: `payload = [+ missing-block-number]` where `missing-block-number = uint`.