Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_shield/src/srv/msg/protocol.rs

11.2 KiB, 75 runs

created by r1870400018:4349, 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::srv::{
2 cfg::ServerConfig,
3 constant,
4 guard::{
5 data::{
6 AddressData,
7 UserData,
8 },
9 user::{
10 UserGuard,
11 UserLog,
12 },
13 },
14 msg::{
15 assemble::{
16 MsgAssembler,
17 MsgAssemblyParams,
18 MsgState,
19 },
20 core::{
21 DefaultIdTypes,
22 IdTypes,
23 },
24 packet::PacketValidator,
25 },
26 pow::DifficultyParams,
27 schemes::{
28 DefaultWireSchemes,
29 WireSchemes,
30 WireSchemesInput,
31 WireSchemeTypes,
32 },
33};
34
35use oxedyne_fe2o3_core::{
36 prelude::*,
37};
38use oxedyne_fe2o3_crypto::{
39 sign::SignatureScheme,
40};
41use oxedyne_fe2o3_hash::{
42 hash::{
43 HasherDefAlt,
44 HashScheme,
45 },
46 map::ShardMap,
47 pow::{
48 ProofOfWork,
49 ZeroBits,
50 },
51};
52use oxedyne_fe2o3_data::ring::RingTimer;
53use oxedyne_fe2o3_iop_crypto::sign::SignerDefAlt;
54use oxedyne_fe2o3_iop_hash::api::HashForm;
55use oxedyne_fe2o3_net::guard::addr::{
56 AddressGuard,
57 AddressLog,
58};
59
60use std::{
61 collections::BTreeMap,
62 fmt,
63 sync::{
64 Arc,
65 RwLock,
66 },
67 time::Duration,
68};
69
70
71#[derive(Clone, Debug)]
72pub enum ProtocolMode {
73 Production,
74 Dev,
75 Test,
76}
77
78pub trait ProtocolTypes<
79 const ML: usize,
80 const SL: usize,
81 const UL: usize,
82>:
83 Clone
84 + fmt::Debug
85{
86 type ID: IdTypes<ML, SL, UL>;
87 type W: WireSchemeTypes;
88}
89
90#[derive(Clone, Debug, Default)]
91pub struct DefaultProtocolTypes<
92 const ML: usize,
93 const SL: usize,
94 const UL: usize,
95>;
96
97impl<
98 const ML: usize,
99 const SL: usize,
100 const UL: usize,
101>
102 ProtocolTypes<ML, SL, UL> for DefaultProtocolTypes<ML, SL, UL>
103 where DefaultIdTypes<ML, SL, UL>: IdTypes<ML, SL, UL>,
104{
105 type ID = DefaultIdTypes<ML, SL, UL>;
106 type W = DefaultWireSchemes;
107}
108
109/// Capture all necessary information, and nothing more, allowing a thread to process an incoming
110/// packet. Rather than pass the entire struct atomically, use multiple interior atomic references
111/// to reduce sharing wait times.
112#[derive(Clone, Debug)]
113pub struct Protocol<
114 const C: usize,
115 const ML: usize,
116 const SL: usize,
117 const UL: usize,
118 P: ProtocolTypes<ML, SL, UL>,
119> {
120 // Let user define these generic parameters.
121 _mid_template: <P::ID as IdTypes<ML, SL, UL>>::M,
122 _sid_template: <P::ID as IdTypes<ML, SL, UL>>::S,
123
124 pub code: [u8; C],
125 pub uid: <P::ID as IdTypes<ML, SL, UL>>::U,
126 pub tx_zbits: ZeroBits,
127
128 pub mode: ProtocolMode,
129 pub schms: WireSchemes<P::W>,
130
131 pub timer: Arc<RwLock<RingTimer<{ constant::REQ_TIMER_LEN }>>>,
132 // Address protection.
133 pub agrd: Arc<AddressGuard<
134 { constant::AGRD_SHARDMAP_INIT_SHARDS },
135 BTreeMap<
136 HashForm,
137 AddressLog<
138 { constant::REQ_TIMER_LEN },
139 AddressData,
140 >,
141 >,
142 HashScheme,
143 { constant::GUARD_SHARDMAP_SALT_LEN },
144 { constant::REQ_TIMER_LEN },
145 AddressData,
146 >>,
147 pub hreq_exp: Duration,
148 // User protection.
149 pub ugrd: Arc<UserGuard<
150 { constant::UGRD_SHARDMAP_INIT_SHARDS },
151 BTreeMap<
152 HashForm,
153 UserLog<UserData<SL, C, <P::ID as IdTypes<ML, SL, UL>>::S>>,
154 >,
155 HashScheme,
156 { constant::GUARD_SHARDMAP_SALT_LEN },
157 UserData<SL, C, <P::ID as IdTypes<ML, SL, UL>>::S>,
158 >>,
159 // Packet validation.
160 pub packval: PacketValidator<
161 HasherDefAlt<HashScheme, <P::W as WireSchemeTypes>::POWH>,
162 SignerDefAlt<SignatureScheme, <P::W as WireSchemeTypes>::SGN>,
163 >,
164 pub gpzparams: DifficultyParams,
165 // Message assembly.
166 pub massembler: Arc<MsgAssembler<
167 { constant::MSG_ASSEMBLY_SHARDS },
168 BTreeMap<HashForm, MsgState>,
169 HashScheme,
170 { constant::GUARD_SHARDMAP_SALT_LEN },
171 >>,
172 pub ma_params: MsgAssemblyParams,
173 // Policy configuration.
174 pub pow_time_horiz: u64,
175 pub accept_unknown: bool,
176}
177
178impl<
179 const C: usize,
180 const ML: usize,
181 const SL: usize,
182 const UL: usize,
183 P: ProtocolTypes<ML, SL, UL> + 'static,
184>
185 Protocol<C, ML, SL, UL, P>
186{
187 pub fn new(
188 cfg: &ServerConfig,
189 schms_input: WireSchemesInput<P::W>,
190 code: [u8; C],
191 _mid_template: <P::ID as IdTypes<ML, SL, UL>>::M,
192 _sid_template: <P::ID as IdTypes<ML, SL, UL>>::S,
193 uid: <P::ID as IdTypes<ML, SL, UL>>::U,
194 mode: ProtocolMode,
195 )
196 -> Outcome<Self>
197 {
198 // Establish wire schemes. The incoming WireSchemesInput uses Alt fields, allowing schemes
199 // to be unspecified. The protocol maintains a WireSchemes using DefAlt fields, which must
200 // be specified.
201 let no_chunker = schms_input.chnk.is_none();
202 let mut schms = WireSchemes::from(schms_input);
203 //// Initialise schemes using defaults. Some of these can be updated in the config file.
204 //schms.powh = HasherDefAlt(res!(ServerConfig::read_hash_scheme(
205 // &cfg.packet_pow_hash_scheme,
206 // &*HasherDefAlt::from(schms.powh),
207 // ServerConfig::default_packet_pow_hash_scheme,
208 // "packet_pow_hash_scheme",
209 //)));
210 //schms.sign = SignerDefAlt(res!(ServerConfig::read_signature_scheme(
211 // &cfg.packet_signature_scheme,
212 // &*SignerDefAlt::from(schms.sign),
213 // ServerConfig::default_packet_signature_scheme,
214 // "packet_signature_scheme",
215 //)));
216 if no_chunker {
217 schms.chnk = cfg.chunk_config(); // Rather than ChunkCOnfig::default()
218 }
219
220 let agrd_map_init = BTreeMap::<
221 HashForm,
222 AddressLog<
223 { constant::REQ_TIMER_LEN },
224 AddressData,
225 >,
226 >::new();
227
228 let agrd = Arc::new(AddressGuard {
229 amap: res!(ShardMap::<
230 {constant::AGRD_SHARDMAP_INIT_SHARDS},
231 {constant::GUARD_SHARDMAP_SALT_LEN},
232 AddressLog<
233 {constant::REQ_TIMER_LEN},
234 AddressData,
235 >,
236 BTreeMap::<
237 HashForm,
238 AddressLog<
239 {constant::REQ_TIMER_LEN},
240 AddressData,
241 >,
242 >,
243 HashScheme,
244 >::new(
245 constant::AGRD_SHARDMAP_INIT_SHARDS as u32,
246 constant::SALT8,
247 agrd_map_init,
248 res!(HashScheme::try_from("Seahash")),
249 )),
250 // Monitor
251 arps_max: constant::MAX_ALLOWED_AVG_REQ_PER_SEC,
252 // Throttle
253 tint_min: constant::THROTTLED_INTERVAL_MIN,
254 tsunset_base: Duration::from_secs(constant::ADDR_THROTTLE_SUNSET_SECS_MIN),
255 tsunset_spread: Duration::from_secs(
256 constant::ADDR_THROTTLE_SUNSET_SECS_MAX
257 .saturating_sub(constant::ADDR_THROTTLE_SUNSET_SECS_MIN)
258 ),
259 blist_cnt: constant::THROTTLE_COUNT_BEFORE_BLACKLIST,
260 // SHIELD does not (yet) cap per-address connection concurrency: its
261 // UDP wire protocol has no long-held connection to bound. The field
262 // is inert here, matching the pre-feature behaviour.
263 conn_max: 0,
264 live_total: std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)),
265 // SHIELD keeps the pre-feature behaviour: no time-based decay of the
266 // throttle history, so this is inert.
267 decay_after: Duration::ZERO,
268 });
269
270 let ugrd_map_init = BTreeMap::<
271 HashForm,
272 UserLog<UserData<SL, C, <P::ID as IdTypes<ML, SL, UL>>::S>>,
273 >::new();
274
275 let ugrd = Arc::new(UserGuard {
276 umap: res!(ShardMap::<
277 {constant::UGRD_SHARDMAP_INIT_SHARDS},
278 {constant::GUARD_SHARDMAP_SALT_LEN},
279 UserLog<UserData<SL, C, <P::ID as IdTypes<ML, SL, UL>>::S>>,
280 BTreeMap::<
281 HashForm,
282 UserLog<UserData<SL, C, <P::ID as IdTypes<ML, SL, UL>>::S>>,
283 >,
284 HashScheme,
285 >::new(
286 constant::UGRD_SHARDMAP_INIT_SHARDS as u32,
287 constant::SALT8,
288 ugrd_map_init,
289 res!(HashScheme::try_from("Seahash")),
290 )),
291 });
292
293 let packval = PacketValidator {
294 pow: Some(res!(ProofOfWork::new(schms.powh.clone()))),
295 sig: Some(schms.sign.clone()),
296 };
297
298 Ok(Self {
299 _mid_template,
300 _sid_template,
301 code,
302 uid,
303 tx_zbits: cfg.server_pow_zbits_min.max(constant::POW_TX_MIN_ZERO_BITS),
304 mode,
305 schms,
306 timer: Arc::new(RwLock::new(RingTimer::<{ constant::REQ_TIMER_LEN }>::default())),
307 agrd: agrd.clone(),
308 hreq_exp: constant::SESSION_REQUEST_EXPIRY,
309 ugrd: ugrd.clone(),
310 packval,
311 gpzparams: DifficultyParams {
312 profile: constant::POW_DIFFICULTY_PROFILE,
313 max: constant::POW_MAX_ZERO_BITS,
314 min: constant::POW_MIN_ZERO_BITS,
315 rps_max: constant::MAX_ALLOWED_AVG_REQ_PER_SEC,
316 },
317 massembler: Arc::new(res!(MsgAssembler::<
318 { constant::MSG_ASSEMBLY_SHARDS },
319 _, _,
320 {constant::GUARD_SHARDMAP_SALT_LEN},
321 >::new(
322 constant::MSG_ASSEMBLY_SHARDS as u32,
323 constant::SALT8,
324 BTreeMap::<HashForm, MsgState>::new(),
325 res!(HashScheme::try_from("Seahash")),
326 ))),
327 ma_params: MsgAssemblyParams {
328 msg_sunset: constant::MSG_ASSEMBLY_SUNSET,
329 idle_max: constant::MSG_ASSEMBLY_IDLE_MAX,
330 rep_tot_lim: constant::MSG_ASSEMBLY_REP_TOTAL_LIM,
331 rep_max_lim: constant::MSG_ASSEMBLY_REP_PACKET_LIM,
332 },
333 pow_time_horiz: constant::POW_TIME_HORIZON_SEC,
334 accept_unknown: true,
335 })
336 }
337}