Module Name:    src
Committed By:   rmind
Date:           Sun Jul  1 18:13:51 UTC 2012

Modified Files:
        src/sys/net/npf: npf_state_tcp.c

Log Message:
npf_state_tcp: fix for FIN retransmission and out-of-order ACK case.


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/net/npf/npf_state_tcp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/npf/npf_state_tcp.c
diff -u src/sys/net/npf/npf_state_tcp.c:1.7 src/sys/net/npf/npf_state_tcp.c:1.8
--- src/sys/net/npf/npf_state_tcp.c:1.7	Fri Jun 22 13:43:17 2012
+++ src/sys/net/npf/npf_state_tcp.c	Sun Jul  1 18:13:51 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: npf_state_tcp.c,v 1.7 2012/06/22 13:43:17 rmind Exp $	*/
+/*	$NetBSD: npf_state_tcp.c,v 1.8 2012/07/01 18:13:51 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010-2012 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.7 2012/06/22 13:43:17 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.8 2012/07/01 18:13:51 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -60,14 +60,15 @@ __KERNEL_RCSID(0, "$NetBSD: npf_state_tc
 #define	NPF_TCPS_SIMSYN_SENT	2
 #define	NPF_TCPS_SYN_RECEIVED	3
 #define	NPF_TCPS_ESTABLISHED	4
-#define	NPF_TCPS_FIN_SEEN	5
-#define	NPF_TCPS_CLOSE_WAIT	6
-#define	NPF_TCPS_FIN_WAIT	7
-#define	NPF_TCPS_CLOSING	8
-#define	NPF_TCPS_LAST_ACK	9
-#define	NPF_TCPS_TIME_WAIT	10
+#define	NPF_TCPS_FIN_SENT	5
+#define	NPF_TCPS_FIN_RECEIVED	6
+#define	NPF_TCPS_CLOSE_WAIT	7
+#define	NPF_TCPS_FIN_WAIT	8
+#define	NPF_TCPS_CLOSING	9
+#define	NPF_TCPS_LAST_ACK	10
+#define	NPF_TCPS_TIME_WAIT	11
 
-#define	NPF_TCP_NSTATES		11
+#define	NPF_TCP_NSTATES		12
 
 /*
  * TCP connection timeout table (in seconds).
@@ -79,12 +80,15 @@ static u_int npf_tcp_timeouts[] __read_m
 	[NPF_TCPS_SYN_SENT]	= 30,
 	[NPF_TCPS_SIMSYN_SENT]	= 30,
 	[NPF_TCPS_SYN_RECEIVED]	= 60,
-	/* Established, timeout: 24 hours. */
+	/* Established: 24 hours. */
 	[NPF_TCPS_ESTABLISHED]	= 60 * 60 * 24,
-	/* Closure cases, timeout: 4 minutes (2 * MSL). */
-	[NPF_TCPS_FIN_SEEN]	= 60 * 2 * 2,
-	[NPF_TCPS_CLOSE_WAIT]	= 60 * 2 * 2,
-	[NPF_TCPS_FIN_WAIT]	= 60 * 2 * 2,
+	/* FIN seen: 4 minutes (2 * MSL). */
+	[NPF_TCPS_FIN_SENT]	= 60 * 2 * 2,
+	[NPF_TCPS_FIN_RECEIVED]	= 60 * 2 * 2,
+	/* Half-closed cases: 6 hours. */
+	[NPF_TCPS_CLOSE_WAIT]	= 60 * 60 * 6,
+	[NPF_TCPS_FIN_WAIT]	= 60 * 60 * 6,
+	/* Full close cases: 30 sec and 2 * MSL. */
 	[NPF_TCPS_CLOSING]	= 30,
 	[NPF_TCPS_LAST_ACK]	= 30,
 	[NPF_TCPS_TIME_WAIT]	= 60 * 2 * 2,
