summary refs log tree commit diff
path: root/net/sctp
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-08-31 03:10:59 +0900
committerVlad Yasevich <vladislav.yasevich@hp.com>2007-08-30 14:12:25 -0400
commit609ee4679b8a0831257552dd2b0e54f509ba0c77 (patch)
tree2a7a4bc4848de6fb6b0bd502e358f2893cfe71d3 /net/sctp
parent498d63071ef378e201979e441aefcc6565702ca7 (diff)
downloadlinux-609ee4679b8a0831257552dd2b0e54f509ba0c77.tar.gz
SCTP: Abort on COOKIE-ECHO if backlog is exceeded.
Currently we abort on the INIT chunk we our backlog is currenlty
exceeded.  Delay this about untill COOKIE-ECHO to give the user
time to accept the socket.  Also, make sure that we treat
sk_max_backlog of 0 as no connections allowed.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_statefuns.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 276e26d3d7da..177528ed3e1b 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -264,7 +264,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
 	struct sctp_chunk *err_chunk;
 	struct sctp_packet *packet;
 	sctp_unrecognized_param_t *unk_param;
-	struct sock *sk;
 	int len;
 
 	/* 6.10 Bundling
@@ -285,16 +284,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
 	if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
 		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
 
-	sk = ep->base.sk;
-	/* If the endpoint is not listening or if the number of associations
-	 * on the TCP-style socket exceed the max backlog, respond with an
-	 * ABORT.
-	 */
-	if (!sctp_sstate(sk, LISTENING) ||
-	    (sctp_style(sk, TCP) &&
-	     sk_acceptq_is_full(sk)))
-		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
-
 	/* 3.1 A packet containing an INIT chunk MUST have a zero Verification
 	 * Tag.
 	 */
@@ -590,6 +579,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
 	struct sctp_ulpevent *ev, *ai_ev = NULL;
 	int error = 0;
 	struct sctp_chunk *err_chk_p;
+	struct sock *sk;
 
 	/* If the packet is an OOTB packet which is temporarily on the
 	 * control endpoint, respond with an ABORT.
@@ -605,6 +595,15 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
 	if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
 		return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
 
+	/* If the endpoint is not listening or if the number of associations
+	 * on the TCP-style socket exceed the max backlog, respond with an
+	 * ABORT.
+	 */
+	sk = ep->base.sk;
+	if (!sctp_sstate(sk, LISTENING) ||
+	    (sctp_style(sk, TCP) && sk_acceptq_is_full(sk)))
+		return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+
 	/* "Decode" the chunk.  We have no optional parameters so we
 	 * are in good shape.
 	 */