[core] Review of draft-bosh-core-new-block-00.txt

Christian Amsüss <christian@amsuess.com> Mon, 11 May 2020 12:55 UTC

Return-Path: <christian@amsuess.com>
X-Original-To: core@ietfa.amsl.com
Delivered-To: core@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id BEB5A3A0A99 for <core@ietfa.amsl.com>; Mon, 11 May 2020 05:55:50 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.899
X-Spam-Level:
X-Spam-Status: No, score=-1.899 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Rakcm8g84FsB for <core@ietfa.amsl.com>; Mon, 11 May 2020 05:55:46 -0700 (PDT)
Received: from prometheus.amsuess.com (prometheus.amsuess.com [5.9.147.112]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 5791F3A0A94 for <core@ietf.org>; Mon, 11 May 2020 05:55:45 -0700 (PDT)
Received: from poseidon-mailhub.amsuess.com (unknown [IPv6:2a02:b18:c13b:8010:a800:ff:fede:b1bd]) by prometheus.amsuess.com (Postfix) with ESMTPS id 3F7FA40648; Mon, 11 May 2020 14:55:43 +0200 (CEST)
Received: from poseidon-mailbox.amsuess.com (hermes.amsuess.com [10.13.13.254]) by poseidon-mailhub.amsuess.com (Postfix) with ESMTP id F0D6B173; Mon, 11 May 2020 14:55:41 +0200 (CEST)
Received: from hephaistos.amsuess.com (unknown [IPv6:2a02:b18:c13b:8010:fd03:b3b6:a60b:761b]) by poseidon-mailbox.amsuess.com (Postfix) with ESMTPSA id AC6FD196; Mon, 11 May 2020 14:55:41 +0200 (CEST)
Received: (nullmailer pid 2587880 invoked by uid 1000); Mon, 11 May 2020 12:55:41 -0000
Date: Mon, 11 May 2020 14:55:41 +0200
From: Christian Amsüss <christian@amsuess.com>
To: mohamed.boucadair@orange.com
Cc: "core@ietf.org" <core@ietf.org>
Message-ID: <20200511125541.GA2576239@hephaistos.amsuess.com>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"; boundary="AqsLC8rIMeq19msA"
Content-Disposition: inline
Archived-At: <https://mailarchive.ietf.org/arch/msg/core/HW-mYZQsP9BwiASO7ts1lOpwIRg>
Subject: [core] Review of draft-bosh-core-new-block-00.txt
X-BeenThere: core@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Constrained RESTful Environments \(CoRE\) Working Group list" <core.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/core>, <mailto:core-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/core/>
List-Post: <mailto:core@ietf.org>
List-Help: <mailto:core-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/core>, <mailto:core-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 11 May 2020 12:55:52 -0000

Hello BOSH authors,
hello CoRE,

I'd like to offer a rough review of the new-block draft. I got
interested in it both because I was curious how it would address the
original DOTS use case, how it'd be useful to other cases that have been
brought up (a-realist comes to mind), and how it'd address other pending
issues around block-wise (eg.  the need for an extra Request-Tag when
access can not guaranteed to be independent per block).

As I understand this proposal, it addresses several issues
simultaneously:

* In Block1, there is no way for the server to indicate missing blocks.

* For Block2, a client can not request more than one block in a single
  request -- especially for observations, and when it would like
  multiple non-contiguous blocks.

My main concern here is the way token values are (re)used, and how that
interacts with proxies (intermediaries): The way multiple responses
arrive on the same token makes the option inherently proxy-unsafe, which
is not something that can entirely be avoided in the context of
block-wise transfer where atomic processing is desired (which I
personally consider more of a corner case). I am also concerned that the
option's implication covering all sub-layers of CoAP (talking about the
request body in the same paragraph as about CON/NON details) makes
things more complicated than they need to be. (CoAP deliberately has all
these sub-layers in a single protocol to allow several optimizations,
but solutions that stick to one layer are preferable in my opinion).

I don't quite understand how the Block Identifier is interacting with
resources that are not updated atomically, and how (in Block4 use) it
differs from the ETag.

There are several other concerns (down to the code 2.05 of the Figure 4
example which there is already 4.08 for), but they're probably best
addressed when the rest is out of the way.


My impression is that all of this can be achieved more generally by
combining tools we already have, or are in development:

