use crate::deps::lair_keystore_api;
use crate::deps::sodoken;
use crate::*;
use lair_keystore_api::prelude::*;
use std::sync::{Arc, Weak};
use tx5_core::{BoxFut, Tx5Url};
pub trait Config: 'static + Send + Sync {
fn max_send_bytes(&self) -> u32;
fn max_recv_bytes(&self) -> u32;
fn max_conn_count(&self) -> u32;
fn max_conn_init(&self) -> std::time::Duration;
fn metrics(&self) -> &prometheus::Registry;
fn lair_client(&self) -> &LairClient;
fn lair_tag(&self) -> &Arc<str>;
fn on_new_sig(&self, sig_url: Tx5Url, seed: state::SigStateSeed);
fn on_new_conn(
&self,
ice_servers: serde_json::Value,
seed: state::ConnStateSeed,
);
}
pub type DynConfig = Arc<dyn Config + 'static + Send + Sync>;
impl std::fmt::Debug for dyn Config + 'static + Send + Sync {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Config")
.field("max_send_bytes", &self.max_send_bytes())
.field("max_recv_bytes", &self.max_recv_bytes())
.field("max_conn_count", &self.max_conn_count())
.finish()
}
}
pub trait IntoConfig: 'static + Send + Sync {
fn into_config(self) -> BoxFut<'static, Result<DynConfig>>;
}
struct DefConfigBuilt {
this: Weak<Self>,
max_send_bytes: u32,
max_recv_bytes: u32,
max_conn_count: u32,
max_conn_init: std::time::Duration,
metrics: prometheus::Registry,
_lair_keystore: Option<lair_keystore_api::in_proc_keystore::InProcKeystore>,
lair_client: LairClient,
lair_tag: Arc<str>,
on_new_sig_cb: Arc<
dyn Fn(DynConfig, Tx5Url, state::SigStateSeed) + 'static + Send + Sync,
>,
on_new_conn_cb: Arc<
dyn Fn(DynConfig, serde_json::Value, state::ConnStateSeed)
+ 'static
+ Send
+ Sync,
>,
}
impl Config for DefConfigBuilt {
fn max_send_bytes(&self) -> u32 {
self.max_send_bytes
}
fn max_recv_bytes(&self) -> u32 {
self.max_recv_bytes
}
fn max_conn_count(&self) -> u32 {
self.max_conn_count
}
fn max_conn_init(&self) -> std::time::Duration {
self.max_conn_init
}
fn metrics(&self) -> &prometheus::Registry {
&self.metrics
}
fn lair_client(&self) -> &LairClient {
&self.lair_client
}
fn lair_tag(&self) -> &Arc<str> {
&self.lair_tag
}
fn on_new_sig(&self, sig_url: Tx5Url, seed: state::SigStateSeed) {
if let Some(this) = self.this.upgrade() {
(self.on_new_sig_cb)(this, sig_url, seed);
}
}
fn on_new_conn(
&self,
ice_servers: serde_json::Value,
seed: state::ConnStateSeed,
) {
if let Some(this) = self.this.upgrade() {
(self.on_new_conn_cb)(this, ice_servers, seed);
}
}
}
#[derive(Default)]
#[allow(clippy::type_complexity)]
pub struct DefConfig {
max_send_bytes: Option<u32>,
max_recv_bytes: Option<u32>,
max_conn_count: Option<u32>,
max_conn_init: Option<std::time::Duration>,
metrics: Option<prometheus::Registry>,
lair_client: Option<LairClient>,
lair_tag: Option<Arc<str>>,
on_new_sig_cb: Option<
Arc<
dyn Fn(DynConfig, Tx5Url, state::SigStateSeed)
+ 'static
+ Send
+ Sync,
>,
>,
on_new_conn_cb: Option<
Arc<
dyn Fn(DynConfig, serde_json::Value, state::ConnStateSeed)
+ 'static
+ Send
+ Sync,
>,
>,
}
impl IntoConfig for DefConfig {
fn into_config(self) -> BoxFut<'static, Result<DynConfig>> {
Box::pin(async move {
let max_send_bytes =
self.max_send_bytes.unwrap_or(16 * 1024 * 1024);
let max_recv_bytes =
self.max_recv_bytes.unwrap_or(16 * 1024 * 1024);
let max_conn_count = self.max_conn_count.unwrap_or(40);
let max_conn_init = self
.max_conn_init
.unwrap_or(std::time::Duration::from_secs(20));
let metrics = self
.metrics
.unwrap_or_else(|| prometheus::default_registry().clone());
let mut lair_keystore = None;
let lair_tag = self.lair_tag.unwrap_or_else(|| {
rand_utf8::rand_utf8(&mut rand::thread_rng(), 32).into()
});
let lair_client = match self.lair_client {
Some(lair_client) => lair_client,
None => {
let passphrase = sodoken::BufRead::new_no_lock(
rand_utf8::rand_utf8(&mut rand::thread_rng(), 32)
.as_bytes(),
);
let keystore_config = PwHashLimits::Minimum
.with_exec(|| {
LairServerConfigInner::new("/", passphrase.clone())
})
.await
.unwrap();
let keystore = PwHashLimits::Minimum
.with_exec(|| {
lair_keystore_api::in_proc_keystore::InProcKeystore::new(
Arc::new(keystore_config),
lair_keystore_api::mem_store::create_mem_store_factory(),
passphrase,
)
})
.await
.unwrap();
let lair_client = keystore.new_client().await.unwrap();
lair_client
.new_seed(lair_tag.clone(), None, false)
.await
.unwrap();
lair_keystore = Some(keystore);
lair_client
}
};
let on_new_sig_cb = self
.on_new_sig_cb
.unwrap_or_else(|| Arc::new(endpoint::on_new_sig));
let on_new_conn_cb = self
.on_new_conn_cb
.unwrap_or_else(|| Arc::new(endpoint::on_new_conn));
let out: DynConfig = Arc::new_cyclic(|this| DefConfigBuilt {
this: this.clone(),
max_send_bytes,
max_recv_bytes,
max_conn_count,
max_conn_init,
metrics,
_lair_keystore: lair_keystore,
lair_client,
lair_tag,
on_new_sig_cb,
on_new_conn_cb,
});
Ok(out)
})
}
}
impl DefConfig {
pub fn set_max_send_bytes(&mut self, max_send_bytes: u32) {
self.max_send_bytes = Some(max_send_bytes);
}
pub fn with_max_send_bytes(mut self, max_send_bytes: u32) -> Self {
self.set_max_send_bytes(max_send_bytes);
self
}
pub fn set_max_recv_bytes(&mut self, max_recv_bytes: u32) {
self.max_recv_bytes = Some(max_recv_bytes);
}
pub fn with_max_recv_bytes(mut self, max_recv_bytes: u32) -> Self {
self.set_max_recv_bytes(max_recv_bytes);
self
}
pub fn set_max_conn_count(&mut self, max_conn_count: u32) {
self.max_conn_count = Some(max_conn_count);
}
pub fn with_max_conn_count(mut self, max_conn_count: u32) -> Self {
self.set_max_conn_count(max_conn_count);
self
}
pub fn set_max_conn_init(&mut self, max_conn_init: std::time::Duration) {
self.max_conn_init = Some(max_conn_init);
}
pub fn with_max_conn_init(
mut self,
max_conn_init: std::time::Duration,
) -> Self {
self.set_max_conn_init(max_conn_init);
self
}
pub fn set_metrics(&mut self, metrics: prometheus::Registry) {
self.metrics = Some(metrics);
}
pub fn with_metrics(mut self, metrics: prometheus::Registry) -> Self {
self.set_metrics(metrics);
self
}
pub fn set_lair_client(&mut self, lair_client: LairClient) {
self.lair_client = Some(lair_client);
}
pub fn with_lair_client(mut self, lair_client: LairClient) -> Self {
self.set_lair_client(lair_client);
self
}
pub fn set_lair_tag(&mut self, lair_tag: Arc<str>) {
self.lair_tag = Some(lair_tag);
}
pub fn with_lair_tag(mut self, lair_tag: Arc<str>) -> Self {
self.set_lair_tag(lair_tag);
self
}
pub fn set_new_sig_cb<Cb>(&mut self, cb: Cb)
where
Cb: Fn(DynConfig, Tx5Url, state::SigStateSeed) + 'static + Send + Sync,
{
self.on_new_sig_cb = Some(Arc::new(cb));
}
pub fn with_new_sig_cb<Cb>(mut self, cb: Cb) -> Self
where
Cb: Fn(DynConfig, Tx5Url, state::SigStateSeed) + 'static + Send + Sync,
{
self.set_new_sig_cb(cb);
self
}
pub fn set_new_conn_cb<Cb>(&mut self, cb: Cb)
where
Cb: Fn(DynConfig, serde_json::Value, state::ConnStateSeed)
+ 'static
+ Send
+ Sync,
{
self.on_new_conn_cb = Some(Arc::new(cb));
}
pub fn with_new_conn_cb<Cb>(mut self, cb: Cb) -> Self
where
Cb: Fn(DynConfig, serde_json::Value, state::ConnStateSeed)
+ 'static
+ Send
+ Sync,
{
self.set_new_conn_cb(cb);
self
}
}