Hi,
Historically there were slow and fast tcp timeouts. That is why
the delack timer has a different implementation.
Let's use the same macros for all TCP timer.
ok?
bluhm
Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.354
diff -u -p -r1.354 tcp_input.c
--- netinet/tcp_input.c 4 Dec 2017 13:40:34 -0000 1.354
+++ netinet/tcp_input.c 8 May 2018 12:07:12 -0000
@@ -176,12 +176,12 @@ do { \
struct ifnet *ifp = NULL; \
if (m && (m->m_flags & M_PKTHDR)) \
ifp = if_get(m->m_pkthdr.ph_ifidx); \
- if ((tp)->t_flags & TF_DELACK || \
+ if (TCP_TIMER_ISARMED(tp, TCPT_DELACK) || \
(tcp_ack_on_push && (tiflags) & TH_PUSH) || \
(ifp && (ifp->if_flags & IFF_LOOPBACK))) \
tp->t_flags |= TF_ACKNOW; \
else \
- TCP_SET_DELACK(tp); \
+ TCP_TIMER_ARM_MSEC(tp, TCPT_DELACK, tcp_delack_msecs); \
if_put(ifp); \
} while (0)
Index: netinet/tcp_output.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.123
diff -u -p -r1.123 tcp_output.c
--- netinet/tcp_output.c 25 Oct 2017 12:38:21 -0000 1.123
+++ netinet/tcp_output.c 8 May 2018 12:07:12 -0000
@@ -1089,8 +1089,8 @@ out:
}
/* Restart the delayed ACK timer, if necessary. */
- if (tp->t_flags & TF_DELACK)
- TCP_RESTART_DELACK(tp);
+ if (TCP_TIMER_ISARMED(tp, TCPT_DELACK))
+ TCP_TIMER_ARM_MSEC(tp, TCPT_DELACK, tcp_delack_msecs);
return (error);
}
@@ -1099,7 +1099,7 @@ out:
tp->t_pmtud_mtu_sent = packetlen;
tcpstat_inc(tcps_sndtotal);
- if (tp->t_flags & TF_DELACK)
+ if (TCP_TIMER_ISARMED(tp, TCPT_DELACK))
tcpstat_inc(tcps_delack);
/*
@@ -1112,7 +1112,7 @@ out:
tp->rcv_adv = tp->rcv_nxt + win;
tp->last_ack_sent = tp->rcv_nxt;
tp->t_flags &= ~TF_ACKNOW;
- TCP_CLEAR_DELACK(tp);
+ TCP_TIMER_DISARM(tp, TCPT_DELACK);
if (sendalot && --maxburst)
goto again;
return (0);
Index: netinet/tcp_subr.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.170
diff -u -p -r1.170 tcp_subr.c
--- netinet/tcp_subr.c 2 Apr 2018 14:19:17 -0000 1.170
+++ netinet/tcp_subr.c 8 May 2018 12:07:20 -0000
@@ -433,7 +433,6 @@ tcp_newtcpcb(struct inpcb *inp)
tp->t_maxseg = tcp_mssdflt;
tp->t_maxopd = 0;
- TCP_INIT_DELACK(tp);
for (i = 0; i < TCPT_NTIMERS; i++)
TCP_TIMER_INIT(tp, i);
@@ -517,7 +516,6 @@ tcp_close(struct tcpcb *tp)
tcp_freeq(tp);
tcp_canceltimers(tp);
- TCP_CLEAR_DELACK(tp);
syn_cache_cleanup(tp);
/* Free SACK holes. */
@@ -529,8 +527,7 @@ tcp_close(struct tcpcb *tp)
}
m_free(tp->t_template);
-
- tp->t_flags |= TF_DEAD;
+ /* Free tcpcb after all pending timers have been run. */
TCP_TIMER_ARM(tp, TCPT_REAPER, 0);
inp->inp_ppcb = NULL;
Index: netinet/tcp_timer.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_timer.c,v
retrieving revision 1.64
diff -u -p -r1.64 tcp_timer.c
--- netinet/tcp_timer.c 7 Feb 2018 00:31:10 -0000 1.64
+++ netinet/tcp_timer.c 8 May 2018 12:07:12 -0000
@@ -71,6 +71,7 @@ void tcp_timer_persist(void *);
void tcp_timer_keep(void *);
void tcp_timer_2msl(void *);
void tcp_timer_reaper(void *);
+void tcp_timer_delack(void *);
const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS] = {
tcp_timer_rexmt,
@@ -78,6 +79,7 @@ const tcp_timer_func_t tcp_timer_funcs[T
tcp_timer_keep,
tcp_timer_2msl,
tcp_timer_reaper,
+ tcp_timer_delack,
};
/*
@@ -104,7 +106,7 @@ tcp_timer_init(void)
* Callout to process delayed ACKs for a TCPCB.
*/
void
-tcp_delack(void *arg)
+tcp_timer_delack(void *arg)
{
struct tcpcb *tp = arg;
@@ -114,8 +116,12 @@ tcp_delack(void *arg)
* ACK callout.
*/
NET_LOCK();
- if (tp->t_flags & TF_DEAD)
+ /* Ignore canceled timeouts or timeouts that have been rescheduled. */
+ if (!ISSET((tp)->t_flags, TF_TMR_DELACK) ||
+ timeout_pending(&tp->t_timer[TCPT_DELACK]))
goto out;
+ CLR((tp)->t_flags, TF_TMR_DELACK);
+
tp->t_flags |= TF_ACKNOW;
(void) tcp_output(tp);
out:
Index: netinet/tcp_timer.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_timer.h,v
retrieving revision 1.17
diff -u -p -r1.17 tcp_timer.h
--- netinet/tcp_timer.h 7 Feb 2018 00:31:10 -0000 1.17
+++ netinet/tcp_timer.h 8 May 2018 12:07:12 -0000
@@ -36,16 +36,16 @@
#define _NETINET_TCP_TIMER_H_
/*
- * Definitions of the TCP timers. These timers are counted
- * down PR_SLOWHZ times a second.
+ * Definitions of the TCP timers.
*/
-#define TCPT_NTIMERS 5
-
#define TCPT_REXMT 0 /* retransmit */
#define TCPT_PERSIST 1 /* retransmit persistence */
#define TCPT_KEEP 2 /* keep alive */
#define TCPT_2MSL 3 /* 2*msl quiet time timer */
#define TCPT_REAPER 4 /* delayed cleanup timeout */
+#define TCPT_DELACK 5 /* delayed ack timeout */
+
+#define TCPT_NTIMERS 6
/*
* The TCPT_REXMT timer is used to force retransmissions.
@@ -110,7 +110,7 @@
#ifdef TCPTIMERS
const char *tcptimers[TCPT_NTIMERS] =
- { "REXMT", "PERSIST", "KEEP", "2MSL", "REAPER" };
+ { "REXMT", "PERSIST", "KEEP", "2MSL", "REAPER", "DELACK" };
#endif /* TCPTIMERS */
/*
@@ -123,6 +123,12 @@ const char *tcptimers[TCPT_NTIMERS] =
do { \
SET((tp)->t_flags, TF_TIMER << (timer)); \
timeout_add_msec(&(tp)->t_timer[(timer)], (nticks) * 500); \
+} while (0)
+
+#define TCP_TIMER_ARM_MSEC(tp, timer, msecs)
\
+do { \
+ SET((tp)->t_flags, TF_TIMER << (timer)); \
+ timeout_add_msec(&(tp)->t_timer[(timer)], (msecs)); \
} while (0)
#define TCP_TIMER_DISARM(tp, timer)
\
Index: netinet/tcp_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.131
diff -u -p -r1.131 tcp_var.h
--- netinet/tcp_var.h 7 Feb 2018 00:31:10 -0000 1.131
+++ netinet/tcp_var.h 8 May 2018 12:07:12 -0000
@@ -78,7 +78,6 @@ struct tcpcb {
char t_force; /* 1 if forcing out a byte */
u_int t_flags;
#define TF_ACKNOW 0x0001 /* ack peer immediately */
-#define TF_DELACK 0x0002 /* ack, but try to delay it */
#define TF_NODELAY 0x0004 /* don't delay packets to
coalesce */
#define TF_NOOPT 0x0008 /* don't use tcp options */
#define TF_SENTFIN 0x0010 /* have sent FIN */
@@ -95,7 +94,6 @@ struct tcpcb {
#define TF_DISABLE_ECN 0x00040000 /* disable ECN for this connection */
#endif
#define TF_LASTIDLE 0x00100000 /* no outstanding ACK on last send */
-#define TF_DEAD 0x00200000 /* dead and to-be-released */
#define TF_PMTUD_PEND 0x00400000 /* Path MTU Discovery pending */
#define TF_NEEDOUTPUT 0x00800000 /* call tcp_output after tcp_input */
#define TF_BLOCKOUTPUT 0x01000000 /* avert tcp_output during tcp_input */
@@ -105,11 +103,11 @@ struct tcpcb {
#define TF_TMR_KEEP 0x10000000 /* keep alive timer armed */
#define TF_TMR_2MSL 0x20000000 /* 2*msl quiet time timer armed */
#define TF_TMR_REAPER 0x40000000 /* delayed cleanup timer armed, dead */
+#define TF_TMR_DELACK 0x80000000 /* delayed ack timer armed */
#define TF_TIMER TF_TMR_REXMT /* used to shift with TCPT values */
struct mbuf *t_template; /* skeletal packet for transmit */
struct inpcb *t_inpcb; /* back pointer to internet pcb */
- struct timeout t_delack_to; /* delayed ACK callback */
/*
* The following fields are used as in the protocol specification.
* See RFC793, Dec. 1981, page 21.
@@ -205,30 +203,6 @@ struct tcpcb {
#define sototcpcb(so) (intotcpcb(sotoinpcb(so)))
#ifdef _KERNEL
-void tcp_delack(void *);
-
-#define TCP_INIT_DELACK(tp) \
- timeout_set_proc(&(tp)->t_delack_to, tcp_delack, tp)
-
-#define TCP_RESTART_DELACK(tp) \
- timeout_add_msec(&(tp)->t_delack_to, tcp_delack_msecs)
-
-#define TCP_SET_DELACK(tp)
\
-do { \
- if (((tp)->t_flags & TF_DELACK) == 0) { \
- (tp)->t_flags |= TF_DELACK; \
- TCP_RESTART_DELACK(tp); \
- } \
-} while (/* CONSTCOND */ 0)
-
-#define TCP_CLEAR_DELACK(tp)
\
-do { \
- if ((tp)->t_flags & TF_DELACK) { \
- (tp)->t_flags &= ~TF_DELACK; \
- timeout_del(&(tp)->t_delack_to); \
- } \
-} while (/* CONSTCOND */ 0)
-
/*
* Handy way of passing around TCP option info.
*/