754afd5621
The peer runtime previously accepted an `enable_mdns: bool` flag, plumbed
through `PeerStartOptions`, `spawn_peer_runtime`, `run_peer`, `Ctx`, and
`PeerCtx`. The lanspread-peer-cli harness exposed the toggle as
`--no-mdns` so test scenarios could fall back to explicit `connect`
commands when mDNS could not be relied on, in particular when multiple
peers ran inside `--network host` containers and could not advertise
independently.
That host-networking workaround no longer exists: the previous commit
moves harness containers onto a macvlan network, where each peer is a
real LAN device and mDNS just works between them. There is no scenario
left in the codebase where disabling mDNS is desirable. Per the project's
protocol policy in CLAUDE.md ("there is only one wire version, no
compatibility shims, no fallback paths"), an opt-out path with no current
caller is exactly the kind of dead code we should not carry.
Remove the flag and every plumbing point that exists only to support it:
- `PeerStartOptions::enable_mdns` and the custom `Default` impl that set
it to `true`; the struct now derives `Default` and just carries
`state_dir`.
- The `enable_mdns` parameter on `start_peer_with_options`,
`spawn_peer_runtime`, `run_peer`, and `Ctx::new`.
- The `enable_mdns` fields on `Ctx` and `PeerCtx` and the propagation
through `to_peer_ctx`.
- The `if ctx.enable_mdns` guard in `spawn_startup_services`;
`spawn_peer_discovery_service` is now always spawned.
- The `if ctx.enable_mdns { ... } else { ... }` branch in
`run_server_component`: the mDNS advertiser and event monitor are now
unconditionally started, and the no-mDNS-fallback log line that read
"mDNS disabled; direct peer address is ..." is gone. The
`direct_connect_addr` helper is kept because the mDNS-on branch still
uses it as a fallback when `local_peer_addr` has not yet been
populated.
- The internal test helpers in `handlers.rs`, `services/local_monitor.rs`,
and `services/stream.rs` that passed `true` as the trailing
`enable_mdns` arg to `Ctx::new`.
- In `lanspread-peer-cli`: the `--no-mdns` arg parsing, the
`Args::enable_mdns` field, the `mdns` key on the `cli-started` event
payload, and the `--no-mdns` mention in the help text and the crate
README.
The `Args::name` field is wired to the harness identity but is otherwise
untouched. The macvlan network created by `just peer-cli-net` is the
runtime prerequisite for this change to be observable across containers;
on a single workstation, two harness binaries on `127.0.0.1` discover
each other through mDNS on the loopback interface as before.
Test Plan:
- `just fmt`
- `just clippy`
- `just test`
- `just peer-cli-build`
- Two peers on macvlan: `just peer-cli-run alpha` and
`just peer-cli-run beta`; check that each emits `peer-discovered` and
`peer-connected` events without an explicit `connect` JSONL command.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
116 lines
3.4 KiB
Rust
116 lines
3.4 KiB
Rust
//! QUIC server accept loop.
|
|
|
|
use std::{net::SocketAddr, time::Duration};
|
|
|
|
use s2n_quic::{Connection, Server, provider::limits::Limits};
|
|
use tokio::sync::mpsc::UnboundedSender;
|
|
|
|
use crate::{
|
|
PeerEvent,
|
|
config::{CERT_PEM, KEY_PEM},
|
|
context::PeerCtx,
|
|
events,
|
|
services::{
|
|
advertise::{monitor_mdns_events, start_mdns_advertiser},
|
|
stream::handle_peer_stream,
|
|
},
|
|
};
|
|
|
|
/// Runs the QUIC server and mDNS advertiser.
|
|
pub async fn run_server_component(
|
|
addr: SocketAddr,
|
|
ctx: PeerCtx,
|
|
tx_notify_ui: UnboundedSender<PeerEvent>,
|
|
) -> eyre::Result<()> {
|
|
let limits = Limits::default()
|
|
.with_max_handshake_duration(Duration::from_secs(3))?
|
|
.with_max_idle_timeout(Duration::from_secs(3))?;
|
|
|
|
let mut server = Server::builder()
|
|
.with_tls((CERT_PEM, KEY_PEM))?
|
|
.with_io(addr)?
|
|
.with_limits(limits)?
|
|
.start()?;
|
|
|
|
let server_addr = server.local_addr()?;
|
|
log::info!("Peer server listening on {server_addr}");
|
|
|
|
let mdns_advertiser = start_mdns_advertiser(&ctx, server_addr).await?;
|
|
let mdns_monitor = mdns_advertiser.monitor.clone();
|
|
let mdns_shutdown = ctx.shutdown.clone();
|
|
ctx.task_tracker.spawn(async move {
|
|
monitor_mdns_events(mdns_monitor, mdns_shutdown).await;
|
|
});
|
|
let ready_addr =
|
|
(*ctx.local_peer_addr.read().await).unwrap_or_else(|| direct_connect_addr(server_addr));
|
|
let _mdns_advertiser = mdns_advertiser;
|
|
|
|
events::send(
|
|
&tx_notify_ui,
|
|
PeerEvent::LocalPeerReady {
|
|
peer_id: ctx.peer_id.as_ref().clone(),
|
|
addr: ready_addr,
|
|
},
|
|
);
|
|
|
|
loop {
|
|
let connection = tokio::select! {
|
|
() = ctx.shutdown.cancelled() => return Ok(()),
|
|
connection = server.accept() => connection,
|
|
};
|
|
|
|
let Some(connection) = connection else {
|
|
eyre::bail!("QUIC server accept loop ended unexpectedly");
|
|
};
|
|
|
|
let ctx = ctx.clone();
|
|
let tx_notify_ui = tx_notify_ui.clone();
|
|
let task_tracker = ctx.task_tracker.clone();
|
|
|
|
task_tracker.spawn(async move {
|
|
if let Err(err) = handle_peer_connection(connection, ctx, tx_notify_ui).await {
|
|
log::error!("Peer connection error: {err}");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
fn direct_connect_addr(server_addr: SocketAddr) -> SocketAddr {
|
|
if server_addr.ip().is_unspecified() {
|
|
return SocketAddr::from(([127, 0, 0, 1], server_addr.port()));
|
|
}
|
|
server_addr
|
|
}
|
|
|
|
async fn handle_peer_connection(
|
|
mut connection: Connection,
|
|
ctx: PeerCtx,
|
|
tx_notify_ui: UnboundedSender<PeerEvent>,
|
|
) -> eyre::Result<()> {
|
|
let remote_addr = connection.remote_addr()?;
|
|
log::info!("{remote_addr} peer connected");
|
|
events::send(&tx_notify_ui, PeerEvent::PeerConnected(remote_addr));
|
|
|
|
loop {
|
|
let stream = tokio::select! {
|
|
() = ctx.shutdown.cancelled() => break,
|
|
stream = connection.accept_bidirectional_stream() => stream,
|
|
};
|
|
|
|
let Some(stream) = stream? else {
|
|
break;
|
|
};
|
|
|
|
let ctx = ctx.clone();
|
|
let task_tracker = ctx.task_tracker.clone();
|
|
task_tracker.spawn(async move {
|
|
if let Err(err) = handle_peer_stream(stream, ctx, Some(remote_addr)).await {
|
|
log::error!("{remote_addr:?} peer stream error: {err}");
|
|
}
|
|
});
|
|
}
|
|
|
|
events::send(&tx_notify_ui, PeerEvent::PeerDisconnected(remote_addr));
|
|
Ok(())
|
|
}
|