diff options
| author | Michael Tuexen <tuexen@FreeBSD.org> | 2020-08-29 06:54:39 +0000 |
|---|---|---|
| committer | Michael Tuexen <tuexen@FreeBSD.org> | 2020-08-29 06:54:39 +0000 |
| commit | 3d32343d1b7c240bbf7057a8f7e0f236a22f8dc9 (patch) | |
| tree | 4fc8b7999a229d1217aea392844dad3be639817c /sys/netinet | |
| parent | 1d535b7e452951f9ed0cb4b75085635b893e0213 (diff) | |
Notes
Diffstat (limited to 'sys/netinet')
| -rw-r--r-- | sys/netinet/sctp_output.c | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 0edcdd1b1a1a..ace06f6679a8 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -13121,11 +13121,10 @@ skip_preblock: 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; @@ -13154,19 +13153,8 @@ skip_preblock: 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 @@ -13178,7 +13166,16 @@ skip_preblock: 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; @@ -13203,6 +13200,11 @@ skip_preblock: 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 */ @@ -13218,6 +13220,9 @@ skip_preblock: 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; } @@ -13277,6 +13282,11 @@ skip_preblock: /* 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 */ @@ -13400,6 +13410,11 @@ skip_preblock: } } SOCKBUF_UNLOCK(&so->so_snd); + SCTP_TCB_SEND_LOCK(stcb); + if (sp != NULL) { + sp->processing = 0; + } + SCTP_TCB_SEND_UNLOCK(stcb); goto out_unlocked; } @@ -13409,9 +13424,15 @@ skip_preblock: } } 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) || |
