use crate::config::signer::SignerClientConfig;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct SignalingConfig {
#[serde(default)]
pub server: SignalingServerConfig,
#[serde(default)]
pub dependencies: SignalingDependencies,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct SignalingServerConfig {
pub ws_path: String,
#[serde(default)]
pub rate_limit: RateLimitConfig,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct RateLimitConfig {
#[serde(default)]
pub connection: ConnectionRateLimit,
#[serde(default)]
pub message: MessageRateLimit,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ConnectionRateLimit {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_connections_per_minute")]
pub per_minute: u32,
#[serde(default = "default_connection_burst")]
pub burst_size: u32,
#[serde(default = "default_max_concurrent_connections")]
pub max_concurrent_per_ip: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MessageRateLimit {
#[serde(default = "default_true")]
pub enabled: bool,
#[serde(default = "default_messages_per_second")]
pub per_second: u32,
#[serde(default = "default_message_burst")]
pub burst_size: u32,
}
fn default_true() -> bool {
true
}
fn default_connections_per_minute() -> u32 {
5
}
fn default_connection_burst() -> u32 {
10
}
fn default_max_concurrent_connections() -> u32 {
100
}
fn default_messages_per_second() -> u32 {
10
}
fn default_message_burst() -> u32 {
50
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct SignalingDependencies {
#[serde(default)]
pub signer: Option<SignerClientConfig>,
#[serde(default)]
pub ais: Option<AisClientConfig>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AisClientConfig {
pub endpoint: String,
#[serde(default = "default_timeout")]
pub timeout_seconds: u64,
}
fn default_timeout() -> u64 {
30
}
impl Default for SignalingServerConfig {
fn default() -> Self {
Self {
ws_path: "/signaling".to_string(),
rate_limit: RateLimitConfig::default(),
}
}
}
impl Default for ConnectionRateLimit {
fn default() -> Self {
Self {
enabled: default_true(),
per_minute: default_connections_per_minute(),
burst_size: default_connection_burst(),
max_concurrent_per_ip: default_max_concurrent_connections(),
}
}
}
impl Default for MessageRateLimit {
fn default() -> Self {
Self {
enabled: default_true(),
per_second: default_messages_per_second(),
burst_size: default_message_burst(),
}
}
}
impl SignalingConfig {
pub fn get_signer_client_config(
&self,
global_config: &super::ActrixConfig,
) -> Option<SignerClientConfig> {
if let Some(ref signer_config) = self.dependencies.signer {
return Some(signer_config.clone());
}
if global_config.is_signer_enabled() && global_config.services.signer.is_some() {
let http_cfg = global_config.bind.http.as_ref();
let port = http_cfg.map(|h| h.port).unwrap_or(8080);
let use_tls = http_cfg.is_some_and(|h| h.is_tls());
let protocol = if use_tls { "https" } else { "http" };
let tls_domain = if use_tls {
http_cfg.map(|h| h.domain_name.clone())
} else {
None
};
return Some(SignerClientConfig {
endpoint: format!("{protocol}://127.0.0.1:{port}"),
timeout_seconds: 30,
enable_tls: use_tls,
tls_domain,
ca_cert: None,
client_cert: None,
client_key: None,
});
}
None
}
pub fn get_ais_client_config(
&self,
global_config: &super::ActrixConfig,
) -> Option<AisClientConfig> {
if let Some(ref ais_config) = self.dependencies.ais {
return Some(ais_config.clone());
}
if global_config.is_ais_enabled() && global_config.services.ais.is_some() {
let http_cfg = global_config.bind.http.as_ref();
let port = http_cfg.map(|h| h.port).unwrap_or(8080);
let protocol = if http_cfg.is_some_and(|h| h.is_tls()) {
"https"
} else {
"http"
};
return Some(AisClientConfig {
endpoint: format!("{protocol}://127.0.0.1:{port}"),
timeout_seconds: 30,
});
}
None
}
}