Subject: [core] draft-ietf-core-new-block: Congestion Control

From: <[email-masked]>
Date: Fri, 23 Oct 2020 17:19:59 +0100

Hi all,

At the virtual meeting on 22nd Oct 2020, I raised the issue of how better to
handle Congestion Control once MAX_PAYLOAD (default 10 blocks) had been hit
[1] Slide 7.

The bottom line issue is there is a delay of ACK_TIMEOUT (CC requirement)
after every transmission of MAX_PAYLOAD blocks which is fine.  This delay
can be reduced by using CON for the MAX_PAYLOAD packet and triggering the
send of the next set of data when the ACK is received, but is likely to
create other timeout issues in a lossy environment (especially is the loss
is un-directional as in DDoS pipe flooding).

Use of NON will always have this ACK_TIMEOUT delay unless there is a way
stimulating a response from the peer (which may get lost) which can trigger
the sending of the next MAX_PAYLOAD packets (or indicate some of the
previous packets are missing).

It was suggested that the No-Response RFC7967 could be used.  I mentioned
that I had looked at it, but did not use it for reasons that I could not
immediately recall.

RFC7967 is not an IETF submission and is Informal.  The No-Response is also
defined for Requests, but not Responses (needed for Quick-Block2) which is
why I did not continue down that route - updating the RFC to include
Responses  could be an interesting challenge...  I am not convinced that
supporting Responses with this option would work with the general CoAP
estate out there - especially as the RFC is titled 'No Server Response'.

Which brings me back to creating another option (not keen on this) or to
have a block layout definition that is different for Quick-Block1/2 when
compared to Block1/2.  My suggestion is then that the block definition
layout is NUM R M SZX instead of NUM M SZX, where R bit, if set, requests
the peer to send an appropriate response which, if received, can trigger the
sending of the next MAX_PAYLOAD packets.

[One cannot assume that MAX_PAYLOAD will be the same at both the client and
server]

Quick-Block1 solicited response would be a 2.31 or 4.08 if some packets were
missing.

Quick-Block2 solicited response for a NON sent from the server gets more
interesting.  It should be a NON and a request (unless we want to consider
role reversal of client/server at this point).  The best I can think of is
the client sends off a request for the next MAX_PAYLOADS (i.e. GET request
with MAX_PAYLOAD worth of Quick-Block2 options) which is messy. However...

It was raised in the meeting about the meaning of "repeat request" in 3.4
[2] . The text does need clarification, but the challenge here is relevant
to the previous para above.  The scenario is that a GET with Quick-Block2
where block.num is 0 can mean one of 2 things.  It can be a request saying
"send me all of the date for this resource" (i.e. all of the blocks) or it
can be a request for a single block that that did not arrive (but block.num
=1 etc. did arrive).  The M bit is used to differentiate as to whether the
server responds with a single block or a set of blocks.  In terms of the
solicited response above, the GET request could just contain the next
Quick-Block2 needed and the use of the M bit indicates that that it is
asking for an individual block or request the net set of blocks.  3.4 [2]
current definition of the use of M bit in Quick-Block2 requests may need to
be inverted - i.e. unset if a single block is requested and set if it is
this block and following blocks requested.

[This then does allow Quick-Block2 to request individual blocks at offset X
as allowed by Block-2 - I expressed that this might be difficult in the
meeting].

I do not know why the Block1/2 option is up to 3 bytes long - this means
that block.num can have a maximum value of 2^20-1 - which supports a maximum
transfer size of ~1GB if individual block size is 1024. Networks with
smaller PDUs will be less because of the block size reduction.  Is there any
reason as to why this could not be extended to 4 bytes (or completely
relaxed to 8 bytes) to support larger transfers?

I am open to other suggestions as to how to move forward with potentially
reducing the ACK_TIMEOUT CC turnaround requirement if the network can cope. 

Regards

Jon

[1]
https://www.ietf.org/proceedings/interim-2020-core-11/slides/slides-interim-
2020-core-11-sessa-coap-block-wise-transfer-options-for-faster-transmission-
draft-ietf-core-new-block-01-00

[2] https://datatracker.ietf.org/doc/html/draft-ietf-core-new-block-01

---

From: Michael Richardson <[email-masked]>
Date: Fri, 23 Oct 2020 12:42:32 -0400

If I understood yesterday, it is possible to send a single package asking for
a specific offset of data, and then get 10 packets worth of reply?

Is that correct?

---

From: "Jon Shallow" <[email-masked]>
Date: Fri, 23 Oct 2020 18:03:04 +0100

