This is because of the discrepancy between how the listen 'backlog'
value is treated
by linux TCP and SCTP until recently.
TCP has always been allowing 'backlog+1' connects to succeed. But in the
original
SCTP implementation, we allowed only 'backlog' connects.
With the recent generalization work done by Arnaldo, he has converted
tcp_acceptq_is_full()
to sk_acceptq_is_full() which in now used by other protocols including
SCTP. This makes
SCTP behavior similar to TCP by allowing 'backlog+1' connects.
So the real fix is to change the expectation in SCTP tests that
connect() will fail after
'backlog+1' connects rather than 'backlog'. This fix is already
available in the latest release
of lksctp-tools that is available at
http://sourceforge.net/project/showfiles.php?group_id=26529
But the SCTP testcases in LTP testsuite are not yet updated. I plan to
submit the latest
version of SCTP tests to LTP in a couple of weeks.
Thanks
Sridhar
Amit Arora wrote:
Hi,
I came across a problem where LTP testsuite testcase
"test_1_to_1_connect" fails on the linux-2.6.15-rc5 kernel.
The test which is failing is TEST7 (connect returns success and not the
expected error - ECONNREFUSED):
/*connect () TEST7: connect when accept queue is full, ECONNREFUSED
Expect error*/
/*Now that accept queue is full, the below connect should fail*/
error = connect(clnt2_sk, (const struct sockaddr *) &conn_addr,len);
if (error != -1 || errno != ECONNREFUSED)
tst_brkm(TBROK, tst_exit, "connect when accept queue is full "
"error:%d, errno:%d", error, errno);
Problem Definition:
-------------------
Initially test_1_to_1_connect.c sets up SK_MAX (defined as literal '10')
as the maximum length for the pending connections queue using "listen()"
call. Then in the Test6 it makes SK_MAX connect calls to fill up the
pending connections queue to SK_MAX:
/*connect () TEST6: Blocking connect, should pass*/
/*All the be below blocking connect should pass as socket will be
listening SK_MAX clients*/
for (i = 0 ; i < SK_MAX ; i++) {
error = connect(clnt_sk[i], (const struct sockaddr *)&conn_addr
len);
Now when Test7 is run (code mentioned above), it fails as the connect
call succeeds returning "0" return code, whereas the test expected
ECONNREFUSED error code.
SOLUTION:
---------
The attached patch when applied to linux-2.6.15-rc5/include/net/sock.h
solves this issue.
The "sk_acceptq_is_full()" is returning "0" even when the
sk->sk_ack_backlog == sk->sk_max_ack_backlog. Because of this, user is
able to create "backlog + 1" number of connects (where "backlog" was set
using "listen()" call) whereas he should not have been allowed to create
"backlog" number of connects.
------------------------------------------------------------------------
Submitted By <aarora@xxxxxxxxxx>
diff -Narpu a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h 2005-12-19 16:26:15.000000000 +0530
+++ b/include/net/sock.h 2005-12-19 16:26:45.000000000 +0530
@@ -419,7 +419,7 @@ static inline void sk_acceptq_added(stru
static inline int sk_acceptq_is_full(struct sock *sk)
{
- return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
+ return sk->sk_ack_backlog >= sk->sk_max_ack_backlog;
}
/*
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html