use crate::relay_service::relay::Relay;
use crate::{Context, RelayServiceOptions};
use core::str::from_utf8;
use ockam_core::compat::boxed::Box;
use ockam_core::{Address, Any, DenyAll, Result, Routed, Worker};
use ockam_node::WorkerBuilder;
#[non_exhaustive]
pub struct RelayService {
options: RelayServiceOptions,
}
impl RelayService {
pub async fn create(
ctx: &Context,
address: impl Into<Address>,
options: RelayServiceOptions,
) -> Result<()> {
let address = address.into();
options.setup_flow_control_for_relay_service(ctx.flow_controls(), &address);
let service_incoming_access_control = options.service_incoming_access_control.clone();
let s = Self { options };
WorkerBuilder::new(s)
.with_address(address.clone())
.with_incoming_access_control_arc(service_incoming_access_control)
.with_outgoing_access_control(DenyAll)
.start(ctx)
.await?;
info!("Relay service started at {address}");
Ok(())
}
}
#[crate::worker]
impl Worker for RelayService {
type Context = Context;
type Message = Any;
async fn handle_message(
&mut self,
ctx: &mut Self::Context,
msg: Routed<Self::Message>,
) -> Result<()> {
let forward_route = msg.return_route();
let payload = msg.payload();
let random_address = Address::random_tagged("Relay.service");
let address = match payload.get(1..) {
Some(address) => match from_utf8(address) {
Ok(v) if v != "register" => Address::from_string(v),
_ => random_address,
},
None => random_address,
};
self.options
.setup_flow_control_for_relay(ctx.flow_controls(), &address);
Relay::create(
ctx,
address,
forward_route,
payload.to_vec(),
self.options.relays_incoming_access_control.clone(),
)
.await?;
Ok(())
}
}