Gossip service implementation for cluster node autodiscovery with failure detection
This commit is contained in:
@@ -1,3 +1,26 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 std::borrow::Cow;
|
||||
|
||||
use directory::Directory;
|
||||
|
||||
@@ -576,24 +576,6 @@ impl Display for Variable<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
trait IntoBool {
|
||||
fn into_bool(self) -> bool;
|
||||
}
|
||||
|
||||
impl IntoBool for f64 {
|
||||
#[inline(always)]
|
||||
fn into_bool(self) -> bool {
|
||||
self != 0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoBool for i64 {
|
||||
#[inline(always)]
|
||||
fn into_bool(self) -> bool {
|
||||
self != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x> From<&'x Constant> for Variable<'x> {
|
||||
fn from(value: &'x Constant) -> Self {
|
||||
match value {
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
/*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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 std::{borrow::Cow, net::IpAddr, sync::Arc};
|
||||
|
||||
use arc_swap::ArcSwap;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
use std::{fmt::Debug, net::IpAddr};
|
||||
use std::{fmt::Debug, net::IpAddr, sync::atomic::AtomicU8};
|
||||
|
||||
use ahash::AHashSet;
|
||||
use parking_lot::RwLock;
|
||||
@@ -35,6 +35,7 @@ use crate::Core;
|
||||
|
||||
pub struct BlockedIps {
|
||||
pub ip_addresses: RwLock<AHashSet<IpAddr>>,
|
||||
pub version: AtomicU8,
|
||||
ip_networks: Vec<IpAddrMask>,
|
||||
has_networks: bool,
|
||||
limiter_rate: Option<Rate>,
|
||||
@@ -71,6 +72,7 @@ impl BlockedIps {
|
||||
has_networks: !ip_networks.is_empty(),
|
||||
ip_networks,
|
||||
limiter_rate: config.property_or_default::<Rate>("authentication.fail2ban", "100/1d"),
|
||||
version: 0.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +105,9 @@ impl Core {
|
||||
}])
|
||||
.await?;
|
||||
|
||||
// Increment version
|
||||
self.network.blocked_ips.increment_version();
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
@@ -126,6 +131,13 @@ impl Core {
|
||||
}
|
||||
}
|
||||
|
||||
impl BlockedIps {
|
||||
pub fn increment_version(&self) {
|
||||
self.version
|
||||
.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for BlockedIps {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
@@ -133,6 +145,7 @@ impl Default for BlockedIps {
|
||||
ip_networks: Default::default(),
|
||||
has_networks: Default::default(),
|
||||
limiter_rate: Default::default(),
|
||||
version: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,6 +157,10 @@ impl Clone for BlockedIps {
|
||||
ip_networks: self.ip_networks.clone(),
|
||||
has_networks: self.has_networks,
|
||||
limiter_rate: self.limiter_rate.clone(),
|
||||
version: self
|
||||
.version
|
||||
.load(std::sync::atomic::Ordering::Relaxed)
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ impl Servers {
|
||||
pub fn spawn(
|
||||
mut self,
|
||||
spawn: impl Fn(Server, TcpAcceptor, watch::Receiver<bool>),
|
||||
) -> watch::Sender<bool> {
|
||||
) -> (watch::Sender<bool>, watch::Receiver<bool>) {
|
||||
// Spawn listeners
|
||||
let (shutdown_tx, shutdown_rx) = watch::channel(false);
|
||||
for server in self.servers {
|
||||
@@ -336,7 +336,7 @@ impl Servers {
|
||||
|
||||
spawn(server, acceptor, shutdown_rx.clone());
|
||||
}
|
||||
shutdown_tx
|
||||
(shutdown_tx, shutdown_rx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -221,6 +221,22 @@ impl BootManager {
|
||||
)));
|
||||
}
|
||||
|
||||
// Generate a Cluster encryption key if missing
|
||||
if config
|
||||
.value("cluster.key")
|
||||
.filter(|v| !v.is_empty())
|
||||
.is_none()
|
||||
{
|
||||
insert_keys.push(ConfigKey::from((
|
||||
"cluster.key",
|
||||
thread_rng()
|
||||
.sample_iter(Alphanumeric)
|
||||
.take(64)
|
||||
.map(char::from)
|
||||
.collect::<String>(),
|
||||
)));
|
||||
}
|
||||
|
||||
// Download SPAM filters if missing
|
||||
if config
|
||||
.value("version.spam-filter")
|
||||
|
||||
Reference in New Issue
Block a user