use serde::{Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum SecurityLevel {
#[default]
Strict,
Balanced,
Trusted,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ThroughputPolicy {
pub per_peer_messages_per_minute: u32,
pub per_peer_bytes_per_minute: u64,
pub global_messages_per_minute: u32,
pub global_bytes_per_minute: u64,
pub max_forward_actions: usize,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SpamPolicy {
pub min_intrinsic_dependence: f64,
pub max_match_distance: f64,
pub intrinsic_dependence_order: i64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TrustPolicy {
pub min_reputation_score: f64,
pub require_signatures_from_known_peers: bool,
pub reject_signed_without_known_key: bool,
pub allow_unsigned_from_unknown_peers: bool,
pub max_outbound_inbound_ratio: f64,
#[serde(default)]
pub auto_key_exchange_mode: AutoKeyExchangeMode,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum AutoKeyExchangeMode {
#[default]
Rsa,
Dh,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ContentPolicy {
pub max_message_bytes: usize,
pub max_body_bytes: usize,
pub max_header_ids: usize,
pub allow_binary_payloads: bool,
pub block_executable_magic: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RoutingPolicy {
pub security_level: SecurityLevel,
pub throughput: ThroughputPolicy,
pub spam: SpamPolicy,
pub trust: TrustPolicy,
pub content: ContentPolicy,
pub cache_max_messages: usize,
pub cache_max_bytes: usize,
}
impl RoutingPolicy {
#[must_use]
pub fn for_level(level: SecurityLevel) -> Self {
match level {
SecurityLevel::Strict => Self {
security_level: level,
throughput: ThroughputPolicy {
per_peer_messages_per_minute: 240,
per_peer_bytes_per_minute: 8 * 1024 * 1024,
global_messages_per_minute: 20_000,
global_bytes_per_minute: 512 * 1024 * 1024,
max_forward_actions: 64,
},
spam: SpamPolicy {
min_intrinsic_dependence: 0.02,
max_match_distance: 500.0,
intrinsic_dependence_order: 8,
},
trust: TrustPolicy {
min_reputation_score: -20.0,
require_signatures_from_known_peers: true,
reject_signed_without_known_key: true,
allow_unsigned_from_unknown_peers: true,
max_outbound_inbound_ratio: 1.8,
auto_key_exchange_mode: AutoKeyExchangeMode::Rsa,
},
content: ContentPolicy {
max_message_bytes: 4 * 1024 * 1024,
max_body_bytes: 2 * 1024 * 1024,
max_header_ids: 1024,
allow_binary_payloads: true,
block_executable_magic: true,
},
cache_max_messages: 200_000,
cache_max_bytes: 2 * 1024 * 1024 * 1024,
},
SecurityLevel::Balanced => Self {
security_level: level,
throughput: ThroughputPolicy {
per_peer_messages_per_minute: 600,
per_peer_bytes_per_minute: 16 * 1024 * 1024,
global_messages_per_minute: 40_000,
global_bytes_per_minute: 1024 * 1024 * 1024,
max_forward_actions: 128,
},
spam: SpamPolicy {
min_intrinsic_dependence: 0.01,
max_match_distance: 700.0,
intrinsic_dependence_order: 8,
},
trust: TrustPolicy {
min_reputation_score: -40.0,
require_signatures_from_known_peers: true,
reject_signed_without_known_key: false,
allow_unsigned_from_unknown_peers: true,
max_outbound_inbound_ratio: 2.5,
auto_key_exchange_mode: AutoKeyExchangeMode::Rsa,
},
content: ContentPolicy {
max_message_bytes: 8 * 1024 * 1024,
max_body_bytes: 4 * 1024 * 1024,
max_header_ids: 2048,
allow_binary_payloads: true,
block_executable_magic: true,
},
cache_max_messages: 400_000,
cache_max_bytes: 4 * 1024 * 1024 * 1024,
},
SecurityLevel::Trusted => Self {
security_level: level,
throughput: ThroughputPolicy {
per_peer_messages_per_minute: 6_000,
per_peer_bytes_per_minute: 128 * 1024 * 1024,
global_messages_per_minute: 200_000,
global_bytes_per_minute: 8 * 1024 * 1024 * 1024,
max_forward_actions: 512,
},
spam: SpamPolicy {
min_intrinsic_dependence: 0.0,
max_match_distance: 800.0,
intrinsic_dependence_order: 8,
},
trust: TrustPolicy {
min_reputation_score: -80.0,
require_signatures_from_known_peers: false,
reject_signed_without_known_key: false,
allow_unsigned_from_unknown_peers: true,
max_outbound_inbound_ratio: 4.0,
auto_key_exchange_mode: AutoKeyExchangeMode::Rsa,
},
content: ContentPolicy {
max_message_bytes: 16 * 1024 * 1024,
max_body_bytes: 12 * 1024 * 1024,
max_header_ids: 4096,
allow_binary_payloads: true,
block_executable_magic: false,
},
cache_max_messages: 1_000_000,
cache_max_bytes: 16 * 1024 * 1024 * 1024,
},
}
}
}
impl Default for RoutingPolicy {
fn default() -> Self {
Self::for_level(SecurityLevel::Strict)
}
}