git: 2450e717321e - stable/13 - sctp: cleanup, no functional change except on error paths
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Feb 2023 22:58:33 UTC
The branch stable/13 has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=2450e717321e94fae39b89eeefcc09edf932d32c commit 2450e717321e94fae39b89eeefcc09edf932d32c Author: Michael Tuexen <tuexen@FreeBSD.org> AuthorDate: 2022-05-28 09:34:20 +0000 Commit: Michael Tuexen <tuexen@FreeBSD.org> CommitDate: 2023-02-01 22:58:10 +0000 sctp: cleanup, no functional change except on error paths (cherry picked from commit 9cb70cb4769d2ef3a2e3b6d8bae8e0e59a4689e8) --- sys/netinet/sctp_output.c | 163 ++++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 84 deletions(-) diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index f35bb0bbafc3..4de6fe4a8b3e 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -11572,7 +11572,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u chk->rec.chunk_id.id = SCTP_ECN_CWR; chk->rec.chunk_id.can_take_data = 1; chk->flags = 0; - chk->asoc = &stcb->asoc; + chk->asoc = asoc; chk->send_size = sizeof(struct sctp_cwr_chunk); chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER); if (chk->data == NULL) { @@ -11590,7 +11590,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u cwr->ch.chunk_flags = override; cwr->ch.chunk_length = htons(sizeof(struct sctp_cwr_chunk)); cwr->tsn = htonl(high_tsn); - TAILQ_INSERT_TAIL(&stcb->asoc.control_send_queue, chk, sctp_next); + TAILQ_INSERT_TAIL(&asoc->control_send_queue, chk, sctp_next); asoc->ctrl_queue_cnt++; } @@ -12458,34 +12458,10 @@ sctp_lower_sosend(struct socket *so, net = NULL; stcb = NULL; - t_inp = inp = (struct sctp_inpcb *)so->so_pcb; - if (inp == NULL) { - error = EINVAL; - goto out_unlocked; - } if ((uio == NULL) && (top == NULL)) { error = EINVAL; goto out_unlocked; } - user_marks_eor = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); - atomic_add_int(&inp->total_sends, 1); - if (uio != NULL) { - if (uio->uio_resid < 0) { - error = EINVAL; - goto out_unlocked; - } - sndlen = uio->uio_resid; - } else { - sndlen = SCTP_HEADER_LEN(top); - } - SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zd\n", - (void *)addr, sndlen); - if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && - SCTP_IS_LISTENING(inp)) { - /* The listener can NOT send. */ - error = EINVAL; - goto out_unlocked; - } if (addr != NULL) { union sctp_sockstore *raddr = (union sctp_sockstore *)addr; @@ -12515,6 +12491,39 @@ sctp_lower_sosend(struct socket *so, } else { port = 0; } + if (uio != NULL) { + if (uio->uio_resid < 0) { + error = EINVAL; + goto out_unlocked; + } + sndlen = uio->uio_resid; + } else { + sndlen = SCTP_HEADER_LEN(top); + } + SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %zd\n", + (void *)addr, sndlen); + + t_inp = inp = (struct sctp_inpcb *)so->so_pcb; + if (inp == NULL) { + error = EINVAL; + goto out_unlocked; + } + user_marks_eor = sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR); + if ((uio == NULL) && (user_marks_eor != 0)) { + /*- + * We do not support eeor mode for + * sending with mbuf chains (like sendfile). + */ + error = EINVAL; + goto out_unlocked; + } + atomic_add_int(&inp->total_sends, 1); + if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && + SCTP_IS_LISTENING(inp)) { + /* The listener can NOT send. */ + error = EINVAL; + goto out_unlocked; + } if (srcv != NULL) { sinfo_flags = srcv->sinfo_flags; @@ -12524,8 +12533,9 @@ sctp_lower_sosend(struct socket *so, error = EINVAL; goto out_unlocked; } - if (srcv->sinfo_flags != 0) + if (srcv->sinfo_flags != 0) { SCTP_STAT_INCR(sctps_sends_with_flags); + } } else { sinfo_flags = inp->def_send.sinfo_flags; sinfo_assoc_id = inp->def_send.sinfo_assoc_id; @@ -12700,6 +12710,7 @@ sctp_lower_sosend(struct socket *so, KASSERT(stcb != NULL, ("stcb is NULL")); KASSERT(hold_tcblock, ("hold_tcblock is false")); SCTP_TCB_LOCK_ASSERT(stcb); + asoc = &stcb->asoc; if ((asoc->state & SCTP_STATE_ABOUT_TO_BE_FREED) || (asoc->state & SCTP_STATE_WAS_ABORTED)) { @@ -12711,10 +12722,13 @@ sctp_lower_sosend(struct socket *so, } goto out_unlocked; } + if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || + (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { + queue_only = 1; + } /* Keep the stcb from being freed under our feet. */ atomic_add_int(&asoc->refcnt, 1); free_cnt_applied = true; - if (srcv == NULL) { srcv = (struct sctp_sndrcvinfo *)&asoc->def_send; sinfo_flags = srcv->sinfo_flags; @@ -12726,10 +12740,11 @@ sctp_lower_sosend(struct socket *so, } } if (sinfo_flags & SCTP_ADDR_OVER) { - if (addr != NULL) + if (addr != NULL) { net = sctp_findnet(stcb, addr); - else + } else { net = NULL; + } if ((net == NULL) || ((port != 0) && (port != stcb->rport))) { error = EINVAL; @@ -12742,20 +12757,34 @@ sctp_lower_sosend(struct socket *so, net = asoc->primary_destination; } } - atomic_add_int(&stcb->total_sends, 1); - + /* Is the stream no. valid? */ + if (srcv->sinfo_stream >= asoc->streamoutcnt) { + /* Invalid stream number */ + error = EINVAL; + goto out_unlocked; + } + if ((asoc->strmout[srcv->sinfo_stream].state != SCTP_STREAM_OPEN) && + (asoc->strmout[srcv->sinfo_stream].state != SCTP_STREAM_OPENING)) { + /* + * Can't queue any data while stream reset is underway. + */ + if (asoc->strmout[srcv->sinfo_stream].state > SCTP_STREAM_OPEN) { + error = EAGAIN; + } else { + error = EINVAL; + } + goto out_unlocked; + } if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NO_FRAGMENT)) { if (sndlen > (ssize_t)asoc->smallest_mtu) { error = EMSGSIZE; goto out_unlocked; } } - if (SCTP_SO_IS_NBIO(so) - || (flags & (MSG_NBIO | MSG_DONTWAIT)) != 0 - ) { + atomic_add_int(&stcb->total_sends, 1); + if (SCTP_SO_IS_NBIO(so) || (flags & (MSG_NBIO | MSG_DONTWAIT)) != 0) { non_blocking = true; } - /* would we block? */ if (non_blocking) { ssize_t amount; @@ -12775,46 +12804,9 @@ sctp_lower_sosend(struct socket *so, } goto out_unlocked; } - asoc->sb_send_resv += (uint32_t)sndlen; - } else { - atomic_add_int(&asoc->sb_send_resv, (int)sndlen); } + atomic_add_int(&asoc->sb_send_resv, (int)sndlen); local_soresv = sndlen; - /* Is the stream no. valid? */ - if (srcv->sinfo_stream >= asoc->streamoutcnt) { - /* Invalid stream number */ - error = EINVAL; - goto out_unlocked; - } - if ((asoc->strmout[srcv->sinfo_stream].state != SCTP_STREAM_OPEN) && - (asoc->strmout[srcv->sinfo_stream].state != SCTP_STREAM_OPENING)) { - /* - * Can't queue any data while stream reset is underway. - */ - if (asoc->strmout[srcv->sinfo_stream].state > SCTP_STREAM_OPEN) { - error = EAGAIN; - } else { - error = EINVAL; - } - goto out_unlocked; - } - if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { - queue_only = 1; - } - if ((SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_SENT) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) || - (asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) { - if ((sinfo_flags & SCTP_ABORT) == 0) { - error = EPIPE; - goto out_unlocked; - } - } - /* Ok, we will attempt a msgsnd :> */ - if (p != NULL) { - p->td_ru.ru_msgsnd++; - } KASSERT(stcb != NULL, ("stcb is NULL")); KASSERT(hold_tcblock, ("hold_tcblock is false")); @@ -12835,7 +12827,7 @@ sctp_lower_sosend(struct socket *so, (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { /* It has to be up before we abort. */ error = EINVAL; - goto out; + goto out_unlocked; } /* How big is the user initiated abort? */ if (top != NULL) { @@ -12932,6 +12924,18 @@ sctp_lower_sosend(struct socket *so, KASSERT((asoc->state & SCTP_STATE_WAS_ABORTED) == 0, ("Association was aborted")); + if ((SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_SENT) || + (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED) || + (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) || + (asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) { + error = EPIPE; + goto out_unlocked; + } + /* Ok, we will attempt a msgsnd :> */ + if (p != NULL) { + p->td_ru.ru_msgsnd++; + } + /* Calculate the maximum we can send */ inqueue_bytes = asoc->total_output_queue_size - (asoc->chunks_on_out_queue * SCTP_DATA_CHUNK_OVERHEAD(stcb)); if (SCTP_SB_LIMIT_SND(so) > inqueue_bytes) { @@ -12946,15 +12950,6 @@ sctp_lower_sosend(struct socket *so, error = EMSGSIZE; goto out_unlocked; } - if ((uio == NULL) && (user_marks_eor != 0)) { - /*- - * We do not support eeor mode for - * sending with mbuf chains (like sendfile). - */ - error = EINVAL; - goto out_unlocked; - } - if (user_marks_eor != 0) { local_add_more = (ssize_t)min(SCTP_SB_LIMIT_SND(so), SCTP_BASE_SYSCTL(sctp_add_more_threshold)); } else {