Subject: [core] Handling potentially-large resource representations

From: Peter Bigot <[email-masked]>
Date: Tue, 7 Sep 2010 04:45:23 -0500

In what follows, I'm considering resource representations that would produce
transaction message lengths that fall into three categories: "short" (within
the path MTU), "oversize" (exceeds the path MTU but within the data layer
MTU (IPv6 1280)), and "too big" (exceeds the data layer MTU).  I believe
that "too big" can be determined by the source natively, while "oversize" is
discovered either by returning a Packet Too Big ICMP message to the source
or by the network dropping the packet before it reaches the destination.

My server provides a resource where the length of the representation in a
given media type varies depending on the resource value.  For some values,
the representation will be oversize or too big, but in most cases the
representation is short.  By default the clients GET the resource without
including a block option in the request.

(1) If the server determines that the representation is too big and
therefore requires a block option for success, how does it communicate this
need to the client?

(2) If a transaction response turns out to be oversize and is not delivered,
but the network returns a ICMP "Packet Too Big" message to the server, is it
the server's responsibility to recognize this and respond to the client as
though the representation was too big?  [I think the answer has to be "no",
because the network might not have returned that indication.]

(3) Assume a client begins to retrieve the resource value using GET with
block options.  During this series of transport transactions, the value of the
resource changes, as does its representation.  How is the client made aware
of this so it does not reconstruct an invalid representation?

[For this last question I think the answer involves ETag, but since ETag is
elective, the server or client or both may not recognize it, and it's not
clearly defined when the server is permitted or obliged to include it in a
response to a request that did not include it.  I think an approach that
allows this situation to arise in a way that a standards-conformant CoAP
client cannot detect it is unacceptable.  The end result may be that ETag
becomes critical when using the Block option.]

(4) I see that draft-bormann-core-coap-block-00 introduces both the Block
option and the Token option, which have been removed from
draft-bormann-coap-misc-06.  I'm concerned that if this pairing remains, it
would implicitly require that both be implemented together in order to claim
conformance to the corresponding RFC, when in fact Token is useful and
warranted independently of the Block option.  Is that a valid concern shared
by anybody else?

(5) As noted in the interim WG telecon, Block is the first option that
clearly applies at the transport level rather than the REST level of CoAP.
The ramifications of this on end-to-end processing are still being
understood.  CoAP would be tremendously simplified by delegating
responsibility for transferring large resource representations to an
alternative protocol such as tftp, and natively supporting only those
resources that fit within the data layer MTU.  Servers would redirect
requests to resources with large descriptions to a URI with a different
scheme; clients would transmit requests using a URI content-type that the
server would have to retrieve (or reject as unsupported).  Is there any
chance that this approach would be acceptable to the community for which
CoAP/CoRE is being developed?  (Note that regardless of whether CoAP defines
the Block option, this mechanism of transferring resource representations
through an external protocol via URIs is still something CoAP must enable.)

Peter

---

From: Zach Shelby <[email-masked]>
Date: Wed, 8 Sep 2010 15:27:41 +0300

A few answers below from my understand of coap-block. One thing to emphasize here - we definitely must define a black transfer option for CoAP. In addition you surely may also use other protocols like TFTP to transfer your resources, but that is out of scope for this WG as there is nothing stopping you from doing so.  

> therefore requires a block option for success, how does it communicate this

coap-block-00 specifies this already, it simply responds with the first block in the response and includes the Block option. It is then up to the client if it wants to request further blocks.

> because the network might not have returned that indication.]

The server should then behave as in (1). I don't see how the client could otherwise find out that it should "try" to request smaller blocks instead of a normal request. 

> becomes critical when using the Block option.]

This is defined in Section 2.2 of coap-block-00, it has a SHOULD for the use of ETag in this way. You are correct, ETag becomes critical when used together with Block.

> warranted independently of the Block option.  Is that a valid concern shared

coap-block-00 is not a WG document yet, so this pairing to me is temporary. Token is not required by Block, but if we find it useful in general the right place for it is in the base coap specification. I think Token is actually still defined in coap-misc-06 right now, but is just shortly mentioned in coap-block-00. I will add consideration of Token for the base coap spec as a ticket aimed at coap-03. We have enough to close already for -02.

> through an external protocol via URIs is still something CoAP must enable.)

