rings-node 0.20.0

Rings is a structured peer-to-peer network implementation using WebRTC, Chord algorithm, and full WebAssembly (WASM) support.
Documentation
use rings_core::ecc::PublicKey;

use super::*;
use crate::onion::circuit::OnionBackwardPath;

struct ClientReturnPath {
    runtime: Arc<OnionTcpRuntime>,
    scope: Scope,
    path: OnionCircuitPath,
    client_return: OnionClientReturn,
}

#[async_trait::async_trait]
impl pump::TcpDuplexEffects for ClientReturnPath {
    async fn send(&mut self, payload: OnionTcpPayload) -> Result<()> {
        send_client_payload(
            &self.runtime.link_sender,
            &self.scope,
            &self.path,
            self.client_return,
            payload,
        )
        .await
    }

    fn remote_failed(&mut self, failure: &OnionExitFailure) {
        tracing::warn!("onion TCP client stream failed: {failure}");
    }
}

pub(super) fn spawn_client_stream<S>(
    runtime: Arc<OnionTcpRuntime>,
    scope: Scope,
    key: TcpStreamKey,
    stream: S,
    path: OnionCircuitPath,
    client_return: OnionClientReturn,
    rx: mpsc::Receiver<TcpInbound>,
) where
    S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send + 'static,
{
    tokio::spawn(async move {
        let mut return_path = ClientReturnPath {
            runtime: runtime.clone(),
            scope,
            path,
            client_return,
        };
        pump::pump_tcp_duplex(stream, rx, &mut return_path).await;
        runtime.remove_client_stream(key);
    });
}

async fn send_client_payload(
    link_sender: &OnionLinkSender,
    scope: &Scope,
    path: &OnionCircuitPath,
    client_return: OnionClientReturn,
    payload: OnionTcpPayload,
) -> Result<()> {
    let payload = encode_tcp_payload(path.service_name(), payload)?;
    let (first_link, payload) = path.encode_forward(client_return, payload)?;
    link_sender
        .send_sealed(scope.clone(), first_link, payload)
        .await
}

pub(super) struct TcpBackwardRoute<'route> {
    pub(super) link_sender: &'route OnionLinkSender,
    pub(super) scope: &'route Scope,
    pub(super) signer: &'route SessionSk,
    pub(super) service: &'route OnionServiceName,
    pub(super) circuit_id: OnionCircuitId,
    pub(super) return_peer: Did,
    pub(super) return_session_public_key: PublicKey<33>,
    pub(super) client: OnionClientReturn,
}

impl TcpBackwardRoute<'_> {
    pub(super) async fn send(
        self,
        sequence: OnionBackwardSequence,
        payload: OnionTcpPayload,
    ) -> Result<()> {
        send_backward(
            self.link_sender,
            self.scope,
            self.signer,
            OnionBackwardPath::new(
                self.circuit_id,
                self.return_peer,
                self.return_session_public_key,
                self.client,
            ),
            sequence,
            encode_tcp_payload(self.service, payload)?,
        )
        .await
    }
}