Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 28 May 2015 18:34:03 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r283662 - head/sys/netinet
Message-ID:  <201505281834.t4SIY399084635@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu May 28 18:34:02 2015
New Revision: 283662
URL: https://svnweb.freebsd.org/changeset/base/283662

Log:
  Fix a bug where messages would not be sent in SHUTDOWN_RECEIVED state.
  This problem was reported by Mark Bonnekessel and Markus Boese.
  Thanks to Irene Ruengeler for helping me to fix the cause of
  the problem. It can be tested with the following packetdrill script:
  
  +0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
  +0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
  +0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
  // Check the handshake with an empty(!) cookie
  +0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
  +0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=0, ...]
  +0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=10000, os=1, is=1, tsn=0, STATE_COOKIE[len=4, val=...]]
  +0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...]
  +0.1 < sctp: COOKIE_ACK[flgs=0]
  +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
  +0.0 write(3, ..., 1024) = 1024
  +0.0 > sctp: DATA[flgs=BE, len=1040, tsn=0, sid=0, ssn=0, ppid=0]
  +0.0 write(3, ..., 1024) = 1024 // Pending due to Nagle
  +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
  +0.0 > sctp: DATA[flgs=BE, len=1040, tsn=1, sid=0, ssn=1, ppid=0]
  +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=10000, gaps=[], dups=[]] // Do we need another SHUTDOWN here?
  +0.0 > sctp: SHUTDOWN_ACK[flgs=0]
  +0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
  +0.0 close(3) = 0
  
  MFC after: 3 days

Modified:
  head/sys/netinet/sctp_asconf.c
  head/sys/netinet/sctp_output.c

Modified: head/sys/netinet/sctp_asconf.c
==============================================================================
--- head/sys/netinet/sctp_asconf.c	Thu May 28 18:24:22 2015	(r283661)
+++ head/sys/netinet/sctp_asconf.c	Thu May 28 18:34:02 2015	(r283662)
@@ -1977,7 +1977,8 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *
 			 * sent when the state goes open.
 			 */
 			if (status == 0 &&
-			    SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+			    ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+			    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
 #ifdef SCTP_TIMER_BASED_ASCONF
 				sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
 				    stcb, stcb->asoc.primary_destination);
@@ -2225,7 +2226,8 @@ sctp_asconf_iterator_stcb(struct sctp_in
 			 * count of queued params.  If in the non-open
 			 * state, these get sent when the assoc goes open.
 			 */
-			if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+			if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+			    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 				if (status >= 0) {
 					num_queued++;
 				}
@@ -2285,7 +2287,8 @@ sctp_set_primary_ip_address_sa(struct sc
 		    "set_primary_ip_address_sa: queued on tcb=%p, ",
 		    (void *)stcb);
 		SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
-		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+		if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+		    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 #ifdef SCTP_TIMER_BASED_ASCONF
 			sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
 			    stcb->sctp_ep, stcb,
@@ -2321,7 +2324,8 @@ sctp_set_primary_ip_address(struct sctp_
 				SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
 				    (void *)stcb);
 				SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
-				if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) {
+				if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
+				    (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 #ifdef SCTP_TIMER_BASED_ASCONF
 					sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
 					    stcb->sctp_ep, stcb,

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Thu May 28 18:24:22 2015	(r283661)
+++ head/sys/netinet/sctp_output.c	Thu May 28 18:34:02 2015	(r283662)
@@ -8535,7 +8535,8 @@ again_one_more_time:
 			omtu = 0;
 			break;
 		}
-		if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) &&
+		if ((((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
+		    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) &&
 		    (skip_data_for_this_net == 0)) ||
 		    (cookie)) {
 			TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505281834.t4SIY399084635>