From staffanu@multivac.fatburen.org  Mon Jun 19 21:45:12 2006
Return-Path: <staffanu@multivac.fatburen.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 8D1CF16A479
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 19 Jun 2006 21:45:12 +0000 (UTC)
	(envelope-from staffanu@multivac.fatburen.org)
Received: from multivac.fatburen.org (multivac.fatburen.org [212.247.27.201])
	by mx1.FreeBSD.org (Postfix) with ESMTP id D283643D46
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 19 Jun 2006 21:45:11 +0000 (GMT)
	(envelope-from staffanu@multivac.fatburen.org)
Received: from multivac.fatburen.org (localhost [127.0.0.1])
	by multivac.fatburen.org (8.13.6/8.13.6) with ESMTP id k5JLj5UQ090790
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Mon, 19 Jun 2006 23:45:05 +0200 (CEST)
	(envelope-from staffanu@multivac.fatburen.org)
Received: (from staffanu@localhost)
	by multivac.fatburen.org (8.13.6/8.13.6/Submit) id k5JLj5Hx090785;
	Mon, 19 Jun 2006 23:45:05 +0200 (CEST)
	(envelope-from staffanu)
Message-Id: <200606192145.k5JLj5Hx090785@multivac.fatburen.org>
Date: Mon, 19 Jun 2006 23:45:05 +0200 (CEST)
From: Staffan Ulfberg <staffan@ulfberg.se>
To: FreeBSD-gnats-submit@freebsd.org
Cc: Staffan Ulfberg <staffan@ulfberg.se>
Subject: FIN in same packet as duplicate ACK is lost
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         99188
>Category:       kern
>Synopsis:       [tcp] [patch] FIN in same packet as duplicate ACK is lost
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    eadler
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 19 21:50:18 GMT 2006
>Closed-Date:    Mon Dec 02 03:14:47 UTC 2013
>Last-Modified:  Tue Jan  7 23:10:06 UTC 2014
>Originator:     Staffan Ulfberg
>Release:        FreeBSD 5.5-PRERELEASE i386
>Organization:
Harmonicode AB 
>Environment:
System: FreeBSD multivac.fatburen.org 5.5-PRERELEASE FreeBSD 5.5-PRERELEASE #5: Mon Jun 19 02:16:36 CEST 2006 staffanu@multivac.fatburen.org:/usr/obj/usr/src/sys/MULTIVAC i386


	
>Description:

When the remote end of a socket sends a FIN, it is lost when the
following critera is met:

	- The packet contains to other data.

	- The packet also contains an ACK for a sequence number that
	  has already been acked.

	- There is un-acked data on the way to the client.

(If the net.inet.tcp.rfc3042 sysctl is cleared, the FIN is not dropped
if this is the first or second duplicate ACK.)

The code that checks the conditions above are there to trigger a
resend to the remote end when a duplicate ACK is received.  It turns
out that the code that does that also drops the packet, probably since
it doesn't contain any data anyway.

It turns out that there is one more exception: if the packet contains
a window update, it is not handled as above, in order not to miss the
window update.  

I believe a FIN should be handled the same way.  That is, handling the
FIN is more important than handling the duplicate ACK.

>How-To-Repeat:

Compile and run the following two programs.  The first one is the
server and runs on FreeBSD.  Compile with g++:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>

