summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2013-04-23 14:06:32 +0000
committerandre <andre@FreeBSD.org>2013-04-23 14:06:32 +0000
commit1f1bd98319ba57830e89bfdbf57da9dfa3da9084 (patch)
treee197c509a4bd793b8be5040952d3128a8da3eb30
parentafbef1895e627cd1993428a252d39b505cf6c085 (diff)
downloadFreeBSD-src-1f1bd98319ba57830e89bfdbf57da9dfa3da9084.zip
FreeBSD-src-1f1bd98319ba57830e89bfdbf57da9dfa3da9084.tar.gz
When doing RFC3042 limited transmit on the first on second
duplicate ACK make sure we actually have new data to send. This prevents us from sending unneccessary pure ACKs. Reported by: Matt Miller <matt@matthewjmiller.net> Tested by: Matt Miller <matt@matthewjmiller.net> MFC after: 2 weeks
-rw-r--r--sys/netinet/tcp_input.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index a7b6ced..a3122a1 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -2564,6 +2564,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
u_long oldcwnd = tp->snd_cwnd;
tcp_seq oldsndmax = tp->snd_max;
u_int sent;
+ int avail;
KASSERT(tp->t_dupacks == 1 ||
tp->t_dupacks == 2,
@@ -2585,7 +2586,17 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
*/
break;
}
- (void) tcp_output(tp);
+ /*
+ * Only call tcp_output when there
+ * is new data available to be sent.
+ * Otherwise we would send pure ACKs.
+ */
+ SOCKBUF_LOCK(&so->so_snd);
+ avail = so->so_snd.sb_cc -
+ (tp->snd_nxt - tp->snd_una);
+ SOCKBUF_UNLOCK(&so->so_snd);
+ if (avail > 0)
+ (void) tcp_output(tp);
sent = tp->snd_max - oldsndmax;
if (sent > tp->t_maxseg) {
KASSERT((tp->t_dupacks == 2 &&
OpenPOWER on IntegriCloud