Page MenuHomeFreeBSD

D58319.diff
No OneTemporary

D58319.diff

diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -496,6 +496,7 @@
tp->sackhint.delivered_data = 0;
tp->sackhint.prr_delivered = 0;
tp->sackhint.prr_out = 0;
+ tp->snd_cwnd = tp->snd_ssthresh;
}
/*
@@ -1496,6 +1497,7 @@
struct tcpopt to;
int tfo_syn;
u_int maxseg = 0;
+ uint32_t prev_sacked_bytes = 0;
bool no_data;
no_data = (tlen == 0);
@@ -2515,6 +2517,7 @@
goto dropafterack;
}
if (tcp_is_sack_recovery(tp, &to)) {
+ prev_sacked_bytes = tp->sackhint.sacked_bytes;
sack_changed = tcp_sack_doack(tp, &to, th->th_ack);
if ((sack_changed != SACK_NOCHANGE) &&
(tp->t_flags & TF_LRD)) {
@@ -2666,12 +2669,15 @@
tp->sackhint.prr_delivered =
imin(tp->snd_max - th->th_ack,
(tp->snd_limited + 1) * maxseg);
+ tp->sackhint.recover_fs = imax(1,
+ (tp->snd_nxt - tp->snd_una) - prev_sacked_bytes
+ + tp->sackhint.delivered_data);
} else {
tp->sackhint.prr_delivered =
maxseg;
- }
- tp->sackhint.recover_fs = max(1,
+ tp->sackhint.recover_fs = max(1,
tp->snd_nxt - tp->snd_una);
+ }
}
tp->snd_limited = 0;
if (tcp_is_sack_recovery(tp, &to)) {
@@ -3994,8 +4000,9 @@
tcp_do_prr_ack(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to,
sackstatus_t sack_changed, u_int *maxsegp)
{
- int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0;
+ int snd_cnt = 0, del_data = 0, pipe = 0;
u_int maxseg;
+ bool safe_ack;
INP_WLOCK_ASSERT(tptoinpcb(tp));
@@ -4021,6 +4028,10 @@
pipe = imax(0, tp->snd_max - tp->snd_una -
imin(INT_MAX / 65536, tp->t_dupacks) * maxseg);
}
+
+ if (del_data == 0)
+ return;
+
tp->sackhint.prr_delivered += del_data;
/*
* Proportional Rate Reduction
@@ -4033,25 +4044,16 @@
tp->snd_ssthresh, tp->sackhint.recover_fs) -
tp->sackhint.prr_out + maxseg - 1;
} else {
- /*
- * PRR 6937bis heuristic:
- * - A partial ack without SACK block beneath snd_recover
- * indicates further loss.
- * - An SACK scoreboard update adding a new hole indicates
- * further loss, so be conservative and send at most one
- * segment.
- * - Prevent ACK splitting attacks, by being conservative
- * when no new data is acked.
- */
- if ((sack_changed == SACK_NEWLOSS) || (del_data == 0)) {
- limit = tp->sackhint.prr_delivered -
- tp->sackhint.prr_out;
- } else {
- limit = imax(tp->sackhint.prr_delivered -
- tp->sackhint.prr_out, del_data) +
- maxseg;
+ safe_ack = SEQ_GT(th->th_ack, tp->snd_una) && (sack_changed != SACK_NEWLOSS);
+ snd_cnt = imax(tp->sackhint.prr_delivered - tp->sackhint.prr_out, del_data);
+ if (safe_ack) {
+ snd_cnt += maxseg;
}
- snd_cnt = imin((tp->snd_ssthresh - pipe), limit);
+ snd_cnt = imin(tp->snd_ssthresh - pipe, snd_cnt);
+ }
+
+ if (tp->sackhint.prr_out == 0 && snd_cnt == 0) {
+ snd_cnt = maxseg;
}
snd_cnt = imax(snd_cnt, 0) / maxseg;
/*

File Metadata

Mime Type
text/plain
Expires
Tue, Jul 21, 8:42 AM (3 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35227943
Default Alt Text
D58319.diff (2 KB)

Event Timeline