int main()
{
  int listenFd;
  if ((listenFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
  {
    fprintf(stderr, "Error creating socket: %s\n", strerror(errno));
    exit(1);
  }

  int trueValue = 1;
  setsockopt(listenFd,
             SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(trueValue));

  sockaddr_in listenAddress;
  listenAddress.sin_family = AF_INET;
  listenAddress.sin_port = htons(5000);
  listenAddress.sin_addr.s_addr = INADDR_ANY;
  if (bind(listenFd, (struct sockaddr *) &listenAddress,
           sizeof(listenAddress)))
  {
    fprintf(stderr, "Bind failed: %s.\n", strerror(errno));
    exit(1);
  }
  if (listen(listenFd, 1) == -1)
  {
    fprintf(stderr, "Listen failed: %s.\n", strerror(errno));
    exit(1);
  }

  sockaddr_in clientSockAddress;
  unsigned int l = sizeof(struct sockaddr_in);
  int clientFd = accept(listenFd, (struct sockaddr *) &clientSockAddress, &l);
  if (clientFd == -1)
  {
    fprintf(stderr, "accept() failed: %s.\n", strerror(errno));
    exit(1);
  }

  char buf[10000];
  for (int i = 0; i < 100; i++)
  {
    int r = send(clientFd, buf, 1360, 0);
    if (r == -1)
    {
      fprintf(stderr, "send() failed: %s.\n", strerror(errno));
      exit(1);
    }
    else if (r != 1360)
    {
      fprintf(stderr, "send() returned %d", r);
    }
  }
  printf("sent everything\n");

  while (read(clientFd, buf, 10000) != 0)
    printf("read something\n");

  printf("closed.\n");

  return 0;
}

The second one is the client and runs on Windows XP SP2:

#include <stdio.h> 
#include <winsock2.h>

int main()
{
  WORD wVersionRequested;
  WSADATA wsaData;
  int err;
  
  wVersionRequested = MAKEWORD(2, 2);
  err = WSAStartup(wVersionRequested, &wsaData);
  if (err != 0) {
    fprintf(stderr, "error starting winsock\n");
    exit(1);
  }

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(5000);
  struct hostent *hostent = gethostbyname("172.22.32.206");
  addr.sin_addr.s_addr = inet_addr("172.22.32.206");
  if (addr.sin_addr.s_addr == INADDR_NONE) {
    fprintf(stderr, "bad remote address\n");
    exit(1);
  }
  
  SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (s == INVALID_SOCKET)
  {
    fprintf(stderr, "could not create socket");
    exit(1);
  }
  
  int r = connect(s, (struct sockaddr *) &addr, sizeof addr);
  if (r == SOCKET_ERROR)
  {
    closesocket(s);
    fprintf(stderr, "connect failed\n");
    exit(1);
  }

  char buf[10000];
  for (int i = 0; i < 99; i++)
  {
    int r = recv(s, buf, 1360, 0);
    if (r == SOCKET_ERROR)
    {
      closesocket(s);
      fprintf(stderr, "read error\n");
      exit(1);
    }
  }
  shutdown(s, SD_SEND);

  Sleep(1000);

  closesocket(s);

  WSACleanup();
  return 0;
}

Compile on Windows using "cl close.cpp wsock32.lib", if the file name
is "close.cpp".

What happens is that the client connects to a server that has the
intent of sending 100 1360 byte messages.  After 99 messages, the
client sends a FIN, by doing shutdown() on its outgoing part of the
socket.  After this, the server will never be able to understand that
this socket is really dead.  (Compare netstat on the Windows machine
and on the FreeBSD machine.)

The test only works on a relatively slow link.  For the bug to be
triggered, it is necessary that the last ack before sending the FIN is
for the same sequence number that is the last received when sending
hte FIN.

>Fix:

I made the following patch to tcp_input.c, which is similar to how a
similar patch was made years ago to fix a problem where window updates
were discarded:

multivac# diff -u tcp_input.c.orig tcp_input.c 
--- tcp_input.c.orig    Thu Mar 30 16:03:34 2006
+++ tcp_input.c Mon Jun 19 02:06:14 2006
@@ -1952,7 +1952,8 @@
        case TCPS_TIME_WAIT:
                KASSERT(tp->t_state != TCPS_TIME_WAIT, ("timewait"));
                if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
-                       if (tlen == 0 && tiwin == tp->snd_wnd) {
+                       if (tlen == 0 && tiwin == tp->snd_wnd && 
+                           !(thflags & TH_FIN)) {
                                tcpstat.tcps_rcvdupack++;
                                /*
                                 * If we have outstanding data (other than

/ Staffan
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: rodrigc 
Responsible-Changed-When: Mon Jun 19 21:54:45 UTC 2006 
Responsible-Changed-Why:  
Send to maintainers 

http://www.freebsd.org/cgi/query-pr.cgi?pr=99188 

From: Staffan Ulfberg <staffan@ulfberg.se>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: [tcp] [patch] FIN in same packet as duplicate ACK is lost
Date: 20 Jun 2006 21:49:16 +0200

 I forgot to say that the Windows XP test code in the PR was compiled
 using the "cl" command line compiler from Microsoft Visual Studio.
 
 Anyway, when runnging the test code in the report, the following is a
 dump of the last packets captured by tcpdumpa dn presented by ethereal:
 
 No.     Time            Source                Destination           Protocol Info
     135 23:48:02.409915 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=122401 Ack=1 Win=65535 Len=1360
     136 23:48:02.409922 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=123761 Ack=1 Win=65535 Len=1360
     137 23:48:02.409926 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=125121 Ack=1 Win=65535 Len=1360
     138 23:48:02.409932 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=126481 Ack=1 Win=65535 Len=1360
     139 23:48:02.409936 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=127841 Ack=1 Win=65535 Len=1360
     140 23:48:02.409939 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=129201 Ack=1 Win=65535 Len=1360
     141 23:48:02.410012 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=1 Ack=121041 Win=65535 Len=0
     142 23:48:02.410029 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=130561 Ack=1 Win=65535 Len=1360
     143 23:48:02.410033 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=131921 Ack=1 Win=65535 Len=1360
     144 23:48:02.410037 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [ACK] Seq=133281 Ack=1 Win=65535 Len=1360
     145 23:48:02.431375 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=1 Ack=125121 Win=65535 Len=0
     146 23:48:02.431378 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=1 Ack=127841 Win=65535 Len=0
     147 23:48:02.431380 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=1 Ack=131921 Win=65535 Len=0
     148 23:48:02.431382 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=1 Ack=134641 Win=65535 Len=0
     149 23:48:02.431384 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [FIN, ACK] Seq=1 Ack=134641 Win=65535 Len=0
     150 23:48:02.431399 172.22.32.206         10.0.3.5              TCP      5000 > 1327 [PSH, ACK] Seq=134641 Ack=1 Win=65535 Len=1360
     151 23:48:02.647004 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [ACK] Seq=2 Ack=136001 Win=65535 Len=0
     152 23:48:03.413573 10.0.3.5              172.22.32.206         TCP      1327 > 5000 [RST, ACK] Seq=2 Ack=136001 Win=0 Len=0
 
 10.0.3.5 was the client computer, and 172.22.32.206 was the server.
 
 After the session above, the socket on the server was in "ESTABLISHED" state.
 
 Staffan
 
Responsible-Changed-From-To: freebsd-net->andre 
Responsible-Changed-By: andre 
Responsible-Changed-When: Mon Jun 26 16:15:49 UTC 2006 
Responsible-Changed-Why:  
Take over. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=99188 
State-Changed-From-To: open->closed 
State-Changed-By: eadler 
State-Changed-When: Mon Dec 2 03:14:46 UTC 2013 
State-Changed-Why:  
finally, commit and close this PR. Thanks for your submission.  In order 
to avoid regressions I do not plan on MFCing this change so the first 
release to see this will be 11.0. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=99188 
Responsible-Changed-From-To: andre->eadler 
Responsible-Changed-By: eadler 
Responsible-Changed-When: Mon Dec 2 03:14:55 UTC 2013 
Responsible-Changed-Why:  
I'll take it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=99188 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Mon,  2 Dec 2013 03:11:34 +0000 (UTC)

 Author: eadler
 Date: Mon Dec  2 03:11:25 2013
 New Revision: 258821
 URL: http://svnweb.freebsd.org/changeset/base/258821
 
 Log:
   In a situation where:
   	- The remote host sends a FIN
   	- in an ACK for a sequence number for which an ACK has already
   	  been received
   	- There is still unacked data on route to the remote host
   	- The packet does not contain a window update
   
   The packet may be dropped without processing the FIN flag.
   
   PR:		kern/99188
   Submitted by:	Staffan Ulfberg <staffan@ulfberg.se>
   Discussed with:	andre
   MFC after:	never
 
 Modified:
   head/sys/netinet/tcp_input.c
 
 Modified: head/sys/netinet/tcp_input.c
 ==============================================================================
 --- head/sys/netinet/tcp_input.c	Mon Dec  2 02:33:03 2013	(r258820)
 +++ head/sys/netinet/tcp_input.c	Mon Dec  2 03:11:25 2013	(r258821)
 @@ -2429,13 +2429,15 @@ tcp_do_segment(struct mbuf *m, struct tc
  		hhook_run_tcp_est_in(tp, th, &to);
  
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				TCPSTAT_INC(tcps_rcvdupack);
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:01:42 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:01:33 2014
 New Revision: 260419
 URL: http://svnweb.freebsd.org/changeset/base/260419
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:             kern/99188
 
 Modified:
   stable/9/sys/netinet/tcp_input.c
 
 Modified: stable/9/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/9/sys/netinet/tcp_input.c	Tue Jan  7 23:01:05 2014	(r260418)
 +++ stable/9/sys/netinet/tcp_input.c	Tue Jan  7 23:01:33 2014	(r260419)
 @@ -2407,13 +2407,15 @@ tcp_do_segment(struct mbuf *m, struct tc
  		hhook_run_tcp_est_in(tp, th, &to);
  
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				TCPSTAT_INC(tcps_rcvdupack);
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:01:06 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:00:58 2014
 New Revision: 260417
 URL: http://svnweb.freebsd.org/changeset/base/260417
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:		kern/99188
 
 Modified:
   stable/10/sys/netinet/tcp_input.c
 
 Modified: stable/10/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/10/sys/netinet/tcp_input.c	Tue Jan  7 22:59:33 2014	(r260416)
 +++ stable/10/sys/netinet/tcp_input.c	Tue Jan  7 23:00:58 2014	(r260417)
 @@ -2429,13 +2429,15 @@ tcp_do_segment(struct mbuf *m, struct tc
  		hhook_run_tcp_est_in(tp, th, &to);
  
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				TCPSTAT_INC(tcps_rcvdupack);
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:04:14 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:04:06 2014
 New Revision: 260423
 URL: http://svnweb.freebsd.org/changeset/base/260423
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:             kern/99188
 
 Modified:
   stable/4/sys/netinet/tcp_input.c
 
 Modified: stable/4/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/4/sys/netinet/tcp_input.c	Tue Jan  7 23:03:31 2014	(r260422)
 +++ stable/4/sys/netinet/tcp_input.c	Tue Jan  7 23:04:06 2014	(r260423)
 @@ -1705,13 +1705,15 @@ trimthenstep6:
  	case TCPS_TIME_WAIT:
  
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				tcpstat.tcps_rcvdupack++;
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:03:39 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:03:31 2014
 New Revision: 260422
 URL: http://svnweb.freebsd.org/changeset/base/260422
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:             kern/99188
 
 Modified:
   stable/6/sys/netinet/tcp_input.c
 
 Modified: stable/6/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/6/sys/netinet/tcp_input.c	Tue Jan  7 23:02:50 2014	(r260421)
 +++ stable/6/sys/netinet/tcp_input.c	Tue Jan  7 23:03:31 2014	(r260422)
 @@ -1858,13 +1858,15 @@ trimthenstep6:
  		    (to.to_nsacks > 0 || !TAILQ_EMPTY(&tp->snd_holes)))
  			tcp_sack_doack(tp, &to, th->th_ack);
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				tcpstat.tcps_rcvdupack++;
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:02:21 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:02:13 2014
 New Revision: 260420
 URL: http://svnweb.freebsd.org/changeset/base/260420
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:             kern/99188
 
 Modified:
   stable/8/sys/netinet/tcp_input.c
 
 Modified: stable/8/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/8/sys/netinet/tcp_input.c	Tue Jan  7 23:01:33 2014	(r260419)
 +++ stable/8/sys/netinet/tcp_input.c	Tue Jan  7 23:02:13 2014	(r260420)
 @@ -2318,13 +2318,15 @@ tcp_do_segment(struct mbuf *m, struct tc
  		hhook_run_tcp_est_in(tp, th, &to);
  
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				TCPSTAT_INC(tcps_rcvdupack);
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/99188: commit references a PR
Date: Tue,  7 Jan 2014 23:02:59 +0000 (UTC)

 Author: peter
 Date: Tue Jan  7 23:02:50 2014
 New Revision: 260421
 URL: http://svnweb.freebsd.org/changeset/base/260421
 
 Log:
   MFC r258821 - fix tcp simultaneous close
   
   PR:             kern/99188
 
 Modified:
   stable/7/sys/netinet/tcp_input.c
 
 Modified: stable/7/sys/netinet/tcp_input.c
 ==============================================================================
 --- stable/7/sys/netinet/tcp_input.c	Tue Jan  7 23:02:13 2014	(r260420)
 +++ stable/7/sys/netinet/tcp_input.c	Tue Jan  7 23:02:50 2014	(r260421)
 @@ -1751,13 +1751,15 @@ tcp_do_segment(struct mbuf *m, struct tc
  		     !TAILQ_EMPTY(&tp->snd_holes)))
  			tcp_sack_doack(tp, &to, th->th_ack);
  		if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
 -			if (tlen == 0 && tiwin == tp->snd_wnd) {
 +			if (tlen == 0 && tiwin == tp->snd_wnd &&
 +			    !(thflags & TH_FIN)) {
  				tcpstat.tcps_rcvdupack++;
  				/*
  				 * If we have outstanding data (other than
  				 * a window probe), this is a completely
  				 * duplicate ack (ie, window info didn't
 -				 * change), the ack is the biggest we've
 +				 * change and FIN isn't set),
 +				 * the ack is the biggest we've
  				 * seen and we've seen exactly our rexmt
  				 * threshhold of them, assume a packet
  				 * has been dropped and retransmit it.
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
