Subject: [tsvwg] Eric Rescorla's No Objection on draft-ietf-tsvwg-sctp-ndata-12: (with COMMENT)

From: Eric Rescorla <[email-masked]>
Date: Sat, 26 Aug 2017 12:21:03 -0700

Eric Rescorla has entered the following ballot position for
draft-ietf-tsvwg-sctp-ndata-12: No Objection

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-ndata/

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

TECHNICAL
I'm not sure I am following the rules about interleaving multiple
messages in the same flight.

   The sender MUST NOT fragment more than one user message in any given
   stream at any time.  At any time, a sender MAY fragment multiple user
   messages, each of them on different streams.

So, say I have one stream and the application sends M1 and M2 and both
need to be fragmented, so I have M1a, M1b and M2a and M2b. Does this
mean that I can't send M2a until M1{a,b} has been acknowledged?
If so what's the need for that requirement? It seems like you could
use MID to reassemble correctly. And given this requirement, why do
you need MID?

Because fragementation is indicated by index, not range,
what happens if you have to reduce MTU? So, say I have a message of
size 2K which I fragment into 1K/1K and then I have to decrease
my MTU to 512 bytes?

EDITORIAL
I think it would be helpful to indicate that B has to be
set for the first chunk in S 2.1. Or perhaps move the overview of
how the sender behaves in S 2.2.2 up in the document?

---

From: Michael Tuexen <[email-masked]>
Date: Mon, 28 Aug 2017 22:42:00 +0200

> On 26. Aug 2017, at 21:21, Eric Rescorla <[email-masked]> wrote:
> 
Hi Eric,

thanks for the review. See my responses in-line.

Best regards
Michael
> mean that I can't send M2a until M1{a,b} has been acknowledged?
No, that is not what is meant.

