Skip to content

fix(failover+config): self-heal never-first-packet inputs; hot-reload egress & hook-root flags#27

Merged
ntt0601zcoder merged 1 commit into
mainfrom
fix/security-critical-high
Jun 15, 2026
Merged

fix(failover+config): self-heal never-first-packet inputs; hot-reload egress & hook-root flags#27
ntt0601zcoder merged 1 commit into
mainfrom
fix/security-critical-high

Conversation

@ntt0601zcoder

Copy link
Copy Markdown
Owner

What

Two related operational fixes found while testing the merged security batch.

1. Failover now covers inputs that connect but never deliver a packet

Previously a switched-to input (manual switch or auto-failover) that opened the connection but never produced a packet stayed non-Active forever, so the packet-timeout monitor never fired and the stream froze with no failover.

  • manager: collectTimeoutIfNeeded no longer gates on StatusActive. It fires for the active input whenever packet silence exceeds the timeout, regardless of status (excluded only while a failover is already in flight). Register stamps LastPacketAt on each input so the timeout window measures connect-to-first-packet as a grace period.
  • ingestor worker: dial errors rejected by the egress guard are classified as fail-immediately, so a blocked input surfaces the error and triggers failover instantly instead of reconnect-looping silently.

2. Config flags are now hot-reloadable (were boot-captured, needed a restart)

  • ingestor allow_private_targets: held in an atomic.Pointer (SetConfig/currentCfg); pull readers are built from the live config on each start/switch; runtime.diff pushes the new value on config change.
  • hooks file_root_dir: held in an atomic.Pointer (SetConfig/FileRootDir); the REST handler reads the root per request instead of caching at boot; runtime.diff pushes the new value on config change.

Tests

Never-active timeout + within-grace cases, egress-blocked fail-fast case, ingestor/hooks SetConfig hot-swap, and handler in/out-of-root file-target enforcement. make check green (vet + lint + test -race).

Audit doc updated: A-5 follow-up marked fixed; hot-reload notes added to the S-2 / S-4 residuals.

…oad SSRF/hook-root flags

Failover:
- manager: an active input that connects but never delivers a packet now
  times out and fails over. collectTimeoutIfNeeded no longer gates on
  StatusActive — it fires for the active input on packet silence past the
  timeout regardless of status (excluded only while a failover is already
  in flight). Register stamps LastPacketAt on each input so the window
  measures connect-to-first-packet as a grace period. Closes the
  connects-but-no-packets blind spot noted as an A-5 follow-up.
- ingestor worker: dial errors blocked by the egress guard are classified
  as fail-immediately, so a rejected input reports the error and triggers
  failover instantly instead of reconnect-looping silently.

Config hot-reload (previously boot-captured, needed a restart):
- ingestor: allow_private_targets is read live. Service holds its config
  in an atomic.Pointer (SetConfig/currentCfg); pull readers are built from
  currentCfg on each start/switch; runtime.diff calls Ingestor.SetConfig
  on config change.
- hooks: file_root_dir is read live. Service holds its config in an
  atomic.Pointer (SetConfig/FileRootDir); the REST handler reads the root
  per request instead of caching at boot; runtime.diff calls
  HooksSvc.SetConfig on config change.

Tests: never-active timeout + within-grace cases, egress-blocked
fail-fast case, ingestor/hooks SetConfig hot-swap, handler in/out-of-root
file-target enforcement. make check green (vet + lint + test -race).
@ntt0601zcoder ntt0601zcoder merged commit 55cb833 into main Jun 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant