Ensure that outgoing streams get reset when they run dry.
MFC after: 1 week
This commit is contained in:
parent
4fe2405f36
commit
e5fb4876d3
@ -2763,6 +2763,11 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
|
||||
panic("No chunks on the queues for sid %u.", tp1->rec.data.stream_number);
|
||||
#endif
|
||||
}
|
||||
if ((stcb->asoc.strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
|
||||
(stcb->asoc.strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
|
||||
TAILQ_EMPTY(&stcb->asoc.strmout[tp1->rec.data.stream_number].outqueue)) {
|
||||
stcb->asoc.trigger_reset = 1;
|
||||
}
|
||||
tp1->sent = SCTP_DATAGRAM_NR_ACKED;
|
||||
if (tp1->data) {
|
||||
/*
|
||||
@ -3736,6 +3741,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ((asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
|
||||
(asoc->strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
|
||||
TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.stream_number].outqueue)) {
|
||||
asoc->trigger_reset = 1;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
|
||||
if (tp1->data) {
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
@ -4461,6 +4471,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ((asoc->strmout[tp1->rec.data.stream_number].chunks_on_queues == 0) &&
|
||||
(asoc->strmout[tp1->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
|
||||
TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.stream_number].outqueue)) {
|
||||
asoc->trigger_reset = 1;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
|
||||
if (PR_SCTP_ENABLED(tp1->flags)) {
|
||||
if (asoc->pr_sctp_cnt != 0)
|
||||
|
@ -6024,7 +6024,7 @@ trigger_send:
|
||||
if (!TAILQ_EMPTY(&stcb->asoc.control_send_queue)) {
|
||||
cnt_ctrl_ready = stcb->asoc.ctrl_queue_cnt - stcb->asoc.ecn_echo_cnt_onq;
|
||||
}
|
||||
if (cnt_ctrl_ready ||
|
||||
if (cnt_ctrl_ready || stcb->asoc.trigger_reset ||
|
||||
((un_sent) &&
|
||||
(stcb->asoc.peers_rwnd > 0 ||
|
||||
(stcb->asoc.peers_rwnd <= 0 && stcb->asoc.total_flight == 0)))) {
|
||||
|
@ -9897,7 +9897,6 @@ sctp_chunk_output(struct sctp_inpcb *inp,
|
||||
asoc = &stcb->asoc;
|
||||
do_it_again:
|
||||
/* The Nagle algorithm is only applied when handling a send call. */
|
||||
stcb->asoc.trigger_reset = 0;
|
||||
if (from_where == SCTP_OUTPUT_FROM_USR_SEND) {
|
||||
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_NODELAY)) {
|
||||
nagle_on = 0;
|
||||
@ -9914,7 +9913,8 @@ do_it_again:
|
||||
if ((un_sent <= 0) &&
|
||||
(TAILQ_EMPTY(&asoc->control_send_queue)) &&
|
||||
(TAILQ_EMPTY(&asoc->asconf_send_queue)) &&
|
||||
(asoc->sent_queue_retran_cnt == 0)) {
|
||||
(asoc->sent_queue_retran_cnt == 0) &&
|
||||
(asoc->trigger_reset == 0)) {
|
||||
/* Nothing to do unless there is something to be sent left */
|
||||
return;
|
||||
}
|
||||
@ -11885,6 +11885,7 @@ sctp_send_stream_reset_out_if_possible(struct sctp_tcb *stcb, int so_locked)
|
||||
uint32_t seq;
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
asoc->trigger_reset = 0;
|
||||
if (asoc->stream_reset_outstanding) {
|
||||
return (EALREADY);
|
||||
}
|
||||
|
@ -442,6 +442,11 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
|
||||
asoc->strmout[chk->rec.data.stream_number].chunks_on_queues--;
|
||||
}
|
||||
}
|
||||
if ((asoc->strmout[chk->rec.data.stream_number].chunks_on_queues == 0) &&
|
||||
(asoc->strmout[chk->rec.data.stream_number].state == SCTP_STREAM_RESET_PENDING) &&
|
||||
TAILQ_EMPTY(&asoc->strmout[chk->rec.data.stream_number].outqueue)) {
|
||||
asoc->trigger_reset = 1;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
|
||||
if (PR_SCTP_ENABLED(chk->flags)) {
|
||||
if (asoc->pr_sctp_cnt != 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user