Subject: [Tsvwg] SCTP Sockets Mapping - Closure of TCP-style SCTP sockets

From: Mike Bartlett <[email-masked]>
Date: Mon, 18 Jun 2001 16:05:58 +0100

This is my third and last email (for the time being) following my review of
the new SCTP Sockets Mapping draft (draft-ietf-tsvwg-sctpsocket-00.txt).
This contains a major concern I have about socket closure for a TCP-style
SCTP socket.  I do not agree with the way that the API forces an application
which wants to initiate association shutdown locally (graceful or
otherwise), to use the same close() call to close down both the SCTP
association and the TCP-style socket.  I believe that an application should
be able to decouple locally-initiated association shutdown from socket
closure.

I understand that we are trying to use the TCP model here as closely as
possible, which in general is a good thing.  Additionally we have decided
not to support the TCP shutdown() call because SCTP does not support
half-close semantics.  I have two separate issues with this.
1. I believe that we still need shutdown() in order to allow an application
which has initiated graceful shutdown of the association to receive all
outstanding user data before it closes the underlying socket.  
2. There is one key difference between TCP and SCTP on non-graceful
association shutdown, namely data retrieval.  I believe that a new
abort()-type call is necessary on the API to allow the application to
decouple non-graceful association shutdown from socket closedown,
particularly so that that it can retrieve unsent/unacknowledged data.
User data (for graceful shutdown) and send-failure notifications containing
unsent/unacknowledged data (for non-graceful shutdown) can both be received
after an application shuts down an association.  If we stay with the
existing behavior then this implies that these events must be received by
the sockets application after it has made the call to close(), or not at
all.
[As a further minor point, it is not explictly stated that the SCTP status
notifications (e.g. association down) are restricted to remotely-initiated
shutdowns.  If this is intended then it should be explictly stated in the
draft.  Otherwise, if an application has requested these status
notifications, it may get them after calling close() to initiate shutdown of
the association, in addition to user data and send-failures.]
For graceful shutdowns, the default behavior is for there to be no timeout -
i.e. close() returns immediately.  For non-graceful shutdown this is the
only behavior.  The application therefore considers the TCP-style socket to
be closed and it would be strange to allow it to receive data or
notifications on the socket.  But if one endpoint cannot receive data during
association shutdown then the shutdown is not graceful by the normal SCTP
definitions.
Even if an application initiates graceful shutdown with a linger timeout
enabled, it must be able to receive these events on calls to recvmsg() [or
for the user data possibly another receive-type call] after making the call
to close() and before the call completes, which implies that the socket
would need to be non-blocking, or the application would need to be
multi-threaded.  The sentence in section 4.1.6 saying that "After an
application calls close() on a socket descriptor, no further socket
operations will suceed [should say succeed] on that descriptor" suggests
that this is not the intended behavior.  In any case the close may time out
before the graceful shutdown completes.
In short I believe that we have two choices.
1. Allow an application optionally to decouple socket closedown from
locally-initiated association shutdown, both for graceful and non-graceful
shutdown.
2. Allow an application to receive data and/or notifications after it has
made a call to close(), and possibly after the call to close() has
completed.
Of these choices I much prefer the first.  What do other people think?
Best wishes

Mike Bartlett
Voice Networking Group
Data Connection Ltd
Tel: +44 20 8366 1177
Fax: +44 20 8363 1039
Email: [email-masked]
Web: http://www.dataconnection.com

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

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Mon, 18 Jun 2001 16:47:21 -0500

Mike,

On Mon, 18 Jun 2001, Mike Bartlett wrote:

[snippage]

> Of these choices I much prefer the first.  What do other people think?

I agree with (1); however, I don't believe that close() should be
completely decoupled from graceful or ungraceful shutdown.  In TCP
implementations it is common to RST a closed socket which has
outstanding data to be sent at the time that the socket is closed.
Otherwise, they could hang around forever.  The user has gone away.
Similarly, when SCTP TCP-style sockets close() if there is outstanding
data to be sent, the association should ABORT (there is no user and
the other end could keep the association alive indefinitely).  If
there is no outstanding data, SHUTDOWN should be sent and, if data
is delivered from the peer, ABORT performed (there is no user to
deliver any received data to.)  The shutdown() mechanism can easily
be adapted to perform graceful shutdown.  Although it would not act
the same as TCP's semantics, I hear that few applications really use
shutdown() anyway.

-- 
Brian F. G. Bidulock
[email-masked]
http://www.openss7.org/

---

From: Kacheong Poon <[email-masked]>
Date: Mon, 18 Jun 2001 20:44:32 -0700 (PDT)

> Of these choices I much prefer the first.  What do other people think?

The current SCTP socket extension on this is closely tied to the SCTP
close semantics.  Becaues SCTP does not have the half-close semantics as
with TCP, the prefer way to implement a "close" in app protocols is to 
have both sides of the app to agree that they have finished communicating
before the shutdown can start, which is a graceful shutdown.

With TCP, shutdown(SHUT_WR) means doing the TCP half-close.  And
shutdown(SHUT_RD) does not mean much except the app cannot receive any
more...  Having the current SCTP close() semantics prevents app programmers
from assuming the TCP like semantics, which I think very few apps actually
use.  This is one reason why shutdown() is not allowed with the current
socket extension.

And in SCTP, once an endpoint receives a SHUTDOWN chunk and enters
the SHUTDOWN-PENDING state, no new data from app is allowed.  This means
that the app probably cannot do anything except closing the socket.  It
cannot send and there is nothing more to be received.  This unusual (and
assymmetric) semantics strongly suggest that app protocols should be very
careful in closing.  So unless we want to have another set of shutdown()
semantics with SCTP which is different from what TCP has, we probably should
avoid having shutdown().  Are you suggesting we come up with a different
meaning of shutdown()?

Note that doing 2 above is probably not a good idea because it simply
breaks the normal meaning of close().

Non-graceful shutdown can be done with the current socket extension by
setting SO_LINGER timeout to 0.  As mentioned above, because of the
unusal close semantics of SCTP, it seems that we should avoid having
shutdown() to minimize the confusion.  But if people really think that
we should have shutdown(), we can think about what it should mean.

							K. Poon.
							[email-masked]

---

From: Kacheong Poon <[email-masked]>
Date: Mon, 18 Jun 2001 21:15:53 -0700 (PDT)

> outstanding data to be sent at the time that the socket is closed.

I think there are 2 issues here.  The first is if there is outstanding
data when a socket is closing.  The second is what happens after a socket
is closed, regardless of whether there is outstanding unsent data.

When there is outstanding data when a socket is closing and SO_LINGER
timeout is set to 0, the common semantics is to send a RST to the other
end.  Otherwise, TCP will continue to send the outstanding data.

After a socket is closed, TCP will send a RST out if new data comes in.
But this is done regardless of the outstanding unsent data.

> the other end could keep the association alive indefinitely).  If

I don't think this is a correct semantics.  If what you are saying is
that after a socket is closed and there is new data received, SCTP
should send an ABORT, this makes sense.  Sending ABORT (similar to
TCP's RST) should have nothing to do with outstanding unsent data.

> the same as TCP's semantics, I hear that few applications really use

The fundamental difference between TCP and SCTP's shutdown is that SCTP's
shutdown is not symmetric.  With SCTP, once a SHUTDOWN chunk is received,
no new data is accepted from the app.  With TCP, after a FIN is received,
the app still can send out new data.  That is why shutdown(SHUT_WR) is
useful with TCP.  With SCTP, it is not easy to have a reasonable, but not
unusal meaning of shutdown(). 

							K. Poon.
							[email-masked]