Subject: Anyone implemented SCTP_PARTIAL_DELIVERY_POINT?

From: Vlad Yasevich <[email-masked]>
Date: Wed, 20 Dec 2006 10:44:04 -0500

Hi All

I was looking at implementing this option, but had
a few questions.

The options specifies message size at which Partial Delivery
is invoked.  However, I am wondering how the following scenario
should play out...

Let PARTIAL_DELIVERY_POINT == 3xMTU

Stream 1 is used to send unordered data records that are smaller
then PARTIAL_DELIVERY_POINT.

Stream 2 is used to send ordered data records that are larger
then PARTIAL_DELIVERY_POINT.

The implementation has received enough data on stream2 to invoke
PD.  It also has received a full data record on Stream1.  In this
example, assume TSN(data on stream2) < TSN(data on stream1).

Should PD be invoked? 

For the sake of freeing up as much receive window and buffer as
possible, it could invoke PD.  But, that will stall Stream2, which
by the time PD completes, may have multiple full records waiting
which seems sub-optimal to me.

Thanks
-vlad

---

From: Randall Stewart <[email-masked]>
Date: Wed, 20 Dec 2006 13:04:33 -0500

> which seems sub-optimal to me.
Vlad:

Yes, BSD implements this and it works.. now
to your scenario.

a) if one then all TSN(data on stream2) < TSN(data on stream1)
    this is required.

b) This means that without loss the message on stream2 will
    totally arrive before the one on stream1..

c) Assuming loss (your scenario I think).. then yes it could happen
    as you say... look at it this way though..

Lets number the TSN 1, 2, 3, 4 and 5.

1 - 4 are on stream 2
5 is on stream 1

So.. lets say 4 is lost..

you get:

<-1
<-2
<-3
<... now your P-D point is met> start pd-api.

The O/S has no idea what is coming in tsn 5 or any after
it..

you could pick a different scenario as well

<-1
X <- 2 lost
<-3
<-4

Now, if it started partial delivery you can only get
1 that could be delivered... this is an artifact
of how the feature is implemented of course.. but
it makes sense that you SHOULD start PD-API.. since
the reason for it to be there is to protect against
some kinds of attacks.. i.e. the app knows it never
has more than 3 MTU messages.. so an attacker is trying
to tie up resources.. so it can ABORT() him..

So you really should implement it so that you start
as soon as that much is queued.

The good news is that when 5<- arrives its sack
will trigger fast retransmit ;-)

I think there is no real way for an implementation to
"know" what is coming in the next packet before it
arrives.. and this is just a consequence of sending
big messages and small messages mixed in different
streams.. you always have this potential to block
one over the other.. and its something the app needs
to keep in mind

R

-- 
Randall Stewart
NSSTG - Cisco Systems Inc.
803-345-0369 <or> 803-317-4952 (cell)

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Wed, 20 Dec 2006 13:38:02 -0700

Randall,

> Lets number the TSN 1, 2, 3, 4 and 5.

OpenSS7 delivers 5 even though 4 is missing and 1-3 have been partially
delivered.  MSG_EOR is intepreted per-stream.  Not doing so would be
sub-optimal, as Vlad points out.  Also, if an implementation blocks
delivery of 5 awaiting completion of 1-4, it must be prepared to reneg
on 5 (and beyond) should they consume sufficient buffer to block the
receive buffer from receiving, say, 4.  Simply delivering is, I think,
easier than more complex reneg logic.

How do you handle the situation where 5 is sufficiently large to block
receipt of 4, when 1-3 have already been paritally delivered?

--brian

-- 
Brian F. G. Bidulock    ¦ The reasonable man adapts himself to the ¦
[email-masked]    ¦ world; the unreasonable one persists in  ¦
http://www.openss7.org/ ¦ trying  to adapt the  world  to himself. ¦
                        ¦ Therefore  all  progress  depends on the ¦
                        ¦ unreasonable man. -- George Bernard Shaw ¦

---

From: Randall Stewart <[email-masked]>
Date: Wed, 20 Dec 2006 16:00:38 -0500

> easier than more complex reneg logic.

One can do this.. it is allowable..but your application had better
be written to be aware of this behavior...

I could have implemented this real easily in BSD.. but I choose
not to since the behavior really needs another socket option
.. something like

FRAGMENT_INTERLEAVE.. which allows a one-2-many socket to
have this behavior but only amongst DIFFERENT associations

If we had such an API (aka an association level fragment interleave)
then I would probably make the minor changes needed to make
this work.. and of course default this behavior to off..

> receipt of 4, when 1-3 have already been paritally delivered?

TSN 4 (in my example) was part of the single message that
is connected with 1-3... aka 1=B(bit) 2=nobits 3=nobits 4 = E(bit) and
5(BE) (and 5 is in stream 1) the others in stream 2..

That was the example.

In such a case 4 would be deliverable as soon as it arrived.
5 on the other hand may or may not be deliverable.. if its get
the BE bit set and is next in sequence.. with your mod's you COULD
deliver it.. In BSD 5 would be held until the partial delivery
of 4 is completed.. if 5 was so big that you could not
fit in 4 (unlikely since its only one MTU).. then 5 would
be reneged.

R