summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/tcp_input.c12
-rw-r--r--sys/netinet/tcp_reass.c12
-rw-r--r--sys/netinet/tcp_sack.c36
3 files changed, 18 insertions, 42 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 37405c1..1784551 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -159,12 +159,6 @@ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
&tcp_reass_overflows, 0,
"Global number of TCP Segment Reassembly Queue Overflows");
-static int tcp_sack_recovery_initburst = 3;
-SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO,
- initburst, CTLFLAG_RW,
- &tcp_sack_recovery_initburst, 0,
- "Initial Number of Rexmits when sack recovery is set up");
-
struct inpcbhead tcb;
#define tcb6 tcb /* for KAME src sync over BSD*'s */
struct inpcbinfo tcbinfo;
@@ -1870,14 +1864,10 @@ trimthenstep6:
if (tp->sack_enable) {
tcpstat.tcps_sack_recovery_episode++;
tp->sack_newdata = tp->snd_nxt;
- tp->snd_cwnd =
- tp->t_maxseg * tcp_sack_recovery_initburst;
+ tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
- tp->snd_cwnd +=
- tp->snd_ssthresh;
goto drop;
}
-
tp->snd_nxt = th->th_ack;
tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c
index 37405c1..1784551 100644
--- a/sys/netinet/tcp_reass.c
+++ b/sys/netinet/tcp_reass.c
@@ -159,12 +159,6 @@ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
&tcp_reass_overflows, 0,
"Global number of TCP Segment Reassembly Queue Overflows");
-static int tcp_sack_recovery_initburst = 3;
-SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO,
- initburst, CTLFLAG_RW,
- &tcp_sack_recovery_initburst, 0,
- "Initial Number of Rexmits when sack recovery is set up");
-
struct inpcbhead tcb;
#define tcb6 tcb /* for KAME src sync over BSD*'s */
struct inpcbinfo tcbinfo;
@@ -1870,14 +1864,10 @@ trimthenstep6:
if (tp->sack_enable) {
tcpstat.tcps_sack_recovery_episode++;
tp->sack_newdata = tp->snd_nxt;
- tp->snd_cwnd =
- tp->t_maxseg * tcp_sack_recovery_initburst;
+ tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
- tp->snd_cwnd +=
- tp->snd_ssthresh;
goto drop;
}
-
tp->snd_nxt = th->th_ack;
tp->snd_cwnd = tp->t_maxseg;
(void) tcp_output(tp);
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
index 6230ff2..8637fa2 100644
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -481,9 +481,14 @@ tcp_free_sackholes(struct tcpcb *tp)
}
/*
- * Checks for partial ack. If partial ack arrives, turn off retransmission
- * timer, deflate the window, do not clear tp->t_dupacks, and return 1.
- * If the ack advances at least to tp->snd_recover, return 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 that will allow
+ * the sender to transmit no more than 2 segments.
+ * If necessary, a better scheme can be adopted at a
+ * later point, but for now, the goal is to prevent the
+ * sender from bursting a large amount of data in the midst
+ * of sack recovery.
*/
void
tcp_sack_partialack(tp, th)
@@ -491,28 +496,19 @@ tcp_sack_partialack(tp, th)
struct tcphdr *th;
{
INP_LOCK_ASSERT(tp->t_inpcb);
- u_long ocwnd = tp->snd_cwnd;
- int sack_bytes_rexmt = 0;
+ int num_segs = 1;
+ int sack_bytes_rxmt = 0;
callout_stop(tp->tt_rexmt);
tp->t_rtttime = 0;
- /*
- * Set cwnd so we can send one more segment (either rexmit based on
- * scoreboard or new segment). Set cwnd to the amount of data
- * rexmitted from scoreboard plus the amount of new data transmitted
- * in this sack recovery episode plus one segment.
- */
- (void)tcp_sack_output(tp, &sack_bytes_rexmt);
- tp->snd_cwnd = sack_bytes_rexmt + (tp->snd_nxt - tp->sack_newdata) +
- tp->t_maxseg;
+ /* send one or 2 segments based on how much new data was acked */
+ if (((th->th_ack - tp->snd_una) / tp->t_maxseg) > 2)
+ num_segs = 2;
+ (void)tcp_sack_output(tp, &sack_bytes_rxmt);
+ tp->snd_cwnd = sack_bytes_rxmt + (tp->snd_nxt - tp->sack_newdata) +
+ num_segs * tp->t_maxseg;
tp->t_flags |= TF_ACKNOW;
(void) tcp_output(tp);
- tp->snd_cwnd = ocwnd;
- /*
- * Partial window deflation. Relies on fact that tp->snd_una
- * not updated yet.
- */
- tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
}
#ifdef TCP_SACK_DEBUG
OpenPOWER on IntegriCloud