svn commit: r359302 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Wed Mar 25 15:29:11 UTC 2020


Author: tuexen
Date: Wed Mar 25 15:29:01 2020
New Revision: 359302
URL: https://svnweb.freebsd.org/changeset/base/359302

Log:
  Revert https://svnweb.freebsd.org/changeset/base/357829
  
  This introduces a regression reported by koobs@ when running a pyhton
  test suite on a loaded system.
  
  This patch resulted in a failing accept() call, when the association
  was setup and gracefully shutdown by the peer before accept was called.
  So the following packetdrill script would fail:
  
  +0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
  +0.0 bind(3, ..., ...) = 0
  +0.0 listen(3, 1) = 0
  +0.0 < sctp: INIT[flgs=0, tag=1, a_rwnd=15000, os=1, is=1, tsn=1]
  +0.0 > sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=..., os=..., is=..., tsn=1, ...]
  +0.1 < sctp: COOKIE_ECHO[flgs=0, len=..., val=...]
  +0.0 > sctp: COOKIE_ACK[flgs=0]
  +0.0 < sctp: DATA[flgs=BE, len=116, tsn=1, sid=0, ssn=0, ppid=0]
  +0.0 > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]]
  +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
  +0.0 > sctp: SHUTDOWN_ACK[flgs=0]
  +0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
  +0.0 accept(3, ..., ...) = 4
  +0.0 close(3) = 0
  +0.0 recv(4, ..., 4096, 0) = 100
  +0.0 recv(4, ..., 4096, 0) = 0
  +0.0 close(4) = 0
  
  Reported by:		koops@

Modified:
  head/sys/netinet/sctp_pcb.c

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Wed Mar 25 13:19:41 2020	(r359301)
+++ head/sys/netinet/sctp_pcb.c	Wed Mar 25 15:29:01 2020	(r359302)
@@ -4739,31 +4739,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tc
 	else
 		so = inp->sctp_socket;
 
-	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
-	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
-		/*
-		 * For TCP type we need special handling when we are
-		 * connected. We also include the peel'ed off ones to.
-		 */
-		if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
-			inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
-			inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
-			if (so) {
-				SOCKBUF_LOCK(&so->so_rcv);
-				so->so_state &= ~(SS_ISCONNECTING |
-				    SS_ISDISCONNECTING |
-				    SS_ISCONFIRMING |
-				    SS_ISCONNECTED);
-				so->so_state |= SS_ISDISCONNECTED;
-				socantrcvmore_locked(so);
-				socantsendmore(so);
-				sctp_sowwakeup(inp, so);
-				sctp_sorwakeup(inp, so);
-				SCTP_SOWAKEUP(so);
-			}
-		}
-	}
-
 	/*
 	 * We used timer based freeing if a reader or writer is in the way.
 	 * So we first check if we are actually being called from a timer,
@@ -4890,6 +4865,31 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tc
 	    (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
 		/* nothing around */
 		so = NULL;
+
+	if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+	    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) {
+		/*
+		 * For TCP type we need special handling when we are
+		 * connected. We also include the peel'ed off ones to.
+		 */
+		if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
+			inp->sctp_flags &= ~SCTP_PCB_FLAGS_CONNECTED;
+			inp->sctp_flags |= SCTP_PCB_FLAGS_WAS_CONNECTED;
+			if (so) {
+				SOCKBUF_LOCK(&so->so_rcv);
+				so->so_state &= ~(SS_ISCONNECTING |
+				    SS_ISDISCONNECTING |
+				    SS_ISCONFIRMING |
+				    SS_ISCONNECTED);
+				so->so_state |= SS_ISDISCONNECTED;
+				socantrcvmore_locked(so);
+				socantsendmore(so);
+				sctp_sowwakeup(inp, so);
+				sctp_sorwakeup(inp, so);
+				SCTP_SOWAKEUP(so);
+			}
+		}
+	}
 
 	/*
 	 * Make it invalid too, that way if its about to run it will abort


More information about the svn-src-head mailing list