| 397 | } |
| 398 | |
| 399 | void |
| 400 | tcp_timer_keep(void *xtp) |
| 401 | { |
| 402 | struct tcpcb *tp = xtp; |
| 403 | struct tcptemp *t_template; |
| 404 | struct inpcb *inp; |
| 405 | struct epoch_tracker et; |
| 406 | CURVNET_SET(tp->t_vnet); |
| 407 | #ifdef TCPDEBUG |
| 408 | int ostate; |
| 409 | |
| 410 | ostate = tp->t_state; |
| 411 | #endif |
| 412 | inp = tp->t_inpcb; |
| 413 | KASSERT(inp != NULL, ("%s: tp %p tp->t_inpcb == NULL", __func__, tp)); |
| 414 | INP_WLOCK(inp); |
| 415 | if (callout_pending(&tp->t_timers->tt_keep) || |
| 416 | !callout_active(&tp->t_timers->tt_keep)) { |
| 417 | INP_WUNLOCK(inp); |
| 418 | CURVNET_RESTORE(); |
| 419 | return; |
| 420 | } |
| 421 | callout_deactivate(&tp->t_timers->tt_keep); |
| 422 | if ((inp->inp_flags & INP_DROPPED) != 0) { |
| 423 | INP_WUNLOCK(inp); |
| 424 | CURVNET_RESTORE(); |
| 425 | return; |
| 426 | } |
| 427 | KASSERT((tp->t_timers->tt_flags & TT_STOPPED) == 0, |
| 428 | ("%s: tp %p tcpcb can't be stopped here", __func__, tp)); |
| 429 | |
| 430 | /* |
| 431 | * Because we don't regularly reset the keepalive callout in |
| 432 | * the ESTABLISHED state, it may be that we don't actually need |
| 433 | * to send a keepalive yet. If that occurs, schedule another |
| 434 | * call for the next time the keepalive timer might expire. |
| 435 | */ |
| 436 | if (TCPS_HAVEESTABLISHED(tp->t_state)) { |
| 437 | u_int idletime; |
| 438 | |
| 439 | idletime = ticks - tp->t_rcvtime; |
| 440 | if (idletime < TP_KEEPIDLE(tp)) { |
| 441 | callout_reset(&tp->t_timers->tt_keep, |
| 442 | TP_KEEPIDLE(tp) - idletime, tcp_timer_keep, tp); |
| 443 | INP_WUNLOCK(inp); |
| 444 | CURVNET_RESTORE(); |
| 445 | return; |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | /* |
| 450 | * Keep-alive timer went off; send something |
| 451 | * or drop connection if idle for too long. |
| 452 | */ |
| 453 | TCPSTAT_INC(tcps_keeptimeo); |
| 454 | if (tp->t_state < TCPS_ESTABLISHED) |
| 455 | goto dropit; |
| 456 | if ((V_tcp_always_keepalive || |
nothing calls this directly
no test coverage detected