From owner-svn-src-all@FreeBSD.ORG Thu Feb 12 17:31:39 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C58EB1065674; Thu, 12 Feb 2009 17:31:39 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 992F78FC08; Thu, 12 Feb 2009 17:31:39 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1CHVdaD062201; Thu, 12 Feb 2009 17:31:39 GMT (envelope-from rrs@svn.freebsd.org) Received: (from rrs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1CHVdD4062199; Thu, 12 Feb 2009 17:31:39 GMT (envelope-from rrs@svn.freebsd.org) Message-Id: <200902121731.n1CHVdD4062199@svn.freebsd.org> From: Randall Stewart Date: Thu, 12 Feb 2009 17:31:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188523 - in stable/7/sys: . netinet X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Feb 2009 17:31:41 -0000 Author: rrs Date: Thu Feb 12 17:31:39 2009 New Revision: 188523 URL: http://svn.freebsd.org/changeset/base/188523 Log: MFC of 184336: 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: stable/7/sys/ (props changed) stable/7/sys/netinet/sctp_output.c Modified: stable/7/sys/netinet/sctp_output.c ============================================================================== --- stable/7/sys/netinet/sctp_output.c Thu Feb 12 17:26:16 2009 (r188522) +++ stable/7/sys/netinet/sctp_output.c Thu Feb 12 17:31:39 2009 (r188523) @@ -11686,7 +11686,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; @@ -12448,7 +12453,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); @@ -13063,7 +13069,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);