/* * Copyright (c) 2023 Stalwart Labs Ltd. * * This file is part of Stalwart Mail Server. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * in the LICENSE file at the top-level directory of this distribution. * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * * You can be released from the requirements of the AGPLv3 license by * purchasing a commercial license. Please contact licensing@stalw.art * for more details. */ use crate::core::{throttle::ThrottleKeyHasherBuilder, TlsConnectors}; use core::{Inner, SmtpInstance, SMTP}; use common::SharedCore; use dashmap::DashMap; use mail_send::smtp::tls::build_tls_connector; use queue::manager::SpawnQueue; use reporting::scheduler::SpawnReport; use tokio::sync::mpsc; use utils::{config::Config, snowflake::SnowflakeIdGenerator}; pub mod core; pub mod inbound; pub mod outbound; pub mod queue; pub mod reporting; pub mod scripts; pub static USER_AGENT: &str = concat!("StalwartSMTP/", env!("CARGO_PKG_VERSION"),); pub static DAEMON_NAME: &str = concat!("Stalwart SMTP v", env!("CARGO_PKG_VERSION"),); impl SMTP { pub async fn init( config: &mut Config, core: SharedCore, #[cfg(feature = "local_delivery")] delivery_tx: mpsc::Sender, ) -> SmtpInstance { // Build inner let capacity = config.property("cache.capacity").unwrap_or(2); let shard = config .property::("cache.shard") .unwrap_or(32) .next_power_of_two() as usize; let (queue_tx, queue_rx) = mpsc::channel(1024); let (report_tx, report_rx) = mpsc::channel(1024); let inner = Inner { worker_pool: rayon::ThreadPoolBuilder::new() .num_threads(std::cmp::max( config .property::("global.thread-pool") .filter(|v| *v > 0) .unwrap_or_else(num_cpus::get), 4, )) .build() .unwrap(), session_throttle: DashMap::with_capacity_and_hasher_and_shard_amount( capacity, ThrottleKeyHasherBuilder::default(), shard, ), queue_throttle: DashMap::with_capacity_and_hasher_and_shard_amount( capacity, ThrottleKeyHasherBuilder::default(), shard, ), queue_tx, report_tx, snowflake_id: config .property::("cluster.node-id") .map(SnowflakeIdGenerator::with_node_id) .unwrap_or_default(), connectors: TlsConnectors { pki_verify: build_tls_connector(false), dummy_verify: build_tls_connector(true), }, #[cfg(feature = "local_delivery")] delivery_tx, }; let inner = SmtpInstance::new(core, inner); // Spawn queue manager queue_rx.spawn(inner.clone()); // Spawn report manager report_rx.spawn(inner.clone()); inner } }