We seem to have good WG consensus that we will standardize an optional Block transfer feature. There is nothing stopping you from developing a server that also makes resources available using e.g. TFTP, but that functionality is out of scope for the WG in my opinion. Web servers often make resources also available via FTP in the same way. 

Zach

> 
> Peter
> _______________________________________________
> core mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/core

-- 
Zach Shelby, Chief Nerd, Sensinode Ltd.
http://zachshelby.org  - My blog "On the Internet of Things"
http://6lowpan.net - My book "6LoWPAN: The Wireless Embedded Internet"
Mobile: +358 40 7796297

---

From: Peter Bigot <[email-masked]>
Date: Wed, 8 Sep 2010 11:03:10 -0500

Thanks.  Responses inline.

> coap-block-00 specifies this already, it simply responds with the first block in the response and includes the Block option. It is then up to the client if it wants to request further blocks.

That the server can add the block option to a response when it was not
present in the request was not clear to me on initial reading, and
still isn't.  I was going to suggest clarifying that, but actually I'm
going to recommend that the server reject the message with a code that
indicates that the response is too big.  If the client isn't
explicitly (and reliably) informed that the response is large, network
limitations out of the control of both the client and the server can
prevent the client from ever getting a response and knowing that the
reason is that it needed to use a block option.  See below.

> The server should then behave as in (1). I don't see how the client could otherwise find out that it should "try" to request smaller blocks instead of a normal request.

If the server receives ICMP messages and correlates them with
responses, it *could* retransmit its response with a (smaller) block
option.  Big "if", IMO: I think we should assume that ICMP "Packet Too
Big" messages are more likely to be absent than available.

To clarify this:  In the normal case, the client sends a request
(without a block option); the server sends the first block of the
response; the network eats it.  The client never gets a response, so
the transaction layer retransmits the same request.  I assume that the
server is *not* permitted to send a different response payload to this
request, since it can't be sure (absent ICMP) why the client didn't
get it, and therefore it can't be sure the client won't still receive
a late-delivered earlier version.  Having multiple distinct responses
to the same request floating about would be very confusing.

Therefore, the server repeatedly sends the same response packet which
gets eaten by the network every time.  The client ultimately times out
because it doesn't get a response, but it doesn't know why.  Normally
this would be because of a more complete network failure between the
client and the server.   Only if the client knew that the document
might be large (because it included the block option) could it assume
that perhaps the loss was due to a path MTU problem, and re-try the
request with a smaller block size.

I don't think there's any way the server can infer from the receipt of
a second request for the same resource, absent a block option, that
the reason the client is asking for it again is because it didn't get
it the first time, and therefore change the block size that it uses.
(Also, if it could infer this, it would still have to remember that
that client had just requested that resource and what block size it
used in the response, which is an unreasonable burden.)

Similarly, if the server had already informed the client the response
would be coming asychronously, from the client's perspective it will
simply never get an answer.  Again it won't know that MTU issues are
the cause.

I believe all this confusion goes away if the server only sends
responses with block options in the case where the client has
explicitly requested it.  Since the maximum size of a block (2048
bytes) is larger than the expected data layer MTU (1280), this should
not significantly increase traffic: requests involving a resource that
is known to potentially exceed an MTU can support this with a one-byte
block option asking for the first 2KB of the response, incurring no
re-request overhead when the response fits in a packet.

For completeness, the server should be permitted to reject a request
that includes a block option if it knows that the requested block size
is too large for the intervening network.  The same response code can
be used for this as for the case when the client does not include a
block option in the request.

> This is defined in Section 2.2 of coap-block-00, it has a SHOULD for the use of ETag in this way. You are correct, ETag becomes critical when used together with Block.

SHOULD is not MUST.  I think we need to require ETag on any
transaction response that includes the block option.

ETag can't (syntactically) be critical unless there's a new ETag
header that has an odd type code.  Requiring it be paired with the
(critical) block would at least allow the specification to mandate its
implementation and recognition in this situation; clients that don't
implement block won't mistakenly interpret the partial response as
complete because block *is* syntactically critical.

Block is really messy once you get into the details, but if we only
permit the server to send the option when it's present in the request,
and we require ETag to be included in every response message that
includes the block option, I think these problems can be avoided.

Peter

---

From: Zach Shelby <[email-masked]>
Date: Thu, 9 Sep 2010 13:46:54 +0300

> includes the block option, I think these problems can be avoided.

Sounds like reasonable advice to me, but I'll defer to the authors of coap-block to take this into account. 

Zach