svn commit: r207924 - head/sys/netinet
Randall Stewart
rrs at FreeBSD.org
Tue May 11 17:02:29 UTC 2010
Author: rrs
Date: Tue May 11 17:02:29 2010
New Revision: 207924
URL: http://svn.freebsd.org/changeset/base/207924
Log:
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 suceed.
Modified:
head/sys/netinet/sctp_constants.h
head/sys/netinet/sctp_input.c
head/sys/netinet/sctp_pcb.c
head/sys/netinet/sctp_usrreq.c
Modified: head/sys/netinet/sctp_constants.h
==============================================================================
--- head/sys/netinet/sctp_constants.h Tue May 11 17:02:12 2010 (r207923)
+++ head/sys/netinet/sctp_constants.h Tue May 11 17:02:29 2010 (r207924)
@@ -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: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c Tue May 11 17:02:12 2010 (r207923)
+++ head/sys/netinet/sctp_input.c Tue May 11 17:02:29 2010 (r207924)
@@ -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: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Tue May 11 17:02:12 2010 (r207923)
+++ head/sys/netinet/sctp_pcb.c Tue May 11 17:02:29 2010 (r207924)
@@ -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: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c Tue May 11 17:02:12 2010 (r207923)
+++ head/sys/netinet/sctp_usrreq.c Tue May 11 17:02:29 2010 (r207924)
@@ -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);
}
More information about the svn-src-head
mailing list