Artifact 31b45343a90a376064e6dec0f56e7fdb545d0051bc864283e417864e029d060f:
- File
iroh-sidecar/src/main.rs
— part of check-in
[eda7960b81]
at
2026-04-23 19:23:42
on branch trunk
— rename module to github.com/danmestas/EdgeSync
Fix the case-sensitive module path to match the actual GitHub repo URL (danmestas/EdgeSync). Remove tracked leaf/leaf binary and ignore .claude/skills/ scratchpad dirs. (user: [email protected], size: 2854) [annotate] [blame] [check-ins using] [more...]
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(()) }