Assume M1 is sent before M2 and you end up in M1a (first fragment),
M1b (second fragment), M2a (first fragment) and M2b (second fragment).
You would assign the TSNs in a way that they are increasing for
M1a, M1b, M2a, and M2b. So you are not interleaving messages on
the same stream. That is the point. So you would not send them as
M1a, M2a, M2b, M1b. You should also not send M1a, M2, M1b (assuming
that M2 doesn't need to be fragmented).

I agree, the above text is not as clear as possible. So what about stating
it as:

  The sender MUST NOT assign TSNs to more than one user message in any given
  stream at any time.  At any time, a sender MAY assign TSNs to multiple user
  messages, each of them on different streams.

> If so what's the need for that requirement? It seems like you could
The reason for this limitation is:
* It is enough to make streams independent of each other as for
  example required for WebRTC
* If you would allow interleaving of messages on the same stream
  you would also need to allow this in the upper layer API of
  SCTP. We did not want to make this API more complex for the user
  as it is already specified in RFC 6458.
  When keeping the API as specified in RFC 6458 but allowing
  the interleaving of user messages within a stream you are
  allowing deadlocks.

During the work on the extension we considered removing this restriction,
but decided it is not worth it. We even considered to allow the interleaving
of an ordered and unordered message. However, that you have required to
add a new interleaving level in
https://tools.ietf.org/html/rfc6458#section-8.1.20
and we decided that it is simpler and cleaner to stick to the interleaving
of messages from different streams.

I just double checked the document and the is a left over in the security
considerations:

   When doing so, an application has to provide
   up to two reassembly buffers (one for ordered messages, one for
   unordered messages) for each incoming stream.

this needs to be changed to:

   When doing so, an application has to provide
   a reassembly buffer for each incoming stream.

> use MID to reassemble correctly. And given this requirement, why do
You need some id to know which fragments belong to the same
user message. You can't derive that from the TSN.
> size 2K which I fragment into 1K/1K and then I have to decrease
SCTP can't adopt, so IP fragmentation will be used.

The reason is that once you sent a DATA chunk or an I-DATA chunk
you assigned a TSN will is used for reliable transfer. So you
have to retransmit it and you can't change the user data contained
in it. This has not changed from the base spec.

Changing the information from index to range for handling reassembly
would not really help, since you still do reliable transfer by using the
TSN assigned to the DATA or I-DATA chunk and you need to retransmit it.
> how the sender behaves in S 2.2.2 up in the document?
Considering this comment and the ones I got from other people
it seems like referring to RFC 4960 and RFC 7053 for the fields
which haven't changed and only describing the new fields doesn't
seem to work well.

I'll add text describing the "old fields".

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Aug 2017 13:56:12 -0700

>   messages, each of them on different streams.

Perhaps you might instead say:

The user messages within a given stream must have strictly increasing TSNs

> user message. You can't derive that from the TSN.

Yeah, I thought you could but after some thought I see you cannot.

-Ekr

---

From: Michael Tuexen <[email-masked]>
Date: Tue, 29 Aug 2017 00:39:40 +0200

> On 28. Aug 2017, at 22:56, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Mon, Aug 28, 2017 at 1:42 PM, Michael Tuexen <[email-masked]> wrote:
Not sure what you are suggesting, since TSN are assigned to chunks, not
user messages. Just considering the simple case of non-fragmented user
messages, you can't guarantee that user messages of a particular stream
have increasing TSNs, since there can be wrap arounds due to chunks
belonging to other streams. The TSN are 32-bit numbers with serial arithmetic...

Best regards
Michael

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 28 Aug 2017 16:04:02 -0700

On Mon, Aug 28, 2017 at 3:39 PM, Michael Tuexen <[email-masked]>
wrote:

> user messages.

The problem here is that  your text focuses on TSN *assignment* which is not
really the relevant property (it's an implementation artifact) rather what
appears
on the wire is. So, the requirement here seems to be that you allocate TSNs
to fragments of user messages in order.

Just considering the simple case of non-fragmented user
> belonging to other streams. The TSN are 32-bit numbers with serial

Hmm... You don't think of these as being infinite precision but taken mod
2^32?

-Ekr

---

From: Michael Tuexen <[email-masked]>
Date: Tue, 29 Aug 2017 09:24:13 +0200

> On 29. Aug 2017, at 01:04, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Mon, Aug 28, 2017 at 3:39 PM, Michael Tuexen <[email-masked]> wrote:
> really the relevant property (it's an implementation artifact) rather what appears
The next sentence in the document states:

The sender MUST assign TSNs in a way that the receiver can make progress.
One way to achieve this is to assign a higher TSN to the later fragments of
a user message and send out the TSNs in sequence.

The reason not to mandate this is that you might you more complex schemes
in case of load-sharing between multiple paths.
> Hmm... You don't think of these as being infinite precision but taken mod 2^32?
In most cases, yes. But I need to take into account that the numbers can wrap
and how this is handled by receivers. That is why the document states some
limitations you the number of outstanding MIDs and FSNs.

Best regards
Michael

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 29 Aug 2017 06:09:01 -0700

> > > > https://datatracker.ietf.org/doc/draft-ietf-tsvwg-sctp-ndata/

That's fine, but I don't find the current text clear and this doesn't help.
Why don't
you try listing the requirements on what appears on the wire from the
receiver's
perspective in response to this message, and then we can discuss how to
write it in the doc.

-Ekr

---

From: Michael Tuexen <[email-masked]>
Date: Tue, 29 Aug 2017 16:51:57 +0200

> On 29. Aug 2017, at 15:09, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Tue, Aug 29, 2017 at 12:24 AM, Michael Tuexen <[email-masked]> wrote:
> That's fine, but I don't find the current text clear and this doesn't help. Why don't
> you try listing the requirements on what appears on the wire from the receiver's
Sure. The point is that there should not occur a deadlock when the sender
and the receiver follow the rules.

Receiver constraint:
* The receiver can not interleave user messages from the same stream when
  delivering data to the user. However, it can do partial delivery. This
  means the receiver can start delivering the user data, delivering the bytes
  in the correct sequence, but not delivering it completely.

Sender contraint:
* When chunks are lost, they are retransmitted giving smaller TSNs priority.
  This is the normal error recovery behaviour, which we don't want to change.

Example of deadlock to avoid:
The sender sends on stream 0 the first n fragments of a big user message,
which are all received by the receiver. Since the buffer space needs to be
freed on the receiver side, it start partial delivery of the message and
delivers the data corresponding to the first n fragments.
Now the sender starts sending the first fragments of another message on
stream 0. These will be received by the receiver, will be buffered,
but can't be delivered, since this would require interleaving two messages
at the receiver side when passing the user data up to the user.
Or, alternatively, the sender starts sending a number of user messages on
stream 0. These also can't be delivered.

That is why the function (the stream scheduler) selecting from which stream
queue data is taken to be filled in a chunk and assigning the TSN should
only select a stream and not a message on that stream. Once you started to
take data from a message in a stream queue, you have to finishing processing
it before you can move on to another message from that stream queue.

Any idea how to write a better text?

Best regards
Michael

---

From: Michael Tuexen <[email-masked]>
Date: Wed, 30 Aug 2017 15:11:42 +0200

> perspective in response to this message, and then we can discuss how to
Let me make another suggestion:

OLD TEXT:

   The sender MUST assign TSNs in a way that the receiver can make
   progress.  One way to achieve this is to assign a higher TSN to the
   later fragments of a user message and send out the TSNs in sequence.

NEW TEXT:

   The sender MUST NOT process (move user data into I-DATA chunks and assign
   a TSN to it) for more than one user message in any given stream at any time.
   At any time, a sender MAY process multiple user messages, each of them on
   different streams.

   The sender MUST assign TSNs to I-DATA chunks in a way that the receiver
   can make progress.  One way to achieve this is to assign a higher TSN to the
   later fragments of a user message and send out the I-DATA chunks such that
   the TSNs are in sequence.

Does that address your issue?

Best regards
Michael