5 types::{ClientId, RoomId, ServerVar}, |
5 types::{ClientId, RoomId, ServerVar}, |
6 }; |
6 }; |
7 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils}; |
7 use crate::{protocol::messages::HwProtocolMessage::Greeting, utils}; |
8 |
8 |
9 use bitflags::*; |
9 use bitflags::*; |
|
10 use chrono::{offset, DateTime}; |
10 use log::*; |
11 use log::*; |
11 use slab; |
12 use slab::Slab; |
12 use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace, num::NonZeroU16}; |
13 use std::{borrow::BorrowMut, collections::HashSet, iter, mem::replace, num::NonZeroU16}; |
13 |
|
14 type Slab<T> = slab::Slab<T>; |
|
15 |
14 |
16 #[derive(Debug)] |
15 #[derive(Debug)] |
17 pub enum CreateRoomError { |
16 pub enum CreateRoomError { |
18 InvalidName, |
17 InvalidName, |
19 AlreadyExists, |
18 AlreadyExists, |
86 pub is_registered: bool, |
85 pub is_registered: bool, |
87 pub is_admin: bool, |
86 pub is_admin: bool, |
88 pub is_contributor: bool, |
87 pub is_contributor: bool, |
89 } |
88 } |
90 |
89 |
|
90 struct Ipv4AddrRange { |
|
91 min: [u8; 4], |
|
92 max: [u8; 4], |
|
93 } |
|
94 |
|
95 impl Ipv4AddrRange { |
|
96 fn contains(&self, addr: [u8; 4]) -> bool { |
|
97 (0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i]) |
|
98 } |
|
99 } |
|
100 |
|
101 struct BanCollection { |
|
102 ban_ips: Vec<Ipv4AddrRange>, |
|
103 ban_timeouts: Vec<DateTime<offset::Utc>>, |
|
104 ban_reasons: Vec<String>, |
|
105 } |
|
106 |
|
107 impl BanCollection { |
|
108 fn new() -> Self { |
|
109 Self { |
|
110 ban_ips: vec![], |
|
111 ban_timeouts: vec![], |
|
112 ban_reasons: vec![], |
|
113 } |
|
114 } |
|
115 |
|
116 fn find(&self, addr: [u8; 4]) -> Option<String> { |
|
117 let time = offset::Utc::now(); |
|
118 self.ban_ips |
|
119 .iter() |
|
120 .enumerate() |
|
121 .find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i]) |
|
122 .map(|(i, _)| self.ban_reasons[i].clone()) |
|
123 } |
|
124 } |
|
125 |
91 pub struct HwAnteroom { |
126 pub struct HwAnteroom { |
92 pub clients: IndexSlab<HwAnteClient>, |
127 pub clients: IndexSlab<HwAnteClient>, |
|
128 bans: BanCollection, |
93 } |
129 } |
94 |
130 |
95 impl HwAnteroom { |
131 impl HwAnteroom { |
96 pub fn new(clients_limit: usize) -> Self { |
132 pub fn new(clients_limit: usize) -> Self { |
97 let clients = IndexSlab::with_capacity(clients_limit); |
133 let clients = IndexSlab::with_capacity(clients_limit); |
98 HwAnteroom { clients } |
134 HwAnteroom { |
|
135 clients, |
|
136 bans: BanCollection::new(), |
|
137 } |
|
138 } |
|
139 |
|
140 pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> { |
|
141 self.bans.find(addr) |
99 } |
142 } |
100 |
143 |
101 pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) { |
144 pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) { |
102 let client = HwAnteClient { |
145 let client = HwAnteClient { |
103 nick: None, |
146 nick: None, |