use std::sync::Arc;
use bitflags::bitflags;
use log::*;
use tari_shutdown::{OptionalShutdownSignal, ShutdownSignal};
use thiserror::Error;
use super::controller::HiddenServiceControllerError;
use crate::{
multiaddr::Multiaddr,
socks,
tor::{
hidden_service::{controller::HiddenServiceController, TorProxyOpts},
Authentication,
PortMapping,
TorIdentity,
},
};
const LOG_TARGET: &str = "comms::tor::hidden_service";
#[derive(Debug, Error)]
pub enum HiddenServiceBuilderError {
#[error("The proxied port mapping was not provided. Use `with_proxied_port_mapping` to set it.")]
ProxiedPortMappingNotProvided,
#[error("The control server address was not provided. Use `with_control_server_address` to set it.")]
TorControlServerAddressNotProvided,
#[error("HiddenServiceControllerError: {0}")]
HiddenServiceControllerError(#[from] HiddenServiceControllerError),
}
bitflags! {
#[derive(Default)]
pub struct HsFlags: u32 {
const NONE = 0x0;
const DETACH = 0x1;
}
}
#[derive(Default)]
pub struct HiddenServiceBuilder {
identity: Option<TorIdentity>,
port_mapping: Option<PortMapping>,
socks_addr_override: Option<Multiaddr>,
control_server_addr: Option<Multiaddr>,
proxy_opts: TorProxyOpts,
control_server_auth: Authentication,
socks_auth: socks::Authentication,
hs_flags: HsFlags,
shutdown_signal: OptionalShutdownSignal,
}
impl HiddenServiceBuilder {
pub fn new() -> Self {
Default::default()
}
}
impl HiddenServiceBuilder {
setter!(
with_control_server_address,
control_server_addr,
Option<Multiaddr>
);
setter!(
with_bypass_proxy_addresses,
proxy_opts.bypass_addresses,
Arc<Vec<Multiaddr>>
);
setter!(
with_control_server_auth,
control_server_auth,
Authentication
);
setter!(
with_socks_authentication,
socks_auth,
socks::Authentication
);
setter!(
with_tor_identity,
identity,
Option<TorIdentity>
);
setter!(
with_hs_flags,
hs_flags,
HsFlags
);
pub fn bypass_tor_for_tcp_addresses(mut self) -> Self {
self.proxy_opts.bypass_for_tcpip = true;
self
}
pub fn with_shutdown_signal(mut self, shutdown_signal: ShutdownSignal) -> Self {
self.shutdown_signal.set(shutdown_signal);
self
}
pub fn with_socks_address_override(mut self, socks_addr_override: Option<Multiaddr>) -> Self {
self.socks_addr_override = socks_addr_override;
self
}
pub fn with_port_mapping<P: Into<PortMapping>>(mut self, port_mapping: P) -> Self {
self.port_mapping = Some(port_mapping.into());
self
}
}
impl HiddenServiceBuilder {
pub fn build(self) -> Result<HiddenServiceController, HiddenServiceBuilderError> {
let proxied_port_mapping = self
.port_mapping
.ok_or(HiddenServiceBuilderError::ProxiedPortMappingNotProvided)?;
let control_server_addr = self
.control_server_addr
.ok_or(HiddenServiceBuilderError::TorControlServerAddressNotProvided)?;
debug!(
target: LOG_TARGET,
"Building tor hidden service with control port '{control_server_addr}' and port mapping '{proxied_port_mapping}'"
);
let controller = HiddenServiceController::new(
control_server_addr,
self.control_server_auth,
proxied_port_mapping,
self.socks_addr_override,
self.socks_auth,
self.identity,
self.hs_flags,
self.proxy_opts,
self.shutdown_signal,
);
Ok(controller)
}
}