Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Oct 2008 14:01:23 +0000 (UTC)
From:      Randall Stewart <rrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r184336 - head/sys/netinet
Message-ID:  <200810271401.m9RE1NGF041281@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rrs
Date: Mon Oct 27 14:01:23 2008
New Revision: 184336
URL: http://svn.freebsd.org/changeset/base/184336

Log:
  Two inter-related bugs.
    - If we send EXACTLY the size left in the send buffer
      and then send again, we end up with exactly 0 bytes and
      don't hit the pre-block code to wait for more space.
    - If we fall into the loop with our max_len == 0 (the bug
      above) we then call in to copy out the data, setup the length
      of the waiting to transmit data to 0 and call the mbuf copy routine
      which 0 indicates copy all the data to the mbuf chain.. which it
      does. This then leaves a "stuck" message on the stream queue with
      its size exactly 0 bytes but all the data there and thus nothing
      left in the uio structure. We then reach a stuck forever state
      never being able to send data.

Modified:
  head/sys/netinet/sctp_output.c

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Mon Oct 27 13:56:27 2008	(r184335)
+++ head/sys/netinet/sctp_output.c	Mon Oct 27 14:01:23 2008	(r184336)
@@ -11682,7 +11682,12 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
 	sp->put_last_out = 0;
 	resv_in_first = sizeof(struct sctp_data_chunk);
 	sp->data = sp->tail_mbuf = NULL;
+	if (sp->length == 0) {
+		*error = 0;
+		goto skip_copy;
+	}
 	*error = sctp_copy_one(sp, uio, resv_in_first);
+skip_copy:
 	if (*error) {
 		sctp_free_a_strmoq(stcb, sp);
 		sp = NULL;
@@ -12443,7 +12448,8 @@ sctp_lower_sosend(struct socket *so,
 		goto skip_preblock;
 	}
 	if (((max_len <= local_add_more) &&
-	    (SCTP_SB_LIMIT_SND(so) > local_add_more)) ||
+	    (SCTP_SB_LIMIT_SND(so) >= local_add_more)) ||
+	    (max_len == 0) ||
 	    ((stcb->asoc.chunks_on_out_queue + stcb->asoc.stream_queue_cnt) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) {	/* if */
 		/* No room right now ! */
 		SOCKBUF_LOCK(&so->so_snd);
@@ -13058,7 +13064,7 @@ skip_out_eof:
 		(void)sctp_med_chunk_output(inp, stcb, &stcb->asoc, &num_out,
 		    &reason, 1, &cwnd_full, 1, &now, &now_filled, frag_point, SCTP_SO_LOCKED);
 	}
-	SCTPDBG(SCTP_DEBUG_OUTPUT1, "USR Send complete qo:%d prw:%d unsent:%d tf:%d cooq:%d toqs:%d err:%d",
+	SCTPDBG(SCTP_DEBUG_OUTPUT1, "USR Send complete qo:%d prw:%d unsent:%d tf:%d cooq:%d toqs:%d err:%d\n",
 	    queue_only, stcb->asoc.peers_rwnd, un_sent,
 	    stcb->asoc.total_flight, stcb->asoc.chunks_on_out_queue,
 	    stcb->asoc.total_output_queue_size, error);



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