summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_timer.h
blob: 53027af4f3a0bec8b75598003ea4289eb0966a86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*	$OpenBSD: tcp_timer.h,v 1.20 2023/03/14 00:24:05 yasuoka Exp $	*/
/*	$NetBSD: tcp_timer.h,v 1.6 1995/03/26 20:32:37 jtc Exp $	*/

/*
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)tcp_timer.h	8.1 (Berkeley) 6/10/93
 */

#ifndef _NETINET_TCP_TIMER_H_
#define _NETINET_TCP_TIMER_H_

/*
 * Definitions of the TCP timers.
 */
#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.
 * The TCP has the TCPT_REXMT timer set whenever segments
 * have been sent for which ACKs are expected but not yet
 * received.  If an ACK is received which advances tp->snd_una,
 * then the retransmit timer is cleared (if there are no more
 * outstanding segments) or reset to the base value (if there
 * are more ACKs expected).  Whenever the retransmit timer goes off,
 * we retransmit one unacknowledged segment, and do a backoff
 * on the retransmit timer.
 *
 * The TCPT_PERSIST timer is used to keep window size information
 * flowing even if the window goes shut.  If all previous transmissions
 * have been acknowledged (so that there are no retransmissions in progress),
 * and the window is too small to bother sending anything, then we start
 * the TCPT_PERSIST timer.  When it expires, if the window is nonzero,
 * we go to transmit state.  Otherwise, at intervals send a single byte
 * into the peer's window to force him to update our window information.
 * We do this at most as often as TCPT_PERSMIN time intervals,
 * but no more frequently than the current estimate of round-trip
 * packet time.  The TCPT_PERSIST timer is cleared whenever we receive
 * a window update from the peer.
 *
 * The TCPT_KEEP timer is used to keep connections alive.  If an
 * connection is idle (no segments received) for TCPTV_KEEP_INIT amount of time,
 * but not yet established, then we drop the connection.  Once the connection
 * is established, if the connection is idle for TCPTV_KEEP_IDLE time
 * (and keepalives have been enabled on the socket), we begin to probe
 * the connection.  We force the peer to send us a segment by sending:
 *	<SEQ=SND.UNA-1><ACK=RCV.NXT><CTL=ACK>
 * This segment is (deliberately) outside the window, and should elicit
 * an ack segment in response from the peer.  If, despite the TCPT_KEEP
 * initiated segments we cannot elicit a response from a peer in TCPT_MAXIDLE
 * amount of time probing, then we drop the connection.
 */

/*
 * Time constants.
 */
#define	TCPTV_MSL	TCP_TIME(30)	/* max seg lifetime (hah!) */
#define	TCPTV_SRTTBASE	0		/* base roundtrip time;
					   if 0, no idea yet */
#define	TCPTV_SRTTDFLT	TCP_TIME(3)	/* assumed RTT if no info */

#define	TCPTV_PERSMIN	TCP_TIME(5)	/* retransmit persistence */
#define	TCPTV_PERSMAX	TCP_TIME(60)	/* maximum persist interval */

#define	TCPTV_KEEP_INIT	TCP_TIME(75)	/* initial connect keep alive */
#define	TCPTV_KEEP_IDLE	TCP_TIME(120*60) /* dflt time before probing */
#define	TCPTV_KEEPINTVL	TCP_TIME(75)	/* default probe interval */
#define	TCPTV_KEEPCNT	8		/* max probes before drop */

#define	TCPTV_MIN	TCP_TIME(1)	/* minimum allowable value */
#define	TCPTV_REXMTMAX	TCP_TIME(64)	/* max allowable REXMT value */

#define	TCP_LINGERTIME	120		/* linger at most 2 minutes */

#define	TCP_MAXRXTSHIFT	12		/* maximum retransmits */

#define	TCP_DELACK_MSECS 200		/* time to delay ACK */

#ifdef	TCPTIMERS
const char *tcptimers[TCPT_NTIMERS] =
    { "REXMT", "PERSIST", "KEEP", "2MSL", "REAPER", "DELACK" };
#endif /* TCPTIMERS */

/*
 * Init, arm, disarm, and test TCP timers.
 */
#define	TCP_TIMER_INIT(tp, timer)					\
	timeout_set_proc(&(tp)->t_timer[(timer)], tcp_timer_funcs[(timer)], tp)

#define	TCP_TIMER_ARM(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)					\
do {									\
	CLR((tp)->t_flags, TF_TIMER << (timer));			\
	timeout_del(&(tp)->t_timer[(timer)]);				\
} while (0)

#define	TCP_TIMER_ISARMED(tp, timer)					\
	ISSET((tp)->t_flags, TF_TIMER << (timer))

/*
 * Force a time value to be in a certain range.
 */
#define	TCPT_RANGESET(tv, value, tvmin, tvmax)				\
do {									\
	(tv) = (value);							\
	if ((tv) < (tvmin))						\
		(tv) = (tvmin);						\
	else if ((tv) > (tvmax))					\
		(tv) = (tvmax);						\
} while (/* CONSTCOND */ 0)

#ifdef _KERNEL
typedef void (*tcp_timer_func_t)(void *);

extern const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS];

extern int tcp_delack_msecs;		/* delayed ACK timeout in millisecs */
extern int tcptv_keep_init;
extern int tcp_always_keepalive;	/* assume SO_KEEPALIVE is always set */
extern int tcp_keepidle;		/* time before keepalive probes begin */
extern int tcp_keepintvl;		/* time between keepalive probes */
extern int tcp_maxidle;			/* time to drop after starting probes */
extern int tcp_ttl;			/* time to live for TCP segs */
extern int tcp_backoff[];

void	tcp_timer_init(void);
#endif /* _KERNEL */
#endif /* _NETINET_TCP_TIMER_H_ */