Subject: [Tsvwg] Re: Should SCTP send ABORT on its Listen Queue Full?

From: Mark Butler <[email-masked]>
Date: Wed, 19 Apr 2006 13:56:40 -0600

RS, Moorthy (STSD) wrote:

> All,
>
> Currently, when SCTP INIT packet is received by server and when the 
> server's listen queue is full - ( i.e sk->sk_ack_backlog exceeds the 
> listen() value specified), SCTP server sends an ABORT packet to the 
> client. This means that the client gets a "connection refused" error - 
> when there is load on the server, and is not able to process its 
> incoming connections faster.
>
> While TCP behaves differently - it just drops the SYN packet, when its 
> listen queue is full. However, in this case, applications will retry 
> and connect eventually. Given that, most TCP clients do not retry on 
> "connection refused" errors, they would have problems while using SCTP 
> (TCP-style one-to-one sockets) and would need to change their code. (I 
> have test scenarios, where even after increasing listen() queue value 
> - 10 times of 10000 connection requests are ABORTed).
>
> I would like to see, SCTP too dropping the INIT packet and not sending 
> an ABORT, when its listen queue is full.
>
> Any thoughts of why that should not be the case?

I agree completely - SCTP should behave like TCP in this matter.  It do 
not believe RFC2960 has anything to say either way.  It might be nice 
someday to even have a control chunk indicating the expected accept 
queue wait time, such that an application could switch to a different 
mirror when a primary was overloaded.

[Cross posting to TSVWG, as this is really an SCTP socket issue, not an 
LKSCTP issue].

> Thanks
> Moorthy

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Wed, 19 Apr 2006 17:45:29 -0600

Mark,

The ABORT should include cause "out of resource."  If the sender translates
that to "connection refused" that is its error.  I return ECONNABORTED
instead of ECONNREFUSED.

IMO, in fitting with the purposes of SCTP, it is better to provide an
indication back (ECONNABORTED) rather than waiting some number of minutes
for the connection establishment process to time out (ETIMEDOUT) as in the
case of TCP.

These are implementation details.  The protocol already provides the
necessary ABORT cause codepoints.

--brian

Mark Butler wrote:                              (Wed, 19 Apr 2006 13:56:40)
>    I  agree  completely - SCTP should behave like TCP in this matter.  It
>    do  not  believe  RFC2960 has anything to say either way.  It might be
>    nice  someday  to  even  have  a control chunk indicating the expected
>    accept  queue  wait  time,  such that an application could switch to a
>    different mirror when a primary was overloaded.
>    [Cross  posting  to TSVWG, as this is really an SCTP socket issue, not
>    an LKSCTP issue].
> 
>      Thanks
>      Moorthy

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

---

From: Rick Jones <[email-masked]>
Date: Wed, 19 Apr 2006 16:56:58 -0700

> that to "connection refused" that is its error.  I return ECONNABORTED

Is there (will there be) a writeup somewhere that says what an 
application should do with an ECONNABORTED (or ECONNREFUSED) on a 
connect() on an SCTP end-point?

> for the connection establishment process to time out (ETIMEDOUT) as in the

OK, I'll step-down from the il-informed peanut gallery and bite - 
perhaps on my own toes :) - why?

A TCP application that concerned about timely connection completion will 
do a non-blocking connect() and give-up if the socket doesn't become 
writable in the length of time it wants anyway.  Which it still must do 
even if connect() returns errors on listen queues being full because 
there is no guarantee that the connection request actually makes it to 
the remote to return the "queue full" indication in the first place. 
So, connect() returning an error on remote queue full doesn't really 
save the application programmer anything.

If the application does not especially care about how quickly the 
connect() completes, should it really be required to make N connect() 
calls to establish its connection when the remote queue is full? (Asked 
he who was ass-u-me-ing that is what would happen with those error 
returns...)  And just what value of N should it use?

sincerely,

rick jones

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Wed, 19 Apr 2006 18:33:31 -0600

Rick,

Rick Jones wrote:                                                    (Wed, 19 Apr 2006 16:56:58)
> connect() on an SCTP end-point?

Sorry, different part of the code (ERROR chunks in response to INIT-ACK).
If I receive an ABORT in COOKIE-WAIT or COOKIE-ECHOED state I return
ECONNREFUSED too.

But as the receiver I do not check max_ack_backlog on receipt of an INIT.
That strikes me as against the concept of not maintaining any state associated
with INITs and invites a denial of service attack.

When I receive a COOKIE-ECHO I check max_ack_backlog before queuing the
connection indication.  If it is exceeded I send ABORT "out of resource".
rather than silently discarding the COOKIE-ECHO (which would be against
RFC 2960).

I believe that ABORT(out of resource) in the COOKIE-WAIT state should be
because there is no listening socket or because the receiver simply cannot
process INITs at this time.  ABORT(out of resource) in the COOKIE-ECHOED
state should be because of ack_backlog issues.

So, rathert than dropping the COOKIE-ECHO chunk, as was suggested, if this
behaviour is important to you, the receiver should reattempt after receiving
ABORT() in the COOKIE-ECHOED state.  Note that it can even use the same
cookie until it expires.

> returns...)  And just what value of N should it use?

I suppose that makes sense.  I'll change the openss7 sockets implementation
to retransmit the COOKIE-ECHO and give it a whirl at the interop.

--brian

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

---

From: "Brian F. G. Bidulock" <[email-masked]>
Date: Wed, 19 Apr 2006 17:53:01 -0600

Mark,

Just one other thing.  Are you sure that max_ack_backlog is being checked
when an INIT is received?  I always respond to INIT with INIT-ACK if there
is a listening socket (as is spelled out in RFC2960).  I don't check
max_ack_backlog until a COOKIE-ECHO is received...

Anyway, the sctp-impl list is probably a better place for these discussions.

--brian

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

---

From: Mark Butler <[email-masked]>
Date: Wed, 19 Apr 2006 22:30:13 -0600

> connect() on an SCTP end-point?

That is up to the application.  What is important to specify is under 
what conditions those errors will be generated.

> A TCP application that concerned about timely connection completion 
> will do a non-blocking connect() and give-up if the socket doesn't 
> become writable in the length of time it wants anyway.  Which it still 
> must do even if connect() returns errors on listen queues being full 
> because there is no guarantee that the connection request actually 
> makes it to the remote to return the "queue full" indication in the 
> first place. So, connect() returning an error on remote queue full 
> doesn't really save the application programmer anything.
>
> calls to establish its connection when the remote queue is full? 
> (Asked he who was ass-u-me-ing that is what would happen with those 
> error returns...)  And just what value of N should it use?

The theory behind dropping an INIT or COOKIE ECHO instead of returning 
an ABORT when the accept queue is full is that way the initiator will 
timeout and retry in the SCTP layer, instead of requiring another level 
of connect / retry code in the application layer.

I agree that this is not an SCTP protocol issue per se, but it is 
definitely an SCTP socket issue.  The SCTP socket draft ought to 
describe what errors are returned under what conditions, whenever the 
errors or conditions diverge from POSIX specified behavior.

 - Mark