| 518 | } |
| 519 | |
| 520 | void |
| 521 | tcp_timer_persist(void *xtp) |
| 522 | { |
| 523 | struct tcpcb *tp = xtp; |
| 524 | struct inpcb *inp; |
| 525 | struct epoch_tracker et; |
| 526 | CURVNET_SET(tp->t_vnet); |
| 527 | #ifdef TCPDEBUG |
| 528 | int ostate; |
| 529 | |
| 530 | ostate = tp->t_state; |
| 531 | #endif |
| 532 | inp = tp->t_inpcb; |
| 533 | KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); |
| 534 | INP_WLOCK(inp); |
| 535 | if (callout_pending(&tp->t_timers->tt_persist) || |
| 536 | !callout_active(&tp->t_timers->tt_persist)) { |
| 537 | INP_WUNLOCK(inp); |
| 538 | CURVNET_RESTORE(); |
| 539 | return; |
| 540 | } |
| 541 | callout_deactivate(&tp->t_timers->tt_persist); |
| 542 | if ((inp->inp_flags & INP_DROPPED) != 0) { |
| 543 | INP_WUNLOCK(inp); |
| 544 | CURVNET_RESTORE(); |
| 545 | return; |
| 546 | } |
| 547 | KASSERT((tp->t_timers->tt_flags & TT_STOPPED) == 0, |
| 548 | ("%s: tp %p tcpcb can't be stopped here", __func__, tp)); |
| 549 | /* |
| 550 | * Persistence timer into zero window. |
| 551 | * Force a byte to be output, if possible. |
| 552 | */ |
| 553 | TCPSTAT_INC(tcps_persisttimeo); |
| 554 | /* |
| 555 | * Hack: if the peer is dead/unreachable, we do not |
| 556 | * time out if the window is closed. After a full |
| 557 | * backoff, drop the connection if the idle time |
| 558 | * (no responses to probes) reaches the maximum |
| 559 | * backoff that we would use if retransmitting. |
| 560 | */ |
| 561 | if (tp->t_rxtshift == TCP_MAXRXTSHIFT && |
| 562 | (ticks - tp->t_rcvtime >= tcp_maxpersistidle || |
| 563 | ticks - tp->t_rcvtime >= TCP_REXMTVAL(tp) * tcp_totbackoff)) { |
| 564 | TCPSTAT_INC(tcps_persistdrop); |
| 565 | if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { |
| 566 | tcp_inpinfo_lock_del(inp, tp); |
| 567 | goto out; |
| 568 | } |
| 569 | NET_EPOCH_ENTER(et); |
| 570 | tp = tcp_drop(tp, ETIMEDOUT); |
| 571 | NET_EPOCH_EXIT(et); |
| 572 | tcp_inpinfo_lock_del(inp, tp); |
| 573 | goto out; |
| 574 | } |
| 575 | /* |
| 576 | * If the user has closed the socket then drop a persisting |
| 577 | * connection after a much reduced timeout. |
nothing calls this directly
no test coverage detected