From owner-svn-src-stable@FreeBSD.ORG Sun May 16 16:42:53 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9038A106566C; Sun, 16 May 2010 16:42:53 +0000 (UTC) (envelope-from rrs@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7DFF48FC0A; Sun, 16 May 2010 16:42:53 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o4GGgrA3056776; Sun, 16 May 2010 16:42:53 GMT (envelope-from rrs@svn.freebsd.org) Received: (from rrs@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o4GGgrGD056771; Sun, 16 May 2010 16:42:53 GMT (envelope-from rrs@svn.freebsd.org) Message-Id: <201005161642.o4GGgrGD056771@svn.freebsd.org> From: Randall Stewart Date: Sun, 16 May 2010 16:42:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r208154 - stable/8/sys/netinet X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 16 May 2010 16:42:53 -0000 Author: rrs Date: Sun May 16 16:42:52 2010 New Revision: 208154 URL: http://svn.freebsd.org/changeset/base/208154 Log: MFC of 207924: This fixes a bug with the one-2-one model socket when a user sets up a socket to a server sends data and closes the socket before the server has called accept(). It used to NOT work at all. Now we add a flag to the assoc and defer assoc cleanup so that the accept will succeed Modified: stable/8/sys/netinet/sctp_constants.h stable/8/sys/netinet/sctp_input.c stable/8/sys/netinet/sctp_pcb.c stable/8/sys/netinet/sctp_usrreq.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/geom/sched/ (props changed) Modified: stable/8/sys/netinet/sctp_constants.h ============================================================================== --- stable/8/sys/netinet/sctp_constants.h Sun May 16 16:33:38 2010 (r208153) +++ stable/8/sys/netinet/sctp_constants.h Sun May 16 16:42:52 2010 (r208154) @@ -498,6 +498,7 @@ __FBSDID("$FreeBSD$"); #define SCTP_STATE_ABOUT_TO_BE_FREED 0x0200 #define SCTP_STATE_PARTIAL_MSG_LEFT 0x0400 #define SCTP_STATE_WAS_ABORTED 0x0800 +#define SCTP_STATE_IN_ACCEPT_QUEUE 0x1000 #define SCTP_STATE_MASK 0x007f #define SCTP_GET_STATE(asoc) ((asoc)->state & SCTP_STATE_MASK) Modified: stable/8/sys/netinet/sctp_input.c ============================================================================== --- stable/8/sys/netinet/sctp_input.c Sun May 16 16:33:38 2010 (r208153) +++ stable/8/sys/netinet/sctp_input.c Sun May 16 16:42:52 2010 (r208154) @@ -2743,6 +2743,14 @@ sctp_handle_cookie_echo(struct mbuf *m, * Now we must move it from one hash table to * another and get the tcb in the right place. */ + + /* + * This is where the one-2-one socket is put into + * the accept state waiting for the accept! + */ + if (*stcb) { + (*stcb)->asoc.state |= SCTP_STATE_IN_ACCEPT_QUEUE; + } sctp_move_pcb_and_assoc(*inp_p, inp, *stcb); atomic_add_int(&(*stcb)->asoc.refcnt, 1); @@ -4859,8 +4867,8 @@ process_control_chunks: } /* * First are we accepting? We do this again here - * sincen it is possible that a previous endpoint - * WAS listening responded to a INIT-ACK and then + * since it is possible that a previous endpoint WAS + * listening responded to a INIT-ACK and then * closed. We opened and bound.. and are now no * longer listening. */ Modified: stable/8/sys/netinet/sctp_pcb.c ============================================================================== --- stable/8/sys/netinet/sctp_pcb.c Sun May 16 16:33:38 2010 (r208153) +++ stable/8/sys/netinet/sctp_pcb.c Sun May 16 16:42:52 2010 (r208154) @@ -4576,12 +4576,13 @@ sctp_free_assoc(struct sctp_inpcb *inp, stcb->block_entry = NULL; } } - if (stcb->asoc.refcnt) { + if ((stcb->asoc.refcnt) || (stcb->asoc.state & SCTP_STATE_IN_ACCEPT_QUEUE)) { /* - * reader or writer in the way, we have hopefully given him - * something to chew on above. + * Someone holds a reference OR the socket is unaccepted + * yet. */ - sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL); + if (stcb->asoc.refcnt) + sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL); SCTP_TCB_UNLOCK(stcb); if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE)) Modified: stable/8/sys/netinet/sctp_usrreq.c ============================================================================== --- stable/8/sys/netinet/sctp_usrreq.c Sun May 16 16:33:38 2010 (r208153) +++ stable/8/sys/netinet/sctp_usrreq.c Sun May 16 16:42:52 2010 (r208154) @@ -1510,7 +1510,7 @@ sctp_do_connect_x(struct socket *so, str added = sctp_connectx_helper_add(stcb, sa, (totaddr - 1), &error); /* Fill in the return id */ if (error) { - (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_12); + (void)sctp_free_assoc(inp, stcb, SCTP_PCBFREE_FORCE, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6); goto out_now; } a_id = (sctp_assoc_t *) optval; @@ -4670,6 +4670,7 @@ sctp_accept(struct socket *so, struct so SCTP_TCB_LOCK(stcb); SCTP_INP_RUNLOCK(inp); store = stcb->asoc.primary_destination->ro._l_addr; + stcb->asoc.state &= ~SCTP_STATE_IN_ACCEPT_QUEUE; SCTP_TCB_UNLOCK(stcb); switch (store.sa.sa_family) { case AF_INET: @@ -4736,6 +4737,10 @@ sctp_accept(struct socket *so, struct so } SCTP_INP_WUNLOCK(inp); } + if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { + SCTP_TCB_LOCK(stcb); + sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7); + } return (0); }