mirror of
https://github.com/jmcorgan/fips.git
synced 2026-08-09 16:24:45 +00:00
Make Nostr-mediated overlay discovery unconditional, mirroring the philosophy of PR #79's collapse of the tui/ble/gateway features in favor of platform cfg gates. nostr / nostr-sdk are pure Rust over WebSockets/TCP, so they build cleanly on every FIPS-supported platform — there is no need for the parallel feature gate. The flag was already in `default = [...]`, so no behavior change for anyone using `cargo build` without `--no-default-features`. Operators who explicitly disabled the feature will now find Nostr code present in the binary; the runtime check `node.discovery.nostr.enabled` still controls whether the runtime starts. Cargo.toml: - Remove the `[features]` table entirely. - Drop `optional = true` from `nostr` and `nostr-sdk`. Source: 27 cfg sites collapsed across 5 files — `src/discovery.rs`, `src/discovery/nostr/mod.rs`, `src/node/handlers/rx_loop.rs`, `src/node/lifecycle.rs`, `src/node/mod.rs`. Two `#[cfg(not(feature = "nostr-discovery"))]` fallback blocks (the udp:nat-without-runtime debug-log path and the "feature not compiled in" warning at startup) were removed as dead code; the always-on path already handles the missing-runtime case via `nostr_discovery: Option<NostrDiscovery>`. Packaging and tooling: - `packaging/openwrt-ipk/Makefile`: drop a stale `--features gateway` flag (the `gateway` feature was already removed in PR #79; this was a leftover that the build path tolerated only because cargo ignored unknown feature names). - `testing/scripts/build.sh`: drop `DEFAULT_CARGO_BUILD_ARGS=(--features nostr-discovery)`; defaults are empty. - `packaging/common/fips.yaml`: drop the "requires the nostr-discovery feature" comment from the discovery section. Bundled cleanup: - Apply `cargo clippy --fix` against three pre-existing warnings in `src/discovery/nostr/runtime.rs` and `src/discovery/nostr/stun.rs` (collapsed `if let Some` chain; two redundant `as i32` casts). These were always present but masked when the feature gate was off; they surface now that the code is unconditionally compiled. - `cargo fmt` settled two minor formatting drift sites in `src/bin/fips-gateway.rs` and `src/config/mod.rs`. Tests: 1083 passed, 0 failed, 4 ignored. clippy clean. fmt clean.
104 lines
3.8 KiB
Rust
104 lines
3.8 KiB
Rust
//! Bootstrap handoff types.
|
|
//!
|
|
//! These types model the boundary between an external rendezvous/bootstrap
|
|
//! runtime and the core FIPS transport/handshake stack. The rendezvous side
|
|
//! owns Nostr/STUN/UDP hole punching; once a direct UDP path is established,
|
|
//! it hands the live socket and selected remote endpoint to FIPS so the
|
|
//! existing Noise/FMP transport path can take over.
|
|
|
|
pub mod nostr;
|
|
|
|
use crate::config::UdpConfig;
|
|
use crate::{NodeAddr, TransportId};
|
|
use std::net::{SocketAddr, UdpSocket};
|
|
|
|
/// Punch-probe magic ("NPTC", network byte order). First byte `0x4E`
|
|
/// collides with FMP's prefix-version high-nibble check, so the UDP
|
|
/// transport silently filters packets carrying this magic to keep
|
|
/// post-adoption handshake logs clean. Defined at the top-level
|
|
/// `discovery` module so the UDP filter and the nostr submodule's
|
|
/// punch sender share the same constant.
|
|
pub const PUNCH_MAGIC: u32 = 0x4E505443;
|
|
|
|
/// Punch-probe-ack magic ("NPTA", network byte order). Same filter as
|
|
/// [`PUNCH_MAGIC`].
|
|
pub const PUNCH_ACK_MAGIC: u32 = 0x4E505441;
|
|
|
|
/// Returns `true` if the first four bytes of `data` match a punch-probe or
|
|
/// punch-ack magic. Used by the UDP transport's receive loop to silently
|
|
/// drop stray probes that arrive on an adopted socket after the remote
|
|
/// peer's punch attempt has already timed out.
|
|
pub fn is_punch_packet(data: &[u8]) -> bool {
|
|
if data.len() < 4 {
|
|
return false;
|
|
}
|
|
let magic = u32::from_be_bytes([data[0], data[1], data[2], data[3]]);
|
|
magic == PUNCH_MAGIC || magic == PUNCH_ACK_MAGIC
|
|
}
|
|
|
|
/// Result of handing an established traversal session into FIPS.
|
|
#[derive(Debug, Clone)]
|
|
pub struct BootstrapHandoffResult {
|
|
/// Newly allocated transport ID used for the adopted UDP socket.
|
|
pub transport_id: TransportId,
|
|
/// Local socket address now owned by the FIPS UDP transport.
|
|
pub local_addr: SocketAddr,
|
|
/// Confirmed remote UDP endpoint selected by traversal.
|
|
pub remote_addr: SocketAddr,
|
|
/// Peer node address derived from the supplied peer identity.
|
|
pub peer_node_addr: NodeAddr,
|
|
/// Nostr session identifier used by the bootstrap runtime.
|
|
pub session_id: String,
|
|
}
|
|
|
|
/// Established UDP traversal ready to be handed into FIPS.
|
|
///
|
|
/// The socket must already be bound and must be the same socket used for the
|
|
/// traversal runtime's STUN and punch traffic so the NAT mapping is preserved.
|
|
#[derive(Debug)]
|
|
pub struct EstablishedTraversal {
|
|
/// Rendezvous session identifier for logging/correlation.
|
|
pub session_id: String,
|
|
/// Remote peer identity in `npub` form.
|
|
pub peer_npub: String,
|
|
/// The selected remote UDP endpoint to use for the FIPS handshake.
|
|
pub remote_addr: SocketAddr,
|
|
/// The live UDP socket carrying the established mapping.
|
|
pub socket: UdpSocket,
|
|
/// Optional name for the adopted UDP transport.
|
|
pub transport_name: Option<String>,
|
|
/// Optional UDP transport tuning overrides.
|
|
pub transport_config: Option<UdpConfig>,
|
|
}
|
|
|
|
impl EstablishedTraversal {
|
|
/// Construct an established traversal handoff.
|
|
pub fn new(
|
|
session_id: impl Into<String>,
|
|
peer_npub: impl Into<String>,
|
|
remote_addr: SocketAddr,
|
|
socket: UdpSocket,
|
|
) -> Self {
|
|
Self {
|
|
session_id: session_id.into(),
|
|
peer_npub: peer_npub.into(),
|
|
remote_addr,
|
|
socket,
|
|
transport_name: None,
|
|
transport_config: None,
|
|
}
|
|
}
|
|
|
|
/// Attach an explicit transport name to the adopted UDP transport.
|
|
pub fn with_transport_name(mut self, name: impl Into<String>) -> Self {
|
|
self.transport_name = Some(name.into());
|
|
self
|
|
}
|
|
|
|
/// Override UDP transport tuning for the adopted socket.
|
|
pub fn with_transport_config(mut self, config: UdpConfig) -> Self {
|
|
self.transport_config = Some(config);
|
|
self
|
|
}
|
|
}
|