rings_node/onion/
gateway.rs1use std::sync::Arc;
4
5use rings_gateway::BoxGatewayDuplex;
6use rings_gateway::FlowId;
7use rings_gateway::GatewayError;
8use rings_gateway::OnionStreamConnector;
9
10use crate::onion::proxy::OnionProxyConfig;
11use crate::onion::tcp::NativeOnionCircuitHandle;
12use crate::onion::OnionProxyTarget;
13use crate::processor::Processor;
14
15pub struct NativeOnionGatewayConnector {
17 processor: Arc<Processor>,
18 onion: NativeOnionCircuitHandle,
19 proxy: OnionProxyConfig,
20}
21
22impl NativeOnionGatewayConnector {
23 pub fn new(
25 processor: Arc<Processor>,
26 onion: NativeOnionCircuitHandle,
27 proxy: OnionProxyConfig,
28 ) -> Self {
29 Self {
30 processor,
31 onion,
32 proxy,
33 }
34 }
35
36 fn onion_error(flow: FlowId, error: impl std::fmt::Display) -> GatewayError {
37 GatewayError::OnionUnavailable {
38 target: flow.target,
39 message: error.to_string(),
40 }
41 }
42}
43
44#[async_trait::async_trait]
45impl OnionStreamConnector for NativeOnionGatewayConnector {
46 async fn open_stream(
47 &self,
48 flow: FlowId,
49 stream: BoxGatewayDuplex,
50 ) -> Result<(), GatewayError> {
51 let target = OnionProxyTarget::parse_authority(&flow.target.to_string())
52 .map_err(|error| Self::onion_error(flow, error))?;
53 let route = self
54 .processor
55 .build_onion_proxy_route(self.proxy.clone(), target)
56 .await
57 .map_err(|error| Self::onion_error(flow, error))?;
58 let opened = self
59 .onion
60 .open_tcp_stream(route.route, route.target)
61 .await
62 .map_err(|error| Self::onion_error(flow, error))?;
63 opened.relay(stream);
64 Ok(())
65 }
66}