diff options
author | tuexen <tuexen@FreeBSD.org> | 2016-08-25 09:16:25 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2016-08-25 09:16:25 +0000 |
commit | 986f593e4573a0f751ae6fa39b49e0a0dcbefbf8 (patch) | |
tree | 25759e0b096af49993553ae7b0f639f532d85b19 | |
parent | c62215e47d6d0ba8dd0a1dc4547b25667475245e (diff) | |
download | FreeBSD-src-986f593e4573a0f751ae6fa39b49e0a0dcbefbf8.zip FreeBSD-src-986f593e4573a0f751ae6fa39b49e0a0dcbefbf8.tar.gz |
MFC r304543:
Unbreak sctp_connectx().
MFC r304573:
Remove duplicate code, which is not protected by the appropriate locks.
MFC r304579:
Improve the locking when sending user messages.
First, keep a ref count on the stcb after looking it up, as
done in the other lookup cases.
Second, before looking again at sp, ensure that it is not
freed, because the assoc is about to be freed.
-rw-r--r-- | sys/netinet/sctp_output.c | 9 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 5 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 6 |
3 files changed, 11 insertions, 9 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 621b25e..88c0895 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -12639,7 +12639,10 @@ sctp_lower_sosend(struct socket *so, } SCTP_INP_RUNLOCK(inp); } else if (sinfo_assoc_id) { - stcb = sctp_findassociation_ep_asocid(inp, sinfo_assoc_id, 0); + stcb = sctp_findassociation_ep_asocid(inp, sinfo_assoc_id, 1); + if (stcb != NULL) { + hold_tcblock = 1; + } } else if (addr) { /*- * Since we did not use findep we must @@ -13404,6 +13407,10 @@ skip_preblock: } } SCTP_TCB_SEND_LOCK(stcb); + if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { + SCTP_TCB_SEND_UNLOCK(stcb); + goto out_unlocked; + } if (sp) { if (sp->msg_is_complete == 0) { strm->last_msg_incomplete = 1; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index fc2b9bb..77dd634 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -1506,11 +1506,6 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval, sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); } SCTP_TCB_UNLOCK(stcb); - if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { - stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; - /* Set the connected flag so we can queue data */ - soisconnecting(so); - } out_now: if (creat_lock_on) { SCTP_ASOC_CREATE_UNLOCK(inp); diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 6d263ed..4d5d497 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -6356,7 +6356,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, struct sctp_tcb *stcb = NULL; unsigned int incr, at, i; - at = incr = 0; + at = 0; sa = addr; *error = *num_v6 = *num_v4 = 0; /* account and validate addresses */ @@ -6364,6 +6364,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, switch (sa->sa_family) { #ifdef INET case AF_INET: + incr = (unsigned int)sizeof(struct sockaddr_in); if (sa->sa_len != incr) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); *error = EINVAL; @@ -6371,7 +6372,6 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, return (NULL); } (*num_v4) += 1; - incr = (unsigned int)sizeof(struct sockaddr_in); break; #endif #ifdef INET6 @@ -6387,6 +6387,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, *bad_addr = 1; return (NULL); } + incr = (unsigned int)sizeof(struct sockaddr_in6); if (sa->sa_len != incr) { SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL); *error = EINVAL; @@ -6394,7 +6395,6 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, return (NULL); } (*num_v6) += 1; - incr = (unsigned int)sizeof(struct sockaddr_in6); break; } #endif |