summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2018-04-07 20:39:09 +0000
committertuexen <tuexen@FreeBSD.org>2018-04-07 20:39:09 +0000
commit6b5b1981ab364f6724b7ebe4aff3e8e233663b20 (patch)
tree10c8dc907d5c393a44937d17b22cf837f46a6498
parent35d2abea68f0f80f94ae5ea5db5de75d16bdbe99 (diff)
downloadFreeBSD-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.c28
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
OpenPOWER on IntegriCloud