| 4469 | } |
| 4470 | |
| 4471 | static void |
| 4472 | key_flush_sad(time_t now) |
| 4473 | { |
| 4474 | SAHTREE_RLOCK_TRACKER; |
| 4475 | struct secashead_list emptyq; |
| 4476 | struct secasvar_list drainq, hexpireq, sexpireq, freeq; |
| 4477 | struct secashead *sah, *nextsah; |
| 4478 | struct secasvar *sav, *nextsav; |
| 4479 | |
| 4480 | LIST_INIT(&drainq); |
| 4481 | LIST_INIT(&hexpireq); |
| 4482 | LIST_INIT(&sexpireq); |
| 4483 | LIST_INIT(&emptyq); |
| 4484 | |
| 4485 | SAHTREE_RLOCK(); |
| 4486 | TAILQ_FOREACH(sah, &V_sahtree, chain) { |
| 4487 | /* Check for empty SAH */ |
| 4488 | if (TAILQ_EMPTY(&sah->savtree_larval) && |
| 4489 | TAILQ_EMPTY(&sah->savtree_alive)) { |
| 4490 | SAH_ADDREF(sah); |
| 4491 | LIST_INSERT_HEAD(&emptyq, sah, drainq); |
| 4492 | continue; |
| 4493 | } |
| 4494 | /* Add all stale LARVAL SAs into drainq */ |
| 4495 | TAILQ_FOREACH(sav, &sah->savtree_larval, chain) { |
| 4496 | if (now - sav->created < V_key_larval_lifetime) |
| 4497 | continue; |
| 4498 | SAV_ADDREF(sav); |
| 4499 | LIST_INSERT_HEAD(&drainq, sav, drainq); |
| 4500 | } |
| 4501 | TAILQ_FOREACH(sav, &sah->savtree_alive, chain) { |
| 4502 | /* lifetimes aren't specified */ |
| 4503 | if (sav->lft_h == NULL) |
| 4504 | continue; |
| 4505 | SECASVAR_LOCK(sav); |
| 4506 | /* |
| 4507 | * Check again with lock held, because it may |
| 4508 | * be updated by SADB_UPDATE. |
| 4509 | */ |
| 4510 | if (sav->lft_h == NULL) { |
| 4511 | SECASVAR_UNLOCK(sav); |
| 4512 | continue; |
| 4513 | } |
| 4514 | /* |
| 4515 | * RFC 2367: |
| 4516 | * HARD lifetimes MUST take precedence over SOFT |
| 4517 | * lifetimes, meaning if the HARD and SOFT lifetimes |
| 4518 | * are the same, the HARD lifetime will appear on the |
| 4519 | * EXPIRE message. |
| 4520 | */ |
| 4521 | /* check HARD lifetime */ |
| 4522 | if ((sav->lft_h->addtime != 0 && |
| 4523 | now - sav->created > sav->lft_h->addtime) || |
| 4524 | (sav->lft_h->usetime != 0 && sav->firstused && |
| 4525 | now - sav->firstused > sav->lft_h->usetime) || |
| 4526 | (sav->lft_h->bytes != 0 && counter_u64_fetch( |
| 4527 | sav->lft_c_bytes) > sav->lft_h->bytes)) { |
| 4528 | SECASVAR_UNLOCK(sav); |
no test coverage detected