tech-invite   World Map     

IETF     RFCs     Groups     SIP     ABNFs    |    3GPP     Specs     Glossaries     Architecture     IMS     UICC    |    search     info

RFC 7959

 
 
 

Block-Wise Transfers in the Constrained Application Protocol (CoAP)

Part 2 of 2, p. 18 to 37
Prev Section

 


prevText      Top      ToC       Page 18 
3.  Examples

   This section gives a number of short examples with message flows for
   a block-wise GET, and for a PUT or POST.  These examples demonstrate
   the basic operation, the operation in the presence of
   retransmissions, and examples for the operation of the block size
   negotiation.

Top      Up      ToC       Page 19 
   In all these examples, a Block option is shown in a decomposed way
   indicating the kind of Block option (1 or 2) followed by a colon, and
   then the block number (NUM), more bit (M), and block size exponent
   (2**(SZX+4)) separated by slashes.  For example, a Block2 Option
   value of 33 would be shown as 2:2/0/32) and a Block1 Option value of
   59 would be shown as 1:3/1/128.

   As in [RFC7252], "MID" is used as an abbreviation for "Message ID".

3.1.  Block2 Examples

   The first example (Figure 2) shows a GET request that is split into
   three blocks.  The server proposes a block size of 128, and the
   client agrees.  The first two ACKs contain a payload of 128 bytes
   each, and the third ACK contains a payload between 1 and 128 bytes.

   CLIENT                                                     SERVER
     |                                                            |
     | CON [MID=1234], GET, /status                       ------> |
     |                                                            |
     | <------   ACK [MID=1234], 2.05 Content, 2:0/1/128          |
     |                                                            |
     | CON [MID=1235], GET, /status, 2:1/0/128            ------> |
     |                                                            |
     | <------   ACK [MID=1235], 2.05 Content, 2:1/1/128          |
     |                                                            |
     | CON [MID=1236], GET, /status, 2:2/0/128            ------> |
     |                                                            |
     | <------   ACK [MID=1236], 2.05 Content, 2:2/0/128          |

                      Figure 2: Simple Block-Wise GET

Top      Up      ToC       Page 20 
   In the second example (Figure 3), the client anticipates the block-
   wise transfer (e.g., because of a size indication in the link-format
   description [RFC6690]) and sends a block size proposal.  All ACK
   messages except for the last carry 64 bytes of payload; the last one
   carries between 1 and 64 bytes.

   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], GET, /status, 2:0/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1234], 2.05 Content, 2:0/1/64         |
     |                                                          |
     | CON [MID=1235], GET, /status, 2:1/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1235], 2.05 Content, 2:1/1/64         |
     :                                                          :
     :                          ...                             :
     :                                                          :
     | CON [MID=1238], GET, /status, 2:4/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1238], 2.05 Content, 2:4/1/64         |
     |                                                          |
     | CON [MID=1239], GET, /status, 2:5/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1239], 2.05 Content, 2:5/0/64         |

              Figure 3: Block-Wise GET with Early Negotiation

Top      Up      ToC       Page 21 
   In the third example (Figure 4), the client is surprised by the need
   for a block-wise transfer, and unhappy with the size chosen
   unilaterally by the server.  As it did not send a size proposal
   initially, the negotiation only influences the size from the second
   message exchange onward.  Since the client already obtained both the
   first and second 64-byte block in the first 128-byte exchange, it
   goes on requesting the third 64-byte block ("2/0/64").  None of this
   is (or needs to be) understood by the server, which simply responds
   to the requests as it best can.

   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], GET, /status                     ------> |
     |                                                          |
     | <------   ACK [MID=1234], 2.05 Content, 2:0/1/128        |
     |                                                          |
     | CON [MID=1235], GET, /status, 2:2/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1235], 2.05 Content, 2:2/1/64         |
     |                                                          |
     | CON [MID=1236], GET, /status, 2:3/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1236], 2.05 Content, 2:3/1/64         |
     |                                                          |
     | CON [MID=1237], GET, /status, 2:4/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1237], 2.05 Content, 2:4/1/64         |
     |                                                          |
     | CON [MID=1238], GET, /status, 2:5/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1238], 2.05 Content, 2:5/0/64         |

              Figure 4: Block-Wise GET with Late Negotiation

   In all these (and the following) cases, retransmissions are handled
   by the CoAP message exchange layer, so they don't influence the block
   operations (Figures 5 and 6).

