Page MenuHomeFreeBSD

D42906.id132358.diff
No OneTemporary

D42906.id132358.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
@@ -439,7 +439,10 @@
case CC_RTO:
tp->t_dupacks = 0;
tp->t_bytes_acked = 0;
- EXIT_RECOVERY(tp->t_flags);
+ if ((tp->t_rxtshift > 1) ||
+ !((tp->t_flags & TF_SACK_PERMIT) &&
+ (!TAILQ_EMPTY(&tp->snd_holes))))
+ EXIT_RECOVERY(tp->t_flags);
if (tp->t_flags2 & TF2_ECN_PERMIT)
tp->t_flags2 |= TF2_ECN_SND_CWR;
break;
@@ -2499,7 +2502,8 @@
goto dropafterack;
}
if (tcp_is_sack_recovery(tp, &to)) {
- if (((sack_changed = tcp_sack_doack(tp, &to, th->th_ack)) != 0) &&
+ if (((sack_changed = tcp_sack_doack(tp, &to, th->th_ack))
+ != SACK_NOCHANGE) &&
(tp->t_flags & TF_LRD)) {
tcp_sack_lost_retransmission(tp, th);
}
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -908,6 +908,25 @@
("tp->sackhint.nexthole == NULL"));
}
+/*
+ * Resend all the currently existing SACK holes of
+ * the scoreboard. This is in line with the Errata to
+ * RFC 2018, which allows the use of SACK data past
+ * an RTO to good effect typically.
+ */
+void
+tcp_resend_sackholes(struct tcpcb *tp)
+{
+ struct sackhole *p;
+
+ INP_WLOCK_ASSERT(tptoinpcb(tp));
+ TAILQ_FOREACH(p, &tp->snd_holes, scblink) {
+ p->rxmit = p->start;
+ }
+ tp->sackhint.nexthole = TAILQ_FIRST(&tp->snd_holes);
+ tp->sackhint.sack_bytes_rexmit = 0;
+}
+
/*
* Partial ack handling within a sack recovery episode. Keeping this very
* simple for now. When a partial ack is received, force snd_cwnd to a value
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -559,7 +559,6 @@
TCP_PROBE2(debug__user, tp, PRU_SLOWTIMO);
CURVNET_SET(inp->inp_vnet);
- tcp_free_sackholes(tp);
if (tp->t_fb->tfb_tcp_rexmit_tmr) {
/* The stack has a timer action too. */
(*tp->t_fb->tfb_tcp_rexmit_tmr)(tp);
@@ -619,8 +618,11 @@
* the retransmitted packet's to_tsval to by tcp_output
*/
tp->t_flags |= TF_PREVVALID;
- } else
+ tcp_resend_sackholes(tp);
+ } else {
tp->t_flags &= ~TF_PREVVALID;
+ tcp_free_sackholes(tp);
+ }
TCPSTAT_INC(tcps_rexmttimeo);
if ((tp->t_state == TCPS_SYN_SENT) ||
(tp->t_state == TCPS_SYN_RECEIVED))
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1499,6 +1499,7 @@
void tcp_do_prr_ack(struct tcpcb *, struct tcphdr *, struct tcpopt *, sackstatus_t);
void tcp_lost_retransmission(struct tcpcb *, struct tcphdr *);
void tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
+void tcp_resend_sackholes(struct tcpcb *tp);
void tcp_free_sackholes(struct tcpcb *tp);
void tcp_sack_lost_retransmission(struct tcpcb *, struct tcphdr *);
int tcp_newreno(struct tcpcb *, struct tcphdr *);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 3:30 AM (5 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30964548
Default Alt Text
D42906.id132358.diff (2 KB)

Event Timeline