summaryrefslogtreecommitdiffstats
path: root/sys/netinet
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 /sys/netinet
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
Diffstat (limited to 'sys/netinet')
-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