Top      Up      ToC       Page 22 
   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], GET, /status                     ------> |
     |                                                          |
     | <------   ACK [MID=1234], 2.05 Content, 2:0/1/128        |
     |                                                          |
     | CON [MID=1235], GE/////////////////////////              |
     |                                                          |
     | (timeout)                                                |
     |                                                          |
     | CON [MID=1235], GET, /status, 2:2/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1235], 2.05 Content, 2:2/1/64         |
     :                                                          :
     :                          ...                             :
     :                                                          :
     | CON [MID=1238], GET, /status, 2:5/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1238], 2.05 Content, 2:5/0/64         |

        Figure 5: Block-Wise GET with Late Negotiation and Lost CON

   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], GET, /status                     ------> |
     |                                                          |
     | <------   ACK [MID=1234], 2.05 Content, 2:0/1/128        |
     |                                                          |
     | CON [MID=1235], GET, /status, 2:2/0/64           ------> |
     |                                                          |
     | //////////////////////////////////tent, 2:2/1/64         |
     |                                                          |
     | (timeout)                                                |
     |                                                          |
     | CON [MID=1235], GET, /status, 2:2/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1235], 2.05 Content, 2:2/1/64         |
     :                                                          :
     :                          ...                             :
     :                                                          :
     | CON [MID=1238], GET, /status, 2:5/0/64           ------> |
     |                                                          |
     | <------   ACK [MID=1238], 2.05 Content, 2:5/0/64         |

        Figure 6: Block-Wise GET with Late Negotiation and Lost ACK

Top      Up      ToC       Page 23 
3.2.  Block1 Examples

   The following examples demonstrate a PUT exchange; a POST exchange
   looks the same, with different requirements on atomicity/idempotence.
   Note that, similar to GET, the responses to the requests that have a
   more bit in the request Block1 Option are provisional and carry the
   response code 2.31 (Continue); only the final response tells the
   client that the PUT succeeded.

   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], PUT, /options, 1:0/1/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1234], 2.31 Continue, 1:0/1/128       |
     |                                                          |
     | CON [MID=1235], PUT, /options, 1:1/1/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1235], 2.31 Continue, 1:1/1/128       |
     |                                                          |
     | CON [MID=1236], PUT, /options, 1:2/0/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1236], 2.04 Changed, 1:2/0/128        |

                  Figure 7: Simple Atomic Block-Wise PUT

   A stateless server that simply builds/updates the resource in place
   (statelessly) may indicate this by not setting the more bit in the
   response (Figure 8); in this case, the response codes are valid
   separately for each block being updated.  This is of course only an
   acceptable behavior of the server if the potential inconsistency
   present during the run of the message exchange sequence does not lead
   to problems, e.g., because the resource being created or changed is
   not yet or not currently in use.

Top      Up      ToC       Page 24 
   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], PUT, /options, 1:0/1/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1234], 2.04 Changed, 1:0/0/128        |
     |                                                          |
     | CON [MID=1235], PUT, /options, 1:1/1/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1235], 2.04 Changed, 1:1/0/128        |
     |                                                          |
     | CON [MID=1236], PUT, /options, 1:2/0/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1236], 2.04 Changed, 1:2/0/128        |

                 Figure 8: Simple Stateless Block-Wise PUT

   Finally, a server receiving a block-wise PUT or POST may want to
   indicate a smaller block size preference (Figure 9).  In this case,
   the client SHOULD continue with a smaller block size; if it does, it
   MUST adjust the block number to properly count in that smaller size.

   CLIENT                                                     SERVER
     |                                                          |
     | CON [MID=1234], PUT, /options, 1:0/1/128    ------>      |
     |                                                          |
     | <------   ACK [MID=1234], 2.31 Continue, 1:0/1/32        |
     |                                                          |
     | CON [MID=1235], PUT, /options, 1:4/1/32     ------>      |
     |                                                          |
     | <------   ACK [MID=1235], 2.31 Continue, 1:4/1/32        |
     |                                                          |
     | CON [MID=1236], PUT, /options, 1:5/1/32     ------>      |
     |                                                          |
     | <------   ACK [MID=1235], 2.31 Continue, 1:5/1/32        |
     |                                                          |
     | CON [MID=1237], PUT, /options, 1:6/0/32     ------>      |
     |                                                          |
     | <------   ACK [MID=1236], 2.04 Changed, 1:6/0/32         |

          Figure 9: Simple Atomic Block-Wise PUT with Negotiation

