Fixes for window probes:
1) WP should never be marked unless flight size is 0 2) When recovering from wp if the peer ack's it we don't mark for retran 3) When recovering, we must assure a timer is still running.
This commit is contained in:
parent
b7baebb91a
commit
5171328bd6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189444
@ -4179,13 +4179,8 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net,
|
||||
struct sctp_tmit_chunk *tp1)
|
||||
{
|
||||
struct sctp_tmit_chunk *chk;
|
||||
|
||||
/* First setup this one and get it moved back */
|
||||
sctp_flight_size_decrease(tp1);
|
||||
sctp_total_flight_decrease(stcb, tp1);
|
||||
tp1->window_probe = 0;
|
||||
if ((tp1->sent == SCTP_FORWARD_TSN_SKIP) || (tp1->data == NULL)) {
|
||||
if ((tp1->sent >= SCTP_DATAGRAM_ACKED) || (tp1->data == NULL)) {
|
||||
/* TSN's skipped we do NOT move back. */
|
||||
sctp_misc_ints(SCTP_FLIGHT_LOG_DWN_WP_FWD,
|
||||
tp1->whoTo->flight_size,
|
||||
@ -4194,7 +4189,12 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb,
|
||||
tp1->rec.data.TSN_seq);
|
||||
return;
|
||||
}
|
||||
tp1->sent = SCTP_DATAGRAM_UNSENT;
|
||||
/* First setup this by shrinking flight */
|
||||
sctp_flight_size_decrease(tp1);
|
||||
sctp_total_flight_decrease(stcb, tp1);
|
||||
/* Now mark for resend */
|
||||
tp1->sent = SCTP_DATAGRAM_RESEND;
|
||||
asoc->sent_queue_retran_cnt++;
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_FLIGHT_LOGGING_ENABLE) {
|
||||
sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_WP,
|
||||
tp1->whoTo->flight_size,
|
||||
@ -4202,26 +4202,6 @@ sctp_window_probe_recovery(struct sctp_tcb *stcb,
|
||||
(uintptr_t) tp1->whoTo,
|
||||
tp1->rec.data.TSN_seq);
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next);
|
||||
TAILQ_INSERT_HEAD(&asoc->send_queue, tp1, sctp_next);
|
||||
asoc->sent_queue_cnt--;
|
||||
asoc->send_queue_cnt++;
|
||||
/*
|
||||
* Now all guys marked for RESEND on the sent_queue must be moved
|
||||
* back too.
|
||||
*/
|
||||
TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
|
||||
if (chk->sent == SCTP_DATAGRAM_RESEND) {
|
||||
/* Another chunk to move */
|
||||
chk->sent = SCTP_DATAGRAM_UNSENT;
|
||||
/* It should not be in flight */
|
||||
TAILQ_REMOVE(&asoc->sent_queue, chk, sctp_next);
|
||||
TAILQ_INSERT_AFTER(&asoc->send_queue, tp1, chk, sctp_next);
|
||||
asoc->sent_queue_cnt--;
|
||||
asoc->send_queue_cnt++;
|
||||
sctp_ucount_decr(asoc->sent_queue_retran_cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -4552,8 +4532,9 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
again:
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
int to_ticks;
|
||||
|
||||
if (win_probe_recovery && (net->window_probe)) {
|
||||
net->window_probe = 0;
|
||||
win_probe_recovered = 1;
|
||||
/*
|
||||
* Find first chunk that was used with window probe
|
||||
@ -4562,25 +4543,35 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
|
||||
if (tp1->window_probe) {
|
||||
/* move back to data send queue */
|
||||
sctp_window_probe_recovery(stcb, asoc, net, tp1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (net->RTO == 0) {
|
||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
||||
} else {
|
||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
||||
}
|
||||
if (net->flight_size) {
|
||||
int to_ticks;
|
||||
|
||||
if (net->RTO == 0) {
|
||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
||||
} else {
|
||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
||||
}
|
||||
j++;
|
||||
(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
|
||||
sctp_timeout_handler, &net->rxt_timer);
|
||||
if (net->window_probe) {
|
||||
net->window_probe = 0;
|
||||
}
|
||||
} else {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
if (net->window_probe) {
|
||||
/*
|
||||
* In window probes we must assure a timer
|
||||
* is still running there
|
||||
*/
|
||||
net->window_probe = 0;
|
||||
if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
|
||||
sctp_timeout_handler, &net->rxt_timer);
|
||||
}
|
||||
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, net,
|
||||
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
|
||||
@ -5563,7 +5554,6 @@ sctp_handle_sack(struct mbuf *m, int offset,
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if (win_probe_recovery && (net->window_probe)) {
|
||||
net->window_probe = 0;
|
||||
win_probe_recovered = 1;
|
||||
/*-
|
||||
* Find first chunk that was used with
|
||||
@ -5582,8 +5572,21 @@ sctp_handle_sack(struct mbuf *m, int offset,
|
||||
j++;
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
|
||||
stcb->sctp_ep, stcb, net);
|
||||
if (net->window_probe) {
|
||||
}
|
||||
} else {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
if (net->window_probe) {
|
||||
/*
|
||||
* In window probes we must assure a timer
|
||||
* is still running there
|
||||
*/
|
||||
|
||||
if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
|
||||
stcb->sctp_ep, stcb, net);
|
||||
|
||||
}
|
||||
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, net,
|
||||
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
|
||||
@ -6553,8 +6556,9 @@ sctp_express_handle_nr_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
again:
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
int to_ticks;
|
||||
|
||||
if (win_probe_recovery && (net->window_probe)) {
|
||||
net->window_probe = 0;
|
||||
win_probe_recovered = 1;
|
||||
/*
|
||||
* Find first chunk that was used with window probe
|
||||
@ -6569,19 +6573,29 @@ sctp_express_handle_nr_sack(struct sctp_tcb *stcb, uint32_t cumack,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (net->RTO == 0) {
|
||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
||||
} else {
|
||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
||||
}
|
||||
if (net->flight_size) {
|
||||
int to_ticks;
|
||||
|
||||
if (net->RTO == 0) {
|
||||
to_ticks = MSEC_TO_TICKS(stcb->asoc.initial_rto);
|
||||
} else {
|
||||
to_ticks = MSEC_TO_TICKS(net->RTO);
|
||||
}
|
||||
j++;
|
||||
(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
|
||||
sctp_timeout_handler, &net->rxt_timer);
|
||||
if (net->window_probe) {
|
||||
net->window_probe = 0;
|
||||
}
|
||||
} else {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
if (net->window_probe) {
|
||||
/*
|
||||
* In window probes we must assure a timer
|
||||
* is still running there
|
||||
*/
|
||||
net->window_probe = 0;
|
||||
(void)SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
|
||||
sctp_timeout_handler, &net->rxt_timer);
|
||||
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, net,
|
||||
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
|
||||
@ -8111,7 +8125,6 @@ sctp_handle_nr_sack(struct mbuf *m, int offset,
|
||||
j = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if (win_probe_recovery && (net->window_probe)) {
|
||||
net->window_probe = 0;
|
||||
win_probe_recovered = 1;
|
||||
/*-
|
||||
* Find first chunk that was used with
|
||||
@ -8130,8 +8143,15 @@ sctp_handle_nr_sack(struct mbuf *m, int offset,
|
||||
j++;
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
|
||||
stcb->sctp_ep, stcb, net);
|
||||
if (net->window_probe) {
|
||||
net->window_probe = 0;
|
||||
}
|
||||
} else {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
if (net->window_probe) {
|
||||
net->window_probe = 0;
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND,
|
||||
stcb->sctp_ep, stcb, net);
|
||||
} else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, net,
|
||||
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
|
||||
|
@ -10036,7 +10036,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_fragusrmsgs);
|
||||
}
|
||||
if ((mtu == 0) || (r_mtu == 0) || (one_chunk)) {
|
||||
if (one_chunk) {
|
||||
if ((one_chunk) && (stcb->asoc.total_flight == 0)) {
|
||||
data_list[0]->window_probe = 1;
|
||||
net->window_probe = 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user