Subject: kern/3737: bug in tcp_fsm.h described in "TCP/IP Illustrated Vol.2"
To: None <gnats-bugs@gnats.netbsd.org>
From: None <frueauf@ira.uka.de>
List: netbsd-bugs
Date: 06/11/1997 21:50:47
>Number:         3737
>Category:       kern
>Synopsis:       bug in tcp_fsm.h described in "TCP/IP Illustrated Vol.2"
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jun 11 13:20:02 1997
>Last-Modified:
>Originator:     Thorsten Frueauf
>Organization:
private
	
>Release:        <NetBSD-current source date> NetBSD current 10.06.1997
>Environment:
	
System: NetBSD cyberlap 1.2F NetBSD 1.2F (CYBERLAP) #6: Wed Jun 11 10:37:05 CEST 1997 frueauf@cyberlap:/usr/src/sys/arch/i386/compile/CYBERLAP i386


>Description:
	
On page 1005 of "TCP/IP Illustrated Vol.2", Exercise 29.5:

"Figure 18.19 in Volume 1 and Figure 14 in RFC 793 both show four segments
exchanged during a simultaneous close. But if we trace a simultaneous close
between two Net/3 systems, or if we watch the close sequence following a self-
connect on a Net/3 system, we see six segments, not four. The extra two
segments are a retransmission of the FIN by each end when the other's FIN
is received. Where is the bug and what is the fix?"

Answer on page 1090:

"The bug is in the entry tcp_outflags[TCPS_CLOSING] shown in Figure 24.16.
It specifies the TH_FIN flag, whereas the state transition diagram
(Figure 24.15) doesn't specify that the FIN should be transmitted. To fix
this, remove TH_FIN from the tcp_outflags entry for this state. The bug is
relatively harmless - it just causes two extra segments to be exchanged - and
a simultaneous close or a close following a self-connetc is rare."

>How-To-Repeat:
	
Read the above cited pages of "TCP/IP Illustrated Vol.2" - a really
great book :-)

>Fix:
	
Apply the following patch to /src/sys/netinet/tcp_fsm.h:

*** tcp_fsm.h-orig	Wed Jun 11 21:31:32 1997
--- tcp_fsm.h	Wed Jun 11 21:36:22 1997
***************
*** 51,57 ****
  #define	TCPS_CLOSE_WAIT		5	/* rcvd fin, waiting for close */
  /* states > TCPS_CLOSE_WAIT are those where user has closed */
  #define	TCPS_FIN_WAIT_1		6	/* have closed, sent fin */
! #define	TCPS_CLOSING		7	/* closed xchd FIN; await FIN ACK */
  #define	TCPS_LAST_ACK		8	/* had fin and close; await FIN ACK */
  /* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
  #define	TCPS_FIN_WAIT_2		9	/* have closed, fin is acked */
--- 51,57 ----
  #define	TCPS_CLOSE_WAIT		5	/* rcvd fin, waiting for close */
  /* states > TCPS_CLOSE_WAIT are those where user has closed */
  #define	TCPS_FIN_WAIT_1		6	/* have closed, sent fin */
! #define	TCPS_CLOSING		7	/* closed xchd FIN; await ACK */
  #define	TCPS_LAST_ACK		8	/* had fin and close; await FIN ACK */
  /* states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */
  #define	TCPS_FIN_WAIT_2		9	/* have closed, fin is acked */
***************
*** 71,77 ****
  u_char	tcp_outflags[TCP_NSTATES] = {
      TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
      TH_ACK, TH_ACK,
!     TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
  };
  #endif
  
--- 71,77 ----
  u_char	tcp_outflags[TCP_NSTATES] = {
      TH_RST|TH_ACK, 0, TH_SYN, TH_SYN|TH_ACK,
      TH_ACK, TH_ACK,
!     TH_FIN|TH_ACK, TH_ACK, TH_FIN|TH_ACK, TH_ACK, TH_ACK,
  };
  #endif
  
>Audit-Trail:
>Unformatted:
bug in tcp_fsm.h described in "TCP/IP Illustrated Vol.2"