* Walk the timer queues, looking for SYN,ACKs that need to be retransmitted. * If we have retransmitted an entry the maximum number of times, expire it. * One separate timer for each bucket row. */
| 463 | * One separate timer for each bucket row. |
| 464 | */ |
| 465 | static void |
| 466 | syncache_timer(void *xsch) |
| 467 | { |
| 468 | struct syncache_head *sch = (struct syncache_head *)xsch; |
| 469 | struct syncache *sc, *nsc; |
| 470 | struct epoch_tracker et; |
| 471 | int tick = ticks; |
| 472 | char *s; |
| 473 | bool paused; |
| 474 | |
| 475 | CURVNET_SET(sch->sch_sc->vnet); |
| 476 | |
| 477 | /* NB: syncache_head has already been locked by the callout. */ |
| 478 | SCH_LOCK_ASSERT(sch); |
| 479 | |
| 480 | /* |
| 481 | * In the following cycle we may remove some entries and/or |
| 482 | * advance some timeouts, so re-initialize the bucket timer. |
| 483 | */ |
| 484 | sch->sch_nextc = tick + INT_MAX; |
| 485 | |
| 486 | /* |
| 487 | * If we have paused processing, unconditionally remove |
| 488 | * all syncache entries. |
| 489 | */ |
| 490 | mtx_lock(&V_tcp_syncache.pause_mtx); |
| 491 | paused = V_tcp_syncache.paused; |
| 492 | mtx_unlock(&V_tcp_syncache.pause_mtx); |
| 493 | |
| 494 | TAILQ_FOREACH_SAFE(sc, &sch->sch_bucket, sc_hash, nsc) { |
| 495 | if (paused) { |
| 496 | syncache_drop(sc, sch); |
| 497 | continue; |
| 498 | } |
| 499 | /* |
| 500 | * We do not check if the listen socket still exists |
| 501 | * and accept the case where the listen socket may be |
| 502 | * gone by the time we resend the SYN/ACK. We do |
| 503 | * not expect this to happens often. If it does, |
| 504 | * then the RST will be sent by the time the remote |
| 505 | * host does the SYN/ACK->ACK. |
| 506 | */ |
| 507 | if (TSTMP_GT(sc->sc_rxttime, tick)) { |
| 508 | if (TSTMP_LT(sc->sc_rxttime, sch->sch_nextc)) |
| 509 | sch->sch_nextc = sc->sc_rxttime; |
| 510 | continue; |
| 511 | } |
| 512 | if (sc->sc_rxmits > V_tcp_ecn_maxretries) { |
| 513 | sc->sc_flags &= ~SCF_ECN; |
| 514 | } |
| 515 | if (sc->sc_rxmits > V_tcp_syncache.rexmt_limit) { |
| 516 | if ((s = tcp_log_addrs(&sc->sc_inc, NULL, NULL, NULL))) { |
| 517 | log(LOG_DEBUG, "%s; %s: Retransmits exhausted, " |
| 518 | "giving up and removing syncache entry\n", |
| 519 | s, __func__); |
| 520 | free(s, M_TCPLOG); |
| 521 | } |
| 522 | syncache_drop(sc, sch); |
nothing calls this directly
no test coverage detected