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 return self.next();
713 }
714 }
715
716 let tlv_type =
718 match self.get_last_mut_cur().read_u8()
719 {
720 Ok(r) => r,
721 Err(e) =>
722 return Some(ProxyV2TlvSource::new_io_error(e)),
723 };
724
725 let tlv_len =
727 match self.get_last_mut_cur().read_u16::<BigEndian>()
728 {
729 Ok(r) => r,
730 Err(e) =>
731 return Some(ProxyV2TlvSource::new_io_error(e)),
732 };
733
734 let tlv_range =
735 self.get_last_cur().position() as usize .. (self.get_last_cur().position()+ tlv_len as u64) as usize;
736
737
738 let mut cur =
740 Cursor::new(&self.get_last_cur().get_ref()[tlv_range]);
741
742
743 let next_item =
745 if PP2Tlvs::is_in_range(tlv_type, self.get_parent_tlv()) == true
746 {
747 ProxyV2TlvSource::new_internal(
748 PP2Tlvs::restore(tlv_type, &mut cur)
749 )
750 }
751 else if EXT::is_in_range(tlv_type, self.get_parent_tlv()) == true
752 {
753 ProxyV2TlvSource::new_external(
754 EXT::restore(tlv_type, &mut cur)
755 )
756 }
757 else
758 {
759 ProxyV2TlvSource::new_error(
760 map_error!(ProtocolUnknownData, "TLV tpye: '{}' out of int/ext ranges", tlv_type)
761 )
762 };
763
764 let new_pos = self.get_last_cur().position()+ tlv_len as u64;
766 self.get_last_mut_cur().set_position(new_pos);
767
768 if next_item.contains_subtype() == true
769 {
770 self.curs.push(
772 ProxyV2TlvIterTlv
773 {
774 cur: cur,
775 parent_tlv_idx: Some(tlv_type),
776 }
777 );
778 }
779
780 return Some(next_item);
781 }
782}
783
784#[cfg(test)]
785mod tests
786{
787 use std::{fmt, io::Cursor};
788
789 use byteorder::{BigEndian, ReadBytesExt};
790
791 use crate::{common, error::HaProxRes, protocol::{protocol::{HdrV2Command, PP2TlvClient, PP2Tlvs, ProtocolVersion, ProxyTransportFam, ProxyV2Addr, ProxyV2AddrType, PP2_TYPE_MIN_CUSTOM}, protocol_raw, PP2TlvDump, PP2TlvRestore}, return_error};
792
793 use super::ProxyV2Parser;
794
795 #[test]
796 fn test_0()
797 {
798 let pkt_ssl =
799b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x2a\
800\x7f\x00\x00\x01\x7f\x00\x00\x43\x9d\xd2\x2e\x6b\x20\x00\x1b\x07\
801\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\x22\x00\
802\x09\x6d\x71\x74\x74\x75\x73\x65\x72\x31";
803
804 let dec = ProxyV2Parser::try_from_slice(pkt_ssl.as_slice()).unwrap();
805
806 assert_eq!(dec.get_transport().is_ok(), true);
807 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
808
809 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
810 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
811
812 assert_eq!(dec.get_address_family().is_ok(), true);
813 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
814
815 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
816
817 let addr = dec.get_address().unwrap();
818
819 assert_eq!(addr.is_some(), true);
820
821 let addr = addr.unwrap();
822 let maddr = ProxyV2Addr::try_from(("127.0.0.1:40402", "127.0.0.67:11883")).unwrap();
823
824 assert_eq!(addr, maddr);
825
826 let tlv_iter = dec.get_tlvs_iter();
827
828 assert_eq!(tlv_iter.is_some(), true);
829
830 let mut tlv_iter = tlv_iter.unwrap();
831
832 let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
833
834 assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
835 let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
836
837 assert_eq!(client, PP2TlvClient::all());
838 assert_eq!(verify, 0);
839
840 let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
841
842 assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
843
844 let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
845
846 assert_eq!(ssl_version, "TLSv1.2");
847
848 let type_ssl_cn = tlv_iter.next().unwrap().take_internal().unwrap();
849
850 assert_eq!(type_ssl_cn.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_CN);
851
852 let PP2Tlvs::TypeSubtypeSslCn(ssl_cn) = type_ssl_cn else { panic!("wrong") };
853
854 assert_eq!(ssl_cn, "mqttuser1");
855 }
856
857 #[test]
858 fn test_1()
859 {
860
861 #[derive(Clone, Debug)]
862 pub enum ProxyV2Dummy2
863 {
864 SomeTlvName(u32, u32),
865 OtherTlv,
866 }
867
868 impl fmt::Display for ProxyV2Dummy2
869 {
870 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
871 {
872 write!(f, "DUMMY external reader")
873 }
874 }
875
876 impl PP2TlvRestore for ProxyV2Dummy2
877 {
878 fn restore(tlv_type: u8, cur: &mut Cursor<&[u8]>) -> HaProxRes<Self> where Self: Sized
879 {
880 match tlv_type
881 {
882 0xE0 =>
883 {
884 let arg0 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
885 let arg1 = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
886
887 return Ok(Self::SomeTlvName(arg0, arg1));
888 },
889 _ =>
890 return_error!(ProtocolUnknownData, "unknown tlv_type: {}", tlv_type)
891 }
892
893 }
894
895 fn is_in_range(tlv_type: u8, _tlv_parent_type: Option<u8>) -> bool
896 {
897 return tlv_type == PP2_TYPE_MIN_CUSTOM;
898 }
899
900 fn contains_subtype(&self) -> bool
901 {
902 return false;
903 }
904 }
905
906 impl PP2TlvDump for ProxyV2Dummy2
907 {
908 fn get_type(&self) -> u8
909 {
910 let Self::SomeTlvName(..) = self else { panic!("wrong") };
911
912 return 0xE0;
913 }
914
915 fn dump(&self, _cur: &mut Cursor<Vec<u8>>) -> HaProxRes<()>
916 {
917 todo!()
918 }
919 }
920
921 let pkt_ssl =
922b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x29\
923\x7f\x00\x00\x01\x7f\x00\x00\x43\x9b\x4a\x2e\x6b\x20\x00\x0f\x01\
924\x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32\xE0\x00\
925\x08\x01\x02\x03\x04\x05\x06\x07\x08";
926
927 let dec = ProxyV2Parser::<ProxyV2Dummy2>::try_from_slice_custom(pkt_ssl.as_slice()).unwrap();
928
929 assert_eq!(dec.get_transport().is_ok(), true);
930 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
931
932 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
933 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
934
935 assert_eq!(dec.get_address_family().is_ok(), true);
936 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
937
938 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
939
940 let addr = dec.get_address().unwrap();
941
942 assert_eq!(addr.is_some(), true);
943
944 let addr = addr.unwrap();
945 let maddr = ProxyV2Addr::try_from(("127.0.0.1:39754", "127.0.0.67:11883")).unwrap();
946
947 assert_eq!(addr, maddr);
948
949 let tlv_iter = dec.get_tlvs_iter();
950
951 assert_eq!(tlv_iter.is_some(), true);
952
953 let mut tlv_iter = tlv_iter.unwrap();
954
955 let type_ssl = tlv_iter.next().unwrap().take_internal().unwrap();
956
957 assert_eq!(type_ssl.get_type(), PP2Tlvs::TYPE_SSL);
958 let PP2Tlvs::TypeSsl { client, verify } = type_ssl else {panic!("wrong")};
959
960 assert_eq!(client, PP2TlvClient::PP2_CLIENT_SSL);
961 assert_eq!(verify, 0);
962
963 let type_ssl_version = tlv_iter.next().unwrap().take_internal().unwrap();
965
966 assert_eq!(type_ssl_version.get_type(), PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION);
967
968 let PP2Tlvs::TypeSubtypeSslVersion(ssl_version) = type_ssl_version else { panic!("wrong") };
969
970 assert_eq!(ssl_version, "TLSv1.2");
971
972 let ext_type_e0 = tlv_iter.next().unwrap().take_external().unwrap();
974
975 assert_eq!(ext_type_e0.get_type(), 0xE0);
976
977 let ProxyV2Dummy2::SomeTlvName(arg0, arg1) = ext_type_e0 else {panic!("wrong")};
978
979 assert_eq!(arg0, 0x01020304);
980 assert_eq!(arg1, 0x05060708);
981
982
983 }
984
985 #[test]
986 fn test_3()
987 {
988 let pkt_ssl =
989b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x0c\
990\x7f\x00\x00\x01\x7f\x00\x00\x01\x8c\x76\x00\x50";
991
992
993 let dec = ProxyV2Parser::try_from_slice(pkt_ssl.as_slice()).unwrap();
994
995 assert_eq!(dec.get_transport().is_ok(), true);
996 assert_eq!(dec.get_transport().unwrap(), ProxyTransportFam::STREAM);
997
998 assert_eq!(dec.get_proto_version(), ProtocolVersion::V2);
999 assert_eq!(dec.get_proto_command(), HdrV2Command::PROXY);
1000
1001 assert_eq!(dec.get_address_family().is_ok(), true);
1002 assert_eq!(dec.get_address_family().unwrap(), ProxyV2AddrType::AfInet);
1003
1004 assert_eq!(dec.get_palyload_len() as usize, pkt_ssl.len() - size_of::<protocol_raw::ProxyHdrV2>());
1005
1006 let addr = dec.get_address().unwrap();
1007
1008 assert_eq!(addr.is_some(), true);
1009
1010 let addr = addr.unwrap();
1011 let maddr = ProxyV2Addr::try_from(("127.0.0.1:35958", "127.0.0.1:80")).unwrap();
1012
1013 assert_eq!(addr, maddr);
1014
1015 let tlv_iter = dec.get_tlvs_iter();
1016
1017 assert_eq!(tlv_iter.is_some(), false);
1018
1019 }
1020
1021}