Top      Up      ToC       Page 25 
3.3.  Combining Block1 and Block2

   Block options may be used in both directions of a single exchange.
   The following example demonstrates a block-wise POST request,
   resulting in a separate block-wise response.

   CLIENT                                                     SERVER
     |                                                              |
     | CON [MID=1234], POST, /soap, 1:0/1/128      ------>          |
     |                                                              |
     | <------   ACK [MID=1234], 2.31 Continue, 1:0/1/128           |
     |                                                              |
     | CON [MID=1235], POST, /soap, 1:1/1/128      ------>          |
     |                                                              |
     | <------   ACK [MID=1235], 2.31 Continue, 1:1/1/128           |
     |                                                              |
     | CON [MID=1236], POST, /soap, 1:2/0/128      ------>          |
     |                                                              |
     | <------   ACK [MID=1236], 2.04 Changed, 2:0/1/128, 1:2/0/128 |
     |                                                              |
     | CON [MID=1237], POST, /soap, 2:1/0/128      ------>          |
     | (no payload for requests with Block2 with NUM != 0)          |
     | (could also do late negotiation by requesting,               |
     |  e.g., 2:2/0/64)                                             |
     |                                                              |
     | <------   ACK [MID=1237], 2.04 Changed, 2:1/1/128            |
     |                                                              |
     | CON [MID=1238], POST, /soap, 2:2/0/128      ------>          |
     |                                                              |
     | <------   ACK [MID=1238], 2.04 Changed, 2:2/1/128            |
     |                                                              |
     | CON [MID=1239], POST, /soap, 2:3/0/128      ------>          |
     |                                                              |
     | <------   ACK [MID=1239], 2.04 Changed, 2:3/0/128            |

        Figure 10: Atomic Block-Wise POST with Block-Wise Response

Top      Up      ToC       Page 26 
   This model does provide for early negotiation input to the Block2
   block-wise transfer, as shown below.

   CLIENT                                                     SERVER
     |                                                              |
     | CON [MID=1234], POST, /soap, 1:0/1/128 ------>               |
     |                                                              |
     | <------   ACK [MID=1234], 2.31 Continue, 1:0/1/128           |
     |                                                              |
     | CON [MID=1235], POST, /soap, 1:1/1/128 ------>               |
     |                                                              |
     | <------   ACK [MID=1235], 2.31 Continue, 1:1/1/128           |
     |                                                              |
     | CON [MID=1236], POST, /soap, 1:2/0/128, 2:0/0/64 ------>     |
     |                                                              |
     | <------   ACK [MID=1236], 2.04 Changed, 1:2/0/128, 2:0/1/64  |
     |                                                              |
     | CON [MID=1237], POST, /soap, 2:1/0/64      ------>           |
     | (no payload for requests with Block2 with NUM != 0)          |
     |                                                              |
     | <------   ACK [MID=1237], 2.04 Changed, 2:1/1/64             |
     |                                                              |
     | CON [MID=1238], POST, /soap, 2:2/0/64      ------>           |
     |                                                              |
     | <------   ACK [MID=1238], 2.04 Changed, 2:2/1/64             |
     |                                                              |
     | CON [MID=1239], POST, /soap, 2:3/0/64      ------>           |
     |                                                              |
     | <------   ACK [MID=1239], 2.04 Changed, 2:3/0/64             |

        Figure 11: Atomic Block-Wise POST with Block-Wise Response,
                             Early Negotiation

