Subject: [Tsvwg] Re: U-SCTP comments

From: Qiaobing Xie <[email-masked]>
Date: Mon, 12 Mar 2001 18:22:21 -0600

Ivan,

Please see my comments in-line...

-Qiaobing

[email-masked] wrote:
> 
>         Hi all!
> 
>         I have some comments about the version 01 of the unreliable
> extension for SCTP. I hope they have not been discussed before in the
> list...
> 
>         - Section 3.1.1: What happens if the "u-stream start" or "u-stream
> end" fields of the Unreliable Streams parameter are bigger than or equal to
> the "Number of Outbound Streams" field of the INIT/INIT ACK chunk? It would
> be caused by an implementation error, but, should we discard the chunk in
> which it comes (and so the whole datagram), or should we do something more
> elaborated like sending an ERROR or ABORT chunk (maybe with the "Invalid
> Stream Identifier" cause of error)?

My feeling is that we don't have to treat it as an error at this point.
For example, if the stream range is 0-19 and we get a "u-stream start =
5" and "u-stream end = 30", we can simply take it as meaning that stream
5-19 will be unreliable. The existing error reporting in RFC2960 will
kick in if the peer later really sends data to stream 20 and above.
 
>         - Section 3.2.2: This is a little bit tricky. If the sender of a
> P-DATA sets the "Checksum Coverage" field exactly to the value of Chunk
> Length - 20, but the P-DATA contains some padding at the end, should those
> bytes (that would be set in theory to 0) be included in the Adler-32
> checksum? The same questions comes if for example there are 3 bytes of
> padding at the end, and the Checksum Coverage is set to Chunk Length - 19,
> for example, should we include also the other 2 bytes of padding in the
> checksum?

Padding is never counted in the Chunk Length and is never covered by the
checksum. This is very clear in RFC2960 and U-SCTP makes no difference
here. We can further clarify this by adding a note.

> 
>         - Section 4.2, A3) C2): The draft says that the FORWARD TSN chunk
> should be sent ONLY when a local advancement of the Peer.Cumulative.TSN is
> done. What happens if that chunk is lost in the way to the peer? If we don't
> have any other mechanism to send again that chunk, and if we don't make any
> local advancement in a long time or ever, we could end having the peer
> considering those chunks as lost, and never knowing that we have stopped
> sending them. In that case, the peer will keep its cumulative TSN to the
> previous TSN to the lost unreliable DATA chunk, and it will report any
> successive DATA chunks with fragments inside the SACK chunks, so we won't
> have to advance locally the TSN, nor sending the FORWARD TSN chunk. So any
> ordered DATA chunk sent to the same stream won't ever be delivered to the
> upper user of the peer endpoint (of course, only if the lost DATA chunk was
> also ordered). In the worst case, we will full the peers buffer, affecting
> also some other stream.

This has been pointed out by John L. and will be fixed in the next
release, by the addition of the following (with some polish):

   The data sender MUST always send a F-TSN containing its latest
   "Peer.Cumulative.TSN" to the data receiver whenever the sender
   receives a SACK which is not out-of-order and carries a Cumulative
   TSN earlier than the current "Peer.Cumulative.TSN". 

> 
>         It is stated in C2 that we shouldn't react in any way when receiving
> SACK not acknowledging TSNs that are previous to the Peer.Cumulative.TSN.
> Resending the FORWARD TSN every time we receive a such a SACK could be maybe
> a lot, since this could make that actually we always send such a chunk lots
> of times (if there are several SACK on the fly coming from the peer, and/or
> several DATA chunks going to the peer).

Since this scenario only happens when you lose the first F-TSN, I think
it shouldn't happen that often.

> 
>         Maybe it could be a little bit messy to implement, maybe not, but
> this could be solved having a variable that keeps the value of the next TSN
> we will send to the peer (the TSN of the next DATA chunk that we will send
> to the peer) at the moment of sending the FORWARD TSN. In that case, if we
> receive the acknowledgement of that TSN but the peer is considering any
> chunk previous to Peer.Cumulative.TSN as missing, we could send a new
> FORWARD TSN, keeping again the value of the next TSN to send and so on.

