Add BLE L2CAP transport with scan-based auto-connect

BLE transport implementation using L2CAP Connection-Oriented Channels
(SeqPacket mode) via the bluer crate, behind cfg(feature = "ble").

Core transport:
- BleTransport<I> generic over BleIo trait (BluerIo prod, MockBleIo test)
- Connection pool with priority eviction (static > discovered, max 7)
- Connect-on-send via connect_inline() matching TCP behavior
- Per-connection receive loops with pool cleanup on disconnect

Discovery and probing:
- Combined scan_probe_loop using select! over scanner events and a
  BinaryHeap delay queue with per-entry random jitter (0-5s) to prevent
  herd effects when multiple nodes see the same beacon simultaneously
- Pre-handshake pubkey exchange ([0x00][pubkey:32]) for IK identity
- Cross-probe tie-breaker: smaller NodeAddr's outbound wins (same
  convention as FMP/FSP rekey dual-initiation)
- Probed peers reported to DiscoveryBuffer; pool fills through normal
  node-layer auto-connect -> send_async -> connect_inline path

Beacon management:
- Periodic advertising: 1s burst every 30s (configurable via
  beacon_interval_secs / beacon_duration_secs)
- FIPS service UUID for scan filtering

Configuration (all fields optional with defaults):
- adapter, psm, mtu, max_connections, connect_timeout_ms
- advertise, scan, auto_connect, accept_connections
- beacon_interval_secs (30), beacon_duration_secs (1)

Hardware validated with two BLE nodes:
- 2048-byte MTU, ~60-160ms RTT, zero-config auto-connect
- BLE spike tool at testing/ble/ for standalone adapter validation

42 unit tests + 4 node-level integration tests, all CI-compatible
via MockBleIo (no hardware required). tokio test-util added for
time-dependent scan/probe tests.
This commit is contained in:
Johnathan Corgan
2026-03-25 04:21:46 +00:00
parent d3385b902a
commit 89352d3218
27 changed files with 5098 additions and 54 deletions
+10 -5
View File
@@ -9,8 +9,9 @@ repository = "https://github.com/jmcorgan/fips"
readme = "README.md"
[features]
default = ["tui"]
default = ["tui", "ble"]
tui = ["dep:ratatui"]
ble = ["dep:bluer"]
[dependencies]
ratatui = { version = "0.30", optional = true }
@@ -37,6 +38,7 @@ futures = "0.3"
simple-dns = "0.11.2"
socket2 = { version = "0.6.2", features = ["all"] }
tokio-socks = "0.5"
bluer = { version = "0.17", features = ["bluetoothd", "l2cap"], optional = true }
[package.metadata.deb]
maintainer = "Johnathan Corgan <jcorgan@corganlabs.com>"
@@ -44,12 +46,14 @@ copyright = "2026 Johnathan Corgan"
license-file = ["LICENSE", "0"]
section = "net"
priority = "optional"
depends = "libc6, systemd"
depends = "libc6, systemd, libdbus-1-3"
recommends = "bluez"
extended-description = """\
FIPS is a distributed, decentralized network routing protocol for mesh \
nodes connecting over arbitrary transports including UDP, TCP, and Ethernet. \
It provides encrypted peer-to-peer connectivity with automatic key management, \
TUN-based virtual networking, and .fips DNS resolution."""
nodes connecting over arbitrary transports including UDP, TCP, Ethernet, \
Tor, and Bluetooth (BLE). It provides encrypted peer-to-peer connectivity \
with automatic key management, TUN-based virtual networking, and .fips DNS \
resolution."""
maintainer-scripts = "packaging/debian/"
assets = [
["target/release/fips", "/usr/bin/", "755"],
@@ -66,6 +70,7 @@ conf-files = ["/etc/fips/fips.yaml", "/etc/fips/hosts"]
[dev-dependencies]
tempfile = "3.15"
criterion = { version = "0.8.2", features = ["html_reports"] }
tokio = { version = "1", features = ["test-util"] }
[[bin]]
name = "fipsctl"