3.4.  Combining Observe and Block2

   In the following example, the server first sends a direct response
   (Observe sequence number 62350) to the initial GET request (the
   resulting block-wise transfer is as in Figure 4 and has therefore
   been left out).  The second transfer is started by a 2.05
   notification that contains just the first block (Observe sequence
   number 62354); the client then goes on to obtain the rest of the
   blocks.

Top      Up      ToC       Page 27 
       CLIENT  SERVER
         |      |
         +----->|     Header: GET 0x41011636
         | GET  |      Token: 0xfb
         |      |   Uri-Path: status-icon
         |      |    Observe: (empty)
         |      |
         |<-----+     Header: 2.05 0x61451636
         | 2.05 |      Token: 0xfb
         |      |     Block2: 0/1/128
         |      |    Observe: 62350
         |      |       ETag: 6f00f38e
         |      |    Payload: [128 bytes]
         |      |
         |      |  (Usual GET transfer left out)
           ...
         |      |  (Notification of first block)
         |      |
         |<-----+     Header: 2.05 0x4145af9c
         | 2.05 |      Token: 0xfb
         |      |     Block2: 0/1/128
         |      |    Observe: 62354
         |      |       ETag: 6f00f392
         |      |    Payload: [128 bytes]
         |      |
         +- - ->|     Header: 0x6000af9c
         |      |
         |      |  (Retrieval of remaining blocks)
         |      |
         +----->|     Header: GET 0x41011637
         | GET  |      Token: 0xfc
         |      |   Uri-Path: status-icon
         |      |     Block2: 1/0/128
         |      |
         |<-----+     Header: 2.05 0x61451637
         | 2.05 |      Token: 0xfc
         |      |     Block2: 1/1/128
         |      |       ETag: 6f00f392
         |      |    Payload: [128 bytes]
         |      |
         +----->|     Header: GET 0x41011638
         | GET  |      Token: 0xfc
         |      |   Uri-Path: status-icon
         |      |     Block2: 2/0/128
         |      |

Top      Up      ToC       Page 28 
         |<-----+     Header: 2.05 0x61451638
         | 2.05 |      Token: 0xfc
         |      |     Block2: 2/0/128
         |      |       ETag: 6f00f392
         |      |    Payload: [53 bytes]

           Figure 12: Observe Sequence with Block-Wise Response

   (Note that the choice of token 0xfc in this example is arbitrary;
   tokens are just shown in this example to illustrate that the requests
   for additional blocks cannot make use of the token of the Observation
   relationship.  As a general comment on tokens, there is no other
   mention of tokens in this document, as block-wise transfers handle
   tokens like any other CoAP exchange.  As usual, the client is free to
   choose tokens for each exchange as it likes.)

   In the following example, the client also uses early negotiation to
   limit the block size to 64 bytes.

       CLIENT  SERVER
         |      |
         +----->|     Header: GET 0x41011636
         | GET  |      Token: 0xfb
         |      |   Uri-Path: status-icon
         |      |    Observe: (empty)
         |      |     Block2: 0/0/64
         |      |
         |<-----+     Header: 2.05 0x61451636
         | 2.05 |      Token: 0xfb
         |      |     Block2: 0/1/64
         |      |    Observe: 62350
         |      |       ETag: 6f00f38e
         |      |    Max-Age: 60
         |      |    Payload: [64 bytes]
         |      |
         |      |  (Usual GET transfer left out)
           ...
         |      |  (Notification of first block)
         |      |
         |<-----+     Header: 2.05 0x4145af9c
         | 2.05 |      Token: 0xfb
         |      |     Block2: 0/1/64
         |      |    Observe: 62354
         |      |       ETag: 6f00f392
         |      |    Payload: [64 bytes]
         |      |

