Artifact b5da003fb6a950459b38710c3068d43b62d4846fd77fae906f5f99874aa4ed26:
- File
iroh-sidecar/src/main.rs
— part of check-in
[eb4b6f52d0]
at
2026-08-12 20:35:17
on branch main
— chore(deps): update Go, Hugo, and cargo dependencies (#194)
* chore(deps): update Go, Hugo, and cargo dependencies
- nats.go 1.49→1.53.1, nats-server 2.12.6→2.14.5, otel 1.43→1.45, modernc sqlite 1.46→1.56, libfossil 0.6.2→0.6.3, hextra 0.12.2→0.12.3 - cargo update for iroh-sidecar; ed25519/pkcs8/signature pinned to the rc series required by iroh's ed25519-dalek 3.0.0-pre.1 - fix traceparent test: nats.go ≥1.50 preserves header case and Get is exact-match; assert via natshdr.Carrier - rustfmt pass on sidecar sources
* chore(deps): bump iroh 0.97→1.0.3, fixes hickory-proto security alerts
SecretKey::generate no longer takes an rng; drop now-unused rand dep. Verified with make test-iroh (peer sync + convergence e2e).
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> (user: [email protected], size: 2831) [annotate] [blame] [check-ins using]
mod acceptor; mod endpoint; mod server; mod tunnel; use clap::Parser; use std::path::PathBuf; use tokio::sync::oneshot; pub const XFER_ALPN: &[u8] = b"/edgesync/xfer/1"; pub const NATS_ALPN: &[u8] = b"/edgesync/nats-leaf/1"; #[derive(Parser)] #[command(name = "iroh-sidecar", about = "Iroh P2P proxy for EdgeSync")] struct Args { /// Unix socket path for the HTTP API #[arg(long)] socket: PathBuf, /// Path to persist the Ed25519 keypair #[arg(long)] key_path: PathBuf, /// URL to forward incoming peer requests to (Go agent's HTTP handler) #[arg(long)] callback: String, /// ALPN protocol identifier #[arg(long, default_value = "/edgesync/xfer/1")] alpn: String, /// Local NATS server address for tunnel connections (e.g. 127.0.0.1:4222) #[arg(long)] nats_addr: Option<String>, } #[tokio::main] async fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); let args = Args::parse(); tracing::info!(socket = %args.socket.display(), "iroh-sidecar starting"); let alpns: Vec<Vec<u8>> = if args.nats_addr.is_some() { vec![args.alpn.as_bytes().to_vec(), NATS_ALPN.to_vec()] } else { vec![args.alpn.as_bytes().to_vec()] }; let (ep, endpoint_id) = endpoint::create_endpoint(&args.key_path, &alpns).await?; tracing::info!(%endpoint_id, "iroh endpoint ready"); // Channel used by POST /shutdown to stop the HTTP server. let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>(); let state = server::AppState::new( ep.clone(), endpoint_id, args.alpn.as_bytes().to_vec(), shutdown_tx, ); // Accept loop for incoming P2P connections. let accept_ep = ep.clone(); let callback_url = args.callback.clone(); let accept_nats_addr = args.nats_addr.clone(); let accept_handle = tokio::spawn(async move { acceptor::run_accept_loop(accept_ep, callback_url, accept_nats_addr).await; }); // Task 3: HTTP server on the Unix socket. let socket_path = args.socket.clone(); let http_handle = tokio::spawn(async move { if let Err(e) = server::run_server(&socket_path, state, shutdown_rx).await { tracing::error!("HTTP server error: {e:#}"); } }); // Wait for either task to finish. // The HTTP server exits when it receives /shutdown; the accept loop exits // when the endpoint is closed. tokio::select! { _ = http_handle => { tracing::info!("HTTP server exited"); } _ = accept_handle => { tracing::info!("accept loop exited unexpectedly"); } _ = tokio::signal::ctrl_c() => { tracing::info!("received ctrl-c"); } } ep.close().await; tracing::info!("iroh-sidecar stopped"); Ok(()) }