1use std::mem::offset_of;
16use std::{fmt, io::Cursor, marker::PhantomData};
17use byteorder::{BigEndian, ReadBytesExt};
18use crc32fast::Hasher;
19
20use crate::common::map_io_err;
21use crate::{error::{HaProxErr, HaProxRes}, map_error, return_error};
22
23use crate::protocol_raw;
24
25use super::
26{
27 protocol::
28 {
29 HdrV2Command,
30 PP2Tlvs,
31 ProtocolVersion,
32 ProxyTransportFam,
33 ProxyV2Addr,
34 ProxyV2AddrType
35 },
36 PP2TlvRestore
37};
38
39#[derive(Debug)]
44pub struct PPV2ParserCopying();
45
46impl fmt::Display for PPV2ParserCopying
47{
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
49 {
50 write!(f, "copying parser")
51 }
52}
53
54#[derive(Debug)]
59pub struct PPV2ParserZeroCopy<'zc>(PhantomData<&'zc ()>);
60
61impl<'zc> fmt::Display for PPV2ParserZeroCopy<'zc>
62{
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
64 {
65 write!(f, "zerocopy parser")
66 }
67}
68
69#[derive(Debug)]
90pub struct ProxyV2Parser<'t, PAR = PPV2ParserZeroCopy<'t>, EXT = ProxyV2Dummy>
91where
92 PAR: PP2TlvRestore<'t>,
93 EXT: PP2TlvRestore<'t>,
94{
95 buffer: &'t [u8],
97
98 _p1: PhantomData<EXT>,
100
101 _p2: PhantomData<PAR>,
103}
104
105impl<'t> ProxyV2Parser<'t>
106{
107 pub
109 fn try_from_slice(value: &'t [u8]) -> HaProxRes<Self>
110 {
111 let pkt_size = Self::new_from(value)?;
112
113 let tmp =
114 Self
115 {
116 buffer: &value[0..pkt_size],
117 _p1: PhantomData,
118 _p2: PhantomData,
119 };
120
121 tmp.post_check()?;
122
123 return Ok(tmp);
124 }
125}
126
127impl<'t, PAR: PP2TlvRestore<'t>, EXT: PP2TlvRestore<'t>> ProxyV2Parser<'t, PAR, EXT>
128{
129 pub
132 fn try_from_slice_custom(value: &'t [u8]) -> HaProxRes<Self>
133 {
134 let pkt_size = Self::new_from(value)?;
135
136 let tmp =
137 Self
138 {
139 buffer: &value[0..pkt_size],
140 _p1: PhantomData,
141 _p2: PhantomData,
142 };
143
144 tmp.post_check()?;
145
146 return Ok(tmp);
147 }
148}
149
150impl<'t, PAR: PP2TlvRestore<'t>, EXT: PP2TlvRestore<'t>> ProxyV2Parser<'t, PAR, EXT>
151{
152 fn post_check(&self) -> HaProxRes<()>
153 {
154 let _ = self.get_address_family()?;
155 let _ = self.get_transport()?;
156
157 return Ok(());
158 }
159
160 fn new_from(value: &[u8]) -> HaProxRes<usize>
165 {
166 if value.len() <= protocol_raw::HEADER_MAGIC_V1.len()
167 {
168 return_error!(IncorrectBanner, "protocol with footprint '{:02X?}' unknown",
169 value);
170 }
171 else if &value[0..protocol_raw::HEADER_MAGIC_V1.len()] == protocol_raw::HEADER_MAGIC_V1
172 {
173 return_error!(ProtocolNotSuported, "V1 protocol is not supported");
174 }
175 else if value.len() < size_of::<protocol_raw::ProxyHdrV2>()
176 {
177 return_error!(ProtocolMsgIncomplete, "protocol with footprint '{:02X?}' unknown",
178 value);
179 }
180 else if &value[0..protocol_raw::HEADER_MAGIC_V2.len()] != protocol_raw::HEADER_MAGIC_V2
181 {
182 return_error!(IncorrectBanner, "protocol with footprint '{:02X?}' unknown",
183 value);
184 }
185 else if value[offset_of!(protocol_raw::ProxyHdrV2, ver_cmd)] & protocol_raw::ProxyHdrV2::VERSION_MASK !=
186 protocol_raw::ProxyHdrV2::VERSION_RAW
187 {
188 return_error!(MalformedData, "protocol version '{:02X?}' incorrect",
189 value[offset_of!(protocol_raw::ProxyHdrV2, ver_cmd)]);
190 }
191
192 let payload_len =
193 [
194 value[offset_of!(protocol_raw::ProxyHdrV2, len)],
195 value[offset_of!(protocol_raw::ProxyHdrV2, len)+1]
196 ];
197
198 let full_size = u16::from_be_bytes(payload_len) + protocol_raw::ProxyHdrV2::HEADER_LEN as u16;
199
200 if value.len() < full_size as usize
201 {
202 return_error!(ProtocolMsgIncomplete, "fragmented pkt received, declared len + header: {}, received len: {}",
203 full_size, value.len());
204 }
205
206 return Ok(full_size as usize);
207 }
208
209 pub
211 fn get_proto_version(&self) -> ProtocolVersion
212 {
213 return ProtocolVersion::decode(self.buffer[offset_of!(protocol_raw::ProxyHdrV2, ver_cmd)]);
214 }
215
216 pub
218 fn get_proto_command(&self) -> HdrV2Command
219 {
220 return HdrV2Command::decode(self.buffer[offset_of!(protocol_raw::ProxyHdrV2, ver_cmd)]);
221 }
222
223 pub
225 fn get_transport(&self) -> HaProxRes<ProxyTransportFam>
226 {
227 return ProxyTransportFam::decode(self.buffer[offset_of!(protocol_raw::ProxyHdrV2, fam)]);
228 }
229
230 pub
232 fn get_address_family(&self) -> HaProxRes<ProxyV2AddrType>
233 {
234 return ProxyV2AddrType::decode(self.buffer[offset_of!(protocol_raw::ProxyHdrV2, fam)]);
235 }
236
237 pub
239 fn get_palyload_len(&self) -> u16
240 {
241 let hi =
242 [
243 self
244 .buffer[offset_of!(protocol_raw::ProxyHdrV2, len)],
245 self
246 .buffer[offset_of!(protocol_raw::ProxyHdrV2, len)+1]
247 ];
248
249
250 return u16::from_be_bytes(hi);
251 }
252
253 pub
255 fn get_full_len(&self) -> u16
256 {
257 let hi =
258 [
259 self
260 .buffer[offset_of!(protocol_raw::ProxyHdrV2, len)],
261 self
262 .buffer[offset_of!(protocol_raw::ProxyHdrV2, len)+1]
263 ];
264
265
266 return u16::from_be_bytes(hi) + protocol_raw::ProxyHdrV2::HEADER_LEN as u16;
267 }
268
269 pub
284 fn get_address(&self) -> HaProxRes<Option<ProxyV2Addr>>
285 {
286 let addr_fam = self.get_address_family()?;
287
288 let Some(addr_len) = addr_fam.get_size_by_addr_family()
289 else { return Ok(None) };
290
291 let buf_len = self.buffer.len() - size_of::<protocol_raw::ProxyHdrV2>();
292
293 if buf_len < addr_len as usize
294 {
295 return_error!(ProtocolMsgIncomplete, "cannot read address, msg len: '{}', addr len: '{}'",
296 buf_len, addr_len);
297 }
298
299 let mut cur = Cursor::new(&self.buffer.as_ref()[offset_of!(protocol_raw::ProxyHdrV2, address)..]);
300
301 return ProxyV2Addr::read(addr_fam, &mut cur);
302 }
303
304 pub
308 fn get_tlvs_iter(&self) -> Option<ProxyV2TlvIter<'t, PAR, EXT>>
309 {
310 let addr_fam = self.get_address_family().ok()?.get_size_by_addr_family()?;
311
312 if self.get_palyload_len() - addr_fam == 0
313 {
314 return None;
315 }
316
317 let addr_size = self.get_address_family().ok()?.get_size_by_addr_family()? as usize;
318
319 let tlv_offset_start =
320 offset_of!(protocol_raw::ProxyHdrV2, address) + addr_size;
321
322 let itr =
323 ProxyV2TlvIter
324 {
325 curs:
326 vec![
327 ProxyV2TlvIterTlv
328 {
329 cur: Cursor::new(&self.buffer.as_ref()[tlv_offset_start..]),
330 parent_tlv_idx: None,
331 },
332 ],
333 _p: PhantomData,
334 _p2: PhantomData,
335 };
336
337 return Some(itr);
338 }
339
340 pub
342 fn check_crc(&self) -> HaProxRes<bool>
343 {
344 let mut crc32: Option<u32> = None;
348
349 let mut hasher = Hasher::new();
351
352 let addr_fam_len =
353 self
354 .get_address_family()?
355 .get_size_by_addr_family()
356 .ok_or_else(||
357 map_error!(ArgumentEinval, "unknown address family")
358 )? as usize;
359
360
361 let full_hdr_len = addr_fam_len + protocol_raw::ProxyHdrV2::HEADER_LEN;
362
363 hasher.update(&self.buffer[0..full_hdr_len]);
365
366 let payload_len = self.get_palyload_len() as usize - addr_fam_len;
367
368 let mut cur = Cursor::new(&self.buffer[full_hdr_len..]);
369
370 while cur.position() < payload_len as u64
371 {
372 let s = cur.position() as usize;
373
374 let op = cur.read_u8().map_err(map_io_err)?;
375 let len = cur.read_u16::<BigEndian>().map_err(map_io_err)?;
376
377 if op == PP2Tlvs::TYPE_CRC32C
378 {
379 crc32 = Some(cur.read_u32::<BigEndian>().map_err(map_io_err)?);
380
381 hasher.update(&[op]);
382 hasher.update(len.to_be_bytes().as_slice());
383 hasher.update(&[0]);
384 }
385 else
386 {
387 let last = s+2+len as usize;
388
389 hasher.update(&self.buffer[s..last]);
390 cur.set_position(last as u64);
391 }
392 }
393
394 if let Some(cr) = crc32
395 {
396 return Ok(cr == hasher.finalize());
397 }
398 else
399 {
400 return_error!(ArgumentEinval, "no CRC TLV found!");
401 }
402 }
403}
404
405
406#[derive(Clone, Debug)]
408pub enum ProxyV2Dummy {}
409
410impl fmt::Display for ProxyV2Dummy
411{
412 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
413 {
414 write!(f, "DUMMY external reader")
415 }
416}
417
418impl<'zc> PP2TlvRestore<'zc> for ProxyV2Dummy
419{
420 type TlvTblRes = PP2Tlvs<'zc>;
421
422 fn is_in_range(_tlv_type: u8, _tlv_parent_type: Option<u8>) -> bool
423 {
424 return false;
425 }
426
427 fn contains_subtype(_item: &Self::TlvTblRes) -> bool
428 {
429 return false;
430 }
431
432 fn restore(_tlv_type: u8, _cur: &mut Cursor<&[u8]>) -> HaProxRes<Self::TlvTblRes>
433 {
434 return_error!(ArgumentEinval, "assertion trap, DUMMY external decoder");
435 }
436}
437
438impl PP2TlvRestore<'static> for PPV2ParserCopying
439{
440 type TlvTblRes = PP2Tlvs<'static>;
441
442 fn contains_subtype(item: &Self::TlvTblRes) -> bool
443 {
444 return item.contains_subtype();
445 }
446
447 fn is_in_range(tlv_type: u8, tlv_parent_type: Option<u8>) -> bool
448 {
449 return PP2Tlvs::<'static>::is_in_range(tlv_type, tlv_parent_type);
450 }
451
452 fn restore(tlv_type: u8, cur: &mut Cursor<&'static [u8]>) -> HaProxRes<Self::TlvTblRes>
453 {
454 return PP2Tlvs::<'static>::restore_copying(tlv_type, cur);
455 }
456}
457
458impl<'zc> PP2TlvRestore<'zc> for PPV2ParserZeroCopy<'zc>
459{
460 type TlvTblRes = PP2Tlvs<'zc>;
461
462 fn contains_subtype(item: &Self::TlvTblRes) -> bool
463 {
464 return item.contains_subtype();
465 }
466
467 fn is_in_range(tlv_type: u8, tlv_parent_type: Option<u8>) -> bool
468 {
469 return PP2Tlvs::<'zc>::is_in_range(tlv_type, tlv_parent_type);
470 }
471
472 fn restore(tlv_type: u8, cur: &mut Cursor<&'zc [u8]>) -> HaProxRes<Self::TlvTblRes>
473 {
474 return PP2Tlvs::<'zc>::restore_zerocopy(tlv_type, cur);
475 }
476}
477
478#[derive(Debug, Clone, PartialEq, Eq)]
482pub enum ProxyV2TlvSource<'zc, PAR: PP2TlvRestore<'zc>, EXT: PP2TlvRestore<'zc>>
483{
484 Internal(PAR::TlvTblRes),
486
487 External(EXT::TlvTblRes),
489
490 Error(HaProxErr),
492}
493
494impl<'zc, PAR: PP2TlvRestore<'zc>, EXT: PP2TlvRestore<'zc>> ProxyV2TlvSource<'zc, PAR, EXT>
495{
496 fn new_internal(pp2: HaProxRes<PAR::TlvTblRes>) -> Self
497 {
498 return
499 pp2.map_or_else(|e| Self::Error(e), |f| Self::Internal(f));
500 }
501
502 fn new_external(pp2: HaProxRes<EXT::TlvTblRes>) -> Self
503 {
504 return
505 pp2
506 .map_or_else(|e| Self::Error(e), |f| Self::External(f));
507 }
508
509 fn new_error(err: HaProxErr) -> Self
510 {
511 return Self::Error(err);
512 }
513
514 fn new_io_error(err: std::io::Error) -> Self
515 {
516 return Self::Error(map_error!(IoError, "while reading TLV, error: {}", err));
517 }
518
519 pub
522 fn take_internal(self) -> Option<PAR::TlvTblRes>
523 {
524 let Self::Internal(s) = self else {return None};
525
526 return Some(s);
527 }
528
529 pub
532 fn take_external(self) -> Option<EXT::TlvTblRes>
533 {
534 let Self::External(s) = self else {return None};
535
536 return Some(s);
537 }
538
539 pub
542 fn contains_subtype(&self) -> bool
543 {
544 match self
545 {
546 Self::Internal(i) =>
547 return PAR::contains_subtype(i),
548 Self::External(e) =>
549 return EXT::contains_subtype(e),
550 _ =>
551 return false
552 }
553 }
554
555}
556
557#[derive(Debug)]
559struct ProxyV2TlvIterTlv<'iter>
560{
561 cur: Cursor<&'iter [u8]>,
563
564 parent_tlv_idx: Option<u8>,
566}
567
568#[derive(Debug)]
570pub struct ProxyV2TlvIter<'iter, PAR: PP2TlvRestore<'iter>, EXT>
571{
572 curs: Vec<ProxyV2TlvIterTlv<'iter>>,
575
576 _p: PhantomData<EXT>,
578
579 _p2: PhantomData<PAR>,
581}
582
583impl<'iter, PAR: PP2TlvRestore<'iter>, EXT: PP2TlvRestore<'iter>> ProxyV2TlvIter<'iter, PAR, EXT>
584{
585 fn get_last_cur(&self) -> &Cursor<&'iter [u8]>
586 {
587 return &self.curs.last().unwrap().cur;
588 }
589
590 fn get_last_mut_cur(&mut self) -> &mut Cursor<&'iter [u8]>
591 {
592 return &mut self.curs.last_mut().unwrap().cur;
593 }
594
595 fn get_parent_tlv(&self) -> Option<u8>
596 {
597 return self.curs.last().unwrap().parent_tlv_idx;
598 }
599}
600
601impl<'iter, PAR: PP2TlvRestore<'iter>, EXT: PP2TlvRestore<'iter>> Iterator for ProxyV2TlvIter<'iter, PAR, EXT>
602{
603 type Item = ProxyV2TlvSource<'iter, PAR, EXT>;
604
605 fn next(&mut self) -> Option<Self::Item>
606 {
607 if self.get_last_cur().get_ref().len() <= self.get_last_cur().position() as usize
609 {
610 if self.curs.len() == 1
611 {
612 return None;
614 }
615 else
616 {
617 let _ = self.curs.pop();
619
620 return self.next();
621 }
622 }
623
624 let tlv_type =
626 match self.get_last_mut_cur().read_u8()
627 {
628 Ok(r) => r,
629 Err(e) =>
630 return Some(ProxyV2TlvSource::new_io_error(e)),
631 };
632
633 let tlv_len =
635 match self.get_last_mut_cur().read_u16::<BigEndian>()
636 {
637 Ok(r) => r,
638 Err(e) =>
639 return Some(ProxyV2TlvSource::new_io_error(e)),
640 };
641
642 let tlv_range =
643 self.get_last_cur().position() as usize .. (self.get_last_cur().position()+ tlv_len as u64) as usize;
644
645
646 let mut cur =
648 Cursor::new(&self.get_last_cur().get_ref()[tlv_range]);
649
650
651 let next_item =
653 if PP2Tlvs::is_in_range(tlv_type, self.get_parent_tlv()) == true
654 {
655 ProxyV2TlvSource::new_internal(
656 PAR::restore(tlv_type, &mut cur)
657 )
658 }
659 else if EXT::is_in_range(tlv_type, self.get_parent_tlv()) == true
660 {
661 ProxyV2TlvSource::new_external(
662 EXT::restore(tlv_type, &mut cur)
663 )
664 }
665 else
666 {
667 ProxyV2TlvSource::new_error(
668 map_error!(ProtocolUnknownData, "TLV tpye: '{}' out of int/ext ranges", tlv_type)
669 )
670 };
671
672 let new_pos = self.get_last_cur().position()+ tlv_len as u64;
674 self.get_last_mut_cur().set_position(new_pos);
675
676 if next_item.contains_subtype() == true
677 {
678 self.curs.push(
680 ProxyV2TlvIterTlv
681 {
682 cur: cur,
683 parent_tlv_idx: Some(tlv_type),
684 }
685 );
686 }
687
688 return Some(next_item);
689 }
690}
691
692#[cfg(test)]
693mod tests
694{
695 use std::{borrow::Cow, fmt, io::Cursor, mem};
696
697 use byteorder::{BigEndian, ReadBytesExt};
698
699 use crate::{PPV2ParserCopying, PPV2ParserZeroCopy, ProxyV2Dummy, common, error::HaProxRes, protocol_raw, protocol_v2::{PP2TlvDump, PP2TlvRestore, protocol::{HdrV2Command, PP2_TYPE_MIN_CUSTOM, PP2TlvClient, PP2Tlvs, ProtocolVersion, ProxyTransportFam, ProxyV2Addr, ProxyV2AddrType}}, return_error};
700
701 use super::ProxyV2Parser;
702
703 #[test]
704 fn test_0_zerocopy()
705 {
706 let pkt_ssl =
707b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x2a\
708\x7f\x00\x00\x01\x7f\x00\x00\x43\x9d\xd2\x2e\x6b\x20\x00\x1b\x07\
709\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\x22\x00\
710\x09\x6d\x71\x74\x74\x75\x73\x65\x72\x31";
711
712 let dec = ProxyV2Parser::try_from_slice(pkt_ssl.as_slice()).unwrap();
713
714 assert_eq!(dec.get_transport().is_ok(), true);
715 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
716
717 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
718 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
719
720 assert_eq!(dec.get_address_family().is_ok(), true);
721 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
722
723 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
724
725 let addr = dec.get_address().unwrap();
726
727 assert_eq!(addr.is_some(), true);
728
729 let addr = addr.unwrap();
730 let maddr = ProxyV2Addr::try_from(("127.0.0.1:40402", "127.0.0.67:11883")).unwrap();
731
732 assert_eq!(addr, maddr);
733
734 let tlv_iter = dec.get_tlvs_iter();
735
736 assert_eq!(tlv_iter.is_some(), true);
737
738 let mut tlv_iter = tlv_iter.unwrap();
739
740 let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
741
742 assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
743 let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
744
745 assert_eq!(client, PP2TlvClient::all());
746 assert_eq!(verify, 0);
747
748 let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
749
750 assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
751
752 let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
753
754 assert_eq!(mem::discriminant(&ssl_version), mem::discriminant(&Cow::Borrowed("TLSv1.2")));
755 assert_eq!(ssl_version, "TLSv1.2");
756
757 let type_ssl_cn = tlv_iter.next().unwrap().take_internal().unwrap();
758
759 assert_eq!(type_ssl_cn.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_CN);
760
761 let PP2Tlvs::TypeSubtypeSslCn(ssl_cn) = type_ssl_cn else { panic!("wrong") };
762
763 assert_eq!(ssl_cn, "mqttuser1");
764 }
765
766 #[test]
767 fn test_0_copy()
768 {
769 let pkt_ssl =
770b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x2a\
771\x7f\x00\x00\x01\x7f\x00\x00\x43\x9d\xd2\x2e\x6b\x20\x00\x1b\x07\
772\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\x22\x00\
773\x09\x6d\x71\x74\x74\x75\x73\x65\x72\x31";
774
775
776 let dec =
777 ProxyV2Parser
778 ::<PPV2ParserCopying, ProxyV2Dummy>
779 ::try_from_slice_custom(pkt_ssl.as_slice())
780 .unwrap();
781
782 assert_eq!(dec.get_transport().is_ok(), true);
783 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
784
785 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
786 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
787
788 assert_eq!(dec.get_address_family().is_ok(), true);
789 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
790
791 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
792
793 let addr = dec.get_address().unwrap();
794
795 assert_eq!(addr.is_some(), true);
796
797 let addr = addr.unwrap();
798 let maddr = ProxyV2Addr::try_from(("127.0.0.1:40402", "127.0.0.67:11883")).unwrap();
799
800 assert_eq!(addr, maddr);
801
802 let tlv_iter = dec.get_tlvs_iter();
803
804 assert_eq!(tlv_iter.is_some(), true);
805
806 let mut tlv_iter = tlv_iter.unwrap();
807
808 let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
809
810 assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
811 let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
812
813 assert_eq!(client, PP2TlvClient::all());
814 assert_eq!(verify, 0);
815
816 let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
817
818 assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
819
820 let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
821
822 assert_eq!(mem::discriminant(&ssl_version), mem::discriminant(&Cow::Owned("TLSv1.2".into())));
823 assert_eq!(ssl_version, "TLSv1.2");
824
825 let type_ssl_cn = tlv_iter.next().unwrap().take_internal().unwrap();
826
827 assert_eq!(type_ssl_cn.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_CN);
828
829 let PP2Tlvs::TypeSubtypeSslCn(ssl_cn) = type_ssl_cn else { panic!("wrong") };
830
831 assert_eq!(ssl_cn, "mqttuser1");
832 }
833
834 #[test]
835 fn test_1()
836 {
837
838 #[derive(Clone, Debug)]
839 pub enum ProxyV2Dummy2
840 {
841 SomeTlvName(u32, u32),
842 OtherTlv,
843 }
844
845 impl fmt::Display for ProxyV2Dummy2
846 {
847 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
848 {
849 write!(f, "DUMMY external reader")
850 }
851 }
852
853 impl PP2TlvRestore<'static> for ProxyV2Dummy2
854 {
855 type TlvTblRes = Self;
856
857 fn restore(tlv_type: u8, cur: &mut Cursor<&[u8]>) -> HaProxRes<Self> where Self: Sized
858 {
859 match tlv_type
860 {
861 0xE0 =>
862 {
863 let arg0 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
864 let arg1 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
865
866 return Ok(Self::SomeTlvName(arg0, arg1));
867 },
868 _ =>
869 return_error!(ProtocolUnknownData, "unknown tlv_type: {}", tlv_type)
870 }
871
872 }
873
874 fn is_in_range(tlv_type: u8, _tlv_parent_type: Option<u8>) -> bool
875 {
876 return tlv_type == PP2_TYPE_MIN_CUSTOM;
877 }
878
879 fn contains_subtype(_item: &Self::TlvTblRes) -> bool
880 {
881 return false;
882 }
883 }
884
885 impl PP2TlvDump for ProxyV2Dummy2
886 {
887 fn get_type(&self) -> u8
888 {
889 let Self::SomeTlvName(..) = self else { panic!("wrong") };
890
891 return 0xE0;
892 }
893
894 fn dump(&self, _cur: &mut Cursor<Vec<u8>>) -> HaProxRes<()>
895 {
896 todo!()
897 }
898 }
899
900 let pkt_ssl =
901b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x29\
902\x7f\x00\x00\x01\x7f\x00\x00\x43\x9b\x4a\x2e\x6b\x20\x00\x0f\x01\
903\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\xE0\x00\
904\x08\x01\x02\x03\x04\x05\x06\x07\x08";
905
906 let dec = ProxyV2Parser::<PPV2ParserZeroCopy, ProxyV2Dummy2>::try_from_slice_custom(pkt_ssl.as_slice()).unwrap();
907
908 assert_eq!(dec.get_transport().is_ok(), true);
909 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
910
911 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
912 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
913
914 assert_eq!(dec.get_address_family().is_ok(), true);
915 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
916
917 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
918
919 let addr = dec.get_address().unwrap();
920
921 assert_eq!(addr.is_some(), true);
922
923 let addr = addr.unwrap();
924 let maddr = ProxyV2Addr::try_from(("127.0.0.1:39754", "127.0.0.67:11883")).unwrap();
925
926 assert_eq!(addr, maddr);
927
928 let tlv_iter = dec.get_tlvs_iter();
929
930 assert_eq!(tlv_iter.is_some(), true);
931
932 let mut tlv_iter = tlv_iter.unwrap();
933
934 let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
935
936 assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
937 let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
938
939 assert_eq!(client, PP2TlvClient::PP2_CLIENT_SSL);
940 assert_eq!(verify, 0);
941
942 let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
944
945 assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
946
947 let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
948
949 assert_eq!(ssl_version, "TLSv1.2");
950
951 let ext_type_e0 = tlv_iter.next().unwrap().take_external().unwrap();
953
954 assert_eq!(ext_type_e0.get_type(), 0xE0);
955
956 let ProxyV2Dummy2::SomeTlvName(arg0, arg1) = ext_type_e0 else {panic!("wrong")};
957
958 assert_eq!(arg0, 0x01020304);
959 assert_eq!(arg1, 0x05060708);
960
961
962 }
963
964 #[test]
965 fn test_3()
966 {
967 let pkt_ssl =
968b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x0c\
969\x7f\x00\x00\x01\x7f\x00\x00\x01\x8c\x76\x00\x50";
970
971
972 let dec = ProxyV2Parser::try_from_slice(pkt_ssl.as_slice()).unwrap();
973
974 assert_eq!(dec.get_transport().is_ok(), true);
975 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
976
977 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
978 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
979
980 assert_eq!(dec.get_address_family().is_ok(), true);
981 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
982
983 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
984
985 let addr = dec.get_address().unwrap();
986
987 assert_eq!(addr.is_some(), true);
988
989 let addr = addr.unwrap();
990 let maddr = ProxyV2Addr::try_from(("127.0.0.1:35958", "127.0.0.1:80")).unwrap();
991
992 assert_eq!(addr, maddr);
993
994 let tlv_iter = dec.get_tlvs_iter();
995
996 assert_eq!(tlv_iter.is_some(), false);
997
998 }
999
1000}