summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>2001-02-25 15:17:24 +0000
committerjlemon <jlemon@FreeBSD.org>2001-02-25 15:17:24 +0000
commit3b8f8e993826da4fcb2243fc5f40428034f61670 (patch)
tree4644ff9b6cbeb4bf0924ba987b48fce6b08bfb83 /sys/netinet/tcp_input.c
parent2f2e24d1af024d942727a0a6dcb0404968a4f1b0 (diff)
downloadFreeBSD-src-3b8f8e993826da4fcb2243fc5f40428034f61670.zip
FreeBSD-src-3b8f8e993826da4fcb2243fc5f40428034f61670.tar.gz
Do not delay a new ack if there already is a delayed ack pending on the
connection, but send it immediately. Prior to this change, it was possible to delay a delayed-ack for multiple times, resulting in degraded TCP behavior in certain corner cases.
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 2c838c6..49cbdee 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -165,6 +165,12 @@ do { \
#endif
/*
+ * Indicate whether this ack should be delayed.
+ */
+#define DELAY_ACK(tp) \
+ (tcp_delack_enabled && !callout_pending(tp->tt_delack))
+
+/*
* Insert segment which inludes th into reassembly queue of tcp with
* control block tp. Return TH_FIN if reassembly now includes
* a segment with FIN. The macro form does the common case inline
@@ -178,7 +184,7 @@ do { \
if ((th)->th_seq == (tp)->rcv_nxt && \
LIST_EMPTY(&(tp)->t_segq) && \
(tp)->t_state == TCPS_ESTABLISHED) { \
- if (tcp_delack_enabled) \
+ if (DELAY_ACK(tp)) \
callout_reset(tp->tt_delack, tcp_delacktime, \
tcp_timer_delack, tp); \
else \
@@ -968,7 +974,7 @@ findpcb:
m_adj(m, drop_hdrlen); /* delayed header drop */
sbappend(&so->so_rcv, m);
sorwakeup(so);
- if (tcp_delack_enabled) {
+ if (DELAY_ACK(tp)) {
callout_reset(tp->tt_delack, tcp_delacktime,
tcp_timer_delack, tp);
} else {
@@ -1153,7 +1159,7 @@ findpcb:
* segment. Otherwise must send ACK now in case
* the other side is slow starting.
*/
- if (tcp_delack_enabled && ((thflags & TH_FIN) ||
+ if (DELAY_ACK(tp) && ((thflags & TH_FIN) ||
(tlen != 0 &&
#ifdef INET6
((isipv6 && in6_localaddr(&inp->in6p_faddr))
@@ -1304,7 +1310,7 @@ findpcb:
* If there's data, delay ACK; if there's also a FIN
* ACKNOW will be turned on later.
*/
- if (tcp_delack_enabled && tlen != 0)
+ if (DELAY_ACK(tp) && tlen != 0)
callout_reset(tp->tt_delack, tcp_delacktime,
tcp_timer_delack, tp);
else
@@ -2170,7 +2176,7 @@ dodata: /* XXX */
* Otherwise, since we received a FIN then no
* more input can be expected, send ACK now.
*/
- if (tcp_delack_enabled && (tp->t_flags & TF_NEEDSYN))
+ if (DELAY_ACK(tp) && (tp->t_flags & TF_NEEDSYN))
callout_reset(tp->tt_delack, tcp_delacktime,
tcp_timer_delack, tp);
else
OpenPOWER on IntegriCloud