git.delta.rocks / fleet / refs/heads / push-kyumtlkprzyo

difftreelog

source

remowt/crates/remowt-endpoints/src/iroh_tunnel.rs2.1 KiBsourcehistory
1use std::sync::{Arc, Mutex};23use bifrostlink::declarative::endpoints;4use bifrostlink::Config;5use camino::Utf8PathBuf;6use iroh::{Endpoint, EndpointId, SecretKey};7use remowt_link_shared::iroh_tunnel::{build_endpoint, TunnelDialer};8use serde::{Deserialize, Serialize};9use std::result::Result;10use tokio::net::UnixStream;11use tracing::{debug, warn};1213#[derive(Serialize, Deserialize, Debug, thiserror::Error)]14pub enum Error {15	#[error("iroh transport pipe unavailable: {0}")]16	Pipe(String),17	#[error("iroh endpoint failed: {0}")]18	Iroh(String),19}2021#[derive(Clone)]22pub struct IrohTunnel {23	dialer: Arc<TunnelDialer>,24	endpoint: Arc<Mutex<Option<Endpoint>>>,25}2627impl IrohTunnel {28	pub fn new(dialer: Arc<TunnelDialer>) -> Self {29		Self {30			dialer,31			endpoint: Arc::new(Mutex::new(None)),32		}33	}34}3536#[endpoints(ns = 11)]37impl IrohTunnel {38	#[endpoints(id = 1)]39	async fn setup(40		&self,41		client_id: EndpointId,42		xport_socket: Utf8PathBuf,43	) -> Result<EndpointId, Error> {44		let stream = UnixStream::connect(&xport_socket)45			.await46			.map_err(|e| Error::Pipe(e.to_string()))?;4748		let secret = SecretKey::generate();49		let agent_id = secret.public();50		let ep = build_endpoint(secret, stream, client_id, true)51			.await52			.map_err(|e| Error::Iroh(e.to_string()))?;5354		let dialer = self.dialer.clone();55		let accept_ep = ep.clone();56		tokio::spawn(async move {57			while let Some(incoming) = accept_ep.accept().await {58				let dialer = dialer.clone();59				match incoming.accept() {60					Ok(accepting) => {61						tokio::spawn(async move {62							match accepting.await {63								Ok(conn) => {64									if conn.remote_id() != client_id {65										warn!("iroh: rejecting connection from unexpected peer");66										conn.close(0u32.into(), b"unexpected peer");67										return;68									}69									debug!("iroh tunnel connection accepted");70									dialer.set_conn(conn);71								}72								Err(e) => warn!("iroh accept failed: {e}"),73							}74						});75					}76					Err(e) => warn!("iroh incoming rejected: {e}"),77				}78			}79		});8081		*self.endpoint.lock().expect("not poisoned") = Some(ep);8283		Ok(agent_id)84	}85}