Browse Source

master: limit amount of servers with same ip

ipv6
Denis Drakhnia 10 months ago
parent
commit
6adb2c98c3
  1. 4
      master/config/main.toml
  2. 6
      master/src/config.rs
  3. 25
      master/src/master_server.rs

4
master/config/main.toml

@ -7,13 +7,15 @@ level = "info"
[server] [server]
ip = "0.0.0.0" ip = "0.0.0.0"
port = 27010 port = 27010
# How many servers with the same ip can be registred
max-servers-per-ip = 14
[server.timeout] [server.timeout]
# Time in seconds while challenge is valid # Time in seconds while challenge is valid
challenge = 10 challenge = 10
# Time in seconds while server is valid # Time in seconds while server is valid
server = 300 server = 300
# TIme in seconds before next admin request is allowed after wrong password # Time in seconds before next admin request is allowed after wrong password
admin = 10 admin = 10
[client] [client]

6
master/src/config.rs

@ -20,6 +20,8 @@ pub const DEFAULT_CHALLENGE_TIMEOUT: u32 = 10;
pub const DEFAULT_SERVER_TIMEOUT: u32 = 300; pub const DEFAULT_SERVER_TIMEOUT: u32 = 300;
pub const DEFAULT_ADMIN_TIMEOUT: u32 = 10; pub const DEFAULT_ADMIN_TIMEOUT: u32 = 10;
pub const DEFAULT_MAX_SERVERS_PER_IP: u16 = 14;
pub const DEFAULT_HASH_LEN: usize = admin::HASH_LEN; pub const DEFAULT_HASH_LEN: usize = admin::HASH_LEN;
macro_rules! impl_helpers { macro_rules! impl_helpers {
@ -76,11 +78,14 @@ impl Default for LogConfig {
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
#[serde(rename_all = "kebab-case")]
pub struct ServerConfig { pub struct ServerConfig {
#[serde(default = "default_server_ip")] #[serde(default = "default_server_ip")]
pub ip: IpAddr, pub ip: IpAddr,
#[serde(default = "default_u16::<DEFAULT_MASTER_SERVER_PORT>")] #[serde(default = "default_u16::<DEFAULT_MASTER_SERVER_PORT>")]
pub port: u16, pub port: u16,
#[serde(default = "default_u16::<DEFAULT_MAX_SERVERS_PER_IP>")]
pub max_servers_per_ip: u16,
#[serde(default)] #[serde(default)]
pub timeout: TimeoutConfig, pub timeout: TimeoutConfig,
} }
@ -90,6 +95,7 @@ impl Default for ServerConfig {
Self { Self {
ip: default_server_ip(), ip: default_server_ip(),
port: DEFAULT_MASTER_SERVER_PORT, port: DEFAULT_MASTER_SERVER_PORT,
max_servers_per_ip: DEFAULT_MAX_SERVERS_PER_IP,
timeout: Default::default(), timeout: Default::default(),
} }
} }

25
master/src/master_server.rs

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
// SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com> // SPDX-FileCopyrightText: 2023 Denis Drakhnia <numas13@gmail.com>
use std::collections::hash_map;
use std::io; use std::io;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, ToSocketAddrs, UdpSocket}; use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, ToSocketAddrs, UdpSocket};
use std::ops::Deref; use std::ops::Deref;
@ -108,6 +109,7 @@ pub struct MasterServer {
challenges_counter: Counter, challenges_counter: Counter,
servers: HashMap<SocketAddrV4, Entry<ServerInfo>>, servers: HashMap<SocketAddrV4, Entry<ServerInfo>>,
servers_counter: Counter, servers_counter: Counter,
max_servers_per_ip: u16,
rng: Rng, rng: Rng,
start_time: Instant, start_time: Instant,
@ -180,6 +182,7 @@ impl MasterServer {
challenges_counter: Counter::new(CHALLENGE_CLEANUP_MAX), challenges_counter: Counter::new(CHALLENGE_CLEANUP_MAX),
servers: Default::default(), servers: Default::default(),
servers_counter: Counter::new(SERVER_CLEANUP_MAX), servers_counter: Counter::new(SERVER_CLEANUP_MAX),
max_servers_per_ip: cfg.server.max_servers_per_ip,
rng: Rng::new(), rng: Rng::new(),
timeout: cfg.server.timeout, timeout: cfg.server.timeout,
clver: cfg.client.version, clver: cfg.client.version,
@ -492,11 +495,25 @@ impl MasterServer {
} }
} }
fn count_servers(&self, addr: &Ipv4Addr) -> u16 {
self.servers.keys().filter(|i| i.ip() == addr).count() as u16
}
fn add_server(&mut self, addr: SocketAddrV4, server: ServerInfo) { fn add_server(&mut self, addr: SocketAddrV4, server: ServerInfo) {
let entry = Entry::new(self.now(), server); let now = self.now();
match self.servers.insert(addr, entry) { match self.servers.entry(addr) {
Some(_) => trace!("{}: Updated GameServer", addr), hash_map::Entry::Occupied(mut e) => {
None => trace!("{}: New GameServer", addr), trace!("{}: Updated GameServer", addr);
e.insert(Entry::new(now, server));
}
hash_map::Entry::Vacant(_) => {
if self.count_servers(addr.ip()) >= self.max_servers_per_ip {
trace!("{}: max servers per ip", addr);
return;
}
trace!("{}: New GameServer", addr);
self.servers.insert(addr, Entry::new(now, server));
}
} }
} }

Loading…
Cancel
Save