Top      Up      ToC       Page 29 
         +- - ->|     Header: 0x6000af9c
         |      |
         |      |  (Retrieval of remaining blocks)
         |      |
         +----->|     Header: GET 0x41011637
         | GET  |      Token: 0xfc
         |      |   Uri-Path: status-icon
         |      |     Block2: 1/0/64
         |      |
         |<-----+     Header: 2.05 0x61451637
         | 2.05 |      Token: 0xfc
         |      |     Block2: 1/1/64
         |      |       ETag: 6f00f392
         |      |    Payload: [64 bytes]
           ....
         |      |
         +----->|     Header: GET 0x41011638
         | GET  |      Token: 0xfc
         |      |   Uri-Path: status-icon
         |      |     Block2: 4/0/64
         |      |
         |<-----+     Header: 2.05 0x61451638
         | 2.05 |      Token: 0xfc
         |      |     Block2: 4/0/64
         |      |       ETag: 6f00f392
         |      |    Payload: [53 bytes]

            Figure 13: Observe Sequence with Early Negotiation

4.  The Size2 and Size1 Options

   In many cases when transferring a large resource representation block
   by block, it is advantageous to know the total size early in the
   process.  Some indication may be available from the maximum size
   estimate attribute "sz" provided in a resource description [RFC6690].
   However, the size may vary dynamically, so a more up-to-date
   indication may be useful.

   This specification defines two CoAP options, Size1 for indicating the
   size of the representation transferred in requests, and Size2 for
   indicating the size of the representation transferred in responses.
   (Size1 has already been defined in Section 5.10.9 of [RFC7252] to
   provide "size information about the resource representation in a
   request"; however, that section only details the narrow case of
   indicating in 4.13 responses the maximum size of request payload that
   the server is able and willing to handle.  The present specification
   provides details about its use as a request option as well.)

Top      Up      ToC       Page 30 
   The Size2 Option may be used for two purposes:

   o  In a request, to ask the server to provide a size estimate along
      with the usual response ("size request").  For this usage, the
      value MUST be set to 0.

   o  In a response carrying a Block2 Option, to indicate the current
      estimate the server has of the total size of the resource
      representation, measured in bytes ("size indication").

   Similarly, the Size1 Option may be used for two purposes:

   o  In a request carrying a Block1 Option, to indicate the current
      estimate the client has of the total size of the resource
      representation, measured in bytes ("size indication").

   o  In a 4.13 response, to indicate the maximum size that would have
      been acceptable [RFC7252], measured in bytes.

   Apart from conveying/asking for size information, the Size options
   have no other effect on the processing of the request or response.
   If the client wants to minimize the size of the payload in the
   resulting response, it should add a Block2 Option to the request with
   a small block size (e.g., setting SZX=0).

   The Size options are "elective", i.e., a client MUST be prepared for
   the server to ignore the size estimate request.  Either Size option
   MUST NOT occur more than once in a single message.

        +-----+---+---+---+---+-------+--------+--------+---------+
        | No. | C | U | N | R | Name  | Format | Length | Default |
        +-----+---+---+---+---+-------+--------+--------+---------+
        |  60 |   |   | x |   | Size1 | uint   |    0-4 | (none)  |
        |     |   |   |   |   |       |        |        |         |
        |  28 |   |   | x |   | Size2 | uint   |    0-4 | (none)  |
        +-----+---+---+---+---+-------+--------+--------+---------+

                       Table 2: Size Option Numbers

   Implementation Notes:

   o  As a quality of implementation consideration, block-wise transfers
      for which the total size considerably exceeds the size of one
      block are expected to include size indications, whenever those can
      be provided without undue effort (preferably with the first block
      exchanged).  If the size estimate does not change, the indication
      does not need to be repeated for every block.

Top      Up      ToC       Page 31 
   o  The end of a block-wise transfer is governed by the M bits in the
      Block options, _not_ by exhausting the size estimates exchanged.

   o  As usual for an option of type uint, the value 0 is best expressed
      as an empty option (0 bytes).  There is no default value for
      either Size option.

   o  The Size options are neither critical nor unsafe, and are marked
      as No-Cache-Key.

