Subject: Is STCP_SENDALL unsupported?

From: "Jan Newmarch" <[email-masked]>
Date: Wed, 25 Apr 2007 21:19:15 +1000

Hi

I thought I would use the SCTP_SENDALL flag on sctp_sndrcvinfo to do a
lazy man's chat server: read a message from anyone, set the
SCTP_SENDALL bit in sctp_sndrcvinfo.sinfo_flags and then just send it
back. But that option isn't supported by Linux (at least, upto kernel
2.6.20). Since the Linux implementation seems to be pretty complete,
I'm wondering if perhaps this is a not-really-supported option. Is it
in other implementations?

Thanks

Jan
--

---

From: Randall Stewart <[email-masked]>
Date: Wed, 25 Apr 2007 08:30:55 -0400

> in other implementations?
Yes, it is a supported option in BSD.. Linux tends to lag
behind..

R

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

---

From: "Jan Newmarch" <[email-masked]>
Date: Thu, 26 Apr 2007 00:03:45 +1000

Thanks Randall

What happens with SCTP_SENDALL if one of the sends to an association
fails? Do attempts to other associations continue or does sendmsg fail
at that point? Does sendmsg return -1 or the number of bytes written
to one of the successful associations? Does each failed association
generate a separate sctp_send_failed event? I couldn't find anything
in the socket API draft 14.

Cheers

Jan
--

---

From: Randall Stewart <[email-masked]>
Date: Wed, 25 Apr 2007 15:30:01 -0400

Jan Newmarch wrote:
> fails?

Well the only way you can find this out is to get the send failure
events.

  Do attempts to other associations continue or does sendmsg fail
> at that point?

The message is queued to every assoc under the socket. In fact
chance are all will be queued before you ever get a failure.. since
the threshold are such (by default) that it takes quite a few
retransmissons to get a failure... In any event there is a
iterator object that goes off and copies the same mbuf
to all pieces of the asoc's

  Does sendmsg return -1 or the number of bytes written
> to one of the successful associations? 

You won't get such an indication.. basically the only
way you find out is with the event.

Does each failed association
> generate a separate sctp_send_failed event?

Yep.

  I couldn't find anything
> in the socket API draft 14.
Hmm... good point we probably need to add text :-D

R

---

From: Michael Tuexen <[email-masked]>
Date: Thu, 26 Apr 2007 19:23:50 +0200

I think sendmsg() with SCTP_SENDALL will queue the message
on all associations for which you could call sendmsg without that
flag. The interesting question however is related to blocking?
So if you use this with a non-blocking socket, it might return
EWOULBLOCK, and you can get no indication on how many associations
the message has been accepted... What does the sendmsg call return?
The size of the message accepted on all associations? The size
accepted in total by the kernel (n times the message size)?
A signal also interrupts the handling of the sendmsg() which
also is hard to restart appropriately...

Best regards
Michael

---

From: Randall Stewart <[email-masked]>
Date: Thu, 26 Apr 2007 14:29:56 -0400

> also is hard to restart appropriately...

Looking at the code.. I somewhat agree.

There is no path for EWOULDBLOCK in the iterator look that
transpires. You COULD get an error if a signal happens since the
uiomove() that is being called would error and we do not restart.
Other than that, the iterator will run and delivery the data to
all associations. Since there is only one copy of the data in the
kernel, I do not place a size restriction on this..

Of course EEOR mode does not work with this :-D

R

---

From: "Jan Newmarch" <[email-masked]>
Date: Mon, 30 Apr 2007 22:42:41 +1000

On 4/26/07, Randall Stewart <[email-masked]> wrote:
>  [...]

Why not return the minimum of all the writes? If it is less than
requested you will quickly know something went wrong in at least one
write, and the events can tell you more

Jan
--

---

From: Randall Stewart <[email-masked]>
Date: Mon, 30 Apr 2007 10:36:57 -0400

> write, and the events can tell you more

Hmm.. I suppose I could.. but the way its currently structured
is to be an async op in the kernel. So the actual sending gets
done by something called an iterator_thread.. (you can see it
with ps -aex
bash-lakerest.net: ps -aex | grep sctp
ps: Process environment requires procfs(5)
    43  ??  DL     0:00.00  [sctp_iterator] <---------------
94753  p7  R+     0:00.00  grep sctp

)

This means that the return to the user completes before
the writes do... The data is of course copied off to
kernel land before the return.. but how many assoc's
got it is not something known until iterator completion.

It would take a bit of special work as well to get this
to work... think hacks into the send system calls themselves.
They are setup to only look at how much data was moved into
the kernel land (they look at a uio structure and how much
data is left, subtracting this from the original amount to
give you a result)..

It involved touching to much for SCTP's sake .. so you need
to use the failure reports.. instead.

R