There will be more clarifications in the next release in this section. I
think that will help.

> 
>         And now, some typos:
> 
>         - Section 3.2.2, Stream Identifier S: "Identifies the stream to
> which the following the user data belongs." should be "Identifies the stream
> to which the following user data belongs."
> 
>         - Section 4: "... we first defines the procedures for opening..."
> should be "... we first define the procedures for opening..."
> 
>         - Section 4.2, A3) C2):"Note, an endpoint MUST NOT use the forward
> TSN..." I guess should be "Note, an endpoint MUST NOT use the FORWARD
> TSN..."
> 
>         - Section 4.4.3: "... the upper layer simply needs to examine the
> the stream..." should be "... the upper layer simply needs to examine the
> stream..."

Got them all. Thanks.

_______________________________________________
tsvwg mailing list
[email-masked]
http://www1.ietf.org/mailman/listinfo/tsvwg

---

From: [email-masked]
Date: Wed, 14 Mar 2001 11:13:10 +0200

> >         Excuse me Qiaobing, maybe I'm wrong but I couldn't 
> find any place in
> > RFC 2960 that says that the paddings are not included in 
> the checksum :-/...
> > Section 6.8 2) says:
> ...snip...
> 
> Sorry, my mistake. I meant to say that the paddings are not 
> included in
> the Chunk Length and RFC2960 states this clearly. And I agree with you
> that the RFC2960 checksum does cover all the paddings in the middle of
> the packet. As to the paddings in the LAST bundled chunk, we should
> clarify it further (maybe we already have noted it down, Randy?).

	I don't know if there is already any decision about this issue, but
I would vote for including the padding of the last chunk also inside the
checksum, so you don't have to parse the datagram before calculating the
checksum... I don't know how people do this, but in my implementation I
receive a bunch of bytes, I calculate the Adler checksum out of those bytes,
and then (if the checksum is valid) I convert those bytes into my own
structures... Summarizing, it would take more time to skip the padding of
the last chunk, just to avoid including up to 3 bytes in every datagram...

> Now let us go back to the P-DATA issue. My inclination is 
> that we should
> NOT include paddings. For example, with the following P-DATA chunk:
> 
>   +-------------------+
>   | chunk header (20) |
>   +-------------------+
>   | user data (37)    |
>   | paddings (3)      |
>   +-------------------+
> 
> we will have Chunk Length = 20 + 37 = 57.
> 
> If the Checksum Coverage = 0, then only the header is covered, 
> If the Checksum Coverage >= 37, then only the first 57 bytes (header +
> user data) are covered. 
> 
> Comments?

	Since once you support the P-DATA chunks you have always to look
first inside the datagram previous to the checksum calculation, I would
support Qiaobing's proposal here.

> -Qiaobing

	BR Iván Arias Rodríguez

---

From: [email-masked]
Date: Wed, 14 Mar 2001 13:22:48 +0200

> Randy and Qiaobing's implementation uses the length value from the IP
> header when calculating the checksum.  I.e. the final padding in an
> SCTP packet IS covered by the checksum.  I think this counts as
> definitive since nearly all existing implementations were validated
> against the user space reference.

	Exactly... that's what my implementation and all the ones I tested
with do. So, finally we agree that all the paddings are covered by the
checksum, don't we?

	Thanks!

	BR Iván Arias Rodríguez

---

From: Jon Berger <[email-masked]>
Date: Wed, 14 Mar 2001 12:49:39 -0000

Maybe I'm missing something but it seems to me that you don't have any
choice but to parse the packet before calculating the checksum.  P-DATA
chunks can occur anywhere in the packet possibly bundled with other P-DATA
and DATA chunks.  
 
