author | alfadur |
Sat, 22 Feb 2025 19:39:31 +0300 | |
changeset 16120 | 5febd2bc5372 |
parent 16018 | fb389df02e3e |
permissions | -rw-r--r-- |
15543 | 1 |
use super::{indexslab::IndexSlab, types::ClientId}; |
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
2 |
use crate::core::client::HwClient; |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
3 |
use crate::core::digest::Sha1Digest; |
15543 | 4 |
use chrono::{offset, DateTime}; |
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
5 |
use std::collections::{HashMap, HashSet}; |
15543 | 6 |
use std::{iter::Iterator, num::NonZeroU16}; |
7 |
||
8 |
pub struct HwAnteroomClient { |
|
9 |
pub nick: Option<String>, |
|
10 |
pub protocol_number: Option<NonZeroU16>, |
|
11 |
pub server_salt: String, |
|
12 |
pub is_checker: bool, |
|
13 |
pub is_local_admin: bool, |
|
14 |
pub is_registered: bool, |
|
15 |
pub is_admin: bool, |
|
16 |
pub is_contributor: bool, |
|
17 |
} |
|
18 |
||
19 |
struct Ipv4AddrRange { |
|
20 |
min: [u8; 4], |
|
21 |
max: [u8; 4], |
|
22 |
} |
|
23 |
||
24 |
impl Ipv4AddrRange { |
|
25 |
fn contains(&self, addr: [u8; 4]) -> bool { |
|
26 |
(0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i]) |
|
27 |
} |
|
28 |
} |
|
29 |
||
30 |
struct BanCollection { |
|
31 |
ban_ips: Vec<Ipv4AddrRange>, |
|
32 |
ban_timeouts: Vec<DateTime<offset::Utc>>, |
|
33 |
ban_reasons: Vec<String>, |
|
34 |
} |
|
35 |
||
36 |
impl BanCollection { |
|
37 |
fn new() -> Self { |
|
16018 | 38 |
//todo!("add nick bans"); |
15543 | 39 |
Self { |
40 |
ban_ips: vec![], |
|
41 |
ban_timeouts: vec![], |
|
42 |
ban_reasons: vec![], |
|
43 |
} |
|
44 |
} |
|
45 |
||
46 |
fn find(&self, addr: [u8; 4]) -> Option<String> { |
|
47 |
let time = offset::Utc::now(); |
|
48 |
self.ban_ips |
|
49 |
.iter() |
|
50 |
.enumerate() |
|
51 |
.find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i]) |
|
52 |
.map(|(i, _)| self.ban_reasons[i].clone()) |
|
53 |
} |
|
54 |
} |
|
55 |
||
56 |
pub struct HwAnteroom { |
|
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
57 |
clients: IndexSlab<HwAnteroomClient>, |
15543 | 58 |
bans: BanCollection, |
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
59 |
taken_nicks: HashSet<String>, |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
60 |
reconnection_tokens: HashMap<String, String>, |
15543 | 61 |
} |
62 |
||
63 |
impl HwAnteroom { |
|
64 |
pub fn new(clients_limit: usize) -> Self { |
|
65 |
let clients = IndexSlab::with_capacity(clients_limit); |
|
66 |
HwAnteroom { |
|
67 |
clients, |
|
68 |
bans: BanCollection::new(), |
|
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
69 |
taken_nicks: Default::default(), |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
70 |
reconnection_tokens: Default::default(), |
15543 | 71 |
} |
72 |
} |
|
73 |
||
74 |
pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> { |
|
75 |
self.bans.find(addr) |
|
76 |
} |
|
77 |
||
78 |
pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) { |
|
79 |
let client = HwAnteroomClient { |
|
80 |
nick: None, |
|
81 |
protocol_number: None, |
|
82 |
server_salt: salt, |
|
83 |
is_checker: false, |
|
84 |
is_local_admin, |
|
85 |
is_registered: false, |
|
86 |
is_admin: false, |
|
87 |
is_contributor: false, |
|
88 |
}; |
|
89 |
self.clients.insert(client_id, client); |
|
90 |
} |
|
91 |
||
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
92 |
pub fn has_client(&self, id: ClientId) -> bool { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
93 |
self.clients.contains(id) |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
94 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
95 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
96 |
pub fn get_client(&mut self, id: ClientId) -> &HwAnteroomClient { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
97 |
&self.clients[id] |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
98 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
99 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
100 |
pub fn get_client_mut(&mut self, id: ClientId) -> &mut HwAnteroomClient { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
101 |
&mut self.clients[id] |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
102 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
103 |
|
15543 | 104 |
pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteroomClient> { |
105 |
let client = self.clients.remove(client_id); |
|
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
106 |
if let Some(HwAnteroomClient { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
107 |
nick: Some(nick), .. |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
108 |
}) = &client |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
109 |
{ |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
110 |
self.taken_nicks.remove(nick); |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
111 |
} |
15543 | 112 |
client |
113 |
} |
|
16120
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
114 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
115 |
pub fn nick_taken(&self, nick: &str) -> bool { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
116 |
self.taken_nicks.contains(nick) |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
117 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
118 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
119 |
pub fn remember_nick(&mut self, nick: String) { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
120 |
self.taken_nicks.insert(nick); |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
121 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
122 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
123 |
pub fn forget_nick(&mut self, nick: &str) { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
124 |
self.taken_nicks.remove(nick); |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
125 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
126 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
127 |
#[inline] |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
128 |
pub fn get_nick_token(&self, nick: &str) -> Option<&str> { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
129 |
self.reconnection_tokens.get(nick).map(|s| &s[..]) |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
130 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
131 |
|
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
132 |
#[inline] |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
133 |
pub fn register_nick_token(&mut self, nick: &str) -> Option<&str> { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
134 |
if self.reconnection_tokens.contains_key(nick) { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
135 |
None |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
136 |
} else { |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
137 |
let token = format!("{:x}", Sha1Digest::random()); |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
138 |
self.reconnection_tokens.insert(nick.to_string(), token); |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
139 |
Some(&self.reconnection_tokens[nick]) |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
140 |
} |
5febd2bc5372
Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents:
16018
diff
changeset
|
141 |
} |
15543 | 142 |
} |