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
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to