tcp_timer.c revision 1.84
1/* $NetBSD: tcp_timer.c,v 1.84 2008/11/10 01:06:43 uebayasi Exp $ */ 2 3/* 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the project nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32/*- 33 * Copyright (c) 1997, 1998, 2001, 2005 The NetBSD Foundation, Inc. 34 * All rights reserved. 35 * 36 * This code is derived from software contributed to The NetBSD Foundation 37 * by Jason R. Thorpe and Kevin M. Lahey of the Numerical Aerospace Simulation 38 * Facility, NASA Ames Research Center. 39 * This code is derived from software contributed to The NetBSD Foundation 40 * by Charles M. Hannum. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 52 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64/* 65 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 66 * The Regents of the University of California. All rights reserved. 67 * 68 * Redistribution and use in source and binary forms, with or without 69 * modification, are permitted provided that the following conditions 70 * are met: 71 * 1. Redistributions of source code must retain the above copyright 72 * notice, this list of conditions and the following disclaimer. 73 * 2. Redistributions in binary form must reproduce the above copyright 74 * notice, this list of conditions and the following disclaimer in the 75 * documentation and/or other materials provided with the distribution. 76 * 3. Neither the name of the University nor the names of its contributors 77 * may be used to endorse or promote products derived from this software 78 * without specific prior written permission. 79 * 80 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 81 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 82 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 83 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 84 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 85 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 86 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 87 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 88 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 89 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 90 * SUCH DAMAGE. 91 * 92 * @(#)tcp_timer.c 8.2 (Berkeley) 5/24/95 93 */ 94 95#include <sys/cdefs.h> 96__KERNEL_RCSID(0, "$NetBSD: tcp_timer.c,v 1.84 2008/11/10 01:06:43 uebayasi Exp $"); 97 98#include "opt_inet.h" 99#include "opt_tcp_debug.h" 100 101#include <sys/param.h> 102#include <sys/systm.h> 103#include <sys/malloc.h> 104#include <sys/mbuf.h> 105#include <sys/socket.h> 106#include <sys/socketvar.h> 107#include <sys/protosw.h> 108#include <sys/errno.h> 109#include <sys/kernel.h> 110 111#include <net/if.h> 112#include <net/route.h> 113 114#include <netinet/in.h> 115#include <netinet/in_systm.h> 116#include <netinet/ip.h> 117#include <netinet/in_pcb.h> 118#include <netinet/ip_var.h> 119#include <netinet/ip_icmp.h> 120 121#ifdef INET6 122#ifndef INET 123#include <netinet/in.h> 124#endif 125#include <netinet/ip6.h> 126#include <netinet6/in6_pcb.h> 127#endif 128 129#include <netinet/tcp.h> 130#include <netinet/tcp_fsm.h> 131#include <netinet/tcp_seq.h> 132#include <netinet/tcp_timer.h> 133#include <netinet/tcp_var.h> 134#include <netinet/tcp_private.h> 135#include <netinet/tcp_congctl.h> 136#include <netinet/tcpip.h> 137#ifdef TCP_DEBUG 138#include <netinet/tcp_debug.h> 139#endif 140 141/* 142 * Various tunable timer parameters. These are initialized in tcp_init(), 143 * unless they are patched. 144 */ 145u_int tcp_keepinit = 0; 146u_int tcp_keepidle = 0; 147u_int tcp_keepintvl = 0; 148u_int tcp_keepcnt = 0; /* max idle probes */ 149 150int tcp_maxpersistidle = 0; /* max idle time in persist */ 151 152/* 153 * Time to delay the ACK. This is initialized in tcp_init(), unless 154 * its patched. 155 */ 156int tcp_delack_ticks = 0; 157 158void tcp_timer_rexmt(void *); 159void tcp_timer_persist(void *); 160void tcp_timer_keep(void *); 161void tcp_timer_2msl(void *); 162 163const tcp_timer_func_t tcp_timer_funcs[TCPT_NTIMERS] = { 164 tcp_timer_rexmt, 165 tcp_timer_persist, 166 tcp_timer_keep, 167 tcp_timer_2msl, 168}; 169 170/* 171 * Timer state initialization, called from tcp_init(). 172 */ 173void 174tcp_timer_init(void) 175{ 176 177 if (tcp_keepinit == 0) 178 tcp_keepinit = TCPTV_KEEP_INIT; 179 180 if (tcp_keepidle == 0) 181 tcp_keepidle = TCPTV_KEEP_IDLE; 182 183 if (tcp_keepintvl == 0) 184 tcp_keepintvl = TCPTV_KEEPINTVL; 185 186 if (tcp_keepcnt == 0) 187 tcp_keepcnt = TCPTV_KEEPCNT; 188 189 if (tcp_maxpersistidle == 0) 190 tcp_maxpersistidle = TCPTV_KEEP_IDLE; 191 192 if (tcp_delack_ticks == 0) 193 tcp_delack_ticks = TCP_DELACK_TICKS; 194} 195 196/* 197 * Callout to process delayed ACKs for a TCPCB. 198 */ 199void 200tcp_delack(void *arg) 201{ 202 struct tcpcb *tp = arg; 203 204 /* 205 * If tcp_output() wasn't able to transmit the ACK 206 * for whatever reason, it will restart the delayed 207 * ACK callout. 208 */ 209 210 mutex_enter(softnet_lock); 211 if ((tp->t_flags & (TF_DEAD | TF_DELACK)) != TF_DELACK) { 212 mutex_exit(softnet_lock); 213 return; 214 } 215 if (!callout_expired(&tp->t_delack_ch)) { 216 mutex_exit(softnet_lock); 217 return; 218 } 219 220 tp->t_flags |= TF_ACKNOW; 221 KERNEL_LOCK(1, NULL); 222 (void) tcp_output(tp); 223 KERNEL_UNLOCK_ONE(NULL); 224 mutex_exit(softnet_lock); 225} 226 227/* 228 * Tcp protocol timeout routine called every 500 ms. 229 * Updates the timers in all active tcb's and 230 * causes finite state machine actions if timers expire. 231 */ 232void 233tcp_slowtimo(void) 234{ 235 236 mutex_enter(softnet_lock); 237 tcp_iss_seq += TCP_ISSINCR; /* increment iss */ 238 tcp_now++; /* for timestamps */ 239 mutex_exit(softnet_lock); 240} 241 242/* 243 * Cancel all timers for TCP tp. 244 */ 245void 246tcp_canceltimers(struct tcpcb *tp) 247{ 248 int i; 249 250 for (i = 0; i < TCPT_NTIMERS; i++) 251 TCP_TIMER_DISARM(tp, i); 252} 253 254const int tcp_backoff[TCP_MAXRXTSHIFT + 1] = 255 { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; 256 257const int tcp_totbackoff = 511; /* sum of tcp_backoff[] */ 258 259/* 260 * TCP timer processing. 261 */ 262 263void 264tcp_timer_rexmt(void *arg) 265{ 266 struct tcpcb *tp = arg; 267 uint32_t rto; 268#ifdef TCP_DEBUG 269 struct socket *so = NULL; 270 short ostate; 271#endif 272 273 mutex_enter(softnet_lock); 274 if ((tp->t_flags & TF_DEAD) != 0) { 275 mutex_exit(softnet_lock); 276 return; 277 } 278 if (!callout_expired(&tp->t_timer[TCPT_REXMT])) { 279 mutex_exit(softnet_lock); 280 return; 281 } 282 283 KERNEL_LOCK(1, NULL); 284 if ((tp->t_flags & TF_PMTUD_PEND) && tp->t_inpcb && 285 SEQ_GEQ(tp->t_pmtud_th_seq, tp->snd_una) && 286 SEQ_LT(tp->t_pmtud_th_seq, (int)(tp->snd_una + tp->t_ourmss))) { 287 extern struct sockaddr_in icmpsrc; 288 struct icmp icmp; 289 290 tp->t_flags &= ~TF_PMTUD_PEND; 291 292 /* XXX create fake icmp message with relevant entries */ 293 icmp.icmp_nextmtu = tp->t_pmtud_nextmtu; 294 icmp.icmp_ip.ip_len = tp->t_pmtud_ip_len; 295 icmp.icmp_ip.ip_hl = tp->t_pmtud_ip_hl; 296 icmpsrc.sin_addr = tp->t_inpcb->inp_faddr; 297 icmp_mtudisc(&icmp, icmpsrc.sin_addr); 298 299 /* 300 * Notify all connections to the same peer about 301 * new mss and trigger retransmit. 302 */ 303 in_pcbnotifyall(&tcbtable, icmpsrc.sin_addr, EMSGSIZE, 304 tcp_mtudisc); 305 KERNEL_UNLOCK_ONE(NULL); 306 mutex_exit(softnet_lock); 307 return; 308 } 309#ifdef TCP_DEBUG 310#ifdef INET 311 if (tp->t_inpcb) 312 so = tp->t_inpcb->inp_socket; 313#endif 314#ifdef INET6 315 if (tp->t_in6pcb) 316 so = tp->t_in6pcb->in6p_socket; 317#endif 318 ostate = tp->t_state; 319#endif /* TCP_DEBUG */ 320 321 /* 322 * Clear the SACK scoreboard, reset FACK estimate. 323 */ 324 tcp_free_sackholes(tp); 325 tp->snd_fack = tp->snd_una; 326 327 /* 328 * Retransmission timer went off. Message has not 329 * been acked within retransmit interval. Back off 330 * to a longer retransmit interval and retransmit one segment. 331 */ 332 333 if (++tp->t_rxtshift > TCP_MAXRXTSHIFT) { 334 tp->t_rxtshift = TCP_MAXRXTSHIFT; 335 TCP_STATINC(TCP_STAT_TIMEOUTDROP); 336 tp = tcp_drop(tp, tp->t_softerror ? 337 tp->t_softerror : ETIMEDOUT); 338 goto out; 339 } 340 TCP_STATINC(TCP_STAT_REXMTTIMEO); 341 rto = TCP_REXMTVAL(tp); 342 if (rto < tp->t_rttmin) 343 rto = tp->t_rttmin; 344 TCPT_RANGESET(tp->t_rxtcur, rto * tcp_backoff[tp->t_rxtshift], 345 tp->t_rttmin, TCPTV_REXMTMAX); 346 TCP_TIMER_ARM(tp, TCPT_REXMT, tp->t_rxtcur); 347 348 /* 349 * If we are losing and we are trying path MTU discovery, 350 * try turning it off. This will avoid black holes in 351 * the network which suppress or fail to send "packet 352 * too big" ICMP messages. We should ideally do 353 * lots more sophisticated searching to find the right 354 * value here... 355 */ 356 if (tp->t_mtudisc && tp->t_rxtshift > TCP_MAXRXTSHIFT / 6) { 357 TCP_STATINC(TCP_STAT_PMTUBLACKHOLE); 358 359#ifdef INET 360 /* try turning PMTUD off */ 361 if (tp->t_inpcb) 362 tp->t_mtudisc = 0; 363#endif 364#ifdef INET6 365 /* try using IPv6 minimum MTU */ 366 if (tp->t_in6pcb) 367 tp->t_mtudisc = 0; 368#endif 369 370 /* XXX: more sophisticated Black hole recovery code? */ 371 } 372 373 /* 374 * If losing, let the lower level know and try for 375 * a better route. Also, if we backed off this far, 376 * our srtt estimate is probably bogus. Clobber it 377 * so we'll take the next rtt measurement as our srtt; 378 * move the current srtt into rttvar to keep the current 379 * retransmit times until then. 380 */ 381 if (tp->t_rxtshift > TCP_MAXRXTSHIFT / 4) { 382#ifdef INET 383 if (tp->t_inpcb) 384 in_losing(tp->t_inpcb); 385#endif 386#ifdef INET6 387 if (tp->t_in6pcb) 388 in6_losing(tp->t_in6pcb); 389#endif 390 tp->t_rttvar += (tp->t_srtt >> TCP_RTT_SHIFT); 391 tp->t_srtt = 0; 392 } 393 tp->snd_nxt = tp->snd_una; 394 tp->snd_high = tp->snd_max; 395 /* 396 * If timing a segment in this window, stop the timer. 397 */ 398 tp->t_rtttime = 0; 399 /* 400 * Remember if we are retransmitting a SYN, because if 401 * we do, set the initial congestion window must be set 402 * to 1 segment. 403 */ 404 if (tp->t_state == TCPS_SYN_SENT) 405 tp->t_flags |= TF_SYN_REXMT; 406 407 /* 408 * Adjust congestion control parameters. 409 */ 410 tp->t_congctl->slow_retransmit(tp); 411 412 (void) tcp_output(tp); 413 414 out: 415#ifdef TCP_DEBUG 416 if (tp && so->so_options & SO_DEBUG) 417 tcp_trace(TA_USER, ostate, tp, NULL, 418 PRU_SLOWTIMO | (TCPT_REXMT << 8)); 419#endif 420 KERNEL_UNLOCK_ONE(NULL); 421 mutex_exit(softnet_lock); 422} 423 424void 425tcp_timer_persist(void *arg) 426{ 427 struct tcpcb *tp = arg; 428 uint32_t rto; 429#ifdef TCP_DEBUG 430 struct socket *so = NULL; 431 short ostate; 432#endif 433 434 mutex_enter(softnet_lock); 435 if ((tp->t_flags & TF_DEAD) != 0) { 436 mutex_exit(softnet_lock); 437 return; 438 } 439 if (!callout_expired(&tp->t_timer[TCPT_PERSIST])) { 440 mutex_exit(softnet_lock); 441 return; 442 } 443 444 KERNEL_LOCK(1, NULL); 445#ifdef TCP_DEBUG 446#ifdef INET 447 if (tp->t_inpcb) 448 so = tp->t_inpcb->inp_socket; 449#endif 450#ifdef INET6 451 if (tp->t_in6pcb) 452 so = tp->t_in6pcb->in6p_socket; 453#endif 454 455 ostate = tp->t_state; 456#endif /* TCP_DEBUG */ 457 458 /* 459 * Persistance timer into zero window. 460 * Force a byte to be output, if possible. 461 */ 462 463 /* 464 * Hack: if the peer is dead/unreachable, we do not 465 * time out if the window is closed. After a full 466 * backoff, drop the connection if the idle time 467 * (no responses to probes) reaches the maximum 468 * backoff that we would use if retransmitting. 469 */ 470 rto = TCP_REXMTVAL(tp); 471 if (rto < tp->t_rttmin) 472 rto = tp->t_rttmin; 473 if (tp->t_rxtshift == TCP_MAXRXTSHIFT && 474 ((tcp_now - tp->t_rcvtime) >= tcp_maxpersistidle || 475 (tcp_now - tp->t_rcvtime) >= rto * tcp_totbackoff)) { 476 TCP_STATINC(TCP_STAT_PERSISTDROPS); 477 tp = tcp_drop(tp, ETIMEDOUT); 478 goto out; 479 } 480 TCP_STATINC(TCP_STAT_PERSISTTIMEO); 481 tcp_setpersist(tp); 482 tp->t_force = 1; 483 (void) tcp_output(tp); 484 tp->t_force = 0; 485 486 out: 487#ifdef TCP_DEBUG 488 if (tp && so->so_options & SO_DEBUG) 489 tcp_trace(TA_USER, ostate, tp, NULL, 490 PRU_SLOWTIMO | (TCPT_PERSIST << 8)); 491#endif 492 KERNEL_UNLOCK_ONE(NULL); 493 mutex_exit(softnet_lock); 494} 495 496void 497tcp_timer_keep(void *arg) 498{ 499 struct tcpcb *tp = arg; 500 struct socket *so = NULL; /* Quell compiler warning */ 501#ifdef TCP_DEBUG 502 short ostate; 503#endif 504 505 mutex_enter(softnet_lock); 506 if ((tp->t_flags & TF_DEAD) != 0) { 507 mutex_exit(softnet_lock); 508 return; 509 } 510 if (!callout_expired(&tp->t_timer[TCPT_KEEP])) { 511 mutex_exit(softnet_lock); 512 return; 513 } 514 515 KERNEL_LOCK(1, NULL); 516 517#ifdef TCP_DEBUG 518 ostate = tp->t_state; 519#endif /* TCP_DEBUG */ 520 521 /* 522 * Keep-alive timer went off; send something 523 * or drop connection if idle for too long. 524 */ 525 526 TCP_STATINC(TCP_STAT_KEEPTIMEO); 527 if (TCPS_HAVEESTABLISHED(tp->t_state) == 0) 528 goto dropit; 529#ifdef INET 530 if (tp->t_inpcb) 531 so = tp->t_inpcb->inp_socket; 532#endif 533#ifdef INET6 534 if (tp->t_in6pcb) 535 so = tp->t_in6pcb->in6p_socket; 536#endif 537 KASSERT(so != NULL); 538 if (so->so_options & SO_KEEPALIVE && 539 tp->t_state <= TCPS_CLOSE_WAIT) { 540 if ((tp->t_maxidle > 0) && 541 ((tcp_now - tp->t_rcvtime) >= 542 tp->t_keepidle + tp->t_maxidle)) 543 goto dropit; 544 /* 545 * Send a packet designed to force a response 546 * if the peer is up and reachable: 547 * either an ACK if the connection is still alive, 548 * or an RST if the peer has closed the connection 549 * due to timeout or reboot. 550 * Using sequence number tp->snd_una-1 551 * causes the transmitted zero-length segment 552 * to lie outside the receive window; 553 * by the protocol spec, this requires the 554 * correspondent TCP to respond. 555 */ 556 TCP_STATINC(TCP_STAT_KEEPPROBE); 557 if (tcp_compat_42) { 558 /* 559 * The keepalive packet must have nonzero 560 * length to get a 4.2 host to respond. 561 */ 562 (void)tcp_respond(tp, tp->t_template, 563 (struct mbuf *)NULL, NULL, tp->rcv_nxt - 1, 564 tp->snd_una - 1, 0); 565 } else { 566 (void)tcp_respond(tp, tp->t_template, 567 (struct mbuf *)NULL, NULL, tp->rcv_nxt, 568 tp->snd_una - 1, 0); 569 } 570 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepintvl); 571 } else 572 TCP_TIMER_ARM(tp, TCPT_KEEP, tp->t_keepidle); 573 574#ifdef TCP_DEBUG 575 if (tp && so->so_options & SO_DEBUG) 576 tcp_trace(TA_USER, ostate, tp, NULL, 577 PRU_SLOWTIMO | (TCPT_KEEP << 8)); 578#endif 579 KERNEL_UNLOCK_ONE(NULL); 580 mutex_exit(softnet_lock); 581 return; 582 583 dropit: 584 TCP_STATINC(TCP_STAT_KEEPDROPS); 585 (void) tcp_drop(tp, ETIMEDOUT); 586 KERNEL_UNLOCK_ONE(NULL); 587 mutex_exit(softnet_lock); 588} 589 590void 591tcp_timer_2msl(void *arg) 592{ 593 struct tcpcb *tp = arg; 594#ifdef TCP_DEBUG 595 struct socket *so = NULL; 596 short ostate; 597#endif 598 599 mutex_enter(softnet_lock); 600 if ((tp->t_flags & TF_DEAD) != 0) { 601 mutex_exit(softnet_lock); 602 return; 603 } 604 if (!callout_expired(&tp->t_timer[TCPT_2MSL])) { 605 mutex_exit(softnet_lock); 606 return; 607 } 608 609 /* 610 * 2 MSL timeout went off, clear the SACK scoreboard, reset 611 * the FACK estimate. 612 */ 613 KERNEL_LOCK(1, NULL); 614 tcp_free_sackholes(tp); 615 tp->snd_fack = tp->snd_una; 616 617#ifdef TCP_DEBUG 618#ifdef INET 619 if (tp->t_inpcb) 620 so = tp->t_inpcb->inp_socket; 621#endif 622#ifdef INET6 623 if (tp->t_in6pcb) 624 so = tp->t_in6pcb->in6p_socket; 625#endif 626 627 ostate = tp->t_state; 628#endif /* TCP_DEBUG */ 629 630 /* 631 * 2 MSL timeout in shutdown went off. If we're closed but 632 * still waiting for peer to close and connection has been idle 633 * too long, or if 2MSL time is up from TIME_WAIT, delete connection 634 * control block. Otherwise, check again in a bit. 635 */ 636 if (tp->t_state != TCPS_TIME_WAIT && 637 ((tp->t_maxidle == 0) || 638 ((tcp_now - tp->t_rcvtime) <= tp->t_maxidle))) 639 TCP_TIMER_ARM(tp, TCPT_2MSL, tp->t_keepintvl); 640 else 641 tp = tcp_close(tp); 642 643#ifdef TCP_DEBUG 644 if (tp && so->so_options & SO_DEBUG) 645 tcp_trace(TA_USER, ostate, tp, NULL, 646 PRU_SLOWTIMO | (TCPT_2MSL << 8)); 647#endif 648 mutex_exit(softnet_lock); 649 KERNEL_UNLOCK_ONE(NULL); 650} 651