5.  HTTP-Mapping Considerations

   In this subsection, we give some brief examples of the influence that
   the Block options might have on intermediaries that map between CoAP
   and HTTP.

   For mapping CoAP requests to HTTP, the intermediary may want to map
   the sequence of block-wise transfers into a single HTTP transfer.
   For example, for a GET request, the intermediary could perform the
   HTTP request once the first block has been requested and could then
   fulfill all further block requests out of its cache.  A constrained
   implementation may not be able to cache the entire object and may use
   a combination of TCP flow control and (in particular if timeouts
   occur) HTTP range requests to obtain the information necessary for
   the next block transfer at the right time.

   For PUT or POST requests, historically there was more variation in
   how HTTP servers might implement ranges; recently, [RFC7233] has
   defined that Range header fields received with a request method other
   than GET are not to be interpreted.  So, in general, the CoAP-to-HTTP
   intermediary will have to try sending the payload of all the blocks
   of a block-wise transfer for these other methods within one HTTP
   request.  If enough buffering is available, this request can be
   started when the last CoAP block is received.  A constrained
   implementation may want to relieve its buffering by already starting
   to send the HTTP request at the time the first CoAP block is
   received; any HTTP 408 status code that indicates that the HTTP
   server became impatient with the resulting transfer can then be
   mapped into a CoAP 4.08 response code (similarly, 413 maps to 4.13).

   For mapping HTTP to CoAP, the intermediary may want to map a single
   HTTP transfer into a sequence of block-wise transfers.  If the HTTP
   client is too slow delivering a request body on a PUT or POST, the
   CoAP server might time out and return a 4.08 response code, which in
   turn maps well to an HTTP 408 status code (again, 4.13 maps to 413).
   HTTP range requests received on the HTTP side may be served out of a
   cache and/or mapped to GET requests that request a sequence of blocks
   that cover the range.

Top      Up      ToC       Page 32 
   (Note that, while the semantics of CoAP 4.08 and HTTP 408 differ,
   this difference is largely due to the different way the two protocols
   are mapped to transport.  HTTP has an underlying TCP connection,
   which supplies connection state, so an HTTP 408 status code can
   immediately be used to indicate that a timeout occurred during
   transmitting a request through that active TCP connection.  The CoAP
   4.08 response code indicates one or more missing blocks, which may be
   due to timeouts or resource constraints; as there is no connection
   state, there is no way to deliver such a response immediately;
   instead, it is delivered on the next block transfer.  Still, HTTP 408
   is probably the best mapping back to HTTP, as the timeout is the most
   likely cause for a CoAP 4.08.  Note that there is no way to
   distinguish a timeout from a missing block for a server without
   creating additional state, the need for which we want to avoid.)

6.  IANA Considerations

   This document adds the following option numbers to the "CoAP Option
   Numbers" registry defined by [RFC7252]:

                      +--------+--------+-----------+
                      | Number | Name   | Reference |
                      +--------+--------+-----------+
                      | 23     | Block2 | RFC 7959  |
                      |        |        |           |
                      | 27     | Block1 | RFC 7959  |
                      |        |        |           |
                      | 28     | Size2  | RFC 7959  |
                      +--------+--------+-----------+

                       Table 3: CoAP Option Numbers

   This document adds the following response codes to the "CoAP Response
   Codes" registry defined by [RFC7252]:

             +------+---------------------------+-----------+
             | Code | Description               | Reference |
             +------+---------------------------+-----------+
             | 2.31 | Continue                  | RFC 7959  |
             |      |                           |           |
             | 4.08 | Request Entity Incomplete | RFC 7959  |
             +------+---------------------------+-----------+

                       Table 4: CoAP Response Codes

