mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-30 19:46:15 +00:00
Drop the nostr-discovery cargo feature flag
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.
This commit is contained in:
@@ -197,6 +197,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Nostr-mediated overlay discovery is now always-on. The
|
||||
`nostr-discovery` cargo feature flag has been dropped along with the
|
||||
`optional = true` markers on `nostr` / `nostr-sdk` dependencies and
|
||||
every `#[cfg(feature = "nostr-discovery")]` source-level gate. Plain
|
||||
`cargo build` produces a binary with overlay discovery available
|
||||
whether or not the operator enables it via
|
||||
`node.discovery.nostr.enabled`. Mirrors PR #79's collapse of the
|
||||
`tui` / `ble` / `gateway` features in favor of platform cfg gates.
|
||||
No runtime behavior change — the feature was in `default` already
|
||||
- MMP link-layer report intervals retuned for constrained transports:
|
||||
steady-state floor raised from 100ms to 1000ms, ceiling from 2000ms
|
||||
to 5000ms. Cold-start uses a 200ms floor for the first 5 SRTT samples
|
||||
|
||||
+2
-6
@@ -8,10 +8,6 @@ authors = ["Johnathan Corgan <jcorgan@corganlabs.com>"]
|
||||
repository = "https://github.com/jmcorgan/fips"
|
||||
readme = "README.md"
|
||||
|
||||
[features]
|
||||
default = ["nostr-discovery"]
|
||||
nostr-discovery = ["dep:nostr", "dep:nostr-sdk"]
|
||||
|
||||
[dependencies]
|
||||
ratatui = "0.30"
|
||||
secp256k1 = { version = "0.30", features = ["rand", "global-context"] }
|
||||
@@ -36,8 +32,8 @@ socket2 = { version = "0.6.2", features = ["all"] }
|
||||
tokio-socks = "0.5"
|
||||
portable-atomic = { version = "1", features = ["std"] }
|
||||
|
||||
nostr = { version = "0.44", features = ["std", "nip59"], optional = true }
|
||||
nostr-sdk = { version = "0.44", optional = true }
|
||||
nostr = { version = "0.44", features = ["std", "nip59"] }
|
||||
nostr-sdk = "0.44"
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
tun = { version = "0.8.5", features = ["async"] }
|
||||
|
||||
@@ -12,7 +12,6 @@ node:
|
||||
# nsec: "nsec1..."
|
||||
discovery:
|
||||
# Optional Nostr-mediated overlay endpoint discovery.
|
||||
# Requires a build of fips compiled with the 'nostr-discovery' feature.
|
||||
# nostr:
|
||||
# enabled: true
|
||||
# policy: configured_only # disabled | configured_only | open
|
||||
|
||||
@@ -82,7 +82,6 @@ define Build/Compile
|
||||
cargo build \
|
||||
--release \
|
||||
--target $(RUST_TARGET) \
|
||||
--features gateway \
|
||||
--bin fips \
|
||||
--bin fipsctl \
|
||||
--bin fipstop \
|
||||
|
||||
@@ -242,10 +242,7 @@ async fn main() {
|
||||
last_failure = Some(format!("recv_from failed: {}", e));
|
||||
}
|
||||
Err(_) => {
|
||||
last_failure = Some(format!(
|
||||
"no response within {}s",
|
||||
PROBE_TIMEOUT_SECS
|
||||
));
|
||||
last_failure = Some(format!("no response within {}s", PROBE_TIMEOUT_SECS));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -71,10 +71,7 @@ fn is_loopback_addr_str(addr: &str) -> bool {
|
||||
Some((h, _)) => h,
|
||||
None => addr,
|
||||
};
|
||||
host == "localhost"
|
||||
|| host == "::1"
|
||||
|| host == "0:0:0:0:0:0:0:1"
|
||||
|| host.starts_with("127.")
|
||||
host == "localhost" || host == "::1" || host == "0:0:0:0:0:0:0:1" || host.starts_with("127.")
|
||||
}
|
||||
|
||||
/// Derive the key file path from a config file path.
|
||||
|
||||
+3
-4
@@ -6,7 +6,6 @@
|
||||
//! it hands the live socket and selected remote endpoint to FIPS so the
|
||||
//! existing Noise/FMP transport path can take over.
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
pub mod nostr;
|
||||
|
||||
use crate::config::UdpConfig;
|
||||
@@ -16,9 +15,9 @@ 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 here (unconditionally
|
||||
/// compiled) rather than inside the `nostr-discovery`-gated submodule so
|
||||
/// the filter applies regardless of feature configuration.
|
||||
/// 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
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![cfg(feature = "nostr-discovery")]
|
||||
|
||||
mod runtime;
|
||||
mod signal;
|
||||
mod stun;
|
||||
|
||||
@@ -829,12 +829,12 @@ impl NostrDiscovery {
|
||||
advert: Option<&OverlayAdvert>,
|
||||
) -> Result<Vec<String>, BootstrapError> {
|
||||
let mut merged = self.find_recipient_inbox_relays(target_pubkey).await?;
|
||||
if let Some(advert) = advert {
|
||||
if let Some(relays) = advert.signal_relays.as_ref() {
|
||||
for relay in relays {
|
||||
if !merged.contains(relay) {
|
||||
merged.push(relay.clone());
|
||||
}
|
||||
if let Some(advert) = advert
|
||||
&& let Some(relays) = advert.signal_relays.as_ref()
|
||||
{
|
||||
for relay in relays {
|
||||
if !merged.contains(relay) {
|
||||
merged.push(relay.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,8 +268,8 @@ fn private_interface_ips() -> Vec<IpAddr> {
|
||||
// SAFETY: `cursor` points at a valid node from the `getifaddrs` list.
|
||||
let entry = unsafe { &*cursor };
|
||||
let flags = entry.ifa_flags as i32;
|
||||
let is_up = (flags & libc::IFF_UP as i32) != 0;
|
||||
let is_loopback = (flags & libc::IFF_LOOPBACK as i32) != 0;
|
||||
let is_up = (flags & libc::IFF_UP) != 0;
|
||||
let is_loopback = (flags & libc::IFF_LOOPBACK) != 0;
|
||||
|
||||
if is_up && !is_loopback && !entry.ifa_addr.is_null() {
|
||||
// SAFETY: `ifa_addr` is non-null and its concrete type matches
|
||||
|
||||
@@ -6,8 +6,8 @@ pub const ADVERT_KIND: u16 = 37195;
|
||||
pub const ADVERT_IDENTIFIER: &str = "fips-overlay-v1";
|
||||
pub const ADVERT_VERSION: u32 = 1;
|
||||
pub const SIGNAL_KIND: u16 = 21059;
|
||||
// Re-exported from `crate::discovery` so the UDP transport's stray-probe
|
||||
// filter compiles regardless of the `nostr-discovery` cargo feature.
|
||||
// Defined at the top-level `discovery` module; re-exported here so the
|
||||
// existing punch sender / receiver imports remain unchanged.
|
||||
pub use crate::discovery::{PUNCH_ACK_MAGIC, PUNCH_MAGIC};
|
||||
pub const PROTOCOL_VERSION: &str = "1";
|
||||
|
||||
|
||||
@@ -115,7 +115,6 @@ impl Node {
|
||||
let now_ms = Self::now_ms();
|
||||
self.reload_peer_acl();
|
||||
self.poll_pending_connects().await;
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
self.poll_nostr_discovery().await;
|
||||
self.resend_pending_handshakes(now_ms).await;
|
||||
self.resend_pending_rekeys(now_ms).await;
|
||||
|
||||
+6
-39
@@ -2,7 +2,6 @@
|
||||
|
||||
use super::{Node, NodeError, NodeState};
|
||||
use crate::config::{ConnectPolicy, PeerAddress, PeerConfig};
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
use crate::discovery::nostr::{
|
||||
ADVERT_IDENTIFIER, ADVERT_VERSION, BootstrapEvent, NostrDiscovery, OverlayAdvert,
|
||||
OverlayEndpointAdvert, OverlayTransportKind,
|
||||
@@ -15,13 +14,11 @@ use crate::protocol::{Disconnect, DisconnectReason};
|
||||
use crate::transport::{Link, LinkDirection, LinkId, TransportAddr, TransportId, packet_channel};
|
||||
use crate::upper::tun::{TunDevice, TunState, run_tun_reader, shutdown_tun_interface};
|
||||
use crate::{NodeAddr, PeerIdentity};
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
use std::collections::HashSet;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
const OPEN_DISCOVERY_RETRY_LIFETIME_MULTIPLIER: u64 = 2;
|
||||
|
||||
impl Node {
|
||||
@@ -381,7 +378,6 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
pub(super) async fn poll_nostr_discovery(&mut self) {
|
||||
let Some(bootstrap) = self.nostr_discovery.clone() else {
|
||||
return;
|
||||
@@ -569,7 +565,6 @@ impl Node {
|
||||
info!(count = self.transports.len(), "Transports initialized");
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
if self.config.node.discovery.nostr.enabled {
|
||||
match NostrDiscovery::start(&self.identity, self.config.node.discovery.nostr.clone())
|
||||
.await
|
||||
@@ -587,13 +582,6 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "nostr-discovery"))]
|
||||
if self.config.node.discovery.nostr.enabled {
|
||||
warn!(
|
||||
"Nostr overlay discovery configured but this build was compiled without the 'nostr-discovery' feature"
|
||||
);
|
||||
}
|
||||
|
||||
// Connect to static peers before TUN is active
|
||||
// This allows handshake messages to be sent before we start accepting packets
|
||||
self.initiate_peer_connections().await;
|
||||
@@ -867,7 +855,6 @@ impl Node {
|
||||
.await;
|
||||
|
||||
// Stop Nostr overlay discovery background work and withdraw any advert.
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
if let Some(bootstrap) = self.nostr_discovery.take()
|
||||
&& let Err(e) = bootstrap.shutdown().await
|
||||
{
|
||||
@@ -989,7 +976,6 @@ impl Node {
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
async fn nostr_peer_fallback_addresses(
|
||||
&self,
|
||||
peer_config: &PeerConfig,
|
||||
@@ -1045,7 +1031,6 @@ impl Node {
|
||||
fallback
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn overlay_endpoint_to_peer_address(
|
||||
endpoint: &OverlayEndpointAdvert,
|
||||
priority: u8,
|
||||
@@ -1074,21 +1059,13 @@ impl Node {
|
||||
if !allow_bootstrap_nat {
|
||||
continue;
|
||||
}
|
||||
#[cfg(not(feature = "nostr-discovery"))]
|
||||
{
|
||||
debug!(npub = %peer_config.npub, "Skipping udp:nat address because this build does not include the nostr-discovery feature");
|
||||
let Some(bootstrap) = self.nostr_discovery.clone() else {
|
||||
debug!(npub = %peer_config.npub, "No Nostr overlay runtime for udp:nat address");
|
||||
continue;
|
||||
}
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
{
|
||||
let Some(bootstrap) = self.nostr_discovery.clone() else {
|
||||
debug!(npub = %peer_config.npub, "No Nostr overlay runtime for udp:nat address");
|
||||
continue;
|
||||
};
|
||||
bootstrap.request_connect(peer_config.clone()).await;
|
||||
info!(npub = %peer_config.npub, "Started Nostr UDP NAT traversal attempt");
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
bootstrap.request_connect(peer_config.clone()).await;
|
||||
info!(npub = %peer_config.npub, "Started Nostr UDP NAT traversal attempt");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let (transport_id, remote_addr) = if addr.transport == "ethernet" {
|
||||
@@ -1163,7 +1140,6 @@ impl Node {
|
||||
)))
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
async fn queue_open_discovery_retries(&mut self, bootstrap: &std::sync::Arc<NostrDiscovery>) {
|
||||
if !self.config.node.discovery.nostr.enabled
|
||||
|| self.config.node.discovery.nostr.policy != crate::config::NostrDiscoveryPolicy::Open
|
||||
@@ -1251,7 +1227,6 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn available_outbound_slots(&self) -> usize {
|
||||
let connection_used = self
|
||||
.connections
|
||||
@@ -1272,7 +1247,6 @@ impl Node {
|
||||
connection_slots.min(peer_slots)
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn open_discovery_enqueue_budget(&self, configured_npubs: &HashSet<String>) -> usize {
|
||||
let current_open_discovery_pending = self
|
||||
.retry_pending
|
||||
@@ -1291,7 +1265,6 @@ impl Node {
|
||||
cap_remaining.min(self.available_outbound_slots())
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn open_discovery_retry_expires_at_ms(&self, now_ms: u64) -> u64 {
|
||||
now_ms.saturating_add(
|
||||
self.config
|
||||
@@ -1304,7 +1277,6 @@ impl Node {
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn build_overlay_advert(&self) -> Option<OverlayAdvert> {
|
||||
if !self.config.node.discovery.nostr.enabled {
|
||||
return None;
|
||||
@@ -1391,7 +1363,6 @@ impl Node {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
async fn refresh_overlay_advert(
|
||||
&self,
|
||||
bootstrap: &std::sync::Arc<NostrDiscovery>,
|
||||
@@ -1400,7 +1371,6 @@ impl Node {
|
||||
bootstrap.update_local_advert(advert).await
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn lookup_udp_config(&self, transport_name: Option<&str>) -> Option<&crate::config::UdpConfig> {
|
||||
match (&self.config.transports.udp, transport_name) {
|
||||
(crate::config::TransportInstances::Single(cfg), None) => Some(cfg),
|
||||
@@ -1409,7 +1379,6 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn lookup_tcp_config(&self, transport_name: Option<&str>) -> Option<&crate::config::TcpConfig> {
|
||||
match (&self.config.transports.tcp, transport_name) {
|
||||
(crate::config::TransportInstances::Single(cfg), None) => Some(cfg),
|
||||
@@ -1418,7 +1387,6 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
fn lookup_tor_config(&self, transport_name: Option<&str>) -> Option<&crate::config::TorConfig> {
|
||||
match (&self.config.transports.tor, transport_name) {
|
||||
(crate::config::TransportInstances::Single(cfg), None) => Some(cfg),
|
||||
@@ -1449,7 +1417,6 @@ impl Node {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
{
|
||||
let fallback = self
|
||||
.nostr_peer_fallback_addresses(peer_config, &static_addresses)
|
||||
|
||||
@@ -431,7 +431,6 @@ pub struct Node {
|
||||
retry_pending: HashMap<NodeAddr, retry::RetryState>,
|
||||
|
||||
/// Optional Nostr/STUN overlay discovery coordinator for `udp:nat` peers.
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
nostr_discovery: Option<Arc<crate::discovery::nostr::NostrDiscovery>>,
|
||||
/// Per-peer UDP transports adopted from NAT traversal handoff.
|
||||
bootstrap_transports: HashSet<TransportId>,
|
||||
@@ -596,7 +595,6 @@ impl Node {
|
||||
),
|
||||
pending_connects: Vec::new(),
|
||||
retry_pending: HashMap::new(),
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
nostr_discovery: None,
|
||||
bootstrap_transports: HashSet::new(),
|
||||
last_parent_reeval: None,
|
||||
@@ -724,7 +722,6 @@ impl Node {
|
||||
discovery_forward_limiter: DiscoveryForwardRateLimiter::new(),
|
||||
pending_connects: Vec::new(),
|
||||
retry_pending: HashMap::new(),
|
||||
#[cfg(feature = "nostr-discovery")]
|
||||
nostr_discovery: None,
|
||||
bootstrap_transports: HashSet::new(),
|
||||
last_parent_reeval: None,
|
||||
|
||||
@@ -19,9 +19,10 @@ if [ ! -f "$PROJECT_ROOT/Cargo.toml" ]; then
|
||||
fi
|
||||
|
||||
BUILD_DOCKER=true
|
||||
# NAT harness binaries need Nostr bootstrap support; everything else is
|
||||
# governed by platform cfg gates after PR #79's feature-matrix collapse.
|
||||
DEFAULT_CARGO_BUILD_ARGS=(--features nostr-discovery)
|
||||
# Default flags for the container-image cargo build. Empty by default;
|
||||
# every subsystem is governed by platform cfg gates with no feature
|
||||
# flags required.
|
||||
DEFAULT_CARGO_BUILD_ARGS=()
|
||||
if [ -n "${FIPS_CARGO_BUILD_ARGS:-}" ]; then
|
||||
# shellcheck disable=SC2206
|
||||
CARGO_BUILD_ARGS=($FIPS_CARGO_BUILD_ARGS)
|
||||
|
||||
Reference in New Issue
Block a user