tcp_timer.c revision 108265
11541Srgrimes/* 211150Swollman * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151541Srgrimes * This product includes software developed by the University of 161541Srgrimes * California, Berkeley and its contributors. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 3311150Swollman * @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95 3450477Speter * $FreeBSD: head/sys/netinet/tcp_timer.c 108265 2002-12-24 21:00:31Z hsu $ 351541Srgrimes */ 361541Srgrimes 3755679Sshin#include "opt_inet6.h" 3829514Sjoerg#include "opt_tcpdebug.h" 3929514Sjoerg 401541Srgrimes#include <sys/param.h> 4112172Sphk#include <sys/kernel.h> 42102967Sbde#include <sys/lock.h> 4378642Ssilby#include <sys/mbuf.h> 44102967Sbde#include <sys/mutex.h> 45102967Sbde#include <sys/protosw.h> 461541Srgrimes#include <sys/socket.h> 471541Srgrimes#include <sys/socketvar.h> 48102967Sbde#include <sys/sysctl.h> 49102967Sbde#include <sys/systm.h> 501541Srgrimes 511541Srgrimes#include <net/route.h> 521541Srgrimes 531541Srgrimes#include <netinet/in.h> 54102967Sbde#include <netinet/in_pcb.h> 551541Srgrimes#include <netinet/in_systm.h> 5655679Sshin#ifdef INET6 5755679Sshin#include <netinet6/in6_pcb.h> 5855679Sshin#endif 591541Srgrimes#include <netinet/ip_var.h> 601541Srgrimes#include <netinet/tcp.h> 611541Srgrimes#include <netinet/tcp_fsm.h> 621541Srgrimes#include <netinet/tcp_timer.h> 631541Srgrimes#include <netinet/tcp_var.h> 641541Srgrimes#include <netinet/tcpip.h> 6517138Sdg#ifdef TCPDEBUG 6617138Sdg#include <netinet/tcp_debug.h> 6717138Sdg#endif 681541Srgrimes 6950682Sjlemonstatic int 7062573Sphksysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS) 7150682Sjlemon{ 7250682Sjlemon int error, s, tt; 7350682Sjlemon 7450682Sjlemon tt = *(int *)oidp->oid_arg1; 75100420Sjdp s = (int)((int64_t)tt * 1000 / hz); 7650682Sjlemon 7750705Sjlemon error = sysctl_handle_int(oidp, &s, 0, req); 7850682Sjlemon if (error || !req->newptr) 7950682Sjlemon return (error); 8050682Sjlemon 81100420Sjdp tt = (int)((int64_t)s * hz / 1000); 8250705Sjlemon if (tt < 1) 8350705Sjlemon return (EINVAL); 8450682Sjlemon 8550682Sjlemon *(int *)oidp->oid_arg1 = tt; 8650682Sjlemon return (0); 8750682Sjlemon} 8850682Sjlemon 8950673Sjlemonint tcp_keepinit; 9050682SjlemonSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINIT, keepinit, CTLTYPE_INT|CTLFLAG_RW, 9150682Sjlemon &tcp_keepinit, 0, sysctl_msec_to_ticks, "I", ""); 9218280Spst 9350673Sjlemonint tcp_keepidle; 9450682SjlemonSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPIDLE, keepidle, CTLTYPE_INT|CTLFLAG_RW, 9550682Sjlemon &tcp_keepidle, 0, sysctl_msec_to_ticks, "I", ""); 9612172Sphk 9750673Sjlemonint tcp_keepintvl; 9850682SjlemonSYSCTL_PROC(_net_inet_tcp, TCPCTL_KEEPINTVL, keepintvl, CTLTYPE_INT|CTLFLAG_RW, 9950682Sjlemon &tcp_keepintvl, 0, sysctl_msec_to_ticks, "I", ""); 10012172Sphk 10150673Sjlemonint tcp_delacktime; 10250682SjlemonSYSCTL_PROC(_net_inet_tcp, TCPCTL_DELACKTIME, delacktime, 10350682Sjlemon CTLTYPE_INT|CTLFLAG_RW, &tcp_delacktime, 0, sysctl_msec_to_ticks, "I", 10450682Sjlemon "Time before a delayed ACK is sent"); 10550673Sjlemon 10650673Sjlemonint tcp_msl; 10750682SjlemonSYSCTL_PROC(_net_inet_tcp, OID_AUTO, msl, CTLTYPE_INT|CTLFLAG_RW, 10850682Sjlemon &tcp_msl, 0, sysctl_msec_to_ticks, "I", "Maximum segment lifetime"); 10950673Sjlemon 110100335Sdillonint tcp_rexmit_min; 111100335SdillonSYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_min, CTLTYPE_INT|CTLFLAG_RW, 112100335Sdillon &tcp_rexmit_min, 0, sysctl_msec_to_ticks, "I", "Minimum Retransmission Timeout"); 113100335Sdillon 114100335Sdillonint tcp_rexmit_slop; 115100335SdillonSYSCTL_PROC(_net_inet_tcp, OID_AUTO, rexmit_slop, CTLTYPE_INT|CTLFLAG_RW, 116100335Sdillon &tcp_rexmit_slop, 0, sysctl_msec_to_ticks, "I", "Retransmission Timer Slop"); 117100335Sdillon 11887499Srwatsonstatic int always_keepalive = 1; 11946381SbillfSYSCTL_INT(_net_inet_tcp, OID_AUTO, always_keepalive, CTLFLAG_RW, 12046381Sbillf &always_keepalive , 0, "Assume SO_KEEPALIVE on all TCP connections"); 12115039Sphk 12212296Sphkstatic int tcp_keepcnt = TCPTV_KEEPCNT; 12312296Sphk /* max idle probes */ 12450673Sjlemonint tcp_maxpersistidle; 12512296Sphk /* max idle time in persist */ 1261541Srgrimesint tcp_maxidle; 12711150Swollman 1281541Srgrimes/* 1291541Srgrimes * Tcp protocol timeout routine called every 500 ms. 13050673Sjlemon * Updates timestamps used for TCP 1311541Srgrimes * causes finite state machine actions if timers expire. 1321541Srgrimes */ 1331541Srgrimesvoid 1341541Srgrimestcp_slowtimo() 1351541Srgrimes{ 1367684Sdg int s; 1371541Srgrimes 1387684Sdg s = splnet(); 1397684Sdg 14011150Swollman tcp_maxidle = tcp_keepcnt * tcp_keepintvl; 1417684Sdg 1421541Srgrimes splx(s); 1431541Srgrimes} 1441541Srgrimes 1451541Srgrimes/* 1461541Srgrimes * Cancel all timers for TCP tp. 1471541Srgrimes */ 1481541Srgrimesvoid 1491541Srgrimestcp_canceltimers(tp) 1501541Srgrimes struct tcpcb *tp; 1511541Srgrimes{ 15250673Sjlemon callout_stop(tp->tt_2msl); 15350673Sjlemon callout_stop(tp->tt_persist); 15450673Sjlemon callout_stop(tp->tt_keep); 15550673Sjlemon callout_stop(tp->tt_rexmt); 1561541Srgrimes} 1571541Srgrimes 15873110Sjlemonint tcp_syn_backoff[TCP_MAXRXTSHIFT + 1] = 15973110Sjlemon { 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 64, 64, 64 }; 16073110Sjlemon 1611541Srgrimesint tcp_backoff[TCP_MAXRXTSHIFT + 1] = 1621541Srgrimes { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; 1631541Srgrimes 16412296Sphkstatic int tcp_totbackoff = 511; /* sum of tcp_backoff[] */ 16511150Swollman 1661541Srgrimes/* 1671541Srgrimes * TCP timer processing. 1681541Srgrimes */ 16998102Shsu 17050673Sjlemonvoid 17150673Sjlemontcp_timer_delack(xtp) 17250673Sjlemon void *xtp; 1731541Srgrimes{ 17450673Sjlemon struct tcpcb *tp = xtp; 17550673Sjlemon int s; 17698102Shsu struct inpcb *inp; 1771541Srgrimes 17850673Sjlemon s = splnet(); 17998102Shsu INP_INFO_RLOCK(&tcbinfo); 18098102Shsu inp = tp->t_inpcb; 181108265Shsu if (!inp) { 182108265Shsu INP_INFO_RUNLOCK(&tcbinfo); 183108265Shsu splx(s); 184108265Shsu return; 185108265Shsu } 18698102Shsu INP_LOCK(inp); 18798102Shsu INP_INFO_RUNLOCK(&tcbinfo); 18865906Sjlemon if (callout_pending(tp->tt_delack) || !callout_active(tp->tt_delack)) { 18998102Shsu INP_UNLOCK(inp); 19050673Sjlemon splx(s); 19150673Sjlemon return; 19250673Sjlemon } 19350673Sjlemon callout_deactivate(tp->tt_delack); 1941541Srgrimes 19550673Sjlemon tp->t_flags |= TF_ACKNOW; 19650673Sjlemon tcpstat.tcps_delack++; 19750673Sjlemon (void) tcp_output(tp); 19898102Shsu INP_UNLOCK(inp); 19950673Sjlemon splx(s); 20050673Sjlemon} 20150673Sjlemon 20250673Sjlemonvoid 20350673Sjlemontcp_timer_2msl(xtp) 20450673Sjlemon void *xtp; 20550673Sjlemon{ 20650673Sjlemon struct tcpcb *tp = xtp; 20750673Sjlemon int s; 20898102Shsu struct inpcb *inp; 20950673Sjlemon#ifdef TCPDEBUG 21050673Sjlemon int ostate; 21150673Sjlemon 21250673Sjlemon ostate = tp->t_state; 21350673Sjlemon#endif 21450673Sjlemon s = splnet(); 21598102Shsu INP_INFO_WLOCK(&tcbinfo); 21698102Shsu inp = tp->t_inpcb; 217108265Shsu if (!inp) { 218108265Shsu INP_INFO_WUNLOCK(&tcbinfo); 219108265Shsu splx(s); 220108265Shsu return; 221108265Shsu } 22298102Shsu INP_LOCK(inp); 22365906Sjlemon if (callout_pending(tp->tt_2msl) || !callout_active(tp->tt_2msl)) { 22498102Shsu INP_UNLOCK(tp->t_inpcb); 22598102Shsu INP_INFO_WUNLOCK(&tcbinfo); 22650673Sjlemon splx(s); 22750673Sjlemon return; 22850673Sjlemon } 22950673Sjlemon callout_deactivate(tp->tt_2msl); 2301541Srgrimes /* 2311541Srgrimes * 2 MSL timeout in shutdown went off. If we're closed but 2321541Srgrimes * still waiting for peer to close and connection has been idle 2331541Srgrimes * too long, or if 2MSL time is up from TIME_WAIT, delete connection 2341541Srgrimes * control block. Otherwise, check again in a bit. 2351541Srgrimes */ 23650673Sjlemon if (tp->t_state != TCPS_TIME_WAIT && 23750673Sjlemon (ticks - tp->t_rcvtime) <= tcp_maxidle) 23850673Sjlemon callout_reset(tp->tt_2msl, tcp_keepintvl, 23950673Sjlemon tcp_timer_2msl, tp); 24050673Sjlemon else 24150673Sjlemon tp = tcp_close(tp); 2421541Srgrimes 24350673Sjlemon#ifdef TCPDEBUG 24497658Stanimura if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) 24597658Stanimura tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, 24697658Stanimura PRU_SLOWTIMO); 24750673Sjlemon#endif 24898102Shsu if (tp) 24998102Shsu INP_UNLOCK(inp); 25098102Shsu INP_INFO_WUNLOCK(&tcbinfo); 25150673Sjlemon splx(s); 25250673Sjlemon} 25350673Sjlemon 25450673Sjlemonvoid 25550673Sjlemontcp_timer_keep(xtp) 25650673Sjlemon void *xtp; 25750673Sjlemon{ 25850673Sjlemon struct tcpcb *tp = xtp; 25978642Ssilby struct tcptemp *t_template; 26050673Sjlemon int s; 26198102Shsu struct inpcb *inp; 26250673Sjlemon#ifdef TCPDEBUG 26350673Sjlemon int ostate; 26450673Sjlemon 26550673Sjlemon ostate = tp->t_state; 26650673Sjlemon#endif 26750673Sjlemon s = splnet(); 26898102Shsu INP_INFO_WLOCK(&tcbinfo); 26998102Shsu inp = tp->t_inpcb; 270108265Shsu if (!inp) { 271108265Shsu INP_INFO_WUNLOCK(&tcbinfo); 272108265Shsu splx(s); 273108265Shsu return; 274108265Shsu } 27598102Shsu INP_LOCK(inp); 27665906Sjlemon if (callout_pending(tp->tt_keep) || !callout_active(tp->tt_keep)) { 27798102Shsu INP_UNLOCK(inp); 27898102Shsu INP_INFO_WUNLOCK(&tcbinfo); 27950673Sjlemon splx(s); 28050673Sjlemon return; 28150673Sjlemon } 28250673Sjlemon callout_deactivate(tp->tt_keep); 2831541Srgrimes /* 28450673Sjlemon * Keep-alive timer went off; send something 28550673Sjlemon * or drop connection if idle for too long. 2861541Srgrimes */ 28750673Sjlemon tcpstat.tcps_keeptimeo++; 28850673Sjlemon if (tp->t_state < TCPS_ESTABLISHED) 28950673Sjlemon goto dropit; 29050673Sjlemon if ((always_keepalive || 29150673Sjlemon tp->t_inpcb->inp_socket->so_options & SO_KEEPALIVE) && 29250673Sjlemon tp->t_state <= TCPS_CLOSING) { 29350673Sjlemon if ((ticks - tp->t_rcvtime) >= tcp_keepidle + tcp_maxidle) 29450673Sjlemon goto dropit; 2951541Srgrimes /* 29650673Sjlemon * Send a packet designed to force a response 29750673Sjlemon * if the peer is up and reachable: 29850673Sjlemon * either an ACK if the connection is still alive, 29950673Sjlemon * or an RST if the peer has closed the connection 30050673Sjlemon * due to timeout or reboot. 30150673Sjlemon * Using sequence number tp->snd_una-1 30250673Sjlemon * causes the transmitted zero-length segment 30350673Sjlemon * to lie outside the receive window; 30450673Sjlemon * by the protocol spec, this requires the 30550673Sjlemon * correspondent TCP to respond. 3061541Srgrimes */ 30750673Sjlemon tcpstat.tcps_keepprobe++; 30878642Ssilby t_template = tcp_maketemplate(tp); 30978642Ssilby if (t_template) { 31078642Ssilby tcp_respond(tp, t_template->tt_ipgen, 31178642Ssilby &t_template->tt_t, (struct mbuf *)NULL, 31278642Ssilby tp->rcv_nxt, tp->snd_una - 1, 0); 31378642Ssilby (void) m_free(dtom(t_template)); 31478642Ssilby } 31550673Sjlemon callout_reset(tp->tt_keep, tcp_keepintvl, tcp_timer_keep, tp); 31697658Stanimura } else 31750673Sjlemon callout_reset(tp->tt_keep, tcp_keepidle, tcp_timer_keep, tp); 31850673Sjlemon 31950673Sjlemon#ifdef TCPDEBUG 32097658Stanimura if (tp->t_inpcb->inp_socket->so_options & SO_DEBUG) 32155679Sshin tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, 32250673Sjlemon PRU_SLOWTIMO); 32350673Sjlemon#endif 32498102Shsu INP_UNLOCK(inp); 32598102Shsu INP_INFO_WUNLOCK(&tcbinfo); 32650673Sjlemon splx(s); 32750673Sjlemon return; 32850673Sjlemon 32950673Sjlemondropit: 33050673Sjlemon tcpstat.tcps_keepdrops++; 33150673Sjlemon tp = tcp_drop(tp, ETIMEDOUT); 33250673Sjlemon 33350673Sjlemon#ifdef TCPDEBUG 33497658Stanimura if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) 33597658Stanimura tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, 33697658Stanimura PRU_SLOWTIMO); 33750673Sjlemon#endif 33898102Shsu if (tp) 33998102Shsu INP_UNLOCK(tp->t_inpcb); 34098102Shsu INP_INFO_WUNLOCK(&tcbinfo); 34150673Sjlemon splx(s); 34250673Sjlemon} 34350673Sjlemon 34450673Sjlemonvoid 34550673Sjlemontcp_timer_persist(xtp) 34650673Sjlemon void *xtp; 34750673Sjlemon{ 34850673Sjlemon struct tcpcb *tp = xtp; 34950673Sjlemon int s; 35098102Shsu struct inpcb *inp; 35150673Sjlemon#ifdef TCPDEBUG 35250673Sjlemon int ostate; 35350673Sjlemon 35450673Sjlemon ostate = tp->t_state; 35550673Sjlemon#endif 35650673Sjlemon s = splnet(); 35798102Shsu INP_INFO_WLOCK(&tcbinfo); 35898102Shsu inp = tp->t_inpcb; 359108265Shsu if (!inp) { 360108265Shsu INP_INFO_WUNLOCK(&tcbinfo); 361108265Shsu splx(s); 362108265Shsu return; 363108265Shsu } 36498102Shsu INP_LOCK(inp); 36565906Sjlemon if (callout_pending(tp->tt_persist) || !callout_active(tp->tt_persist)){ 36698102Shsu INP_UNLOCK(inp); 36798102Shsu INP_INFO_WUNLOCK(&tcbinfo); 36850673Sjlemon splx(s); 36950673Sjlemon return; 37050673Sjlemon } 37150673Sjlemon callout_deactivate(tp->tt_persist); 37250673Sjlemon /* 37350673Sjlemon * Persistance timer into zero window. 37450673Sjlemon * Force a byte to be output, if possible. 37550673Sjlemon */ 37650673Sjlemon tcpstat.tcps_persisttimeo++; 37750673Sjlemon /* 37850673Sjlemon * Hack: if the peer is dead/unreachable, we do not 37950673Sjlemon * time out if the window is closed. After a full 38050673Sjlemon * backoff, drop the connection if the idle time 38150673Sjlemon * (no responses to probes) reaches the maximum 38250673Sjlemon * backoff that we would use if retransmitting. 38350673Sjlemon */ 38450673Sjlemon if (tp->t_rxtshift == TCP_MAXRXTSHIFT && 38550673Sjlemon ((ticks - tp->t_rcvtime) >= tcp_maxpersistidle || 38650673Sjlemon (ticks - tp->t_rcvtime) >= TCP_REXMTVAL(tp) * tcp_totbackoff)) { 38750673Sjlemon tcpstat.tcps_persistdrop++; 38850673Sjlemon tp = tcp_drop(tp, ETIMEDOUT); 38950673Sjlemon goto out; 39050673Sjlemon } 39150673Sjlemon tcp_setpersist(tp); 39250673Sjlemon tp->t_force = 1; 39350673Sjlemon (void) tcp_output(tp); 39450673Sjlemon tp->t_force = 0; 39550673Sjlemon 39650673Sjlemonout: 39750673Sjlemon#ifdef TCPDEBUG 39897658Stanimura if (tp && tp->t_inpcb->inp_socket->so_options & SO_DEBUG) 39997658Stanimura tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, 40097658Stanimura PRU_SLOWTIMO); 40150673Sjlemon#endif 40298102Shsu if (tp) 40398102Shsu INP_UNLOCK(inp); 40498102Shsu INP_INFO_WUNLOCK(&tcbinfo); 40550673Sjlemon splx(s); 40650673Sjlemon} 40750673Sjlemon 40850673Sjlemonvoid 40950673Sjlemontcp_timer_rexmt(xtp) 41050673Sjlemon void *xtp; 41150673Sjlemon{ 41250673Sjlemon struct tcpcb *tp = xtp; 41350673Sjlemon int s; 41450673Sjlemon int rexmt; 41598102Shsu int headlocked; 41698102Shsu struct inpcb *inp; 41750673Sjlemon#ifdef TCPDEBUG 41850673Sjlemon int ostate; 41950673Sjlemon 42050673Sjlemon ostate = tp->t_state; 42150673Sjlemon#endif 42250673Sjlemon s = splnet(); 42398102Shsu INP_INFO_WLOCK(&tcbinfo); 42498102Shsu headlocked = 1; 42598102Shsu inp = tp->t_inpcb; 426108265Shsu if (!inp) { 427108265Shsu INP_INFO_WUNLOCK(&tcbinfo); 428108265Shsu splx(s); 429108265Shsu return; 430108265Shsu } 43198102Shsu INP_LOCK(inp); 43265906Sjlemon if (callout_pending(tp->tt_rexmt) || !callout_active(tp->tt_rexmt)) { 43398102Shsu INP_UNLOCK(inp); 43498102Shsu INP_INFO_WUNLOCK(&tcbinfo); 43550673Sjlemon splx(s); 43650673Sjlemon return; 43750673Sjlemon } 43850673Sjlemon callout_deactivate(tp->tt_rexmt); 43950673Sjlemon /* 44050673Sjlemon * Retransmission timer went off. Message has not 44150673Sjlemon * been acked within retransmit interval. Back off 44250673Sjlemon * to a longer retransmit interval and retransmit one segment. 44350673Sjlemon */ 44450673Sjlemon if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { 44550673Sjlemon tp->t_rxtshift = TCP_MAXRXTSHIFT; 44650673Sjlemon tcpstat.tcps_timeoutdrop++; 44750673Sjlemon tp = tcp_drop(tp, tp->t_softerror ? 44850673Sjlemon tp->t_softerror : ETIMEDOUT); 44950673Sjlemon goto out; 45050673Sjlemon } 45198102Shsu INP_INFO_WUNLOCK(&tcbinfo); 45298102Shsu headlocked = 0; 45350673Sjlemon if (tp->t_rxtshift == 1) { 45413229Solah /* 45550673Sjlemon * first retransmit; record ssthresh and cwnd so they can 45650673Sjlemon * be recovered if this turns out to be a "bad" retransmit. 45750673Sjlemon * A retransmit is considered "bad" if an ACK for this 45850673Sjlemon * segment is received within RTT/2 interval; the assumption 45950673Sjlemon * here is that the ACK was already in flight. See 46050673Sjlemon * "On Estimating End-to-End Network Path Properties" by 46150673Sjlemon * Allman and Paxson for more details. 4621541Srgrimes */ 46350673Sjlemon tp->snd_cwnd_prev = tp->snd_cwnd; 46450673Sjlemon tp->snd_ssthresh_prev = tp->snd_ssthresh; 46550673Sjlemon tp->t_badrxtwin = ticks + (tp->t_srtt >> (TCP_RTT_SHIFT + 1)); 46650673Sjlemon } 46750673Sjlemon tcpstat.tcps_rexmttimeo++; 46873110Sjlemon if (tp->t_state == TCPS_SYN_SENT) 46973110Sjlemon rexmt = TCP_REXMTVAL(tp) * tcp_syn_backoff[tp->t_rxtshift]; 47073110Sjlemon else 47173110Sjlemon rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; 47250673Sjlemon TCPT_RANGESET(tp->t_rxtcur, rexmt, 47350673Sjlemon tp->t_rttmin, TCPTV_REXMTMAX); 47450673Sjlemon /* 47577539Sjesper * Disable rfc1323 and rfc1644 if we havn't got any response to 47677539Sjesper * our third SYN to work-around some broken terminal servers 47777539Sjesper * (most of which have hopefully been retired) that have bad VJ 47877539Sjesper * header compression code which trashes TCP segments containing 47977539Sjesper * unknown-to-them TCP options. 48077539Sjesper */ 48177539Sjesper if ((tp->t_state == TCPS_SYN_SENT) && (tp->t_rxtshift == 3)) 48277539Sjesper tp->t_flags &= ~(TF_REQ_SCALE|TF_REQ_TSTMP|TF_REQ_CC); 48377539Sjesper /* 48450673Sjlemon * If losing, let the lower level know and try for 48550673Sjlemon * a better route. Also, if we backed off this far, 48650673Sjlemon * our srtt estimate is probably bogus. Clobber it 48750673Sjlemon * so we'll take the next rtt measurement as our srtt; 48850673Sjlemon * move the current srtt into rttvar to keep the current 48950673Sjlemon * retransmit times until then. 49050673Sjlemon */ 49150673Sjlemon if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { 49255679Sshin#ifdef INET6 49355679Sshin if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) 49455679Sshin in6_losing(tp->t_inpcb); 49555679Sshin else 49655679Sshin#endif 49750673Sjlemon in_losing(tp->t_inpcb); 49850673Sjlemon tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); 49950673Sjlemon tp->t_srtt = 0; 50050673Sjlemon } 50150673Sjlemon tp->snd_nxt = tp->snd_una; 50250673Sjlemon /* 50360067Sjlemon * Note: We overload snd_recover to function also as the 50460067Sjlemon * snd_last variable described in RFC 2582 50560067Sjlemon */ 50660067Sjlemon tp->snd_recover = tp->snd_max; 50760067Sjlemon /* 50850673Sjlemon * Force a segment to be sent. 50950673Sjlemon */ 51050673Sjlemon tp->t_flags |= TF_ACKNOW; 51150673Sjlemon /* 51250673Sjlemon * If timing a segment in this window, stop the timer. 51350673Sjlemon */ 51450673Sjlemon tp->t_rtttime = 0; 51550673Sjlemon /* 51650673Sjlemon * Close the congestion window down to one segment 51750673Sjlemon * (we'll open it by one segment for each ack we get). 51850673Sjlemon * Since we probably have a window's worth of unacked 51950673Sjlemon * data accumulated, this "slow start" keeps us from 52050673Sjlemon * dumping all that data as back-to-back packets (which 52150673Sjlemon * might overwhelm an intermediate gateway). 52250673Sjlemon * 52350673Sjlemon * There are two phases to the opening: Initially we 52450673Sjlemon * open by one mss on each ack. This makes the window 52550673Sjlemon * size increase exponentially with time. If the 52650673Sjlemon * window is larger than the path can handle, this 52750673Sjlemon * exponential growth results in dropped packet(s) 52850673Sjlemon * almost immediately. To get more time between 52950673Sjlemon * drops but still "push" the network to take advantage 53050673Sjlemon * of improving conditions, we switch from exponential 53150673Sjlemon * to linear window opening at some threshhold size. 53250673Sjlemon * For a threshhold, we use half the current window 53350673Sjlemon * size, truncated to a multiple of the mss. 53450673Sjlemon * 53550673Sjlemon * (the minimum cwnd that will give us exponential 53650673Sjlemon * growth is 2 mss. We don't allow the threshhold 53750673Sjlemon * to go below this.) 53850673Sjlemon */ 53950673Sjlemon { 5401541Srgrimes u_int win = min(tp->snd_wnd, tp->snd_cwnd) / 2 / tp->t_maxseg; 5411541Srgrimes if (win < 2) 5421541Srgrimes win = 2; 5431541Srgrimes tp->snd_cwnd = tp->t_maxseg; 5441541Srgrimes tp->snd_ssthresh = win * tp->t_maxseg; 5451541Srgrimes tp->t_dupacks = 0; 54650673Sjlemon } 54750673Sjlemon (void) tcp_output(tp); 5481541Srgrimes 54950673Sjlemonout: 55050673Sjlemon#ifdef TCPDEBUG 55197658Stanimura if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG)) 55297658Stanimura tcp_trace(TA_USER, ostate, tp, (void *)0, (struct tcphdr *)0, 55397658Stanimura PRU_SLOWTIMO); 5541541Srgrimes#endif 55598102Shsu if (tp) 55698102Shsu INP_UNLOCK(inp); 55798102Shsu if (headlocked) 55898102Shsu INP_INFO_WUNLOCK(&tcbinfo); 55950673Sjlemon splx(s); 5601541Srgrimes} 561