Top      Up      ToC       Page 33 
7.  Security Considerations

   Providing access to blocks within a resource may lead to surprising
   vulnerabilities.  Where requests are not implemented atomically, an
   attacker may be able to exploit a race condition or confuse a server
   by inducing it to use a partially updated resource representation.
   Partial transfers may also make certain problematic data invisible to
   Intrusion Detection Systems (IDSs); it is RECOMMENDED that an IDS
   that analyzes resource representations transferred by CoAP implement
   the Block options to gain access to entire resource representations.
   Still, approaches such as transferring even-numbered blocks on one
   path and odd-numbered blocks on another path, or even transferring
   blocks multiple times with different content and obtaining a
   different interpretation of temporal order at the IDS than at the
   server, may prevent an IDS from seeing the whole picture.  These
   kinds of attacks are well understood from IP fragmentation and TCP
   segmentation; CoAP does not add fundamentally new considerations.

   Where access to a resource is only granted to clients making use of
   specific security associations, all blocks of that resource MUST be
   subject to the same security checks; it MUST NOT be possible for
   unprotected exchanges to influence blocks of an otherwise protected
   resource.  As a related consideration, where object security is
   employed, PUT/POST should be implemented in the atomic fashion,
   unless the object security operation is performed on each access and
   the creation of unusable resources can be tolerated.  Future end-to-
   end security mechanisms that may be added to CoAP itself may have
   related security considerations, this includes considerations about
   caching of blocks in clients and in proxies (see Sections 2.10 and 5
   for different strategies in performing this caching); these security
   considerations will need to be described in the specifications of
   those mechanisms.

   A stateless server might be susceptible to an attack where the
   adversary sends a Block1 (e.g., PUT) block with a high block number:
   A naive implementation might exhaust its resources by creating a huge
   resource representation.

   Misleading size indications may be used by an attacker to induce
   buffer overflows in poor implementations, for which the usual
   considerations apply.

7.1.  Mitigating Resource Exhaustion Attacks

   Certain block-wise requests may induce the server to create state,
   e.g., to create a snapshot for the block-wise GET of a fast-changing
   resource to enable consistent access to the same version of a
   resource for all blocks, or to create temporary resource

Top      Up      ToC       Page 34 
   representations that are collected until pressed into service by a
   final PUT or POST with the more bit unset.  All mechanisms that
   induce a server to create state that cannot simply be cleaned up
   create opportunities for denial-of-service attacks.  Servers SHOULD
   avoid being subject to resource exhaustion based on state created by
   untrusted sources.  But even if this is done, the mitigation may
   cause a denial-of-service to a legitimate request when it is drowned
   out by other state-creating requests.  Wherever possible, servers
   should therefore minimize the opportunities to create state for
   untrusted sources, e.g., by using stateless approaches.

   Performing segmentation at the application layer is almost always
   better in this respect than at the transport layer or lower (IP
   fragmentation, adaptation-layer fragmentation), for instance, because
   there are application-layer semantics that can be used for mitigation
   or because lower layers provide security associations that can
   prevent attacks.  However, it is less common to apply timeouts and
   keepalive mechanisms at the application layer than at lower layers.
   Servers MAY want to clean up accumulated state by timing it out (cf.
   response code 4.08), and clients SHOULD be prepared to run block-wise
   transfers in an expedient way to minimize the likelihood of running
   into such a timeout.

7.2.  Mitigating Amplification Attacks

   [RFC7252] discusses the susceptibility of CoAP endpoints for use in
   amplification attacks.

   A CoAP server can reduce the amount of amplification it provides to
   an attacker by offering large resource representations only in
   relatively small blocks.  With this, e.g., for a 1000-byte resource,
   a 10-byte request might result in an 80-byte response (with a 64-byte
   block) instead of a 1016-byte response, considerably reducing the
   amplification provided.

8.  References

8.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <http://www.rfc-editor.org/info/rfc2119>.

   [RFC7252]  Shelby, Z., Hartke, K., and C. Bormann, "The Constrained
              Application Protocol (CoAP)", RFC 7252,
              DOI 10.17487/RFC7252, June 2014,
              <http://www.rfc-editor.org/info/rfc7252>.

Top      Up      ToC       Page 35 
   [RFC7641]  Hartke, K., "Observing Resources in the Constrained
              Application Protocol (CoAP)", RFC 7641,
              DOI 10.17487/RFC7641, September 2015,
              <http://www.rfc-editor.org/info/rfc7641>.

