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:
Randall Stewart 2009-03-06 11:03:52 +00:00
parent b7baebb91a
commit 5171328bd6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189444
2 changed files with 70 additions and 50 deletions

View File

@ -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);

View File

@ -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;
}