Hi Michael,

The original concept of Quick-Block2 was to get all of the data over in an
efficient manner (subject to congestion control) and reduce the number of
requests needed as a part of that process.  An Observe trigger just needed
to send over all of the data within the body.

"Selective" access to resource data was not required but is provided by
Block2 (but missing blocks can be re-requested using Quick-Block2).  When
asked yesterday, I knew that there were likely to be issues in this area and
my answer was not well thought through - hence what you picked up.

It is possible to ask for a specific offset and the blocks following as the
Quick-Block2 option can be used multiple times in a single GET request -
they would be the base offset (as indicated by block.num and block.szx) and
the remaining options used for block.num+1, block.num+2 etc.  If more than
MAX_PAYLOAD options were defined, the first MAX_PAYLOAD would come back,
then an ACK_TIMEOUT pause and then the next blocks etc.

Regards

Jon

> -----Original Message-----
> From: Michael Richardson [mailto: [email-masked]]
> Sent: 23 October 2020 17:43
> To: [email-masked]
> Cc: [email-masked]
> Subject: Re: [core] draft-ietf-core-new-block: Congestion Control
>

---

From: Michael Richardson <[email-masked]>
Date: Sat, 24 Oct 2020 16:46:47 -0400

Jon Shallow <[email-masked]> wrote:
    > The original concept of Quick-Block2 was to get all of the data over in
    > an efficient manner (subject to congestion control) and reduce the
    > number of requests needed as a part of that process.  An Observe
    > trigger just needed to send over all of the data within the body.

    > Block2 (but missing blocks can be re-requested using Quick-Block2).
    > When asked yesterday, I knew that there were likely to be issues in
    > this area and my answer was not well thought through - hence what you
    > picked up.

I'm asking if a return reachability check is needed before the multiple
packet reply.

That is, is there an amplication attack possible here is one can forge the
source address.

It might be that nobody will never use *-Block[12] (I also like Robust)
without an OSCORE context, in which case there is probably enough security to
prevent abuse by forged source address.

    > It is possible to ask for a specific offset and the blocks following as
    > the Quick-Block2 option can be used multiple times in a single GET
    > request - they would be the base offset (as indicated by block.num and
    > block.szx) and the remaining options used for block.num+1, block.num+2
    > etc.  If more than MAX_PAYLOAD options were defined, the first
    > MAX_PAYLOAD would come back, then an ACK_TIMEOUT pause and then the
    > next blocks etc.

So, given a Christmas-Tree-Packet (largest packet, every possible option
space used, every extension turned on...) how much data can I get back? :-)

If it is legit to include multiple copies of the options, can I ask for the
same offset to be sent to me multiple times?

--
Michael Richardson <[email-masked]>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide

---

From: "Jon Shallow" <[email-masked]>
Date: Mon, 26 Oct 2020 14:42:26 -0000

Hi Michael,

It is good to have these thought provoking questions.

See inline.

Regards

Jon

> From: Michael Richardson [mailto:[email-masked]]
> Sent: 24 October 2020 21:47
> To: Jon Shallow
> Cc: [email-masked]

There is none at present.  This is only an issue if using NoSec security mode as any other mode implies reachability is there.

> That is, is there an amplication attack possible here is one can forge the

Yes.  This is covered in part by https://tools.ietf.org/html/rfc7252#section-11.3 .  If a security mode other than NoSec, then this should not be an issue as it becomes very difficult to spoof a source address.

In the case of the DOTS protocol which triggered this draft,, Security is a requirement https://tools.ietf.org/html/rfc8782#section-10 .  That said, it is worth adding something to https://datatracker.ietf.org/doc/html/draft-ietf-core-new-block-01#section-11 to recommend a security mode other than NoSec as picked up from https://tools.ietf.org/html/rfc7252#section-11.4 .

> without an OSCORE context, in which case there is probably enough security
> to prevent abuse by forged source address.

Agreed.

> space used, every extension turned on...) how much data can I get back? :-)

If the server is unable to use the smallest block size (16) (lack of PDU space) and there is 16 or more bytes, then no data will get transferred back.  This issue is the same as for the regular Block2. 

I believe that this should generate a 4.13 (Request Entity Too Large), but am open to other suggestions.

> 
> If it is legit to include multiple copies of the options, can I ask for the same
> offset to be sent to me multiple times?

Good catch. No as there is no point in supporting this. The text will get updated to indicate this is invalid and will get rejected.