diff options
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index f98a81e..0f8fa0b 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3242,12 +3242,13 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, } void -sctp_report_all_outbound(struct sctp_tcb *stcb) +sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock) { struct sctp_association *asoc; struct sctp_stream_out *outs; struct sctp_tmit_chunk *chk; struct sctp_stream_queue_pending *sp; + int i; asoc = &stcb->asoc; @@ -3257,9 +3258,12 @@ sctp_report_all_outbound(struct sctp_tcb *stcb) return; } /* now through all the gunk freeing chunks */ - - TAILQ_FOREACH(outs, &asoc->out_wheel, next_spoke) { - /* now clean up any chunks here */ + if (holds_lock == 0) + SCTP_TCB_SEND_LOCK(stcb); + for (i = 0; i < stcb->asoc.streamoutcnt; i++) { + /* For each stream */ + outs = &stcb->asoc.strmout[i]; + /* clean up any sends there */ stcb->asoc.locked_on_sending = NULL; sp = TAILQ_FIRST(&outs->outqueue); while (sp) { @@ -3338,6 +3342,8 @@ sctp_report_all_outbound(struct sctp_tcb *stcb) chk = TAILQ_FIRST(&asoc->sent_queue); } } + if (holds_lock == 0) + SCTP_TCB_SEND_UNLOCK(stcb); } void @@ -3350,7 +3356,7 @@ sctp_abort_notification(struct sctp_tcb *stcb, int error) return; } /* Tell them we lost the asoc */ - sctp_report_all_outbound(stcb); + sctp_report_all_outbound(stcb, 1); if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) || ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) { |