@@ -176,7 +180,7 @@ static const int npf_tcp_fsm[NPF_TCP_NST
 			/* SYN-ACK response to original SYN. */
 			[TCPFC_SYNACK]	= NPF_TCPS_SYN_RECEIVED,
 			/* FIN may be sent early. */
-			[TCPFC_FIN]	= NPF_TCPS_FIN_SEEN,
+			[TCPFC_FIN]	= NPF_TCPS_FIN_RECEIVED,
 		},
 	},
 	[NPF_TCPS_SYN_RECEIVED] = {
@@ -184,7 +188,7 @@ static const int npf_tcp_fsm[NPF_TCP_NST
 			/* Handshake (3): ACK is expected. */
 			[TCPFC_ACK]	= NPF_TCPS_ESTABLISHED,
 			/* FIN may be sent early. */
-			[TCPFC_FIN]	= NPF_TCPS_FIN_SEEN,
+			[TCPFC_FIN]	= NPF_TCPS_FIN_SENT,
 		},
 		[NPF_FLOW_BACK] = {
 			/* SYN-ACK may be retransmitted. */
@@ -192,7 +196,7 @@ static const int npf_tcp_fsm[NPF_TCP_NST
 			/* XXX: ACK of late SYN in simultaneous case? */
 			[TCPFC_ACK]	= NPF_TCPS_OK,
 			/* FIN may be sent early. */
-			[TCPFC_FIN]	= NPF_TCPS_FIN_SEEN,
+			[TCPFC_FIN]	= NPF_TCPS_FIN_RECEIVED,
 		},
 	},
 	[NPF_TCPS_ESTABLISHED] = {
@@ -203,28 +207,38 @@ static const int npf_tcp_fsm[NPF_TCP_NST
 		[NPF_FLOW_FORW] = {
 			[TCPFC_ACK]	= NPF_TCPS_OK,
 			/* FIN by the sender. */
-			[TCPFC_FIN]	= NPF_TCPS_FIN_SEEN,
+			[TCPFC_FIN]	= NPF_TCPS_FIN_SENT,
 		},
 		[NPF_FLOW_BACK] = {
 			[TCPFC_ACK]	= NPF_TCPS_OK,
 			/* FIN by the receiver. */
-			[TCPFC_FIN]	= NPF_TCPS_FIN_SEEN,
+			[TCPFC_FIN]	= NPF_TCPS_FIN_RECEIVED,
 		},
 	},
-	[NPF_TCPS_FIN_SEEN] = {
+	[NPF_TCPS_FIN_SENT] = {
+		[NPF_FLOW_FORW] = {
+			/* FIN may be re-transmitted.  Late ACK as well. */
+			[TCPFC_ACK]	= NPF_TCPS_OK,
+			[TCPFC_FIN]	= NPF_TCPS_OK,
+		},
+		[NPF_FLOW_BACK] = {
+			/* If ACK, connection is half-closed now. */
+			[TCPFC_ACK]	= NPF_TCPS_FIN_WAIT,
+			/* FIN or FIN-ACK race - immediate closing. */
+			[TCPFC_FIN]	= NPF_TCPS_CLOSING,
+		},
+	},
+	[NPF_TCPS_FIN_RECEIVED] = {
 		/*
-		 * FIN was seen.  If ACK only, connection is half-closed now,
-		 * need to determine which end is closed (sender or receiver).
-		 * However, both FIN and FIN-ACK may race here - in which
-		 * case we are closing immediately.
+		 * FIN was received.  Equivalent scenario to sent FIN.
 		 */
 		[NPF_FLOW_FORW] = {
 			[TCPFC_ACK]	= NPF_TCPS_CLOSE_WAIT,
 			[TCPFC_FIN]	= NPF_TCPS_CLOSING,
 		},
 		[NPF_FLOW_BACK] = {
-			[TCPFC_ACK]	= NPF_TCPS_FIN_WAIT,
-			[TCPFC_FIN]	= NPF_TCPS_CLOSING,
+			[TCPFC_ACK]	= NPF_TCPS_OK,
+			[TCPFC_FIN]	= NPF_TCPS_OK,
 		},
 	},
 	[NPF_TCPS_CLOSE_WAIT] = {

Reply via email to