rust/hedgewars-server/src/core/server.rs
changeset 15517 abd5eb807166
parent 15516 b907b9071ec5
child 15518 e705d30e0f10
--- a/rust/hedgewars-server/src/core/server.rs	Tue Dec 17 18:54:17 2019 +0300
+++ b/rust/hedgewars-server/src/core/server.rs	Thu Dec 19 23:13:58 2019 +0300
@@ -7,12 +7,11 @@
 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils};
 
 use bitflags::*;
+use chrono::{offset, DateTime};
 use log::*;
-use slab;
+use slab::Slab;
 use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace, num::NonZeroU16};
 
-type Slab<T> = slab::Slab<T>;
-
 #[derive(Debug)]
 pub enum CreateRoomError {
     InvalidName,
@@ -88,14 +87,58 @@
     pub is_contributor: bool,
 }
 
+struct Ipv4AddrRange {
+    min: [u8; 4],
+    max: [u8; 4],
+}
+
+impl Ipv4AddrRange {
+    fn contains(&self, addr: [u8; 4]) -> bool {
+        (0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i])
+    }
+}
+
+struct BanCollection {
+    ban_ips: Vec<Ipv4AddrRange>,
+    ban_timeouts: Vec<DateTime<offset::Utc>>,
+    ban_reasons: Vec<String>,
+}
+
+impl BanCollection {
+    fn new() -> Self {
+        Self {
+            ban_ips: vec![],
+            ban_timeouts: vec![],
+            ban_reasons: vec![],
+        }
+    }
+
+    fn find(&self, addr: [u8; 4]) -> Option<String> {
+        let time = offset::Utc::now();
+        self.ban_ips
+            .iter()
+            .enumerate()
+            .find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i])
+            .map(|(i, _)| self.ban_reasons[i].clone())
+    }
+}
+
 pub struct HwAnteroom {
     pub clients: IndexSlab<HwAnteClient>,
+    bans: BanCollection,
 }
 
 impl HwAnteroom {
     pub fn new(clients_limit: usize) -> Self {
         let clients = IndexSlab::with_capacity(clients_limit);
-        HwAnteroom { clients }
+        HwAnteroom {
+            clients,
+            bans: BanCollection::new(),
+        }
+    }
+
+    pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
+        self.bans.find(addr)
     }
 
     pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) {