1use std::collections::HashMap;
28use std::net::SocketAddr;
29use std::sync::RwLock;
30use std::time::Instant;
31
32use bytes::Bytes;
33
34use crate::error::{Error, Result};
35use crate::v3::UsmSecurityParams;
36
37pub const TIME_WINDOW: u32 = 150;
39
40pub const DEFAULT_MSG_MAX_SIZE: u32 = 65507;
42
43pub mod report_oids {
45 use crate::Oid;
46 use crate::oid;
47
48 pub fn unsupported_sec_levels() -> Oid {
50 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 1, 0)
51 }
52
53 pub fn not_in_time_windows() -> Oid {
55 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 2, 0)
56 }
57
58 pub fn unknown_user_names() -> Oid {
60 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 3, 0)
61 }
62
63 pub fn unknown_engine_ids() -> Oid {
65 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 4, 0)
66 }
67
68 pub fn wrong_digests() -> Oid {
70 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 5, 0)
71 }
72
73 pub fn decryption_errors() -> Oid {
75 oid!(1, 3, 6, 1, 6, 3, 15, 1, 1, 6, 0)
76 }
77}
78
79#[derive(Debug, Clone)]
81pub struct EngineState {
82 pub engine_id: Bytes,
84 pub engine_boots: u32,
86 pub engine_time: u32,
88 pub synced_at: Instant,
90 pub latest_received_engine_time: u32,
92 pub msg_max_size: u32,
94}
95
96impl EngineState {
97 pub fn new(engine_id: Bytes, engine_boots: u32, engine_time: u32) -> Self {
99 Self {
100 engine_id,
101 engine_boots,
102 engine_time,
103 synced_at: Instant::now(),
104 latest_received_engine_time: engine_time,
105 msg_max_size: DEFAULT_MSG_MAX_SIZE,
106 }
107 }
108
109 pub fn with_msg_max_size(
111 engine_id: Bytes,
112 engine_boots: u32,
113 engine_time: u32,
114 msg_max_size: u32,
115 ) -> Self {
116 Self {
117 engine_id,
118 engine_boots,
119 engine_time,
120 synced_at: Instant::now(),
121 latest_received_engine_time: engine_time,
122 msg_max_size,
123 }
124 }
125
126 pub fn with_msg_max_size_capped(
131 engine_id: Bytes,
132 engine_boots: u32,
133 engine_time: u32,
134 reported_msg_max_size: u32,
135 session_max: u32,
136 ) -> Self {
137 let msg_max_size = if reported_msg_max_size > session_max {
138 tracing::debug!(
139 reported = reported_msg_max_size,
140 session_max = session_max,
141 "capping msgMaxSize to session limit"
142 );
143 session_max
144 } else {
145 reported_msg_max_size
146 };
147
148 Self {
149 engine_id,
150 engine_boots,
151 engine_time,
152 synced_at: Instant::now(),
153 latest_received_engine_time: engine_time,
154 msg_max_size,
155 }
156 }
157
158 pub fn estimated_time(&self) -> u32 {
162 let elapsed = self.synced_at.elapsed().as_secs() as u32;
163 self.engine_time.saturating_add(elapsed)
164 }
165
166 pub fn update_time(&mut self, response_boots: u32, response_time: u32) -> bool {
172 if response_boots > self.engine_boots {
173 self.engine_boots = response_boots;
175 self.engine_time = response_time;
176 self.synced_at = Instant::now();
177 self.latest_received_engine_time = response_time;
178 true
179 } else if response_boots == self.engine_boots
180 && response_time > self.latest_received_engine_time
181 {
182 self.engine_time = response_time;
184 self.synced_at = Instant::now();
185 self.latest_received_engine_time = response_time;
186 true
187 } else {
188 false
189 }
190 }
191
192 pub fn is_in_time_window(&self, msg_boots: u32, msg_time: u32) -> bool {
199 if self.engine_boots == 2147483647 {
201 return false;
202 }
203
204 if msg_boots != self.engine_boots {
206 return false;
207 }
208
209 let local_time = self.estimated_time();
211 let diff = msg_time.abs_diff(local_time);
212
213 diff <= TIME_WINDOW
214 }
215}
216
217#[derive(Debug, Default)]
242pub struct EngineCache {
243 engines: RwLock<HashMap<SocketAddr, EngineState>>,
244}
245
246impl EngineCache {
247 pub fn new() -> Self {
249 Self {
250 engines: RwLock::new(HashMap::new()),
251 }
252 }
253
254 pub fn get(&self, target: &SocketAddr) -> Option<EngineState> {
256 self.engines.read().ok()?.get(target).cloned()
257 }
258
259 pub fn insert(&self, target: SocketAddr, state: EngineState) {
261 if let Ok(mut engines) = self.engines.write() {
262 engines.insert(target, state);
263 }
264 }
265
266 pub fn update_time(
270 &self,
271 target: &SocketAddr,
272 response_boots: u32,
273 response_time: u32,
274 ) -> bool {
275 if let Ok(mut engines) = self.engines.write()
276 && let Some(state) = engines.get_mut(target)
277 {
278 return state.update_time(response_boots, response_time);
279 }
280 false
281 }
282
283 pub fn remove(&self, target: &SocketAddr) -> Option<EngineState> {
285 self.engines.write().ok()?.remove(target)
286 }
287
288 pub fn clear(&self) {
290 if let Ok(mut engines) = self.engines.write() {
291 engines.clear();
292 }
293 }
294
295 pub fn len(&self) -> usize {
297 self.engines.read().map(|e| e.len()).unwrap_or(0)
298 }
299
300 pub fn is_empty(&self) -> bool {
302 self.len() == 0
303 }
304}
305
306impl Clone for EngineCache {
307 fn clone(&self) -> Self {
308 let engines = self.engines.read().map(|e| e.clone()).unwrap_or_default();
310 Self {
311 engines: RwLock::new(engines),
312 }
313 }
314}
315
316pub fn parse_discovery_response(security_params: &Bytes) -> Result<EngineState> {
321 parse_discovery_response_with_limits(
322 security_params,
323 DEFAULT_MSG_MAX_SIZE,
324 DEFAULT_MSG_MAX_SIZE,
325 )
326}
327
328pub fn parse_discovery_response_with_limits(
334 security_params: &Bytes,
335 reported_msg_max_size: u32,
336 session_max: u32,
337) -> Result<EngineState> {
338 let usm = UsmSecurityParams::decode(security_params.clone())?;
339
340 if usm.engine_id.is_empty() {
341 return Err(Error::UnknownEngineId { target: None });
342 }
343
344 Ok(EngineState::with_msg_max_size_capped(
345 usm.engine_id,
346 usm.engine_boots,
347 usm.engine_time,
348 reported_msg_max_size,
349 session_max,
350 ))
351}
352
353pub fn is_unknown_engine_id_report(pdu: &crate::pdu::Pdu) -> bool {
357 use crate::pdu::PduType;
358
359 if pdu.pdu_type != PduType::Report {
360 return false;
361 }
362
363 let unknown_engine_ids_oid = report_oids::unknown_engine_ids();
364 pdu.varbinds
365 .iter()
366 .any(|vb| vb.oid == unknown_engine_ids_oid)
367}
368
369pub fn is_not_in_time_window_report(pdu: &crate::pdu::Pdu) -> bool {
373 use crate::pdu::PduType;
374
375 if pdu.pdu_type != PduType::Report {
376 return false;
377 }
378
379 let not_in_time_windows_oid = report_oids::not_in_time_windows();
380 pdu.varbinds
381 .iter()
382 .any(|vb| vb.oid == not_in_time_windows_oid)
383}
384
385pub fn is_wrong_digest_report(pdu: &crate::pdu::Pdu) -> bool {
389 use crate::pdu::PduType;
390
391 if pdu.pdu_type != PduType::Report {
392 return false;
393 }
394
395 let wrong_digests_oid = report_oids::wrong_digests();
396 pdu.varbinds.iter().any(|vb| vb.oid == wrong_digests_oid)
397}
398
399pub fn is_unsupported_sec_level_report(pdu: &crate::pdu::Pdu) -> bool {
403 use crate::pdu::PduType;
404
405 if pdu.pdu_type != PduType::Report {
406 return false;
407 }
408
409 let oid = report_oids::unsupported_sec_levels();
410 pdu.varbinds.iter().any(|vb| vb.oid == oid)
411}
412
413pub fn is_unknown_user_name_report(pdu: &crate::pdu::Pdu) -> bool {
417 use crate::pdu::PduType;
418
419 if pdu.pdu_type != PduType::Report {
420 return false;
421 }
422
423 let oid = report_oids::unknown_user_names();
424 pdu.varbinds.iter().any(|vb| vb.oid == oid)
425}
426
427pub fn is_decryption_error_report(pdu: &crate::pdu::Pdu) -> bool {
431 use crate::pdu::PduType;
432
433 if pdu.pdu_type != PduType::Report {
434 return false;
435 }
436
437 let oid = report_oids::decryption_errors();
438 pdu.varbinds.iter().any(|vb| vb.oid == oid)
439}
440
441#[cfg(test)]
442mod tests {
443 use super::*;
444
445 #[test]
446 fn test_engine_state_estimated_time() {
447 let state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
448
449 let estimated = state.estimated_time();
451 assert!(estimated >= 1000);
452 }
453
454 #[test]
455 fn test_engine_state_update_time() {
456 let mut state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
457
458 assert!(state.update_time(1, 1100));
460 assert_eq!(state.latest_received_engine_time, 1100);
461
462 assert!(!state.update_time(1, 1050));
464 assert_eq!(state.latest_received_engine_time, 1100);
465
466 assert!(state.update_time(2, 500));
468 assert_eq!(state.engine_boots, 2);
469 assert_eq!(state.latest_received_engine_time, 500);
470 }
471
472 #[test]
478 fn test_anti_replay_rejects_old_time() {
479 let mut state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
480 state.latest_received_engine_time = 1500; assert!(
485 !state.update_time(1, 1400),
486 "Should reject replay: time 1400 < latest 1500"
487 );
488 assert_eq!(
489 state.latest_received_engine_time, 1500,
490 "Latest should not change"
491 );
492
493 assert!(
495 !state.update_time(1, 1500),
496 "Should reject replay: time 1500 == latest 1500"
497 );
498 assert_eq!(state.latest_received_engine_time, 1500);
499
500 assert!(
502 state.update_time(1, 1501),
503 "Should accept: time 1501 > latest 1500"
504 );
505 assert_eq!(state.latest_received_engine_time, 1501);
506 }
507
508 #[test]
513 fn test_anti_replay_new_boot_cycle_resets() {
514 let mut state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
515 state.latest_received_engine_time = 5000; assert!(
520 state.update_time(2, 100),
521 "New boot cycle should accept even with lower time"
522 );
523 assert_eq!(state.engine_boots, 2);
524 assert_eq!(state.engine_time, 100);
525 assert_eq!(
526 state.latest_received_engine_time, 100,
527 "Latest should reset to new time"
528 );
529
530 assert!(
532 !state.update_time(2, 50),
533 "Should reject older time in same boot cycle"
534 );
535 assert!(state.update_time(2, 150), "Should accept newer time");
536 assert_eq!(state.latest_received_engine_time, 150);
537 }
538
539 #[test]
543 fn test_anti_replay_rejects_old_boot_cycle() {
544 let mut state = EngineState::new(Bytes::from_static(b"engine"), 5, 1000);
545 state.latest_received_engine_time = 1000;
546
547 assert!(
549 !state.update_time(4, 9999),
550 "Should reject old boot cycle even with high time"
551 );
552 assert_eq!(state.engine_boots, 5, "Boots should not change");
553 assert_eq!(
554 state.latest_received_engine_time, 1000,
555 "Latest should not change"
556 );
557
558 assert!(!state.update_time(0, 9999), "Should reject boots=0 replay");
560 }
561
562 #[test]
564 fn test_anti_replay_boundary_values() {
565 let mut state = EngineState::new(Bytes::from_static(b"engine"), 1, 0);
566
567 assert_eq!(state.latest_received_engine_time, 0);
569
570 assert!(state.update_time(1, 1));
572 assert_eq!(state.latest_received_engine_time, 1);
573
574 assert!(!state.update_time(1, 0));
576
577 assert!(state.update_time(1, u32::MAX - 1));
579 assert_eq!(state.latest_received_engine_time, u32::MAX - 1);
580
581 assert!(state.update_time(1, u32::MAX));
583 assert_eq!(state.latest_received_engine_time, u32::MAX);
584
585 assert!(!state.update_time(1, u32::MAX));
587 }
588
589 #[test]
590 fn test_engine_state_time_window() {
591 let state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
592
593 assert!(state.is_in_time_window(1, 1000));
595 assert!(state.is_in_time_window(1, 1100)); assert!(state.is_in_time_window(1, 900)); assert!(!state.is_in_time_window(2, 1000));
600 assert!(!state.is_in_time_window(0, 1000));
601
602 assert!(!state.is_in_time_window(1, 2000)); }
605
606 #[test]
611 fn test_time_window_150s_exact_boundary() {
612 let state = EngineState::new(Bytes::from_static(b"engine"), 1, 10000);
614
615 assert!(
620 state.is_in_time_window(1, 10150),
621 "Message at exactly +150s boundary should be in window"
622 );
623
624 assert!(
626 !state.is_in_time_window(1, 10151),
627 "Message at +151s should be outside window"
628 );
629
630 assert!(
632 state.is_in_time_window(1, 9850),
633 "Message at exactly -150s boundary should be in window"
634 );
635
636 assert!(
638 !state.is_in_time_window(1, 9849),
639 "Message at -151s should be outside window"
640 );
641 }
642
643 #[test]
648 fn test_time_window_boots_latched() {
649 let state = EngineState::new(Bytes::from_static(b"engine"), 2147483647, 1000);
652
653 assert!(
655 !state.is_in_time_window(2147483647, 1000),
656 "Latched boots should reject all messages"
657 );
658
659 assert!(!state.is_in_time_window(2147483647, 1100));
661 assert!(!state.is_in_time_window(2147483647, 900));
662 }
663
664 #[test]
668 fn test_time_window_boots_mismatch() {
669 let state = EngineState::new(Bytes::from_static(b"engine"), 100, 1000);
670
671 assert!(!state.is_in_time_window(101, 1000));
673 assert!(!state.is_in_time_window(200, 1000));
674
675 assert!(!state.is_in_time_window(99, 1000));
677 assert!(!state.is_in_time_window(0, 1000));
678 }
679
680 #[test]
681 fn test_engine_cache_basic_operations() {
682 let cache = EngineCache::new();
683 let addr: SocketAddr = "192.168.1.1:161".parse().unwrap();
684
685 assert!(cache.is_empty());
687 assert!(cache.get(&addr).is_none());
688
689 let state = EngineState::new(Bytes::from_static(b"engine1"), 1, 1000);
691 cache.insert(addr, state);
692
693 assert_eq!(cache.len(), 1);
694 assert!(!cache.is_empty());
695
696 let retrieved = cache.get(&addr).unwrap();
698 assert_eq!(retrieved.engine_id.as_ref(), b"engine1");
699 assert_eq!(retrieved.engine_boots, 1);
700
701 assert!(cache.update_time(&addr, 1, 1100));
703
704 let removed = cache.remove(&addr).unwrap();
706 assert_eq!(removed.latest_received_engine_time, 1100);
707 assert!(cache.is_empty());
708 }
709
710 #[test]
711 fn test_engine_cache_clone() {
712 let cache1 = EngineCache::new();
713 let addr: SocketAddr = "192.168.1.1:161".parse().unwrap();
714
715 cache1.insert(
716 addr,
717 EngineState::new(Bytes::from_static(b"engine1"), 1, 1000),
718 );
719
720 let cache2 = cache1.clone();
722 assert_eq!(cache2.len(), 1);
723 assert!(cache2.get(&addr).is_some());
724
725 cache2.clear();
727 assert_eq!(cache1.len(), 1);
728 assert_eq!(cache2.len(), 0);
729 }
730
731 #[test]
732 fn test_parse_discovery_response() {
733 let usm = UsmSecurityParams::new(b"test-engine-id".as_slice(), 42, 12345, b"".as_slice());
734 let encoded = usm.encode();
735
736 let state = parse_discovery_response(&encoded).unwrap();
737 assert_eq!(state.engine_id.as_ref(), b"test-engine-id");
738 assert_eq!(state.engine_boots, 42);
739 assert_eq!(state.engine_time, 12345);
740 }
741
742 #[test]
743 fn test_parse_discovery_response_empty_engine_id() {
744 let usm = UsmSecurityParams::empty();
745 let encoded = usm.encode();
746
747 let result = parse_discovery_response(&encoded);
748 assert!(matches!(result, Err(Error::UnknownEngineId { .. })));
749 }
750
751 #[test]
752 fn test_is_unknown_engine_id_report() {
753 use crate::Value;
754 use crate::VarBind;
755 use crate::pdu::{Pdu, PduType};
756
757 let mut pdu = Pdu {
759 pdu_type: PduType::Report,
760 request_id: 1,
761 error_status: 0,
762 error_index: 0,
763 varbinds: vec![VarBind {
764 oid: report_oids::unknown_engine_ids(),
765 value: Value::Counter32(1),
766 }],
767 };
768
769 assert!(is_unknown_engine_id_report(&pdu));
770
771 pdu.varbinds[0].oid = report_oids::not_in_time_windows();
773 assert!(!is_unknown_engine_id_report(&pdu));
774
775 pdu.pdu_type = PduType::Response;
777 assert!(!is_unknown_engine_id_report(&pdu));
778 }
779
780 #[test]
789 fn test_engine_boots_transition_to_max() {
790 let mut state = EngineState::new(Bytes::from_static(b"engine"), 2147483646, 1000);
791
792 assert!(
794 state.update_time(2147483647, 100),
795 "Transition to boots=2147483647 should be accepted"
796 );
797 assert_eq!(state.engine_boots, 2147483647);
798 assert_eq!(state.engine_time, 100);
799 }
800
801 #[test]
808 fn test_engine_boots_latched_update_behavior() {
809 let mut state = EngineState::new(Bytes::from_static(b"engine"), 2147483647, 1000);
810
811 assert!(
813 state.update_time(2147483647, 2000),
814 "Time tracking updates should still work"
815 );
816 assert_eq!(state.latest_received_engine_time, 2000);
817
818 assert!(!state.update_time(2147483647, 1500));
820 assert_eq!(state.latest_received_engine_time, 2000);
821
822 assert!(
824 !state.is_in_time_window(2147483647, 2000),
825 "Latched state should still reject all messages"
826 );
827 }
828
829 #[test]
835 fn test_engine_boots_latched_time_window_always_fails() {
836 let state = EngineState::new(Bytes::from_static(b"engine"), 2147483647, 1000);
837
838 assert!(!state.is_in_time_window(2147483647, 0));
840 assert!(!state.is_in_time_window(2147483647, 1000));
841 assert!(!state.is_in_time_window(2147483647, 1001));
842 assert!(!state.is_in_time_window(2147483647, u32::MAX));
843
844 assert!(!state.is_in_time_window(2147483646, 1000));
846 assert!(!state.is_in_time_window(0, 1000));
847 }
848
849 #[test]
854 fn test_engine_state_created_latched() {
855 let state = EngineState::new(Bytes::from_static(b"engine"), 2147483647, 5000);
856
857 assert_eq!(state.engine_boots, 2147483647);
858 assert_eq!(state.engine_time, 5000);
859 assert_eq!(state.latest_received_engine_time, 5000);
860
861 assert!(
863 !state.is_in_time_window(2147483647, 5000),
864 "Newly created latched engine should reject all messages"
865 );
866 }
867
868 #[test]
872 fn test_engine_boots_near_max_operates_normally() {
873 let mut state = EngineState::new(Bytes::from_static(b"engine"), 2147483645, 1000);
874
875 assert!(state.is_in_time_window(2147483645, 1000));
877 assert!(state.is_in_time_window(2147483645, 1100));
878 assert!(!state.is_in_time_window(2147483645, 1200)); assert!(state.update_time(2147483646, 500));
882 assert_eq!(state.engine_boots, 2147483646);
883 assert!(state.is_in_time_window(2147483646, 500));
884
885 assert!(state.update_time(2147483647, 100));
887 assert_eq!(state.engine_boots, 2147483647);
888
889 assert!(!state.is_in_time_window(2147483647, 100));
891 }
892
893 #[test]
896 fn test_engine_boots_high_value_update_logic() {
897 let mut state = EngineState::new(Bytes::from_static(b"engine"), 2147483640, 1000);
898
899 assert!(!state.update_time(2147483639, 9999));
901 assert!(!state.update_time(0, 9999));
902
903 assert!(!state.update_time(2147483640, 500));
905
906 assert!(state.update_time(2147483640, 1500));
908 assert_eq!(state.latest_received_engine_time, 1500);
909
910 assert!(state.update_time(2147483641, 100));
912 assert_eq!(state.engine_boots, 2147483641);
913 }
914
915 #[test]
920 fn test_engine_cache_latched_engine() {
921 let cache = EngineCache::new();
922 let addr: SocketAddr = "192.168.1.1:161".parse().unwrap();
923
924 cache.insert(
926 addr,
927 EngineState::new(Bytes::from_static(b"latched"), 2147483647, 1000),
928 );
929
930 assert!(
932 cache.update_time(&addr, 2147483647, 2000),
933 "Time tracking should update even for latched engine"
934 );
935
936 let state = cache.get(&addr).unwrap();
938 assert_eq!(state.latest_received_engine_time, 2000);
939
940 assert!(
942 !state.is_in_time_window(2147483647, 2000),
943 "Latched engine should reject all time window checks"
944 );
945 }
946
947 #[test]
959 fn test_engine_state_stores_msg_max_size() {
960 let state = EngineState::with_msg_max_size(Bytes::from_static(b"engine"), 1, 1000, 65507);
961 assert_eq!(state.msg_max_size, 65507);
962 }
963
964 #[test]
969 fn test_engine_state_default_msg_max_size() {
970 let state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
971 assert_eq!(
972 state.msg_max_size, DEFAULT_MSG_MAX_SIZE,
973 "Default msg_max_size should be the maximum UDP datagram size"
974 );
975 }
976
977 #[test]
983 fn test_engine_state_msg_max_size_capped_to_session_max() {
984 let state = EngineState::with_msg_max_size_capped(
986 Bytes::from_static(b"engine"),
987 1,
988 1000,
989 2_000_000_000, 65507, );
992 assert_eq!(
993 state.msg_max_size, 65507,
994 "msg_max_size should be capped to session maximum"
995 );
996 }
997
998 #[test]
1003 fn test_engine_state_msg_max_size_within_limit_not_capped() {
1004 let state = EngineState::with_msg_max_size_capped(
1005 Bytes::from_static(b"engine"),
1006 1,
1007 1000,
1008 1472, 65507, );
1011 assert_eq!(
1012 state.msg_max_size, 1472,
1013 "msg_max_size within limit should not be capped"
1014 );
1015 }
1016
1017 #[test]
1021 fn test_engine_state_msg_max_size_at_exact_boundary() {
1022 let state = EngineState::with_msg_max_size_capped(
1023 Bytes::from_static(b"engine"),
1024 1,
1025 1000,
1026 65507, 65507, );
1029 assert_eq!(state.msg_max_size, 65507);
1030 }
1031
1032 #[test]
1037 fn test_engine_state_msg_max_size_tcp_limit() {
1038 const TCP_MAX: u32 = 0x7FFFFFFF; let state = EngineState::with_msg_max_size_capped(
1042 Bytes::from_static(b"engine"),
1043 1,
1044 1000,
1045 TCP_MAX,
1046 TCP_MAX,
1047 );
1048 assert_eq!(state.msg_max_size, TCP_MAX);
1049
1050 let state = EngineState::with_msg_max_size_capped(
1052 Bytes::from_static(b"engine"),
1053 1,
1054 1000,
1055 u32::MAX, TCP_MAX,
1057 );
1058 assert_eq!(
1059 state.msg_max_size, TCP_MAX,
1060 "Values exceeding session max should be capped"
1061 );
1062 }
1063
1064 #[test]
1066 fn test_engine_state_new_uses_default_constant() {
1067 let state = EngineState::new(Bytes::from_static(b"engine"), 1, 1000);
1068
1069 assert_eq!(state.msg_max_size, DEFAULT_MSG_MAX_SIZE);
1071 }
1072}