Consolidate the duplicated JSON codec into `transport` and relocate the iroh edge-transport pieces into `iroh-driver`, dissolving the `mvp-system` transport shim. - `transport`: add a canonical `json_codec::JsonCodec<M>` (re-exported from the crate root) as the single JSON codec for serde message types - `distribution`/`datastream`: drop the per-crate `JsonCodec` copies and the `impl_json_codec!` macro; register SWIM/gossip and publisher messages against the shared `swactor_transport::JsonCodec` - `iroh-driver`: move `driver_pumps` and `endpoint_advertisement` out of `mvp-system/src/transport/`, re-exporting `EndpointAddrMask`/`advertised_endpoint`/`MVP_IROH_ENDPOINT_ADDR_MASK_ENV`, and relocate the endpoint guarantee test to `iroh-driver/tests/endpoint_advertisement.rs` - `mvp-system`: delete the `transport/` module and keep codec aggregation in a new `codecs.rs` (`register_mvp_actor_codecs`) - `mvp-system/node`: shrink `worker_node_runtime.rs` (~260 lines) by adopting the relocated modules and collapsing verbose `emit_stdio_node_event` calls into local `boot()`/`worker_evt()` closures Signed-off-by: Zachery Aaron Shores-Chmielewski <zacheryasc@gmail.com>
76 lines
2.3 KiB
Rust
76 lines
2.3 KiB
Rust
//! Endpoint advertisement masking.
|
|
//!
|
|
//! Controls how much of an iroh [`EndpointAddr`] a node advertises to peers.
|
|
//! `relay-only` strips direct IP/socket addresses so peers can only reach the
|
|
//! node via its relay URL — useful for NAT-egress-only or hidden nodes.
|
|
|
|
use std::fmt;
|
|
|
|
use iroh::EndpointAddr;
|
|
|
|
/// Environment variable selecting the advertised endpoint address mask.
|
|
///
|
|
/// Recognized values: `full` (default) and `relay-only`.
|
|
pub const MVP_IROH_ENDPOINT_ADDR_MASK_ENV: &str = "MVP_IROH_ENDPOINT_ADDR_MASK";
|
|
|
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
|
pub enum EndpointAddrMask {
|
|
/// Advertise the full endpoint address: relays and direct addresses.
|
|
#[default]
|
|
Full,
|
|
/// Advertise relay URLs only, omitting direct socket addresses.
|
|
RelayOnly,
|
|
}
|
|
|
|
impl EndpointAddrMask {
|
|
pub fn parse(value: &str) -> Result<Self, String> {
|
|
match value.trim().to_ascii_lowercase().as_str() {
|
|
"" | "full" | "none" => Ok(Self::Full),
|
|
"relay-only" | "relay_only" | "relay" => Ok(Self::RelayOnly),
|
|
other => Err(format!(
|
|
"unsupported {MVP_IROH_ENDPOINT_ADDR_MASK_ENV}={other:?}; use full or relay-only"
|
|
)),
|
|
}
|
|
}
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
match self {
|
|
Self::Full => "full",
|
|
Self::RelayOnly => "relay-only",
|
|
}
|
|
}
|
|
|
|
pub fn requires_relay(self) -> bool {
|
|
matches!(self, Self::RelayOnly)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for EndpointAddrMask {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
f.write_str(self.as_str())
|
|
}
|
|
}
|
|
|
|
/// Apply `mask` to `endpoint`, returning the address to advertise to peers.
|
|
pub fn advertised_endpoint(
|
|
endpoint: EndpointAddr,
|
|
mask: EndpointAddrMask,
|
|
) -> Result<EndpointAddr, String> {
|
|
match mask {
|
|
EndpointAddrMask::Full => Ok(endpoint),
|
|
EndpointAddrMask::RelayOnly => relay_only_endpoint(endpoint),
|
|
}
|
|
}
|
|
|
|
fn relay_only_endpoint(endpoint: EndpointAddr) -> Result<EndpointAddr, String> {
|
|
let relays = endpoint.relay_urls().cloned().collect::<Vec<_>>();
|
|
if relays.is_empty() {
|
|
return Err("relay-only endpoint address mask requires an endpoint relay URL".to_owned());
|
|
}
|
|
|
|
let mut out = EndpointAddr::new(endpoint.id);
|
|
for relay in relays {
|
|
out = out.with_relay_url(relay);
|
|
}
|
|
Ok(out)
|
|
}
|