8.2.  Informative References

   [REST]     Fielding, R., "Architectural Styles and the Design of
              Network-based Software Architectures", Ph.D. Dissertation,
              University of California, Irvine, 2000,
              <http://www.ics.uci.edu/~fielding/pubs/dissertation/
              fielding_dissertation.pdf>.

   [RFC4919]  Kushalnagar, N., Montenegro, G., and C. Schumacher, "IPv6
              over Low-Power Wireless Personal Area Networks (6LoWPANs):
              Overview, Assumptions, Problem Statement, and Goals",
              RFC 4919, DOI 10.17487/RFC4919, August 2007,
              <http://www.rfc-editor.org/info/rfc4919>.

   [RFC4944]  Montenegro, G., Kushalnagar, N., Hui, J., and D. Culler,
              "Transmission of IPv6 Packets over IEEE 802.15.4
              Networks", RFC 4944, DOI 10.17487/RFC4944, September 2007,
              <http://www.rfc-editor.org/info/rfc4944>.

   [RFC6690]  Shelby, Z., "Constrained RESTful Environments (CoRE) Link
              Format", RFC 6690, DOI 10.17487/RFC6690, August 2012,
              <http://www.rfc-editor.org/info/rfc6690>.

   [RFC7228]  Bormann, C., Ersue, M., and A. Keranen, "Terminology for
              Constrained-Node Networks", RFC 7228,
              DOI 10.17487/RFC7228, May 2014,
              <http://www.rfc-editor.org/info/rfc7228>.

   [RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
              Protocol (HTTP/1.1): Message Syntax and Routing",
              RFC 7230, DOI 10.17487/RFC7230, June 2014,
              <http://www.rfc-editor.org/info/rfc7230>.

   [RFC7233]  Fielding, R., Ed., Lafon, Y., Ed., and J. Reschke, Ed.,
              "Hypertext Transfer Protocol (HTTP/1.1): Range Requests",
              RFC 7233, DOI 10.17487/RFC7233, June 2014,
              <http://www.rfc-editor.org/info/rfc7233>.

Top      Up      ToC       Page 36 
Acknowledgements

   Much of the content of this document is the result of discussions
   with the [RFC7252] authors, and via many CoRE WG discussions.

   Charles Palmer provided extensive editorial comments to a previous
   draft version of this document, some of which have been covered in
   this document.  Esko Dijk reviewed a more recent version, leading to
   a number of further editorial improvements, a solution to the 4.13
   ambiguity problem, and the section about combining Block and
   multicast (Section 2.8).  Markus Becker proposed getting rid of an
   ill-conceived default value for the Block2 and Block1 Options.  Peter
   Bigot insisted on a more systematic coverage of the options and
   response code.  Qin Wu provided a review for the IETF Operations
   directorate, and Goeran Selander commented on the security
   considerations.

   Kepeng Li, Linyi Tian, and Barry Leiba wrote up an early version of
   the Size option, which is described in this document.  Klaus Hartke
   wrote some of the text describing the interaction of Block2 with
   Observe.  Matthias Kovatsch provided a number of significant
   simplifications of the protocol.

   The IESG reviewers provided very useful comments.  Spencer Dawkins
   even suggested new text.  He and Mirja Kuehlewind insisted on more
   explicit information about the layering of block-wise transfers on
   top of the base protocol.  Ben Campbell helped untangle some MUST/
   SHOULD soup.  Comments by Alexey Melnikov, as well as the Gen-ART
   review by Jouni Korhonen, resulted in further improvements to the
   text.

Top      Up      ToC       Page 37 
Authors' Addresses

   Carsten Bormann
   Universitaet Bremen TZI
   Postfach 330440
   Bremen  D-28359
   Germany

   Phone: +49-421-218-63921
   Email: cabo@tzi.org


   Zach Shelby (editor)
   ARM
   150 Rose Orchard
   San Jose, CA  95134
   United States of America

   Phone: +1-408-203-9434
   Email: zach.shelby@arm.com