Fix a regression with the explicit EOR mode I introduced in r364268.

A short MFC time as discussed with the secteam.

Reported by:		Taylor Brandstetter
MFC after:		1 day
This commit is contained in:
Michael Tuexen 2020-08-28 20:05:18 +00:00
parent 5c4f8d801c
commit 404ff76bda
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=364937

View File

@ -13118,11 +13118,10 @@ sctp_lower_sosend(struct socket *so,
error = EINVAL;
goto out;
}
SCTP_TCB_SEND_UNLOCK(stcb);
strm = &stcb->asoc.strmout[srcv->sinfo_stream];
if (strm->last_msg_incomplete == 0) {
do_a_copy_in:
SCTP_TCB_SEND_UNLOCK(stcb);
sp = sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
if (error) {
goto out;
@ -13151,19 +13150,8 @@ sctp_lower_sosend(struct socket *so,
sp->processing = 1;
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, asoc, strm, sp, 1);
SCTP_TCB_SEND_UNLOCK(stcb);
} else {
SCTP_TCB_SEND_LOCK(stcb);
sp = TAILQ_LAST(&strm->outqueue, sctp_streamhead);
if (sp->processing) {
SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
error = EINVAL;
goto out;
} else {
sp->processing = 1;
}
SCTP_TCB_SEND_UNLOCK(stcb);
if (sp == NULL) {
/* ???? Huh ??? last msg is gone */
#ifdef INVARIANTS
@ -13175,7 +13163,16 @@ sctp_lower_sosend(struct socket *so,
goto do_a_copy_in;
}
if (sp->processing) {
SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
error = EINVAL;
goto out;
} else {
sp->processing = 1;
}
}
SCTP_TCB_SEND_UNLOCK(stcb);
while (uio->uio_resid > 0) {
/* How much room do we have? */
struct mbuf *new_tail, *mm;
@ -13200,6 +13197,11 @@ sctp_lower_sosend(struct socket *so,
if (mm) {
sctp_m_freem(mm);
}
SCTP_TCB_SEND_LOCK(stcb);
if (sp != NULL) {
sp->processing = 0;
}
SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
/* Update the mbuf and count */
@ -13215,6 +13217,9 @@ sctp_lower_sosend(struct socket *so,
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
error = ECONNRESET;
}
if (sp != NULL) {
sp->processing = 0;
}
SCTP_TCB_SEND_UNLOCK(stcb);
goto out;
}
@ -13274,6 +13279,11 @@ sctp_lower_sosend(struct socket *so,
/* wait for space now */
if (non_blocking) {
/* Non-blocking io in place out */
SCTP_TCB_SEND_LOCK(stcb);
if (sp != NULL) {
sp->processing = 0;
}
SCTP_TCB_SEND_UNLOCK(stcb);
goto skip_out_eof;
}
/* What about the INIT, send it maybe */
@ -13401,6 +13411,11 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
SCTP_TCB_SEND_LOCK(stcb);
if (sp != NULL) {
sp->processing = 0;
}
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
@ -13410,9 +13425,15 @@ sctp_lower_sosend(struct socket *so,
}
}
SOCKBUF_UNLOCK(&so->so_snd);
SCTP_TCB_SEND_LOCK(stcb);
if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
if (sp != NULL) {
sp->processing = 0;
}
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_unlocked;
}
SCTP_TCB_SEND_UNLOCK(stcb);
}
SCTP_TCB_SEND_LOCK(stcb);
if ((stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) ||