Jabrique opened a new pull request, #13373:
URL: https://github.com/apache/trafficserver/pull/13373

   When a `traffic_ctl config reload` encounters a broken entry in
   `ssl_multicert.yaml`, the current behavior is all-or-nothing: the
   entire new SSLCertLookup is thrown away and the old configuration stays
   active. This is safe but operationally painful, a single bad cert
   blocks all other cert updates from going live until the broken one is
   fixed.
   
   This PR adds `proxy.config.ssl.server.multicert.partial_reload` (INT,
   default 0). When set to 1, a reload that finds one or more unloadable
   certs still commits the rest of the certs rather than discarding
   everything. Any skipped cert produces an ERROR in diags.log and
   increments the new `proxy.process.ssl.ssl_multicert_load_failures`
   counter, so the degraded state is never silent.
   
   The default (0) keeps the existing strict/atomic behaviour, no
   existing deployments are affected.
   
   **Implementation notes:**
   
   - The commit gate is in `SSLCertificateConfig::reconfigure()`. The new
     `partialCommit` path only activates when `configPartialReload == 1`
     AND `SSL_CTX_get0_certificate(lookup->ssl_default.get()) != nullptr`.
     The second check distinguishes a real user-loaded default from the
     bare bootstrap context that `load()` creates when all certs fail,
     committing a bare context would silently break TLS for every
     connection.
   
   - `retStatus` is flipped to `true` after a partial commit **only on
     live reloads** (i.e. when `configid != 0` at entry). At initial
     startup the lookup is always committed anyway (via the existing
     `configid == 0` path), and `retStatus` must stay `false` so that
     `startup()` can still honour `exit_on_load_fail`. This distinction
     is captured via a `const bool initialLoad = (configid == 0)` that is
     read before `configProcessor.set()` mutates `configid`.
   
   - The new metric increment in `_load_items()` is guarded by a null
     pointer check. Unlike other counters that are only incremented from
     paths that execute after `SSLInitializeStatistics()`, `_load_items()`
     can be called during early startup before the stats block is fully
     initialized. The guard is intentional defensive programming, not an
     inconsistency.
   
   - This knob applies only to `SSLCertificateConfig` (TLS server certs).
     `QUICCertConfig` (HTTP/3) retains strict all-or-nothing.
   
   **Files changed:**
   
   | File | Change |
   |---|---|
   | `src/records/RecordsConfig.cc` | Register new knob (`RECU_DYNAMIC`) |
   | `src/iocore/net/P_SSLConfig.h` | Add `configPartialReload` field |
   | `src/iocore/net/SSLConfig.cc` | Partial-commit gate in `reconfigure()` 
with startup guard |
   | `src/iocore/net/SSLStats.h/.cc` | New counter 
`ssl_multicert_load_failures` |
   | `src/iocore/net/SSLUtils.cc` | Increment counter on cert load failure 
(with guard + comment) |
   | `doc/admin-guide/files/records.yaml.en.rst` | Document new knob 
(`:reloadable:`, QUIC limitation note) |
   | `doc/admin-guide/monitoring/statistics/core/ssl.en.rst` | Document new 
metric |
   | `tests/gold_tests/tls/ssl_multicert_partial_reload.test.py` | New gold 
test |
   
   **Testing:**
   
   Gold test `ssl_multicert_partial_reload` covers:
   - **Scenario A** strict mode (default): a single bad cert causes the
     whole reload to fail and the old config stays intact (verified by
     CN of served cert).
   - **Scenario B** partial mode: a bad cert is skipped, the newly
     generated default cert (distinct CN `reloaded.example.com`) is
     committed, proving the new config was applied and not the old one
     silently retained. Also verifies:
     - `ERROR` still appears in `diags.log` (degraded state is not silent)
     - `proxy.process.ssl.ssl_multicert_load_failures` counter is ≥ 1
       after the reload (via `traffic_ctl metric get`)
   
   No regressions against the existing `ssl_multicert_loader` gold test.
   
   **Known limitations / future work:**
   - `QUICCertConfig` (HTTP/3) does not support partial reload yet.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to