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 {