From owner-svn-src-all@FreeBSD.ORG Tue Feb 14 12:00:35 2012 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 36FCE1065714; Tue, 14 Feb 2012 12:00:35 +0000 (UTC) (envelope-from tuexen@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 255DD8FC0C; Tue, 14 Feb 2012 12:00:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q1EC0Z8l097099; Tue, 14 Feb 2012 12:00:35 GMT (envelope-from tuexen@svn.freebsd.org) Received: (from tuexen@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q1EC0YDw097097; Tue, 14 Feb 2012 12:00:34 GMT (envelope-from tuexen@svn.freebsd.org) Message-Id: <201202141200.q1EC0YDw097097@svn.freebsd.org> From: Michael Tuexen Date: Tue, 14 Feb 2012 12:00:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r231672 - head/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: Tue, 14 Feb 2012 12:00:35 -0000 Author: tuexen Date: Tue Feb 14 12:00:34 2012 New Revision: 231672 URL: http://svn.freebsd.org/changeset/base/231672 Log: Fix a bug where the wrong protocol overhead was used. This can lead to a deadlock of an association when an IPv6 socket was used to communcate with IPv4 and an ICMPv4 fragmentation needed message was received. While there, simplify the code a bit. MFC after: 3 days. Modified: head/sys/netinet/sctp_output.c Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Tue Feb 14 11:51:32 2012 (r231671) +++ head/sys/netinet/sctp_output.c Tue Feb 14 12:00:34 2012 (r231672) @@ -7612,16 +7612,22 @@ sctp_fill_outqueue(struct sctp_tcb *stcb SCTP_TCB_LOCK_ASSERT(stcb); asoc = &stcb->asoc; + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: + goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; + break; +#endif #ifdef INET6 - if (net->ro._l_addr.sin6.sin6_family == AF_INET6) { + case AF_INET6: goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; - } else { - /* ?? not sure what else to do */ - goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; - } -#else - goal_mtu = net->mtu - SCTP_MIN_OVERHEAD; + break; #endif + default: + /* TSNH */ + goal_mtu = net->mtu; + break; + } /* Need an allowance for the data chunk header too */ goal_mtu -= sizeof(struct sctp_data_chunk); @@ -8180,10 +8186,21 @@ again_one_more_time: if (!no_out_cnt) *num_out += ctl_cnt; /* recalc a clean slate and setup */ - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - mtu = (net->mtu - SCTP_MIN_OVERHEAD); - } else { - mtu = (net->mtu - SCTP_MIN_V4_OVERHEAD); + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: + mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; + break; +#endif +#ifdef INET6 + case AF_INET6: + mtu = net->mtu - SCTP_MIN_OVERHEAD; + break; +#endif + default: + /* TSNH */ + mtu = net->mtu; + break; } to_out = 0; no_fragmentflg = 1; @@ -8446,10 +8463,21 @@ again_one_more_time: if (!no_out_cnt) *num_out += ctl_cnt; /* recalc a clean slate and setup */ - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - mtu = (net->mtu - SCTP_MIN_OVERHEAD); - } else { - mtu = (net->mtu - SCTP_MIN_V4_OVERHEAD); + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: + mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; + break; +#endif +#ifdef INET6 + case AF_INET6: + mtu = net->mtu - SCTP_MIN_OVERHEAD; + break; +#endif + default: + /* TSNH */ + mtu = net->mtu; + break; } to_out = 0; no_fragmentflg = 1; @@ -9492,10 +9520,21 @@ sctp_chunk_retransmission(struct sctp_in } /* pick up the net */ net = chk->whoTo; - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { - mtu = (net->mtu - SCTP_MIN_OVERHEAD); - } else { + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: mtu = net->mtu - SCTP_MIN_V4_OVERHEAD; + break; +#endif +#ifdef INET6 + case AF_INET6: + mtu = net->mtu - SCTP_MIN_OVERHEAD; + break; +#endif + default: + /* TSNH */ + mtu = net->mtu; + break; } if ((asoc->peers_rwnd < mtu) && (asoc->total_flight > 0)) { @@ -9816,12 +9855,10 @@ one_chunk_around: return (0); } - -static int +static void sctp_timer_validation(struct sctp_inpcb *inp, struct sctp_tcb *stcb, - struct sctp_association *asoc, - int ret) + struct sctp_association *asoc) { struct sctp_nets *net; @@ -9829,7 +9866,7 @@ sctp_timer_validation(struct sctp_inpcb TAILQ_FOREACH(net, &asoc->nets, sctp_next) { if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { /* Here is a timer */ - return (ret); + return; } } SCTP_TCB_LOCK_ASSERT(stcb); @@ -9840,7 +9877,7 @@ sctp_timer_validation(struct sctp_inpcb } else { sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, asoc->primary_destination); } - return (ret); + return; } void @@ -9950,7 +9987,7 @@ sctp_chunk_output(struct sctp_inpcb *inp #ifdef SCTP_AUDITING_ENABLED sctp_auditing(8, inp, stcb, NULL); #endif - (void)sctp_timer_validation(inp, stcb, asoc, ret); + sctp_timer_validation(inp, stcb, asoc); return; } if (ret < 0) {