Skip to content

v1.2.6 — bug-fix + correctness pass

Latest

Choose a tag to compare

@BitF4rmer BitF4rmer released this 25 Apr 14:15

Comprehensive bug-fix release driven by smoke testing + a full code review

This release replaces the v1.2.5 "sleep 500ms and hope" shutdown with a real probe-drain barrier, eliminates two classes of silent event loss, and adds three regression tests for subtle state-machine behaviour.

Fixed

  • Re-catch ladder waste: Connect / raw / SYN-race schedulers no longer spawn a fresh ladder run when the port-state tracker reports an already-Open re-catch. Was hammering single-threaded upstream services and emitting orphan events the TUI silently discarded.
  • Ladder fresh-connect timeout: inter-probe `TcpStream::connect` now bounded by `DEFAULT_PROBE_TIMEOUT`. An overloaded target no longer stalls the ladder indefinitely.
  • Probe shutdown drain: catch-receiver tracks every spawned ladder run in a `tokio::task::JoinSet` and drains it via `join_next` (with a 2s outer deadline) before `EngagementFinished` is emitted. Real shutdown barrier, not a magic sleep.
  • Mutex poison panic in `PortStateTracker`: replaced `.unwrap()` on lock with `.unwrap_or_else(|p| p.into_inner())`. The critical section can't leave inconsistent state.
  • Spurious flap event: `WaitingForClose → Open` recovery transition no longer emits a fresh `PortOpenDetected` (no matching `PortClosedDetected` had been emitted, so re-emitting Open looked like a flap to consumers).
  • SYN-race false-close: handoff connect failure after a confirmed SYN-ACK no longer feeds `Observation::Transient` to the tracker. TIME_WAIT / contention no longer flips a still-open port to Closed.
  • Hold-open silent miss: `spawn_hold_open_manager` no longer papers over a missing `catch_id` with `CatchId::default()`. Logs an error and skips that catch.
  • Hold-open CA failure log level: `warn!` → `error!` for both no-config-dir and CA load failures.
  • u64 truncation on `Duration::as_millis()`: replaced with `u64::try_from(...).unwrap_or(u64::MAX)`.

Added

  • TUI Port Status empty-state hint — first-time users on the default `ephemeral-iana` range now see guidance + example invocations instead of an empty table.
  • Tests: `engine_label_round_trips_on_port_open_detected` and `one_transient_then_open_resets_without_emit`.

Changed

  • Dispatcher doc-comment corrected: lossless delivery is received-scoped, not accepted-scoped (`broadcast::Lagged` still drops on slow subscribers).
  • `PortLiveState::Flapping` doc-comment matches implementation (≥4 transitions).

Verified

Smoke-tested on Windows against a multi-threaded local HTTP listener: full pipeline (PortOpenDetected → HoldOpenReady → 3 ProbeAttempted → FingerprintCaptured{protocol=http11, conf=0.90} → CatchComplete → EngagementFinished) lands in JSONL with no events lost. CI green across Linux / macOS / Windows.

Install

```bash
cargo install --git https://github.com/IntegSec/PortSnatcher --tag v1.2.6 --bin portsnatcher
```

Prebuilt binaries attached below.

Full changelog

https://github.com/IntegSec/PortSnatcher/blob/v1.2.6/CHANGELOG.md