diff options
author | tuexen <tuexen@FreeBSD.org> | 2018-04-07 20:39:09 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2018-04-07 20:39:09 +0000 |
commit | 6b5b1981ab364f6724b7ebe4aff3e8e233663b20 (patch) | |
tree | 10c8dc907d5c393a44937d17b22cf837f46a6498 | |
parent | 35d2abea68f0f80f94ae5ea5db5de75d16bdbe99 (diff) | |
download | FreeBSD-src-6b5b1981ab364f6724b7ebe4aff3e8e233663b20.zip FreeBSD-src-6b5b1981ab364f6724b7ebe4aff3e8e233663b20.tar.gz |
MFC r328066:
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.
-rw-r--r-- | sys/netinet/sctp_indata.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 8a12d3c..f420d72 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -3362,7 +3362,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; } @@ -3386,8 +3387,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 @@ -3672,7 +3675,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? */ @@ -4601,6 +4604,13 @@ hopeless_peer: 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) { @@ -4728,16 +4738,6 @@ hopeless_peer: 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 * handling NEWLY ACKED chunks. this_sack_lowest_newack is |