I agree that this is a pain because you effectively need your checksum code
to understand the SCTP protocol.  Also you have to accept that if your DATA
chunk gets flipped on the wire into a P-DATA chunk, you'll need to
retransmit.  This sort of problem is always possible even in "regular" SCTP
as the checksum is not 100% infallible.

Jon

-----Original Message-----
From: La Monte Henry Piggy Yarroll [mailto:[email-masked]]
Sent: 14 March 2001 12:10
To: Qiaobing Xie
Cc: [email-masked]; [email-masked]
Subject: Re: [Tsvwg] Re: U-SCTP comments 

Qiaobing Xie <[email-masked]> writes:
> >         Excuse me Qiaobing, maybe I'm wrong but I couldn't find
> > any place in RFC 2960 that says that the paddings are not included
> > in the checksum :-/.. 
 .
> > Section 6.8 2) says:
> ...snip...
> 
> Sorry, my mistake. I meant to say that the paddings are not included in
> Now let us go back to the P-DATA issue. My inclination is that we should

I agree.  If we are going to go to the trouble of parsing the whole
packet before checksumming, then there is no percentage in including
the padding bytes.

I'm a little concerned about parsing the packet based on data that has
not (yet) been confirmed by checksum.  At the very least it will
require some very careful thought.  Invalid chunk types and invalid
lengths are two problems that leap to mind.

Is there are fast way to detect packets with P-DATA chunks in them?
I'd really rather not pollute my checksum fast-path with them.

---

From: [email-masked]
Date: Fri, 16 Mar 2001 21:30:06 +0200

> Ivan,
> 
> Interesting proposal! But the issue raised by LaMonte still 
> concerns me
> and your this proposal doesn't change it. You still need to parse
> through the data structure __before__ you can validate the 
> checksum/data
> integrity. Your proposal just makes the calculation easier. 
> 
> I think this issue is fundamental and needs to be addressed somehow. 

	Well, yes..., you still have to "be confident" on one chunk before
you validate the checksum...

	But in any case, if the checksum is calculated differently depending
on the chunks carried inside the datagram, you need some information before
calculating the checksum... Unless you make kind of same partial checksum
calculation for all the datagrams (something that could be negotiated in
advance), I think that the information about the coverage of the checksum
must be included in the datagram... so you must trust it before you can
calculate the checksum...

	Well... thinking about it... Actually if the association is made so
partial coverage is supported that already makes the Adler-32 checksum not
covering the whole datagram... So... we can always cover with that checksum
a small and fixed part of the datagram in which we would have enough
information to calculate the checksum for the whole datagram... This can be
interesting...

	I have a new idea... that maybe somebody could find interesting... I
will also use the basis of the previous proposal... First, take a look to
the new P-CHECKSUM I'm thinking about:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |1 1 0 0 0 0 1 1|  Chunk Flags  |    Chunk Length = 12 + N*4    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                     Second Adler-32 Checksum                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Byte Block Uncovered Start #1 |  Byte Block  Uncovered End #1 |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   \                                                               \
   /                              ...                              /
   \                                                               \
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   | Byte Block Uncovered Start #N |  Byte Block Uncovered End #N  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                      Third Adler-32 Checksum                  |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

	Imagine that in case the 'Partial Checksum Support' parameter is
included in both the INIT and INIT ACK, you continue with the COOKIE ECHO
and COOKIE ACK using the Adler-32 as always, and not including this
P-CHECKSUM chunk, but then, once the association is established, the
Adler-32 Checksum only covers the SCTP header, and the next 8 bytes. And you
have to include the P-CHECKSUM chunk in every datagram. Then with this
Adler-32 Checksum of the common header (First Adler-32 Checksum), you
validate the P-CHECKSUM header and the Second Adler-32 Checksum... You can
trust them...

	That value of Second Adler-32 Checksum would be the checksum for the
