1use std::borrow::Cow;
14use std::ffi::CStr;
15use std::fmt;
16use std::io::{Cursor, Read, Write};
17use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
18use std::ops::RangeInclusive;
19use std::os::unix::ffi::OsStrExt;
20use std::os::unix::net;
21use std::str::FromStr;
22
23use bitflags::bitflags;
24use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
25
26use crate::{common, map_error, return_error};
27use crate::error::{HaProxErr, HaProxRes};
28
29use super::protocol_raw::{self, HEADER_UNIX_ADDR_LEN};
30
31pub const PP2_TYPE_MIN_CUSTOM: u8 = 0xE0;
39
40pub const PP2_TYPE_MAX_CUSTOM: u8 = 0xEF;
43
44pub const PP2_TYPE_MIN_EXPERIMENT: u8 = 0xF0;
51
52pub const PP2_TYPE_MAX_EXPERIMENT: u8 = 0xF7;
55
56pub const PP2_TYPE_MIN_FUTURE: u8 = 0xF8;
62
63pub const PP2_TYPE_MAX_FUTURE: u8 = 0xFF;
65
66
67pub const MAX_UNIQ_ID_LEN_BYTES: u16 = 128;
70
71pub const TLV_HEADER_LEN: u16 = 3;
73
74
75
76#[repr(u8)]
81#[derive(Clone, Copy, PartialEq, Eq, Debug)]
82pub enum HdrV2Command
83{
84 LOCAL = 0,
85 PROXY = 1,
86 UNKNOWN,
87}
88
89impl From<HdrV2Command> for u8
90{
91 fn from(value: HdrV2Command) -> Self
92 {
93 if value == HdrV2Command::UNKNOWN
94 {
95 panic!("can not encode the unknown command");
96 }
97
98 return value as u8;
99 }
100}
101
102impl HdrV2Command
103{
104 pub(crate)
105 fn decode(raw: u8) -> Self
106 {
107 match raw & protocol_raw::ProxyHdrV2::COMMAND_MASK
108 {
109 r if r == HdrV2Command::LOCAL.into() => return Self::LOCAL,
110 r if r == HdrV2Command::PROXY.into() => return Self::PROXY,
111 _ => return Self::UNKNOWN,
112 }
113 }
114}
115
116#[repr(u8)]
118#[derive(Clone, Copy, PartialEq, Eq, Debug)]
119pub enum ProtocolVersion
120{
121 V1 = 1,
122 V2 = 2,
123 UNKNOWN,
124}
125
126impl From<ProtocolVersion> for u8
127{
128 fn from(value: ProtocolVersion) -> Self
129 {
130 if value == ProtocolVersion::UNKNOWN
131 {
132 panic!("can not encode the unknown version");
133 }
134
135 return (value as u8) << 4;
136 }
137}
138
139impl ProtocolVersion
140{
141 pub(crate)
142 fn decode(raw: u8) -> Self
143 {
144 match raw >> 4
145 {
146 1 => return Self::V1,
147 2 => return Self::V2,
148 _ => return Self::UNKNOWN,
149 }
150 }
151}
152
153bitflags! {
154 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
156 pub struct PP2TlvClient: u8
157 {
158 const PP2_CLIENT_SSL = 0x01;
160
161 const PP2_CLIENT_CERT_CONN = 0x02;
163
164 const PP2_CLIENT_CERT_SESS = 0x04;
167 }
168}
169
170#[test]
171fn ttt()
172{
173 let bi: u8 = 7;
174
175 println!("{} {:?}", PP2TlvClient::all().bits(), PP2TlvClient::from_bits(bi));
176}
177
178#[derive(Clone, Debug, PartialEq, Eq)]
179pub struct PP2TlvsTypeSsl
180{
181 pub(crate) client: PP2TlvClient,
183
184 pub(crate) verify: u32,
187
188 pub(crate) sub_tlv: Vec<PP2Tlvs>
190}
191
192impl fmt::Display for PP2TlvsTypeSsl
193{
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
195 {
196 write!(f, "CLIENT: {:?}, VERIFY: {}, TLVs: {}",
197 self.client, self.verify,
198 self.sub_tlv.iter().map(|t| t.to_string()).collect::<Vec<String>>().join(", "))
199 }
200}
201
202#[repr(u8)]
213#[derive(Clone, Debug, PartialEq, Eq)]
214pub enum PP2Tlvs
215{
216 TypeAlpn(Vec<Vec<u8>>) = Self::TYPE_ALPN,
218
219 TypeAuthority(String) = Self::TYPE_AUTHORITY,
222
223 TypeCrc32c(u32) = Self::TYPE_CRC32C,
225
226 TypeNoop = Self::TYPE_NOOP,
230
231 TypeUniqId(Vec<u8>) = Self::TYPE_UNIQID,
234
235 TypeSsl
237 {
238 client: PP2TlvClient,
239 verify: u32,
240 } = Self::TYPE_SSL,
241
242 TypeSubtypeSslVersion(Cow<'static, str>) = Self::TYPE_SUBTYPE_SSL_VERSION,
244
245 TypeSubtypeSslCn(Cow<'static, str>) = Self::TYPE_SUBTYPE_SSL_CN,
249
250 TypeSubtypeSslCipher(Cow<'static, str>) = Self::TYPE_SUBTYPE_SSL_CIPHER,
252
253 TypeSubtypeSslSigAlg(Cow<'static, str>) = Self::TYPE_SUBTYPE_SSL_SIGALG,
257
258 TypeSubtypeSslKeyAlg(Cow<'static, str>) = Self::TYPE_SUBTYPE_SSL_KEYALG,
262
263 TypeNetNs(String) = Self::TYPE_NETNS,
265}
266
267impl fmt::Display for PP2Tlvs
268{
269 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
270 {
271 let id : u8= self.into();
272
273 match self
274 {
275 PP2Tlvs::TypeAlpn(alpns) =>
276 {
277 let alpns_dec =
278 alpns
279 .iter()
280 .map(
281 |a|
282 std
283 ::str
284 ::from_utf8(a)
285 .map_err(|e| map_error!(MalformedData, "{}", e))
286 )
287 .collect::<HaProxRes<Vec<&str>>>()
288 .map_err(|_e| fmt::Error)?
289 .join(",");
290
291 write!(f, "ALPNS({:02X}): {}", id, alpns_dec)
292 },
293 PP2Tlvs::TypeAuthority(sni) =>
294 write!(f, "SNI({:02X}): {}", id, sni),
295 PP2Tlvs::TypeCrc32c(crc) =>
296 write!(f, "CRC({:02X}): {}", id, crc),
297 PP2Tlvs::TypeNoop =>
298 write!(f, "NOOP({:02X})", id),
299 PP2Tlvs::TypeUniqId(items) =>
300 write!(f, "UNIQID({:02X}): {:02X?}", id, items),
301 PP2Tlvs::TypeSsl{client, verify} =>
302 write!(f, "SSL({:02X}): client: {:?}, verify: {}", id, client, verify),
303 PP2Tlvs::TypeSubtypeSslVersion(ver) =>
304 write!(f, "SSL VERSION({:02X}): {}", id, ver),
305 PP2Tlvs::TypeSubtypeSslCn(cn) =>
306 write!(f, "SSL CN({:02X}): {}", id, cn),
307 PP2Tlvs::TypeSubtypeSslCipher(c) =>
308 write!(f, "SSL CIPHER({:02X}): {}", id, c),
309 PP2Tlvs::TypeSubtypeSslSigAlg(sa) =>
310 write!(f, "SSL SIGALG({:02X}): {}", id, sa),
311 PP2Tlvs::TypeSubtypeSslKeyAlg(ka) =>
312 write!(f, "SSL KEYALG({:02X}): {}", id, ka),
313 PP2Tlvs::TypeNetNs(ns) =>
314 write!(f, "NETNS({:02X}): {}", id, ns),
315 }
316 }
317}
318
319impl From<PP2Tlvs> for u8
320{
321 fn from(value: PP2Tlvs) -> Self
322 {
323 return (&value).into();
324 }
325}
326
327impl From<&PP2Tlvs> for u8
328{
329 fn from(value: &PP2Tlvs) -> Self
330 {
331 return unsafe { *<*const _>::from(value).cast::<Self>() };
332 }
333}
334
335
336
337impl PP2Tlvs
338{
339 pub const TLV_TYPE_MAIN_RANGES: &'static [RangeInclusive<u8>] =
341 &[
342 Self::TYPE_ALPN..=Self::TYPE_SSL,
343 Self::TYPE_NETNS ..= Self::TYPE_NETNS
344 ];
345
346 pub const TLV_TYPE_SSL_SUB_RANGE: &'static [RangeInclusive<u8>] =
348 &[Self::TYPE_SUBTYPE_SSL_VERSION ..= Self::TYPE_SUBTYPE_SSL_KEYALG];
349
350 pub const TYPE_ALPN: u8 = 0x01;
351
352 pub const TYPE_AUTHORITY: u8 = 0x02;
353
354 pub const TYPE_CRC32C: u8 = 0x03;
355
356 pub const TYPE_NOOP: u8 = 0x04;
357
358 pub const TYPE_UNIQID: u8 = 0x05;
359
360 pub const TYPE_SSL: u8 = 0x20;
361
362 pub const TYPE_SUBTYPE_SSL_VERSION: u8 = 0x21;
363
364 pub const TYPE_SUBTYPE_SSL_CN: u8 = 0x22;
365
366 pub const TYPE_SUBTYPE_SSL_CIPHER: u8 = 0x23;
367
368 pub const TYPE_SUBTYPE_SSL_SIGALG: u8 = 0x24;
369
370 pub const TYPE_SUBTYPE_SSL_KEYALG: u8 = 0x25;
371
372 pub const TYPE_NETNS: u8 = 0x30;
373
374 pub
375 fn contains_subtype(&self) -> bool
376 {
377 let Self::TypeSsl{ .. } = self else { return false };
378
379 return true;
380 }
381
382 pub
383 fn conntains_subtype_discr(discr: u8) -> bool
384 {
385 return discr == Self::TYPE_SSL;
386 }
387}
388
389#[repr(u8)]
393#[derive(Clone, Copy, Debug, PartialEq, Eq)]
394pub enum ProxyV2AddrType
395{
396 AfUnspec = 0x00,
403
404 AfInet = 0x01,
409
410 AfInet6 = 0x02,
415
416 AfUnix = 0x03,
420}
421
422impl From<ProxyV2AddrType> for u8
423{
424 fn from(value: ProxyV2AddrType) -> Self
425 {
426 return value as u8;
427 }
428}
429
430impl ProxyV2AddrType
431{
432 pub const DEF_IPV4_ADDR_LEN: u16 = 12;
433 pub const DEF_IPV6_ADDR_LEN: u16 = 36;
434 pub const DEF_UNIX_ADDR_LEN: u16 = 216;
435
436 pub(crate)
437 fn decode(raw: u8) -> HaProxRes<Self>
438 {
439 match raw >> 4
440 {
441 r if r == ProxyV2AddrType::AfUnspec.into() =>
442 return Ok(Self::AfUnspec),
443 r if r == ProxyV2AddrType::AfInet.into() =>
444 return Ok(Self::AfInet),
445 r if r == ProxyV2AddrType::AfInet6.into() =>
446 return Ok(Self::AfInet6),
447 r if r == ProxyV2AddrType::AfUnix.into() =>
448 return Ok(Self::AfUnix),
449 r =>
450 return_error!(ProtocolUnknownData, "can not decode address type: '{:02X}'", r),
451 }
452 }
453
454 pub
455 fn get_size_by_addr_family(&self) -> Option<u16>
456 {
457 match self
458 {
459 Self::AfUnspec =>
460 return None,
461 Self::AfInet =>
462 return Some(Self::DEF_IPV4_ADDR_LEN),
463 Self::AfInet6 =>
464 return Some(Self::DEF_IPV6_ADDR_LEN),
465 Self::AfUnix =>
466 return Some(Self::DEF_UNIX_ADDR_LEN),
467 }
468 }
469}
470
471
472#[derive(Clone, Debug)]
482pub enum ProxyV2Addr
483{
484 Ip
486 {
487 src: SocketAddr,
488 dst: SocketAddr,
489 },
490
491 Unix
493 {
494 src: net::SocketAddr,
495 dst: net::SocketAddr,
496 }
497}
498
499impl Eq for ProxyV2Addr {}
500
501impl PartialEq for ProxyV2Addr
502{
503 fn eq(&self, other: &Self) -> bool
504 {
505 match (self, other)
506 {
507 (
508 Self::Ip { src: l_src, dst: l_dst },
509 Self::Ip { src: r_src, dst: r_dst }
510 ) =>
511 l_src == r_src && l_dst == r_dst,
512
513 (
514 Self::Unix { src: l_src, dst: l_dst },
515 Self::Unix { src: r_src, dst: r_dst }
516 ) =>
517 l_src.as_pathname() == r_src.as_pathname() && l_dst.as_pathname() == r_dst.as_pathname(),
518 _ => false,
519 }
520 }
521}
522
523impl fmt::Display for ProxyV2Addr
524{
525 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
526 {
527 match self
528 {
529 ProxyV2Addr::Ip{ src, dst } =>
530 write!(f, "SRC: {}, DST: {}", src, dst),
531 ProxyV2Addr::Unix{ src, dst } =>
532 write!(f, "SRC: {:?}, DST: {:?}", src, dst)
533 }
534 }
535}
536
537impl TryFrom<(IpAddr, u16, IpAddr, u16)> for ProxyV2Addr
538{
539 type Error = HaProxErr;
540
541 fn try_from(value: (IpAddr, u16, IpAddr, u16)) -> Result<Self, Self::Error>
551 {
552 let src = SocketAddr::new(value.0, value.1);
553 let dst = SocketAddr::new(value.2, value.3);
554
555 return Ok(Self::Ip{ src: src, dst: dst });
556 }
557}
558
559impl TryFrom<(SocketAddr, SocketAddr)> for ProxyV2Addr
560{
561 type Error = HaProxErr;
562
563 fn try_from(value: (SocketAddr, SocketAddr)) -> Result<Self, Self::Error>
569 {
570 return Ok(Self::Ip{ src: value.0, dst: value.1 });
571 }
572}
573
574impl TryFrom<(net::SocketAddr, net::SocketAddr)> for ProxyV2Addr
575{
576 type Error = HaProxErr;
577
578 fn try_from(value: (net::SocketAddr, net::SocketAddr)) -> Result<Self, Self::Error>
584 {
585 return Ok(Self::Unix{ src: value.0, dst: value.1 });
586 }
587}
588
589
590impl TryFrom<(&str, &str)> for ProxyV2Addr
591{
592 type Error = HaProxErr;
593
594 fn try_from(value: (&str, &str)) -> Result<Self, Self::Error>
600 {
601 if let Ok(src) = SocketAddr::from_str(value.0)
602 {
603 let Ok(dst) = SocketAddr::from_str(value.1)
604 else
605 {
606 return_error!(ArgumentEinval, "can not convert '{}' to SocketAddr",
607 common::sanitize_str_unicode(value.1));
608 };
609
610 return Ok(Self::Ip{ src: src, dst: dst });
611 }
612 else if let Ok(src) = net::SocketAddr::from_pathname(value.0)
613 {
614 let Ok(dst) = net::SocketAddr::from_pathname(value.1)
615 else
616 {
617 return_error!(ArgumentEinval, "can not convert '{}' to net::SocketAddr",
618 common::sanitize_str_unicode(value.1));
619 };
620
621 return Ok(Self::Unix{ src: src, dst: dst });
622 }
623 else
624 {
625 return_error!(ArgumentEinval, "can not convert '{}' to either SocketAddr or net::SocketAddr",
626 common::sanitize_str_unicode(value.0));
627 }
628 }
629}
630
631impl ProxyV2Addr
632{
633 #[inline]
634 pub
635 fn get_len(&self) -> u16
636 {
637 return self.as_addr_family().get_size_by_addr_family().unwrap();
638 }
639
640 #[inline]
642 pub
643 fn as_addr_family(&self) -> ProxyV2AddrType
644 {
645 match self
646 {
647 ProxyV2Addr::Ip{ src, .. } =>
648 {
649 if src.is_ipv4() == true
650 {
651 return ProxyV2AddrType::AfInet;
652 }
653 else
654 {
655 return ProxyV2AddrType::AfInet6;
656 }
657 }
658 ProxyV2Addr::Unix{ .. } =>
659 return ProxyV2AddrType::AfUnix
660 }
661 }
662
663 pub
672 fn read(addr_fam: ProxyV2AddrType, cur: &mut Cursor<&[u8]>) -> HaProxRes<Option<Self>>
673 {
674 match addr_fam
675 {
676 ProxyV2AddrType::AfUnspec => Ok(None),
677 ProxyV2AddrType::AfInet =>
678 {
679 let src = IpAddr::from(Ipv4Addr::from_bits(cur.read_u32::<BigEndian>().map_err(common::map_io_err)?));
680 let dst = IpAddr::from(Ipv4Addr::from_bits(cur.read_u32::<BigEndian>().map_err(common::map_io_err)?));
681 let src_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
682 let dst_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
683
684 return Ok(Some(Self::try_from((src, src_port, dst, dst_port))?));
685 },
686 ProxyV2AddrType::AfInet6 =>
687 {
688 let src = IpAddr::from(Ipv6Addr::from_bits(cur.read_u128::<BigEndian>().map_err(common::map_io_err)?));
689 let dst = IpAddr::from(Ipv6Addr::from_bits(cur.read_u128::<BigEndian>().map_err(common::map_io_err)?));
690 let src_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
691 let dst_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
692
693 return Ok(Some(Self::try_from((src, src_port, dst, dst_port))?));
694 },
695 ProxyV2AddrType::AfUnix =>
696 {
697 let mut n_src: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
698 cur.read(&mut n_src).map_err(common::map_io_err)?;
699
700 let mut n_dst: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
701 cur.read(&mut n_dst).map_err(common::map_io_err)?;
702
703 let src_s =
704 net::SocketAddr::from_pathname(
705 CStr::from_bytes_until_nul(&n_src)
706 .map_err(|e|
707 map_error!(MalformedData, "cannot read unix path, error: {}", e)
708 )?
709 .to_str()
710 .map_err(|e|
711 map_error!(MalformedData, "cannot read unix path, error: {}", e)
712 )?
713 )
714 .map_err(|e|
715 map_error!(MalformedData, "cannot read unix path, error: {}", e)
716 )?;
717
718 let dst_s =
719 net::SocketAddr::from_pathname(
720 CStr::from_bytes_until_nul(&n_dst)
721 .map_err(|e|
722 map_error!(MalformedData, "cannot read unix path, error: {}", e)
723 )?
724 .to_str()
725 .map_err(|e|
726 map_error!(MalformedData, "cannot read unix path, error: {}", e)
727 )?
728 )
729 .map_err(|e|
730 map_error!(MalformedData, "cannot read unix path, error: {}", e)
731 )?;
732
733 return Ok(Some(Self::try_from((src_s, dst_s))?));
734 },
735 }
736 }
737
738 pub
742 fn write(&self, cur: &mut Cursor<Vec<u8>>) -> HaProxRes<()>
743 {
744 match self
745 {
746 ProxyV2Addr::Ip{ src, dst } =>
747 {
748 match src.ip()
749 {
750 IpAddr::V4(ipv4_addr) =>
751 cur.write_u32::<BigEndian>(ipv4_addr.to_bits()).map_err(common::map_io_err)?,
752 IpAddr::V6(ipv6_addr) =>
753 cur.write_u128::<BigEndian>(ipv6_addr.to_bits()).map_err(common::map_io_err)?,
754 }
755
756 match dst.ip()
757 {
758 IpAddr::V4(ipv4_addr) =>
759 cur.write_u32::<BigEndian>(ipv4_addr.to_bits()).map_err(common::map_io_err)?,
760 IpAddr::V6(ipv6_addr) =>
761 cur.write_u128::<BigEndian>(ipv6_addr.to_bits()).map_err(common::map_io_err)?,
762 }
763
764 cur.write_u16::<BigEndian>(src.port()).map_err(common::map_io_err)?;
765 cur.write_u16::<BigEndian>(dst.port()).map_err(common::map_io_err)?;
766 },
767 ProxyV2Addr::Unix { src, dst } =>
768 {
769 let src_p =
770 src.as_pathname().ok_or_else(|| map_error!(ArgumentEinval, "UNIX src socket addr is not path"))?;
771 let dst_p =
772 dst.as_pathname().ok_or_else(|| map_error!(ArgumentEinval, "UNIX src socket addr is not path"))?;
773
774 let src_b = src_p.as_os_str().as_bytes();
775 let dst_b = dst_p.as_os_str().as_bytes();
776
777 if src_b.len() > HEADER_UNIX_ADDR_LEN
778 {
779 return_error!(ArgumentEinval, "socket path: '{}' longer than: '{}'",
780 src_p.display(), HEADER_UNIX_ADDR_LEN);
781 }
782 else if dst_b.len() > HEADER_UNIX_ADDR_LEN
783 {
784 return_error!(ArgumentEinval, "socket path: '{}' longer than: '{}'",
785 dst_p.display(), HEADER_UNIX_ADDR_LEN);
786 }
787
788
789 let mut n_src: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
790 n_src[0..src_b.len()].copy_from_slice(src_b);
791
792 cur.write_all(&n_src).map_err(common::map_io_err)?;
793
794 let mut n_dst: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
795 n_dst[0..dst_b.len()].copy_from_slice(dst_b);
796
797 cur.write_all(&n_dst).map_err(common::map_io_err)?;
798 }
799 }
800
801 return Ok(());
802 }
803}
804
805#[repr(u8)]
809#[derive(Clone, Debug, PartialEq, Eq)]
810pub enum ProxyTransportFam
811{
812 UNSPEC = 0x00,
818
819 STREAM,
824
825 DGRAM,
830}
831
832impl fmt::Display for ProxyTransportFam
833{
834 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
835 {
836 match self
837 {
838 Self::UNSPEC => write!(f, "UNSPEC"),
839 Self::STREAM => write!(f, "STREAM"),
840 Self::DGRAM => write!(f, "DGRAM"),
841 }
842 }
843}
844
845impl From<ProxyTransportFam> for u8
846{
847 fn from(value: ProxyTransportFam) -> Self
848 {
849 return value as u8;
850 }
851}
852
853impl From<&ProxyTransportFam> for u8
854{
855 fn from(value: &ProxyTransportFam) -> Self
856 {
857 return unsafe { *<*const _>::from(value).cast::<Self>() };
858 }
859}
860
861impl ProxyTransportFam
862{
863 pub(crate)
864 fn decode(value: u8) -> HaProxRes<Self>
865 {
866 match value & protocol_raw::ProxyHdrV2::TRANSPT_MASK
867 {
868 v if ProxyTransportFam::UNSPEC as u8 == v => return Ok(Self::UNSPEC),
869 v if ProxyTransportFam::STREAM as u8 == v => return Ok(Self::STREAM),
870 v if ProxyTransportFam::DGRAM as u8 == v => return Ok(Self::DGRAM),
871 _ => return_error!(ProtocolUnknownData, "unknown transport {:02X}", value)
872 }
873 }
874}
875
876#[cfg(test)]
877mod tests
878{
879 use core::fmt;
880 use std::{slice, time::Instant};
881
882 use crate::protocol::{protocol::{PP2TlvClient, ProxyTransportFam, ProxyV2Addr}, protocol_composer::{HdrV2OpLocal, HdrV2OpProxy, ProxyHdrV2}, protocol_raw::{self, HEADER_MAGIC_V2, HEADER_MAGINC_LEN}, PP2TlvUniqId};
883 #[test]
884 fn test_hdr1()
885 {
886
887 for _ in 0..10
888 {
889 let s = Instant::now();
890 let _local = ProxyHdrV2::<HdrV2OpLocal>::new();
891
892 let e = s.elapsed();
893
894 println!("{:?}", e);
895 }
896
897 let buf = ProxyHdrV2::<HdrV2OpLocal>::new();
898
899
900
901 let mut sign: [u8; HEADER_MAGINC_LEN] = [0_u8; HEADER_MAGINC_LEN];
902 sign.copy_from_slice(HEADER_MAGIC_V2);
903 let ctrl =
904 vec![
905 protocol_raw::ProxyHdrV2
906 {
907 signature: sign,
908 ver_cmd: 0x20,
909 fam: 0,
910 len: 0,
911 address: [],
912 }
913 ];
914
915 println!("{} {}", buf.len(), size_of::<protocol_raw::ProxyHdrV2>());
916 let ctrl_buf = unsafe { slice::from_raw_parts(ctrl.as_ptr() as *const _ as *const u8, size_of::<protocol_raw::ProxyHdrV2>()) };
917
918 assert_eq!(buf.as_slice(), ctrl_buf);
919 }
920
921 #[test]
922 fn test_proxy_compose()
923 {
924 struct UniqIdHolder;
925 impl UniqIdHolder
926 {
927 const ID: &'static [u8] = b"ABCD12345678901234567890";
928 }
929 impl fmt::Display for UniqIdHolder
930 {
931 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
932 {
933 write!(f, "")
934 }
935 }
936 impl PP2TlvUniqId for UniqIdHolder
937 {
938 fn into_bytes(&self) -> Vec<u8>
939 {
940 Self::ID.to_vec()
941 }
942
943 fn get_len(&self) -> u16
944 {
945 Self::ID.len() as u16
946 }
947 }
948 for _ in 0..10
949 {
950 let addr: ProxyV2Addr = ProxyV2Addr::try_from(("127.0.0.1:4567", "127.0.0.1:443")).unwrap();
951 let id = UniqIdHolder;
952
953 let s = Instant::now();
954 let mut proxy =
955 ProxyHdrV2::<HdrV2OpProxy>::new(ProxyTransportFam::STREAM, addr).unwrap();
956
957 let mut plts = proxy.set_plts();
958 plts.add_crc32().unwrap();
959 plts.add_authority("www.example.com").unwrap();
960 plts.add_uniq_id(id).unwrap();
961 drop(plts);
962
963 let e = s.elapsed();
964
965 println!("prep: {:?}", e);
966
967 let s = Instant::now();
968 let _buf: Vec<u8> = proxy.try_into().unwrap();
969 let e = s.elapsed();
970
971 println!("{:?}", e);
972 }
973
974 return;
976 }
977
978 #[test]
979 fn test_hdr2()
980 {
981 let addr: ProxyV2Addr = ProxyV2Addr::try_from(("127.0.0.1:39754", "127.0.0.67:11883")).unwrap();
982
983 let s = Instant::now();
984 let mut proxy =
985 ProxyHdrV2::<HdrV2OpProxy>::new(ProxyTransportFam::STREAM, addr).unwrap();
986
987 let plts = proxy.set_plts();
988
989 let mut sub_ssl = plts.add_ssl(PP2TlvClient::PP2_CLIENT_SSL, 0).unwrap();
990
991 sub_ssl.add_ssl_sub_version("TLSv1.2").unwrap();
992
993 sub_ssl.done().unwrap();
994
995
996 let e = s.elapsed();
997
998 println!("prep: {:?}", e);
999
1000 let s = Instant::now();
1001 let buf: Vec<u8> = proxy.try_into().unwrap();
1002 let e = s.elapsed();
1003
1004 println!("{:?}", e);
1005
1006
1007 let reference =
1008 b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x1e\
1009 \x7f\x00\x00\x01\x7f\x00\x00\x43\x9b\x4a\x2e\x6b\x20\x00\x0f\x01\
1010 \x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32";
1011
1012 assert_eq!(buf.as_slice(), reference.as_slice());
1015 }
1016}