Fix a bug related to fast retransmissions.

When processing a SACK advancing the cumtsn-ack in fast recovery,
increment the miss-indications for all TSN's reported as missing.

Thanks to Fabian Ising for finding the bug and to Timo Voelker
for provinding a fix.

This fix moves also CMT related initialisation of some variables
to a more appropriate place.

MFC after:	1 week
This commit is contained in:
Michael Tuexen 2018-01-16 21:58:38 +00:00
parent 454ce38321
commit e9a3a1b13c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=328066

View File

@ -3364,7 +3364,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
}
}
}
if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap)) {
if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap) &&
!(accum_moved && asoc->fast_retran_loss_recovery)) {
/* we are beyond the tsn in the sack */
break;
}
@ -3388,8 +3389,10 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
* FR using this SACK.
*/
continue;
} else if (tp1->whoTo && SCTP_TSN_GT(tp1->rec.data.tsn,
tp1->whoTo->this_sack_highest_newack)) {
} else if (tp1->whoTo &&
SCTP_TSN_GT(tp1->rec.data.tsn,
tp1->whoTo->this_sack_highest_newack) &&
!(accum_moved && asoc->fast_retran_loss_recovery)) {
/*
* CMT: New acks were receieved for data sent to
* this dest. But no new acks were seen for data
@ -3674,7 +3677,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
}
} else {/* CMT is OFF */
} else { /* CMT is OFF */
#ifdef SCTP_FR_TO_ALTERNATE
/* Can we find an alternate? */
@ -4603,6 +4606,13 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) {
(*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net);
}
/*
* CMT: SFR algo (and HTNA) - this_sack_highest_newack has
* to be greater than the cumack. Also reset saw_newack to 0
* for all dests.
*/
net->saw_newack = 0;
net->this_sack_highest_newack = last_tsn;
}
/* process the new consecutive TSN first */
TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
@ -4729,16 +4739,6 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
if ((num_seg > 0) || (num_nr_seg > 0)) {
/*
* CMT: SFR algo (and HTNA) - this_sack_highest_newack has
* to be greater than the cumack. Also reset saw_newack to 0
* for all dests.
*/
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
net->saw_newack = 0;
net->this_sack_highest_newack = last_tsn;
}
/*
* thisSackHighestGap will increase while handling NEW
* segments this_sack_highest_newack will increase while