* For the server to indicate missing blocks in processing, a response
  payload for 4.08 Request Entity Incomple would be sufficient; that
  could be a simple CBOR array indicating the byte offsets of missing
  slices or a more generic format like [1].

  Then, figures 3 and 4 would look like this:

           CoAP        CoAP
          Client      Server
            |          |
            +--------->| PUT /path B1:0/1/1024 No-Response:2.xx
            +----X     | PUT /path B1:1/1/1024 No-Response:2.xx
            +----X     | PUT /path B1:2/1/1024 No-Response:2.xx
            +--------->| PUT /path B1:3/1/1024 No-Response:2.xx
            |          |
            |<---------+ 4.18, payload `missing 1024-3072`
            +--------->| PUT /path B2:1/1/1024 No-Response:2.xx
            +----X     | PUT /path B2:2/1/1024 No-Response:2.xx
            |          |
            +--------->| PUT /path B1:4/1/1024 No-Response:2.xx
            |<---------+ 4.18, payload `missnig 2048-3072`
                ...

  Note that this is mentioning no message IDs, tokens or message types;
  the client would probably pick NON for the No-Response requests as
  long as it's within its probing rate. It may skip the No-Response and
  send a CON whenever it feels uncomfortable with the silence.

  This *does* expose one difference to the B3 behavior described, and I
  can't tell yet whether that's good or bad: Unlike with B3, whether a
  "these blocks are missing" message comes depends on the server's
  implementation. If it requires blocks to arrive sequentially, it'd
  send a 4.18 immediately at the next block (as is depicted above). If
  it spools them all up, it'd send a cumulative error to the final
  request.

  If it does not do atomic processing, it would just process the request
  with the resource's last state -- which is a bug in this use case but
  a feature in others. For cases where this could bite, I trust (hope?)
  that protocol designers have the wisdom to ensure that this does not
  happen at application level.

* For returning multiple responses to a single request, there is the
  core-responses draft[2] that would need more work but should
  eventually be where the specification for sending data on a token
  that already had its response could be done.

  Assuming that a later version of it offers a proxy-unsafe
  Lesiure-For-Responses:uint option that grants the serve a number of
  additional responses short-term responses on the same token (which may
  contain a Response-For option, but may also not if other options
  already clearly make the response incompatible to the original request
  but suitable for processing anyway), figures 5 and 6 could look like
  this:

           CoAP        CoAP
          Client      Server
            |          |
            +--------->| GET /path T:0xf0 O:0 B2:0/0/1024
            |<---------+ 2.05 T:0xf0 O:1234 B2:0/1/1024 ETag: 21
            |<---------+ 2.05 T:0xf0 O:1234 B2:1/1/1024 ETag: 21
            |<---------+ 2.05 T:0xf0 O:1234 B2:2/1/1024 ETag: 21
            |<---------+ 2.05 T:0xf0 O:1234 B2:3/0/1024 ETag: 21
                ...
               [[Observe triggered]]
            |<---------+ 2.05 T:0xf0 O:1235 B2:0/1/1024 ETag: 22
            |<---------+ 2.05 T:0xf0 O:1235 B2:1/1/1024 ETag: 22
            |<---------+ 2.05 T:0xf0 O:1235 B2:2/1/1024 ETag: 22
            |<---------+ 2.05 T:0xf0 O:1235 B2:3/0/1024 ETag: 22

  Note that tokens *are* shown here now, as that very option would
  interfere with token handling, and thus be proxy unsafe.

  If any of the triggered messages does *not* make it through, the
  client is at leisure to send a `GET /path T:0xf1 B2:2/0/1024` and
  reassemble it with the rest of the burst provided the ETag matches, as
  it always could.

  That outlined mechanism would not allow specifically requesting what
  should be in the follow-up blocks. Like in HTTP/2 push, the server
  would send what it thinks best, which would in the blockwise case be
  the next n blocks -- so this is where a new option *would* be helpful,
  but that option could be very much noncommittal, and I'd expect some
  such options to be specified along along with such a
  Leisure-For-Responses option (eg. "Send these and those blocks", "if
  the response is a link just assume I'll send a GET there next", "and
  send me a current representation after the PATCH I've sent", "and let
  me know if anything else changed as a result").

Looking forward to more direct discussion on Wednesday.

Kind regards,
Christian

[1]: https://tools.ietf.org/html/draft-bosh-core-new-block-00
[2]: https://tools.ietf.org/html/draft-bormann-core-responses-00

-- 
The detailed semantics of CoAP methods are "almost, but not entirely
unlike" [HHGTTG] those of HTTP methods.
[HHGTTG]: Adams, D., "The Hitchhiker's Guide to the Galaxy", October 1979.
  -- Shelby, et al., Internet-Draft Constrained Application Protocol (CoAP)