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