summary refs log tree commit diff
path: root/net/dccp
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@mandriva.com>2005-08-13 20:36:01 -0300
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 15:59:50 -0700
commit8649b0d4166e6e80ffa298e75abd8f2afdd491a6 (patch)
treee6024532d165f5dc9987fe38fb84cb2076c86100 /net/dccp
parent725ba8eee3881e619c8e5a0116f1bdb6480ac2d9 (diff)
downloadlinux-8649b0d4166e6e80ffa298e75abd8f2afdd491a6.tar.gz
[DCCP]: Fix RESET handling in dccp_rcv_state_process
To avoid holding TIMEWAIT state for sockets in the LISTEN state.

Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/input.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 4b8638f153a5..9dadfc362511 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -402,7 +402,48 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 	const int old_state = sk->sk_state;
 	int queued = 0;
 
-	if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING) {
+	/*
+	 *  Step 3: Process LISTEN state
+	 *  	(Continuing from dccp_v4_do_rcv and dccp_v6_do_rcv)
+	 *
+	 *     If S.state == LISTEN,
+	 *	  If P.type == Request or P contains a valid Init Cookie
+	 *	  	option,
+	 *	     * Must scan the packet's options to check for an Init
+	 *		Cookie.  Only the Init Cookie is processed here,
+	 *		however; other options are processed in Step 8.  This
+	 *		scan need only be performed if the endpoint uses Init
+	 *		Cookies *
+	 *	     * Generate a new socket and switch to that socket *
+	 *	     Set S := new socket for this port pair
+	 *	     S.state = RESPOND
+	 *	     Choose S.ISS (initial seqno) or set from Init Cookie
+	 *	     Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
+	 *	     Continue with S.state == RESPOND
+	 *	     * A Response packet will be generated in Step 11 *
+	 *	  Otherwise,
+	 *	     Generate Reset(No Connection) unless P.type == Reset
+	 *	     Drop packet and return
+	 *
+	 * NOTE: the check for the packet types is done in
+	 *	 dccp_rcv_state_process
+	 */
+	if (sk->sk_state == DCCP_LISTEN) {
+		if (dh->dccph_type == DCCP_PKT_REQUEST) {
+			if (dccp_v4_conn_request(sk, skb) < 0)
+				return 1;
+
+			/* FIXME: do congestion control initialization */
+			goto discard;
+		}
+		if (dh->dccph_type == DCCP_PKT_RESET)
+			goto discard;
+
+		/* Caller (dccp_v4_do_rcv) will send Reset(No Connection)*/
+		return 1;
+	}
+
+	if (sk->sk_state != DCCP_REQUESTING) {
 		if (dccp_check_seqno(sk, skb))
 			goto discard;
 
@@ -484,23 +525,6 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
 	case DCCP_CLOSED:
 		return 1;
 
-	case DCCP_LISTEN:
-		if (dh->dccph_type == DCCP_PKT_ACK ||
-		    dh->dccph_type == DCCP_PKT_DATAACK)
-			return 1;
-
-		if (dh->dccph_type == DCCP_PKT_RESET)
-			goto discard;
-
-		if (dh->dccph_type == DCCP_PKT_REQUEST) {
-			if (dccp_v4_conn_request(sk, skb) < 0)
-				return 1;
-
-			/* FIXME: do congestion control initialization */
-			goto discard;
-		}
-		goto discard;
-
 	case DCCP_REQUESTING:
 		/* FIXME: do congestion control initialization */