next 4 + N*4 bytes (byte blocks plus the Third Adler-32 Checksum). So you
calculate the Adler-32 checksum of those 4 + N*4 bytes and compare the value
obtained with the Second Adler-32 Checksum (already validated). Now you can
trust on the byte blocks and the Third Adler-32 Checksum.

	Finally, with the information of the byte blocks, you calculate the
Adler-32 of the rest of the datagram as the last proposal (not including any
of the bytes already "trustable"), and that value should be equal to the
Third Adler-32 Checksum... As a result you have never taken information of
any byte not already proved to be uncorrupted... To make easier this last
checksum calculation, maybe the "byte number 0" in the byte blocks could be
the first byte after the P-CHECKSUM chunk...

	You would need only two Adler-32 calculations if the number N
wouldn't be variable... but I guess this is not that useful...

	To calculate the checksums when sending the datagram, you should,
first calculate the Adler-32 of all the chunks of the datagram (not
including the P-CHECKSUM), taking into account the byte blocks as stated in
the previous proposal, and include that value in the 'Third Adler-32
Checksum' field of the P-CHECKSUM. You also should fill in the Byte Block
values...

	Then you calculate the Adler-32 checksum of those fields (byte
blocks and 3rd checksum), and you include that value in the 2nd checksum,
and you also fill in the value of the Chunk Length of the P-CHECKSUM chunk.
Finally, you calculate the Adler-32 of the common header (with the Adler-32
field of the common header set to all 0s), the P-CHECKSUM header and the 2nd
Adler-32, and you fill in the Adler-32 Checksum of the common header...

	This seems complicated to do, but maybe it is not such a big extra
task... Actually the calculation of the Third Adler-32 Checksum is almost
the same as the calculation of the normal Adler-32... And the other two ones
are made over just a few bytes... So I don't think that the extra
calculation would take that much time... maybe it can be the price you have
to pay for having this partial checksum coverage and not being able to trust
anything that hasn't already passed the checksum...

	I think this could be a solution to avoid the problem you were
pointing... It also makes easier the calculation of the Adler-32 checksum
due to the "Byte Blocks" (at least the most complex one, the 'Third Adler-32
Checksum'), as the previous proposal... On the other hand it gives you some
extra work, and 12 more bytes per datagram...

	Thinking a little bit more... With this new mechanism, apart from
'Partial Checksum Support' ('P C Support')I think we should have 'Partial
Checksum Use' ('P C Use') or something like that... If the sender of the
INIT supports the partial checksum, it should send the 'P C Support' (this
can be thought as an invitation to the peer to use partial checksumming, we
can receive them, but it doesn't mean we are going to send them), but if it
wants to send P-CHECKSUM chunks and so on, it should also send the 'P C Use'
parameter (this can be considered as a petition to the peer, we are going to
send them)... Maybe in case we send the 'P C Use' we don't have to send at
all the 'P C Support' parameter at all...

	If the receiver of the INIT also support this extension (otherwise
it would send an ERROR chunk with the 'Unrecognized Parameters' error code),
should answer with an INIT ACK with the 'P C Support' in case the 'P C Use'
was included in the INIT, and also should include the 'P C Use' in case it
wants to send partial covered chunks (and then the 'P C Support' wouldn't be
necessary), but this can be done only if it wants to send P-CHECKSUM chunks
AND the sender of the INIT supports them (it has sent 'P C Use' or 'P C
Support').

	This need is because now one peer not only have to know if the other
peer supports our "modified" datagrams (so we can send them), but also, if
it is going to send us "modified" datagrams (so we can calculate the
checksum in the right way)...

	Comments? For sure this mechanism is not the ideal one, but maybe it
can help people to think about a better one... I hope it helps somehow to
solve the problem...

> I am also contemplating to put the partial checksum DATA into 
> a separate
> draft from U-SCTP draft, just to ease the discussions.

	I think it would be a good idea, since both things are not really
very much related...

> -Qiaobing

	Thanks for you valuable time!

	BR Iván Arias Rodríguez