tcp_timer.c revision 130989
142421Syokota/*
242421Syokota * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
342421Syokota *	The Regents of the University of California.  All rights reserved.
442421Syokota *
542421Syokota * Redistribution and use in source and binary forms, with or without
642421Syokota * modification, are permitted provided that the following conditions
742421Syokota * are met:
842421Syokota * 1. Redistributions of source code must retain the above copyright
942421Syokota *    notice, this list of conditions and the following disclaimer.
1042421Syokota * 2. Redistributions in binary form must reproduce the above copyright
1142421Syokota *    notice, this list of conditions and the following disclaimer in the
1242421Syokota *    documentation and/or other materials provided with the distribution.
1342421Syokota * 4. Neither the name of the University nor the names of its contributors
1442421Syokota *    may be used to endorse or promote products derived from this software
1542421Syokota *    without specific prior written permission.
1642421Syokota *
1742421Syokota * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1842421Syokota * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1942421Syokota * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2042421Syokota * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2142421Syokota * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2242421Syokota * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2342421Syokota * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2442421Syokota * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2542421Syokota * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2642421Syokota * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2742421Syokota * SUCH DAMAGE.
28119418Sobrien *
29119418Sobrien *	@(#)tcp_timer.c	8.2 (Berkeley) 5/24/95
30119418Sobrien * $FreeBSD: head/sys/netinet/tcp_timer.c 130989 2004-06-23 21:04:37Z ps $
3142421Syokota */
3242421Syokota
3342421Syokota#include "opt_inet6.h"
3442421Syokota#include "opt_tcpdebug.h"
3542421Syokota#include "opt_tcp_sack.h"
3642421Syokota
3742421Syokota#include <sys/param.h>
38139193Sphk#include <sys/kernel.h>
3942421Syokota#include <sys/lock.h>
40164033Srwatson#include <sys/mbuf.h>
41112050Sdwmalone#include <sys/mutex.h>
42180777Sed#include <sys/protosw.h>
43112050Sdwmalone#include <sys/socket.h>
4442421Syokota#include <sys/socketvar.h>
4542421Syokota#include <sys/sysctl.h>
4666834Sphk#include <sys/systm.h>
4742421Syokota
4842421Syokota#include <net/route.h>
4942421Syokota
50183397Sed#include <netinet/in.h>
5150154Syokota#include <netinet/in_pcb.h>
52193512Sed#include <netinet/in_systm.h>
53193512Sed#ifdef INET6
54193512Sed#include <netinet6/in6_pcb.h>
5550154Syokota#endif
5650154Syokota#include <netinet/ip_var.h>
5750154Syokota#include <netinet/tcp.h>
5850154Syokota#include <netinet/tcp_fsm.h>
59193512Sed#include <netinet/tcp_timer.h>
60193512Sed#include <netinet/tcp_var.h>
61193512Sed#include <netinet/tcpip.h>
6250154Syokota#ifdef TCPDEBUG
6350154Syokota#include <netinet/tcp_debug.h>
6460938Sjake#endif
65127751Sdes
6654545Syokotastatic int
6778161Spetersysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS)
6878161Speter{
6942421Syokota	int error, s, tt;
7042421Syokota
7142421Syokota	tt = *(int *)oidp->oid_arg1;
7242421Syokota	s = (int)((int64_t)tt * 1000 / hz);
7342421Syokota
7442421Syokota	error = sysctl_handle_int(oidp, &s, 0, req);
7542421Syokota	if (error || !req->newptr)
7642564Syokota		return (error);
7742564Syokota
7842421Syokota	tt = (int)((int64_t)s * hz / 1000);
7942564Syokota	if (tt < 1)
8042421Syokota		return (EINVAL);
8142421Syokota
8242421Syokota	*(int *)oidp->oid_arg1 = tt;
83112050Sdwmalone        return (0);
84227309Sed}
85112050Sdwmalone
86112050Sdwmaloneint	tcp_keepinit;
87112050SdwmaloneSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit, CTLTYPE_INT|CTLFLAG_RW,
8842421Syokota    &tcp_keepinit, 0, sysctl_msec_to_ticks, "I", "");
8942421Syokota
9044628Syokotaint	tcp_keepidle;
9142421SyokotaSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPIDLE, keepidle, CTLTYPE_INT|CTLFLAG_RW,
9242421Syokota    &tcp_keepidle, 0, sysctl_msec_to_ticks, "I", "");
9342421Syokota
9442421Syokotaint	tcp_keepintvl;
9542421SyokotaSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINTVL, keepintvl, CTLTYPE_INT|CTLFLAG_RW,
9642421Syokota    &tcp_keepintvl, 0, sysctl_msec_to_ticks, "I", "");
9742421Syokota
9842421Syokotaint	tcp_delacktime;
99298848SpfgSYSCTL_PROC(_net_inet_tcp, TCPCTL_DELACKTIME, delacktime,
10069781Sdwmalone    CTLTYPE_INT|CTLFLAG_RW, &tcp_delacktime, 0, sysctl_msec_to_ticks, "I",
10144628Syokota    "Time before a delayed ACK is sent");
10244628Syokota
103127752Sdesint	tcp_msl;
10444628SyokotaSYSCTL_PROC(_net_inet_tcp, OID_AUTO, msl, CTLTYPE_INT|CTLFLAG_RW,
10569781Sdwmalone    &tcp_msl, 0, sysctl_msec_to_ticks, "I", "Maximum segment lifetime");
10669781Sdwmalone
10744628Syokotaint	tcp_rexmit_min;
10844628SyokotaSYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_min, CTLTYPE_INT|CTLFLAG_RW,
10944628Syokota    &tcp_rexmit_min, 0, sysctl_msec_to_ticks, "I", "Minimum Retransmission Timeout");
110127752Sdes
11144628Syokotaint	tcp_rexmit_slop;
11242421SyokotaSYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT|CTLFLAG_RW,
11342421Syokota    &tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I", "Retransmission Timer Slop");
11442421Syokota
11542421Syokotastatic int	always_keepalive = 1;
11642421SyokotaSYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW,
11742421Syokota    &always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections");
11842421Syokota
11942421Syokotastatic int	tcp_keepcnt = TCPTV_KEEPCNT;
12042421Syokota	/* max idle probes */
12142421Syokotaint	tcp_maxpersistidle;
12242421Syokota	/* max idle time in persist */
12342421Syokotaint	tcp_maxidle;
12442421Syokota
12544628Syokota/*
126127752Sdes * Tcp protocol timeout routine called every 500 ms.
12742421Syokota * Updates timestamps used for TCP
12842421Syokota * causes finite state machine actions if timers expire.
12942421Syokota */
13042421Syokotavoid
13142421Syokotatcp_slowtimo()
13242421Syokota{
13342421Syokota	int s;
13442421Syokota
13542421Syokota	s = splnet();
13642421Syokota	tcp_maxidle = tcp_keepcnt * tcp_keepintvl;
13742421Syokota	splx(s);
13842421Syokota	INP_INFO_WLOCK(&tcbinfo);
13942421Syokota	(void) tcp_timer_2msl_tw(0);
14042421Syokota	INP_INFO_WUNLOCK(&tcbinfo);
14142421Syokota}
14242421Syokota
14342421Syokota/*
14442421Syokota * Cancel all timers for TCP tp.
14544628Syokota */
14642421Syokotavoid
14742421Syokotatcp_canceltimers(tp)
14842421Syokota	struct tcpcb *tp;
14942421Syokota{
15042421Syokota	callout_stop(tp->tt_2msl);
15142421Syokota	callout_stop(tp->tt_persist);
15242421Syokota	callout_stop(tp->tt_keep);
15342421Syokota	callout_stop(tp->tt_rexmt);
15444628Syokota}
15544628Syokota
15654382Syokotaint	tcp_syn_backoff[TCP_MAXRXTSHIFT + 1] =
15780040Syokota    { 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 64, 64 };
15842421Syokota
15942421Syokotaint	tcp_backoff[TCP_MAXRXTSHIFT + 1] =
16042421Syokota    { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 512, 512, 512 };
16142421Syokota
16242421Syokotastatic int tcp_totbackoff = 2559;	/* sum of tcp_backoff[] */
16342421Syokota
16442421Syokota/*
16542421Syokota * TCP timer processing.
16642421Syokota */
16742421Syokota
16842421Syokotavoid
16942421Syokotatcp_timer_delack(xtp)
17054545Syokota	void *xtp;
17154545Syokota{
17254545Syokota	struct tcpcb *tp = xtp;
17354545Syokota	int s;
17454545Syokota	struct inpcb *inp;
175127752Sdes
17654545Syokota	s = splnet();
177127752Sdes	INP_INFO_RLOCK(&tcbinfo);
17854545Syokota	inp = tp->t_inpcb;
17954545Syokota	if (!inp) {
18054545Syokota		INP_INFO_RUNLOCK(&tcbinfo);
18154545Syokota		splx(s);
18254545Syokota		return;
18360938Sjake	}
18454545Syokota	INP_LOCK(inp);
185127752Sdes	INP_INFO_RUNLOCK(&tcbinfo);
18654545Syokota	if (callout_pending(tp->tt_delack) || !callout_active(tp->tt_delack)) {
18754545Syokota		INP_UNLOCK(inp);
18842421Syokota		splx(s);
18942421Syokota		return;
19042421Syokota	}
19142421Syokota	callout_deactivate(tp->tt_delack);
19247295Syokota
19347295Syokota	tp->t_flags |= TF_ACKNOW;
194156126Semax	tcpstat.tcps_delack++;
195156126Semax	(void) tcp_output(tp);
19642421Syokota	INP_UNLOCK(inp);
19742421Syokota	splx(s);
198156126Semax}
199156126Semax
20042421Syokotavoid
20142421Syokotatcp_timer_2msl(xtp)
20242421Syokota	void *xtp;
20342421Syokota{
20444628Syokota	struct tcpcb *tp = xtp;
20544628Syokota	int s;
206127752Sdes	struct inpcb *inp;
20744628Syokota#ifdef TCPDEBUG
20842421Syokota	int ostate;
20942421Syokota
21042421Syokota	ostate = tp->t_state;
21142421Syokota#endif
21242421Syokota	s = splnet();
21342421Syokota	INP_INFO_WLOCK(&tcbinfo);
21442421Syokota	inp = tp->t_inpcb;
21542421Syokota	if (!inp) {
21642421Syokota		INP_INFO_WUNLOCK(&tcbinfo);
21754545Syokota		splx(s);
21854545Syokota		return;
21954545Syokota	}
22054545Syokota	INP_LOCK(inp);
221156126Semax	tcp_free_sackholes(tp);
222156126Semax	if (callout_pending(tp->tt_2msl) || !callout_active(tp->tt_2msl)) {
223156126Semax		INP_UNLOCK(tp->t_inpcb);
224156126Semax		INP_INFO_WUNLOCK(&tcbinfo);
225156126Semax		splx(s);
226156126Semax		return;
227213770Srpaulo	}
228156126Semax	callout_deactivate(tp->tt_2msl);
229156126Semax	/*
230127752Sdes	 * 2 MSL timeout in shutdown went off.  If we're closed but
23154545Syokota	 * still waiting for peer to close and connection has been idle
23254545Syokota	 * too long, or if 2MSL time is up from TIME_WAIT, delete connection
23378161Speter	 * control block.  Otherwise, check again in a bit.
23478161Speter	 */
23542421Syokota	if (tp->t_state != TCPS_TIME_WAIT &&
23642421Syokota	    (ticks - tp->t_rcvtime) <= tcp_maxidle)
23742421Syokota		callout_reset(tp->tt_2msl, tcp_keepintvl,
238156126Semax			      tcp_timer_2msl, tp);
239156126Semax	else
240156126Semax		tp = tcp_close(tp);
241156126Semax
242156126Semax#ifdef TCPDEBUG
243156126Semax	if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
244213770Srpaulo		tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
245156126Semax			  PRU_SLOWTIMO);
246156126Semax#endif
247127752Sdes	if (tp)
24842421Syokota		INP_UNLOCK(inp);
24942421Syokota	INP_INFO_WUNLOCK(&tcbinfo);
25042421Syokota	splx(s);
251127752Sdes}
25242421Syokota
25342421Syokotastruct twlist {
25442421Syokota	LIST_HEAD(, tcptw)	tw_list;
25542421Syokota	struct tcptw	tw_tail;
25642421Syokota};
25742421Syokota#define TWLIST_NLISTS	2
25842421Syokotastatic struct twlist twl_2msl[TWLIST_NLISTS];
25942421Syokotastatic struct twlist *tw_2msl_list[] = { &twl_2msl[0], &twl_2msl[1], NULL };
26042421Syokota
261127752Sdesvoid
26242421Syokotatcp_timer_init(void)
263127752Sdes{
26442421Syokota	int i;
26542421Syokota	struct twlist *twl;
26642421Syokota
26742421Syokota	for (i = 0; i < TWLIST_NLISTS; i++) {
268127752Sdes		twl = &twl_2msl[i];
26942421Syokota		LIST_INIT(&twl->tw_list);
27042421Syokota		LIST_INSERT_HEAD(&twl->tw_list, &twl->tw_tail, tw_2msl);
271127752Sdes	}
27242421Syokota}
27342421Syokota
27442421Syokotavoid
275127752Sdestcp_timer_2msl_reset(struct tcptw *tw, int timeo)
27642421Syokota{
27742421Syokota	int i;
27842421Syokota	struct tcptw *tw_tail;
27942421Syokota
28042421Syokota	if (tw->tw_time != 0)
28142421Syokota		LIST_REMOVE(tw, tw_2msl);
28242421Syokota	tw->tw_time = timeo + ticks;
283127752Sdes	i = timeo > tcp_msl ? 1 : 0;
28442421Syokota	tw_tail = &twl_2msl[i].tw_tail;
28542421Syokota	LIST_INSERT_BEFORE(tw_tail, tw, tw_2msl);
286298955Spfg}
28742421Syokota
28842421Syokotavoid
28942421Syokotatcp_timer_2msl_stop(struct tcptw *tw)
29047295Syokota{
29147295Syokota
29242421Syokota	if (tw->tw_time != 0)
29354545Syokota		LIST_REMOVE(tw, tw_2msl);
29454545Syokota}
295127752Sdes
29654545Syokotastruct tcptw *
29778161Spetertcp_timer_2msl_tw(int reuse)
29878161Speter{
29942421Syokota	struct tcptw *tw, *tw_tail;
300127752Sdes	struct twlist *twl;
30142421Syokota	int i;
30242421Syokota
303127752Sdes	for (i = 0; i < 2; i++) {
30442421Syokota		twl = tw_2msl_list[i];
30542421Syokota		tw_tail = &twl->tw_tail;
30642421Syokota		for (;;) {
30742421Syokota			tw = LIST_FIRST(&twl->tw_list);
30842421Syokota			if (tw == tw_tail || (!reuse && tw->tw_time > ticks))
30942421Syokota				break;
31042421Syokota			INP_LOCK(tw->tw_inpcb);
31142421Syokota			if (tcp_twclose(tw, reuse) != NULL)
31242421Syokota				return (tw);
313147980Semax		}
314147980Semax	}
315147980Semax	return (NULL);
316147980Semax}
31742421Syokota
318147980Semaxvoid
31942421Syokotatcp_timer_keep(xtp)
32042421Syokota	void *xtp;
32142421Syokota{
322147980Semax	struct tcpcb *tp = xtp;
323147980Semax	struct tcptemp *t_template;
324147980Semax	int s;
325147980Semax	struct inpcb *inp;
32642421Syokota#ifdef TCPDEBUG
32742421Syokota	int ostate;
32842421Syokota
32942421Syokota	ostate = tp->t_state;
33042421Syokota#endif
33142421Syokota	s = splnet();
33242421Syokota	INP_INFO_WLOCK(&tcbinfo);
33342421Syokota	inp = tp->t_inpcb;
334127752Sdes	if (!inp) {
33542421Syokota		INP_INFO_WUNLOCK(&tcbinfo);
336147980Semax		splx(s);
337127752Sdes		return;
33842421Syokota	}
33942421Syokota	INP_LOCK(inp);
340147980Semax	if (callout_pending(tp->tt_keep) || !callout_active(tp->tt_keep)) {
341147980Semax		INP_UNLOCK(inp);
342147980Semax		INP_INFO_WUNLOCK(&tcbinfo);
343147980Semax		splx(s);
344147980Semax		return;
345147980Semax	}
346147980Semax	callout_deactivate(tp->tt_keep);
34742421Syokota	/*
34842421Syokota	 * Keep-alive timer went off; send something
34942421Syokota	 * or drop connection if idle for too long.
35042421Syokota	 */
35142421Syokota	tcpstat.tcps_keeptimeo++;
35242421Syokota	if (tp->t_state < TCPS_ESTABLISHED)
35342421Syokota		goto dropit;
35442421Syokota	if ((always_keepalive || inp->inp_socket->so_options & SO_KEEPALIVE) &&
35542421Syokota	    tp->t_state <= TCPS_CLOSING) {
356127752Sdes		if ((ticks - tp->t_rcvtime) >= tcp_keepidle + tcp_maxidle)
35742421Syokota			goto dropit;
35842421Syokota		/*
35942421Syokota		 * Send a packet designed to force a response
36042421Syokota		 * if the peer is up and reachable:
36142421Syokota		 * either an ACK if the connection is still alive,
36242421Syokota		 * or an RST if the peer has closed the connection
363127752Sdes		 * due to timeout or reboot.
36442421Syokota		 * Using sequence number tp->snd_una-1
36542421Syokota		 * causes the transmitted zero-length segment
36642421Syokota		 * to lie outside the receive window;
36742421Syokota		 * by the protocol spec, this requires the
36842421Syokota		 * correspondent TCP to respond.
369174984Swkoszek		 */
37042421Syokota		tcpstat.tcps_keepprobe++;
37142421Syokota		t_template = tcpip_maketemplate(inp);
372127752Sdes		if (t_template) {
37342421Syokota			tcp_respond(tp, t_template->tt_ipgen,
37442421Syokota				    &t_template->tt_t, (struct mbuf *)NULL,
37542421Syokota				    tp->rcv_nxt, tp->snd_una - 1, 0);
37642421Syokota			(void) m_free(dtom(t_template));
37742421Syokota		}
37842421Syokota		callout_reset(tp->tt_keep, tcp_keepintvl, tcp_timer_keep, tp);
37942421Syokota	} else
38042421Syokota		callout_reset(tp->tt_keep, tcp_keepidle, tcp_timer_keep, tp);
38142421Syokota
38242421Syokota#ifdef TCPDEBUG
38342421Syokota	if (inp->inp_socket->so_options & SO_DEBUG)
38442421Syokota		tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
38542421Syokota			  PRU_SLOWTIMO);
38642421Syokota#endif
38742421Syokota	INP_UNLOCK(inp);
38842421Syokota	INP_INFO_WUNLOCK(&tcbinfo);
38942421Syokota	splx(s);
39042421Syokota	return;
391174984Swkoszek
39242421Syokotadropit:
39342421Syokota	tcpstat.tcps_keepdrops++;
39442421Syokota	tp = tcp_drop(tp, ETIMEDOUT);
395127752Sdes
39642421Syokota#ifdef TCPDEBUG
39742421Syokota	if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
39842421Syokota		tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
39942421Syokota			  PRU_SLOWTIMO);
40042421Syokota#endif
40142421Syokota	if (tp)
40242421Syokota		INP_UNLOCK(tp->t_inpcb);
40342421Syokota	INP_INFO_WUNLOCK(&tcbinfo);
40442421Syokota	splx(s);
40542421Syokota}
40642421Syokota
40742421Syokotavoid
40842421Syokotatcp_timer_persist(xtp)
40942421Syokota	void *xtp;
41042421Syokota{
41142421Syokota	struct tcpcb *tp = xtp;
41242421Syokota	int s;
41342421Syokota	struct inpcb *inp;
41442421Syokota#ifdef TCPDEBUG
41542421Syokota	int ostate;
41642421Syokota
41742421Syokota	ostate = tp->t_state;
418127752Sdes#endif
41942421Syokota	s = splnet();
42042421Syokota	INP_INFO_WLOCK(&tcbinfo);
42142421Syokota	inp = tp->t_inpcb;
42242421Syokota	if (!inp) {
42342421Syokota		INP_INFO_WUNLOCK(&tcbinfo);
42442421Syokota		splx(s);
42542421Syokota		return;
426127752Sdes	}
42750154Syokota	INP_LOCK(inp);
428127752Sdes	if (callout_pending(tp->tt_persist) || !callout_active(tp->tt_persist)){
42942421Syokota		INP_UNLOCK(inp);
430127752Sdes		INP_INFO_WUNLOCK(&tcbinfo);
431127752Sdes		splx(s);
43242421Syokota		return;
43342421Syokota	}
43442421Syokota	callout_deactivate(tp->tt_persist);
43542421Syokota	/*
43642421Syokota	 * Persistance timer into zero window.
43742421Syokota	 * Force a byte to be output, if possible.
43842421Syokota	 */
43942421Syokota	tcpstat.tcps_persisttimeo++;
44042421Syokota	/*
44142421Syokota	 * Hack: if the peer is dead/unreachable, we do not
44242421Syokota	 * time out if the window is closed.  After a full
44347295Syokota	 * backoff, drop the connection if the idle time
44447295Syokota	 * (no responses to probes) reaches the maximum
44542421Syokota	 * backoff that we would use if retransmitting.
44654545Syokota	 */
44754545Syokota	if (tp->t_rxtshift == TCP_MAXRXTSHIFT &&
44854545Syokota	    ((ticks - tp->t_rcvtime) >= tcp_maxpersistidle ||
44954545Syokota	     (ticks - tp->t_rcvtime) >= TCP_REXMTVAL(tp) * tcp_totbackoff)) {
45078161Speter		tcpstat.tcps_persistdrop++;
45178161Speter		tp = tcp_drop(tp, ETIMEDOUT);
45242421Syokota		goto out;
45342421Syokota	}
45442421Syokota	tcp_setpersist(tp);
45542421Syokota	tp->t_force = 1;
456127752Sdes	(void) tcp_output(tp);
45742421Syokota	tp->t_force = 0;
45842421Syokota
45942421Syokotaout:
46042421Syokota#ifdef TCPDEBUG
46142421Syokota	if (tp && tp->t_inpcb->inp_socket->so_options & SO_DEBUG)
46242421Syokota		tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
46342421Syokota			  PRU_SLOWTIMO);
46442421Syokota#endif
46542421Syokota	if (tp)
46642421Syokota		INP_UNLOCK(inp);
467183397Sed	INP_INFO_WUNLOCK(&tcbinfo);
46842421Syokota	splx(s);
46950154Syokota}
47050154Syokota
47150154Syokotavoid
47250154Syokotatcp_timer_rexmt(xtp)
47350154Syokota	void *xtp;
47450154Syokota{
47542421Syokota	struct tcpcb *tp = xtp;
47642421Syokota	int s;
47742421Syokota	int rexmt;
478126080Sphk	int headlocked;
479126080Sphk	struct inpcb *inp;
480111815Sphk#ifdef TCPDEBUG
481111815Sphk	int ostate;
482111815Sphk
483111815Sphk	ostate = tp->t_state;
484111815Sphk#endif
485111815Sphk	s = splnet();
486111815Sphk	INP_INFO_WLOCK(&tcbinfo);
48742421Syokota	headlocked = 1;
48842421Syokota	inp = tp->t_inpcb;
48942421Syokota	if (!inp) {
49050154Syokota		INP_INFO_WUNLOCK(&tcbinfo);
49142421Syokota		splx(s);
49242421Syokota		return;
49342421Syokota	}
494127752Sdes	INP_LOCK(inp);
49542421Syokota	if (callout_pending(tp->tt_rexmt) || !callout_active(tp->tt_rexmt)) {
496127752Sdes		INP_UNLOCK(inp);
49742421Syokota		INP_INFO_WUNLOCK(&tcbinfo);
498127751Sdes		splx(s);
499127751Sdes		return;
500125087Sdes	}
501120502Sphk	callout_deactivate(tp->tt_rexmt);
502127751Sdes	tcp_free_sackholes(tp);
50342421Syokota	/*
504127752Sdes	 * Retransmission timer went off.  Message has not
50542421Syokota	 * been acked within retransmit interval.  Back off
50642421Syokota	 * to a longer retransmit interval and retransmit one segment.
50742421Syokota	 */
50850154Syokota	if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) {
50942421Syokota		tp->t_rxtshift = TCP_MAXRXTSHIFT;
51054545Syokota		tcpstat.tcps_timeoutdrop++;
51142421Syokota		tp = tcp_drop(tp, tp->t_softerror ?
512127752Sdes			      tp->t_softerror : ETIMEDOUT);
51342421Syokota		goto out;
514127752Sdes	}
51542421Syokota	INP_INFO_WUNLOCK(&tcbinfo);
516120502Sphk	headlocked = 0;
517120502Sphk	if (tp->t_rxtshift == 1) {
51854545Syokota		/*
519127752Sdes		 * first retransmit; record ssthresh and cwnd so they can
52042421Syokota	 	 * be recovered if this turns out to be a "bad" retransmit.
52142421Syokota		 * A retransmit is considered "bad" if an ACK for this
52242421Syokota		 * segment is received within RTT/2 interval; the assumption
52342421Syokota		 * here is that the ACK was already in flight.  See
52442421Syokota		 * "On Estimating End-to-End Network Path Properties" by
52542421Syokota		 * Allman and Paxson for more details.
52642421Syokota		 */
52742421Syokota		tp->snd_cwnd_prev = tp->snd_cwnd;
528193512Sed		tp->snd_ssthresh_prev = tp->snd_ssthresh;
529193512Sed		tp->snd_recover_prev = tp->snd_recover;
530193512Sed		if (IN_FASTRECOVERY(tp))
531193512Sed		  tp->t_flags |= TF_WASFRECOVERY;
53242421Syokota		else
533193512Sed		  tp->t_flags &= ~TF_WASFRECOVERY;
534193512Sed		tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1));
535193512Sed	}
536193512Sed	tcpstat.tcps_rexmttimeo++;
537193512Sed	if (tp->t_state == TCPS_SYN_SENT)
538193512Sed		rexmt = TCP_REXMTVAL(tp) * tcp_syn_backoff[tp->t_rxtshift];
539193512Sed	else
540193512Sed		rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
541193512Sed	TCPT_RANGESET(tp->t_rxtcur, rexmt,
542193512Sed		      tp->t_rttmin, TCPTV_REXMTMAX);
543193512Sed	/*
544193512Sed	 * Disable rfc1323 and rfc1644 if we havn't got any response to
545193512Sed	 * our third SYN to work-around some broken terminal servers
546193512Sed	 * (most of which have hopefully been retired) that have bad VJ
547193512Sed	 * header compression code which trashes TCP segments containing
548193512Sed	 * unknown-to-them TCP options.
549193512Sed	 */
550193512Sed	if ((tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3))
551193512Sed		tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_REQ_CC);
552193512Sed	/*
553193512Sed	 * If we backed off this far, our srtt estimate is probably bogus.
554193512Sed	 * Clobber it so we'll take the next rtt measurement as our srtt;
555193512Sed	 * move the current srtt into rttvar to keep the current
556193512Sed	 * retransmit times until then.
557193512Sed	 */
558193512Sed	if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) {
559193512Sed#ifdef INET6
560193512Sed		if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0)
56142421Syokota			in6_losing(tp->t_inpcb);
56242421Syokota		else
56350154Syokota#endif
564130585Sphk		tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT);
56542421Syokota		tp->t_srtt = 0;
56650154Syokota	}
56750154Syokota	tp->snd_nxt = tp->snd_una;
56842421Syokota	tp->snd_recover = tp->snd_max;
56942421Syokota	/*
57042421Syokota	 * Force a segment to be sent.
57142421Syokota	 */
57250154Syokota	tp->t_flags |= TF_ACKNOW;
57350154Syokota	/*
57450154Syokota	 * If timing a segment in this window, stop the timer.
57542421Syokota	 */
576127752Sdes	tp->t_rtttime = 0;
57742421Syokota	/*
57842421Syokota	 * Close the congestion window down to one segment
579127751Sdes	 * (we'll open it by one segment for each ack we get).
58042421Syokota	 * Since we probably have a window's worth of unacked
58142421Syokota	 * data accumulated, this "slow start" keeps us from
582127752Sdes	 * dumping all that data as back-to-back packets (which
58342421Syokota	 * might overwhelm an intermediate gateway).
58442421Syokota	 *
58542421Syokota	 * There are two phases to the opening: Initially we
58642421Syokota	 * open by one mss on each ack.  This makes the window
58742421Syokota	 * size increase exponentially with time.  If the
58842421Syokota	 * window is larger than the path can handle, this
58942421Syokota	 * exponential growth results in dropped packet(s)
59042421Syokota	 * almost immediately.  To get more time between
59142421Syokota	 * drops but still "push" the network to take advantage
592193512Sed	 * of improving conditions, we switch from exponential
59342421Syokota	 * to linear window opening at some threshhold size.
59442421Syokota	 * For a threshhold, we use half the current window
595127752Sdes	 * size, truncated to a multiple of the mss.
59642421Syokota	 *
59742421Syokota	 * (the minimum cwnd that will give us exponential
59850154Syokota	 * growth is 2 mss.  We don't allow the threshhold
599130585Sphk	 * to go below this.)
60042421Syokota	 */
60150154Syokota	{
60250154Syokota		u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg;
60342421Syokota		if (win < 2)
60442421Syokota			win = 2;
60542421Syokota		tp->snd_cwnd = tp->t_maxseg;
60642421Syokota		tp->snd_ssthresh = win * tp->t_maxseg;
60750154Syokota		tp->t_dupacks = 0;
60842421Syokota	}
60942421Syokota	EXIT_FASTRECOVERY(tp);
61050154Syokota	(void) tcp_output(tp);
61150154Syokota
61250154Syokotaout:
61350154Syokota#ifdef TCPDEBUG
61450154Syokota	if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
61550154Syokota		tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0,
61650154Syokota			  PRU_SLOWTIMO);
61742421Syokota#endif
618127752Sdes	if (tp)
61942421Syokota		INP_UNLOCK(inp);
62042421Syokota	if (headlocked)
62150154Syokota		INP_INFO_WUNLOCK(&tcbinfo);
622130585Sphk	splx(s);
62342421Syokota}
62450154Syokota