mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Merge maint into master after v0.2.1 release
Uses the 'ours' merge strategy to keep all of master's tree verbatim with one carve-out: the v0.2.1 release notes archive at docs/releases/release-notes-v0.2.1.md is retained as a permanent docs artifact. Discarded from maint's release-prep commit: Cargo.toml / Cargo.lock version bumps (master stays on v0.3.0-dev), README v0.2.1 badge and prose, and the RELEASE-NOTES.md root mirror (master's root mirror will eventually carry the v0.3.0 release notes when v0.3.0 ships from this line). CHANGELOG: the v0.2.1 release section is integrated between [Unreleased] (v0.3.0-dev work) and the [0.2.0] historical section. Items that landed on maint during the v0.2.1 cycle are removed from [Unreleased] so [0.2.1] is the canonical home for those changes (Linux release artifact and AUR workflows; bloom fill-ratio validation; seven maint-line bug fixes).
This commit is contained in:
+57
-38
@@ -204,9 +204,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
#### Packaging and Deployment
|
||||
|
||||
- Linux release artifact workflow: builds x86_64 and aarch64 tarballs
|
||||
and `.deb` packages on `v*` tag push, with SHA-256 checksums
|
||||
- AUR publish workflow for tagged stable releases
|
||||
- Arch Linux AUR packaging for `fips` (release) and `fips-git`
|
||||
(development) packages with sysusers.d/tmpfiles.d integration
|
||||
([#21](https://github.com/jmcorgan/fips/pull/21),
|
||||
@@ -352,16 +349,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
(`backoff_base_secs`/`backoff_max_secs` now both `0`); operators
|
||||
with chatty apps generating repeat lookups against unreachable
|
||||
destinations can opt back in
|
||||
- Validate bloom filter fill ratio on FilterAnnounce ingress.
|
||||
Inbound FilterAnnounce messages whose derived false-positive
|
||||
rate exceeds `node.bloom.max_inbound_fpr` (new config field,
|
||||
default 0.05) are rejected silently on the wire, logged at WARN,
|
||||
and counted in a new `bloom.fill_exceeded` counter. A
|
||||
rate-limited WARN also fires if our own outgoing filter's FPR
|
||||
exceeds the cap. `BloomFilter::estimated_count` now takes
|
||||
`max_fpr` and returns `Option<f64>`, returning `None` for
|
||||
saturated filters; this propagates through `compute_mesh_size`
|
||||
into `estimated_mesh_size` (already `Option<u64>`)
|
||||
- The `docs/` tree is reorganised so readers can find content by
|
||||
what they're trying to do: tutorials for new users, how-to guides
|
||||
for specific tasks, reference material for configuration and
|
||||
@@ -583,22 +570,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
matching the Tor `HiddenServicePort` convention) controls the
|
||||
advertised port; operators with non-default virtual ports can
|
||||
override.
|
||||
- Control socket path detection in fipsctl and fipstop now checks for
|
||||
the `/run/fips/` directory instead of the socket file inside it, so
|
||||
users not yet in the `fips` group get a clear "Permission denied"
|
||||
error instead of a misleading "No such file" fallback to
|
||||
`$XDG_RUNTIME_DIR` ([#30](https://github.com/jmcorgan/fips/issues/30),
|
||||
reported by [@Sebastix](https://github.com/Sebastix))
|
||||
- OpenWrt ipk build excluded BLE feature that requires D-Bus, which is
|
||||
unavailable on OpenWrt targets
|
||||
- IPv6 routing policy rule added at TUN setup to protect `fd00::/8`
|
||||
from interception by Tailscale's table 52 default route
|
||||
- Bloom filter routing no longer swallows traffic when no bloom
|
||||
candidate is strictly closer than the current node. `find_next_hop`
|
||||
now falls through to greedy tree routing in that case instead of
|
||||
returning `NoRoute`, which previously caused dropped packets in
|
||||
topologies where the tree parent was closer but not a bloom
|
||||
candidate
|
||||
- TCP-over-FIPS reliability on mesh paths with mixed transport
|
||||
MTUs (e.g. a UDP-1280 hop in the picker set) improved. Three
|
||||
interlocking changes: `Node::transport_mtu()` is now deterministic
|
||||
@@ -636,6 +607,55 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
the cooldown window are silent. New `protocol_mismatch_cooldown_secs`
|
||||
config field under `node.discovery.nostr` (default 86400 = 24h),
|
||||
separate from the transient-failure `extended_cooldown_secs`.
|
||||
- `fipstop` now uses `ratatui::try_init()` instead of `ratatui::init()`,
|
||||
so terminal initialization failures (e.g. Docker on macOS Sequoia,
|
||||
or environments without a usable tty) produce a clean error message
|
||||
instead of a hard crash
|
||||
- Spanning-tree updates that change only the internal path between
|
||||
root and leaf — without changing the root or the depth — now
|
||||
propagate to leaves correctly. Previously a leaf could continue
|
||||
routing against a stale internal path until the parent or depth
|
||||
also changed.
|
||||
|
||||
## [0.2.1] - 2026-05-11
|
||||
|
||||
### Added
|
||||
|
||||
- Linux release artifact workflow: builds x86_64 and aarch64 tarballs
|
||||
and `.deb` packages on `v*` tag push, with SHA-256 checksums
|
||||
- AUR publish workflow for tagged stable releases
|
||||
|
||||
### Changed
|
||||
|
||||
- Validate bloom filter fill ratio on FilterAnnounce ingress.
|
||||
Inbound FilterAnnounce messages whose derived false-positive
|
||||
rate exceeds `node.bloom.max_inbound_fpr` (new config field,
|
||||
default 0.05) are rejected silently on the wire, logged at WARN,
|
||||
and counted in a new `bloom.fill_exceeded` counter. A
|
||||
rate-limited WARN also fires if our own outgoing filter's FPR
|
||||
exceeds the cap. `BloomFilter::estimated_count` now takes
|
||||
`max_fpr` and returns `Option<f64>`, returning `None` for
|
||||
saturated filters; this propagates through `compute_mesh_size`
|
||||
into `estimated_mesh_size` (already `Option<u64>`)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Control socket path detection in fipsctl and fipstop now checks for
|
||||
the `/run/fips/` directory instead of the socket file inside it, so
|
||||
users not yet in the `fips` group get a clear "Permission denied"
|
||||
error instead of a misleading "No such file" fallback to
|
||||
`$XDG_RUNTIME_DIR` ([#30](https://github.com/jmcorgan/fips/issues/30),
|
||||
reported by [@Sebastix](https://github.com/Sebastix))
|
||||
- OpenWrt ipk build excluded BLE feature that requires D-Bus, which is
|
||||
unavailable on OpenWrt targets
|
||||
- IPv6 routing policy rule added at TUN setup to protect `fd00::/8`
|
||||
from interception by Tailscale's table 52 default route
|
||||
- Bloom filter routing no longer swallows traffic when no bloom
|
||||
candidate is strictly closer than the current node. `find_next_hop`
|
||||
now falls through to greedy tree routing in that case instead of
|
||||
returning `NoRoute`, which previously caused dropped packets in
|
||||
topologies where the tree parent was closer but not a bloom
|
||||
candidate
|
||||
- Auto-connect peers now reconnect after a graceful `Disconnect`
|
||||
notification from the remote side. `handle_disconnect` previously
|
||||
removed the peer without scheduling a reconnect, orphaning the
|
||||
@@ -649,19 +669,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
bind with `EAFNOSUPPORT`
|
||||
([#61](https://github.com/jmcorgan/fips/issues/61),
|
||||
reported by [@SwapMarket](https://github.com/SwapMarket))
|
||||
- `fipstop` now uses `ratatui::try_init()` instead of `ratatui::init()`,
|
||||
so terminal initialization failures (e.g. Docker on macOS Sequoia,
|
||||
or environments without a usable tty) produce a clean error message
|
||||
instead of a hard crash
|
||||
- Tighten TreeAnnounce ancestry validation to match the spanning
|
||||
tree specification. The receive path now verifies that the
|
||||
ancestry is structurally consistent with the signed parent
|
||||
declaration before mutating tree state.
|
||||
- Spanning-tree updates that change only the internal path between
|
||||
root and leaf — without changing the root or the depth — now
|
||||
propagate to leaves correctly. Previously a leaf could continue
|
||||
routing against a stale internal path until the parent or depth
|
||||
also changed.
|
||||
- Make the tree ancestry acceptance unit test deterministic.
|
||||
`test_tree_announce_validate_semantics_accepts_valid_non_root`
|
||||
generated a random signing identity while pinning the fixed root
|
||||
to `node_addr[0] = 0x01`; about 2 in 256 random identities were
|
||||
numerically smaller than the claimed root, triggering
|
||||
`AncestryRootNotMinimum`. The test now regenerates the identity
|
||||
until its `node_addr` is strictly larger than both the fixed
|
||||
parent and root.
|
||||
|
||||
## [0.2.0] - 2026-03-22
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
# FIPS v0.2.1
|
||||
|
||||
**Released**: 2026-05-11
|
||||
|
||||
v0.2.1 is a maintenance release on the v0.2.x line. No new features
|
||||
and no wire-format changes; operators running v0.2.0 can upgrade in
|
||||
place. The release rolls up bug fixes and operational hardening for
|
||||
issues surfaced in v0.2.0 deployments, plus a bloom-filter fill-ratio
|
||||
validation that protects mesh-size estimates from saturated-filter
|
||||
inputs.
|
||||
|
||||
## At a glance
|
||||
|
||||
- 22 commits since v0.2.0, 5 committers plus 2 issue reporters.
|
||||
- All changes are backwards-compatible with v0.2.0 on the wire.
|
||||
- Bloom filter fill-ratio validation hardens the FilterAnnounce
|
||||
ingress path.
|
||||
- TreeAnnounce ancestry validation tightened to match the
|
||||
spanning-tree specification.
|
||||
- Signed-tarball + `.deb` artifact workflow added for tagged
|
||||
releases; AUR auto-publish on stable tags.
|
||||
|
||||
## Behavior changes worth flagging
|
||||
|
||||
- **Bloom filter fill-ratio validation** runs on every inbound
|
||||
`FilterAnnounce`. Filters whose derived false-positive rate exceeds
|
||||
`node.bloom.max_inbound_fpr` (new config field, default `0.05`) are
|
||||
rejected silently on the wire, logged at WARN, and counted in a
|
||||
new `bloom.fill_exceeded` counter. A rate-limited WARN also fires
|
||||
when the local outgoing filter exceeds the cap.
|
||||
`BloomFilter::estimated_count` now takes `max_fpr` and returns
|
||||
`Option<f64>`, returning `None` for saturated filters; this
|
||||
propagates through `compute_mesh_size` into `estimated_mesh_size`.
|
||||
- **TreeAnnounce ancestry validation** is now run before tree-state
|
||||
mutation, enforcing ancestry-self-match, root-single-entry,
|
||||
parent-second-entry, and root-is-minimum-NodeAddr. Non-conforming
|
||||
announces are rejected with a WARN. Mixed v0.2.0 / v0.2.1 meshes
|
||||
may produce WARN log lines on the v0.2.1 side until all peers
|
||||
upgrade; behavior is correct, log noise only.
|
||||
|
||||
## Notable bug fixes
|
||||
|
||||
- **Control socket path detection** in `fipsctl` and `fipstop` now
|
||||
checks for the `/run/fips/` directory instead of the socket file
|
||||
inside it. Users not yet in the `fips` group get a clear
|
||||
"Permission denied" error instead of a misleading "No such file"
|
||||
fallback to `$XDG_RUNTIME_DIR`
|
||||
([#30](https://github.com/jmcorgan/fips/issues/30), reported by
|
||||
[@Sebastix](https://github.com/Sebastix)).
|
||||
- **`fd00::/8` routing protected from Tailscale interception.** The
|
||||
daemon installs an IPv6 routing-policy rule
|
||||
(`ip -6 rule to fd00::/8 lookup main priority 5265`) at TUN setup,
|
||||
so Tailscale's table 52 default route can no longer divert mesh
|
||||
traffic.
|
||||
- **Bloom filter routing greedy-tree fallback.** `find_next_hop` no
|
||||
longer returns `NoRoute` when the bloom candidate set is non-empty
|
||||
but no candidate is strictly closer than the current node; it
|
||||
falls through to greedy tree routing instead. Previously, this
|
||||
caused dropped packets in topologies where the tree parent was
|
||||
closer but not a bloom candidate.
|
||||
- **Auto-connect peers reconnect after a graceful Disconnect.**
|
||||
Previously, a clean upstream shutdown left the auto-connect peer
|
||||
orphaned; only the link-dead, decrypt-fail, and peer-restart paths
|
||||
scheduled a reconnect
|
||||
([#60](https://github.com/jmcorgan/fips/issues/60), reported by
|
||||
[@SwapMarket](https://github.com/SwapMarket)).
|
||||
- **`fipsctl connect` rejects FIPS mesh addresses** (`fd00::/8`) for
|
||||
`udp`, `tcp`, and `ethernet` transports with a clear error message
|
||||
instead of echoing success while the daemon silently failed the
|
||||
bind with `EAFNOSUPPORT`
|
||||
([#61](https://github.com/jmcorgan/fips/issues/61), reported by
|
||||
[@SwapMarket](https://github.com/SwapMarket)).
|
||||
- **OpenWrt ipk** cross-compiles cleanly again after excluding the
|
||||
BLE feature that requires D-Bus, which is unavailable on OpenWrt
|
||||
targets.
|
||||
|
||||
## Packaging
|
||||
|
||||
- **Linux release artifact workflow** builds x86_64 and aarch64
|
||||
tarballs and `.deb` packages on `v*` tag push, with SHA-256
|
||||
checksums, and publishes them to the GitHub release page.
|
||||
- **AUR publish workflow** auto-publishes the `fips` PKGBUILD on
|
||||
stable `v*` tags.
|
||||
|
||||
## Upgrade notes
|
||||
|
||||
Operator-actionable items when moving from v0.2.0 to v0.2.1:
|
||||
|
||||
- **Bloom filter fill-ratio cap (default 0.05).** Inbound
|
||||
`FilterAnnounce` messages whose derived FPR exceeds the cap are
|
||||
rejected silently on the wire. Operators with unusually saturated
|
||||
filters in the field may want to confirm that the default applies
|
||||
cleanly to their deployment; check the new `bloom.fill_exceeded`
|
||||
counter if mesh-size estimates drift after upgrade.
|
||||
- **TreeAnnounce ancestry tightening.** Mixed v0.2.0 / v0.2.1 meshes
|
||||
may produce WARN log lines on the v0.2.1 side until all peers
|
||||
upgrade. Behavior is correct, log noise only.
|
||||
|
||||
## Getting v0.2.1
|
||||
|
||||
- **Linux x86_64 / aarch64**: `.deb` and tarball at the
|
||||
[v0.2.1 release page](https://github.com/jmcorgan/fips/releases/tag/v0.2.1).
|
||||
- **Arch Linux**: `fips` from the AUR.
|
||||
- **OpenWrt**: `.ipk` at the v0.2.1 release page.
|
||||
- **From source**: `cargo build --release` from a checkout of the
|
||||
v0.2.1 tag.
|
||||
|
||||
The full per-commit changelog lives in
|
||||
[`CHANGELOG.md`](../../CHANGELOG.md). Issues and discussion at
|
||||
[github.com/jmcorgan/fips](https://github.com/jmcorgan/fips).
|
||||
|
||||
## Contributors
|
||||
|
||||
Thanks to everyone who contributed code or bug reports to this
|
||||
release.
|
||||
|
||||
**Code and packaging**:
|
||||
|
||||
- [@jcorgan](https://github.com/jmcorgan): release shepherd, bloom
|
||||
fill-ratio validation, auto-connect reconnect fix, `fipsctl`
|
||||
mesh-address rejection, control-socket path detection,
|
||||
Tailscale-vs-`fd00::/8` routing policy, bloom routing greedy
|
||||
fallback, rustfmt baseline.
|
||||
- [@Origami74](https://github.com/Origami74): OpenWrt ipk
|
||||
BLE-feature build fix.
|
||||
- [@jodobear](https://github.com/jodobear): Linux release-artifact
|
||||
workflow and target-aware build scripts.
|
||||
- [@dskvr](https://github.com/dskvr): AUR publish workflow.
|
||||
- [@SatsAndSports](https://github.com/SatsAndSports): TreeAnnounce
|
||||
semantic validation.
|
||||
|
||||
**Issue reports that drove fixes in this release**:
|
||||
|
||||
- [@Sebastix](https://github.com/Sebastix): `fipsctl` / `fipstop`
|
||||
control-socket path detection
|
||||
([#30](https://github.com/jmcorgan/fips/issues/30)).
|
||||
- [@SwapMarket](https://github.com/SwapMarket): auto-connect
|
||||
reconnect after graceful disconnect
|
||||
([#60](https://github.com/jmcorgan/fips/issues/60)) and
|
||||
`fipsctl` mesh-address rejection
|
||||
([#61](https://github.com/jmcorgan/fips/issues/61)).
|
||||
Reference in New Issue
Block a user