Commit Graph
6 Commits
Author SHA1 Message Date
Johnathan Corgan f5be8ec07d Meter established-link msg1 separately from stranger admission
The msg1 rate limiter ran before the established-peer carve-out, so a
rekey or restart msg1 arriving on an existing link was refused on
exactly the same terms as a stranger's first packet and the carve-out
below it never applied to the traffic it was written for. On a node
with many peers this refuses a large share of ordinary maintenance
traffic: a field node at roughly 245 peers refused 8753 msg1 in 25
minutes, and 159 of the 201 distinct sources were peers it already
held sessions with.

Classify the source before metering it, and give established-link msg1
its own token bucket instead of a bypass. A bypass was rejected
deliberately: the limiter is global precisely because UDP sources are
spoofable, and an established-peer exemption is by construction keyed
on source address, so metering the exempted class keeps that property
where bypassing discards it.

The bucket is derived from settings the operator already sets, burst
from max_peers and rate from max_peers, the rekey interval and the
resend budget, so raising the peer limit sizes it automatically rather
than leaving a constant nobody revisits. Both parameters can be set
explicitly; an explicit zero burst or non-positive rate is rejected at
config validation, because it would refuse every rekey msg1 from an
established peer rather than disabling the limit.

Split out the established-link test as its own predicate so the
rate-limit classifier and the accept_connections gate cannot drift,
and convert the limiter's pending slot to a guard released on drop.
The slot was previously acquired in one place and released explicitly
at eighteen exit paths; once some paths stop acquiring one, any path
that still released one would have freed a slot belonging to a
different in-flight handshake, lifting effective concurrency above the
configured maximum with no counter moving and no log firing.

The "Msg1 rate limited" line now reports which limb refused, the
pending count or the token bucket, which it did not distinguish
before.

Classification costs an O(peers) scan on every inbound msg1 including
refused ones, where the previous order refused at O(1). The scan is
only needed because addr_to_link is keyed on the unresolved dial
address; correcting that keying reduces this to a single O(1) lookup.
Recorded at the predicate.
2026-07-29 17:10:29 +00:00
Johnathan Corgan e9da598f8a Apply rustfmt to master-only code 2026-04-10 08:47:02 +00:00
Johnathan Corgan 6196307f0e Merge branch 'maint'
# Conflicts:
#	src/bin/fips.rs
#	src/bin/fipstop/app.rs
#	src/config/mod.rs
#	src/config/node.rs
#	src/config/transport.rs
#	src/mmp/receiver.rs
#	src/mmp/sender.rs
#	src/node/handlers/handshake.rs
#	src/node/handlers/rekey.rs
#	src/node/lifecycle.rs
#	src/node/mod.rs
#	src/transport/ethernet/socket.rs
#	src/transport/mod.rs
#	src/upper/tun.rs
2026-04-10 08:46:54 +00:00
Johnathan Corgan 13c0b70dc3 Add rustfmt formatting policy and reformat codebase
Add rustfmt.toml with stable defaults and apply cargo fmt to all
source files. This establishes a consistent formatting baseline
for CI enforcement.
2026-04-10 08:27:07 +00:00
Origami74 e693f4fb7e Add macOS support, fix bloom filter routing and MMP intervals
macOS platform:
- Platform-native TUN interface management with shutdown pipe
- Raw Ethernet transport with macOS socket backend (socket_macos.rs)
- EthernetTransport and TransportHandle::Ethernet ungated from Linux-only
- macOS .pkg packaging (build-pkg.sh, launchd plist, uninstall script)
- CI: macOS build and unit test jobs; x86_64 cross-compiled from
  macos-latest via rustup target add x86_64-apple-darwin

Gateway feature flag:
- New opt-in `gateway` Cargo feature activates optional `rustables` dep
- `pub mod gateway` and `Config.gateway` gated behind the feature so
  macOS builds never pull in Linux-only nftables bindings
- `fips-gateway` bin has `required-features = ["gateway"]`
- All Linux/OpenWrt/AUR packaging passes `--features gateway`

CI / packaging:
- package-linux, package-macos, package-openwrt now trigger on push to
  master/maint/next and on pull requests; release uploads remain tag-gated
- Bloom filter routing fix: fall through to tree routing when no candidate
  is strictly closer
- MMP intervals: raise MIN to 1s / MAX to 5s with 5-sample cold-start phase
2026-04-09 20:03:42 +01:00
Johnathan Corgan b8a1f322c2 Module reorganization and clippy cleanup
Move single-consumer modules into node/:
- rate_limit.rs, wire.rs, dns.rs — exclusively used by node subsystem
- Reduces top-level lib.rs from 16 to 13 modules

Split large files into focused subdirectories:
- noise.rs (1475 lines) → noise/{mod, handshake, session, replay, tests}.rs
- tree.rs (1479 lines) → tree/{mod, coordinate, declaration, state, tests}.rs
- bloom.rs (849 lines) → bloom/{mod, filter, state, tests}.rs
- All public APIs re-exported from mod.rs, no external import changes

Remove unused rate_limit defaults:
- HANDSHAKE_TIMEOUT_SECS, MAX_PENDING_INBOUND constants
- Default constructor eliminated in favor of with_params() taking config values

Fix all clippy warnings across codebase:
- Remove .clone() on Copy types, collapse nested ifs, replace match-return-None
  with ?, remove/gate unused code, fix loop indexing, remove unnecessary casts
- Box large PeerSlot enum variants to reduce size disparity
- cargo clippy --all-targets now reports zero warnings
2026-02-15 15:07:42 +00:00