Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_shield/src/srv/cfg.rs

12.5 KiB, 68 runs

created by r1870400018:858, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use crate::{
2 srv::constant,
3 //packet::PacketValidator,
4 //schemes::{
5 // WireSchemes,
6 //},
7};
8
9use oxedyne_fe2o3_core::{
10 prelude::*,
11 path::NormPathBuf,
12 //alt::DefAlt,
13};
14use oxedyne_fe2o3_crypto::sign::SignatureScheme;
15//use oxedyne_fe2o3_iop_crypto::{
16// sign::{
17// Signer,
18// SignerDefAlt,
19// },
20// enc::Encrypter,
21//};
22use oxedyne_fe2o3_jdat::{
23 prelude::*,
24 cfg::Config,
25 chunk::{
26 Chunker,
27 ChunkConfig,
28 },
29 //file::JdatFile,
30};
31use oxedyne_fe2o3_hash::{
32 hash::{
33 HashScheme,
34 //HasherDefAlt,
35 },
36 //pow::ProofOfWork,
37};
38//use oxedyne_fe2o3_iop_hash::{
39// api::Hasher,
40// csum::Checksummer,
41//};
42
43use std::{
44 collections::BTreeMap,
45 net::{
46 IpAddr,
47 SocketAddr,
48 ToSocketAddrs,
49 },
50 str::FromStr,
51};
52
53use local_ip_address::local_ip;
54
55
56#[derive(Clone, Debug, Eq, PartialEq, FromDatMap, ToDatMap)]
57pub struct ServerConfig {
58 // Schemes
59 pub schemes_db_path: String,
60 // Chunking
61 pub wire_chunk_threshold: u64, // applies only to values
62 pub wire_chunk_bytes: u64,
63 // Server
64 pub log_level: String,
65 pub server_address: String,
66 pub server_port_udp: u16,
67 pub server_rps_zbits_profile: u8, // 0 = linear, ..
68 pub server_pow_zbits_min: u16, // min zero bits for all packet pows
69 pub server_pow_zbits_max: u16, // when rps reaches max, the reqd pow zbit reaches this level
70 pub server_pow_time_horiz_secs: u64, // timestamp must be no older in seconds to now
71 pub server_rps_max: u16, // the requests per second corresponding to maximum pow zbits
72 //pub packet_pow_hash_scheme: String,
73 //pub packet_signature_scheme: String,
74 pub addr_guard_map_bins: u32, // Number of bins in shared map of incoming addresses.
75 pub user_guard_map_bins: u32, // Number of bins in shared map of users.
76 pub msg_assembler_map_bins: u32, // Number of bins in shared map of message pieces.
77 // Server policy
78 // An attacker can flood us with HReq1 messages with random uids and public keys. A reasonable
79 // defence is to set a relatively high difficulty for HReq1.
80 pub server_accept_unknown_users: bool,
81 pub trusted_seeds: Vec<String>,
82}
83
84impl Config for ServerConfig {
85
86 fn check_and_fix(&mut self) -> Outcome<()> {
87 // Checks that read only.
88 res!(self.check_wire_chunk_config(&self.chunk_config()));
89 Ok(())
90 }
91}
92
93impl Default for ServerConfig {
94 fn default() -> Self {
95 Self {
96 // Schemes
97 schemes_db_path: fmt!("../oxedyne_fe2o3_namex/namex.jdat"),
98 // Chunking
99 wire_chunk_threshold: 1_500,
100 wire_chunk_bytes: 1_000,
101 // Server
102 log_level: fmt!("debug"),
103 server_address: fmt!("127.0.0.1"),
104 server_port_udp: 60000, // numeric keypad mapping for "o3db"
105 server_rps_zbits_profile: 0, // 0 = linear, ..
106 server_pow_zbits_min: 2, // all packets must have a proof of work with at least this many zero bits
107 server_pow_zbits_max: 15, // when rps reaches max, the reqd pow zbit reaches this level
108 server_pow_time_horiz_secs: 600, // timestamp must be no older in seconds to now
109 server_rps_max: 30_000, // the requests per second corresponding to maximum pow zbits
110 //packet_pow_hash_scheme: fmt!("Seahash"),
111 //packet_signature_scheme: fmt!("Ed25519"), // try SIKE
112 addr_guard_map_bins: 128, // arbitrary
113 user_guard_map_bins: 128, // arbitrary
114 msg_assembler_map_bins: 128, // arbitrary
115 // Server policy.
116 server_accept_unknown_users: false,
117 trusted_seeds: vec![],
118 }
119 }
120}
121
122impl ServerConfig {
123
124 pub fn validate(
125 &self,
126 _root: &NormPathBuf,
127 )
128 -> Outcome<()>
129 {
130 Ok(())
131 }
132
133 pub fn try_default() -> Outcome<Self> {
134 Ok(Self::default())
135 }
136
137 pub fn bind_ip(&self) -> Outcome<IpAddr> {
138 let raw = self.server_address.trim();
139 if raw.is_empty() || raw.eq_ignore_ascii_case("local") {
140 return Ok(res!(local_ip(), IO, Network));
141 }
142 match IpAddr::from_str(raw) {
143 Ok(ip) => Ok(ip),
144 Err(e) => Err(err!(e,
145 "ServerConfig: server_address '{}' is neither an IP address nor the \
146 word 'local'.", self.server_address;
147 Invalid, Input, Network)),
148 }
149 }
150
151 //pub fn syntax_default() -> Outcome<SyntaxRef> {
152 // let syntax = SyntaxRef(Arc::new(res!(syntax::build())));
153 // Ok(syntax)
154 //}
155
156 /// Hard-wired default proof of work hash scheme.
157 pub fn default_packet_pow_hash_scheme() -> Option<HashScheme> {
158 Some(HashScheme::new_seahash())
159 }
160
161 /// Hard-wired default signature scheme.
162 pub fn default_packet_signature_scheme() -> Option<SignatureScheme> {
163 Some(SignatureScheme::empty_ed25519())
164 }
165
166 //// Data scheme updaters.
167 //pub fn update_packet_validator<
168 // WENC: Encrypter,
169 // WCS: Checksummer,
170 // POWH: Hasher,
171 // SGN: Signer,
172 // HS: Encrypter,
173 // //// Proof of work validation.
174 // //const N: usize, // Pristine + Nonce size.
175 // //const P0: usize, // Length of pristine prefix bytes (i.e. not included in artefact).
176 // //const P1: usize, // Length of pristine bytes (i.e. included in artefact).
177 // //PRIS: Pristine<P0, P1>, // Pristine supplied to hasher.
178 //>(
179 // &self,
180 // wschms: &WireSchemes<WENC, WCS, POWH, SGN, HS>,
181 //)
182 // -> Outcome<PacketValidator<
183 // HasherDefAlt<HashScheme, POWH>,
184 // SignerDefAlt<SignatureScheme, SGN>,
185 // >>
186 //{
187 // let pow_def_alt = res!(Self::read_hash_scheme(
188 // &self.packet_pow_hash_scheme,
189 // &*wschms.powh,
190 // Self::default_packet_pow_hash_scheme,
191 // "packet_pow_hash_scheme",
192 // ));
193 // let sig_def_alt = res!(Self::read_signature_scheme(
194 // &self.packet_signature_scheme,
195 // &*wschms.sign,
196 // Self::default_packet_signature_scheme,
197 // "packet_signature_scheme",
198 // ));
199 // Ok(PacketValidator {
200 // pow: match pow_def_alt {
201 // DefAlt::Given(..) | DefAlt::Default(..) =>
202 // Some(ProofOfWork::new(HasherDefAlt(pow_def_alt))),
203 // DefAlt::None => None,
204 // },
205 // sig: match sig_def_alt {
206 // DefAlt::Given(..) | DefAlt::Default(..) =>
207 // Some(SignerDefAlt(sig_def_alt)),
208 // DefAlt::None => None,
209 // },
210 // })
211 //}
212
213 /// Return a rest chunk configuration from the database configuration.
214 pub fn chunk_config(&self) -> ChunkConfig {
215 ChunkConfig {
216 threshold_bytes: self.wire_chunk_threshold as usize,
217 chunk_size: self.wire_chunk_bytes as usize,
218 dat_wrap: false,
219 pad_last: true,
220 }
221 }
222
223 pub fn chunker(cfg: ChunkConfig) -> Chunker {
224 Chunker::default().set_config(cfg)
225 }
226
227 pub fn wire_chunk_size(&self) -> usize { self.wire_chunk_bytes as usize }
228 pub fn wire_chunking_threshold(&self) -> usize { self.wire_chunk_threshold as usize }
229
230 pub fn new_chunk_cfg(
231 threshold_bytes: usize,
232 chunk_size: usize,
233 dat_wrap: bool,
234 pad_last: bool,
235 )
236 -> ChunkConfig
237 {
238 ChunkConfig {
239 threshold_bytes,
240 chunk_size,
241 dat_wrap,
242 pad_last,
243 }
244 }
245
246 pub fn chunker_default(&self) -> ChunkConfig {
247 ChunkConfig {
248 threshold_bytes: self.wire_chunk_threshold as usize,
249 chunk_size: self.wire_chunk_bytes as usize,
250 dat_wrap: false,
251 pad_last: true,
252 }
253 }
254
255 pub fn check_wire_chunk_config(&self, chunk_cfg: &ChunkConfig) -> Outcome<()> {
256 if chunk_cfg.chunk_size > u16::MAX as usize {
257 return Err(err!(
258 "Chunk size of {} is less than the current minimum of {}.",
259 chunk_cfg.chunk_size, constant::MIN_CHUNK_SIZE;
260 TooBig, Configuration));
261 }
262 Ok(())
263 }
264
265 pub fn dump(self) -> Outcome<()> {
266 let dat = Self::to_datmap(self);
267 for line in dat.to_lines(" ", true) {
268 info!(async_log::stream(), "{}", line);
269 }
270 Ok(())
271 }
272
273 // Servers.
274 pub fn addr_guard_map_bins(&self) -> u32 {
275 self.addr_guard_map_bins
276 }
277
278 pub fn user_guard_map_bins(&self) -> u32 {
279 self.user_guard_map_bins
280 }
281
282 pub fn msg_assembler_map_bins(&self) -> u32 {
283 self.msg_assembler_map_bins
284 }
285
286 ///// Build the `PacketValidator`
287 //pub fn packet_validator<
288 // // Proof of work validator.
289 // H: Hasher + Send + 'static, // Proof of work hasher.
290 // const N: usize, // Pristine + Nonce size.
291 // const P0: usize, // Length of pristine prefix bytes (i.e. not included in artefact).
292 // const P1: usize, // Length of pristine bytes (i.e. included in artefact).
293 // PRIS: Pristine<P0, P1>, // Pristine supplied to hasher.
294 // // Digital signature validation.
295 // S: Signer,
296 //>(
297 // &self,
298 // pow_opt: Option<(ProofOfWork<HasherDefAlt<HashScheme, POWH>>, PowParams<P0, P1, PRIS>)>,
299 // sigpk_opt: Option<Vec<u8>>,
300 //)
301 // -> Outcome<PacketValidator>
302 //{
303 // Ok(PacketValidator {
304 // pow: match self.packet_pow_hash_schemevalidation {
305 // true => match pvars_opt {
306 // Some(pvars) => (
307 // ProofOfWork::new(HashScheme::new_seahash()),
308 // PowParams {
309 // pvars,
310 // time_lim: constant::POW_CREATE_TIMEOUT,
311 // count_lim: constant::POW_CREATE_COUNT_LIM,
312 // },
313 // ),
314 // None => return Err(err!(
315 // "The configuration currently requires a proof of work validator, \
316 // but the PowVars supplied is None.",
317 // ), Bug, Configuration)),
318 // },
319 // false => None,
320 // },
321 // sig: match self.packet_sign_validation {
322 // true => match sigpk_opt {
323 // Some(sigpk) => (
324 // ProofOfWork::new(HashScheme::new_seahash()),
325 // PowParams {
326 // pvars,
327 // time_lim: constant::POW_CREATE_TIMEOUT,
328 // count_lim: constant::POW_CREATE_COUNT_LIM,
329 // },
330 // ),
331 // None => return Err(err!(
332 // "The configuration currently requires a proof of work validator, \
333 // but the PowVars supplied is None.",
334 // ), Bug, Configuration)),
335
336 // },
337 // false => None,
338 // }
339 // })
340 //}
341
342 pub fn get_trusted_seeds(&self) -> Outcome<Vec<SocketAddr>> {
343
344 if self.trusted_seeds.len() < constant::TRUSTED_SEEDS_MIN {
345 return Err(err!(
346 "ServerConfig: The number of trusted seeds must be at least {}.",
347 constant::TRUSTED_SEEDS_MIN;
348 Invalid, Input, TooSmall));
349 }
350
351 let mut result = Vec::new();
352 for seed in &self.trusted_seeds {
353 match fmt!("{}:{}", seed, self.server_port_udp).to_socket_addrs() {
354 Ok(mut addrs) => match addrs.next() {
355 Some(addr) => result.push(addr),
356 None => return Err(err!(
357 "Could not resolve trusted seed '{}'.", seed;
358 Invalid, Input, Network)),
359 },
360 Err(e) => return Err(err!(e,
361 "Could not resolve trusted seed '{}'.", seed;
362 Invalid, Input, Network)),
363 }
364 }
365 Ok(result)
366 }
367}