1use std::borrow::Cow;
16use std::ffi::CStr;
17use std::fmt;
18use std::io::{Cursor, Read, Write};
19use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
20use std::ops::RangeInclusive;
21use std::os::unix::ffi::OsStrExt;
22use std::os::unix::net;
23use std::str::FromStr;
24
25use bitflags::bitflags;
26use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
27
28use crate::{ReadExtZeroCopy, common, map_error, return_error};
29use crate::error::{HaProxErr, HaProxRes};
30
31use crate::protocol_raw::{self, HEADER_UNIX_ADDR_LEN};
32
33pub const PP2_TYPE_MIN_CUSTOM: u8 = 0xE0;
41
42pub const PP2_TYPE_MAX_CUSTOM: u8 = 0xEF;
45
46pub const PP2_TYPE_MIN_EXPERIMENT: u8 = 0xF0;
53
54pub const PP2_TYPE_MAX_EXPERIMENT: u8 = 0xF7;
57
58pub const PP2_TYPE_MIN_FUTURE: u8 = 0xF8;
64
65pub const PP2_TYPE_MAX_FUTURE: u8 = 0xFF;
67
68
69pub const MAX_UNIQ_ID_LEN_BYTES: u16 = 128;
72
73pub const TLV_HEADER_LEN: u16 = 3;
75
76
77
78#[repr(u8)]
83#[derive(Clone, Copy, PartialEq, Eq, Debug)]
84pub enum HdrV2Command
85{
86 LOCAL = 0,
87 PROXY = 1,
88 UNKNOWN,
89}
90
91impl From<HdrV2Command> for u8
92{
93 fn from(value: HdrV2Command) -> Self
94 {
95 if value == HdrV2Command::UNKNOWN
96 {
97 panic!("can not encode the unknown command");
98 }
99
100 return value as u8;
101 }
102}
103
104impl HdrV2Command
105{
106 pub(crate)
107 fn decode(raw: u8) -> Self
108 {
109 match raw & protocol_raw::ProxyHdrV2::COMMAND_MASK
110 {
111 r if r == HdrV2Command::LOCAL.into() => return Self::LOCAL,
112 r if r == HdrV2Command::PROXY.into() => return Self::PROXY,
113 _ => return Self::UNKNOWN,
114 }
115 }
116}
117
118#[repr(u8)]
120#[derive(Clone, Copy, PartialEq, Eq, Debug)]
121pub enum ProtocolVersion
122{
123 V1 = 1,
124 V2 = 2,
125 UNKNOWN,
126}
127
128impl From<ProtocolVersion> for u8
129{
130 fn from(value: ProtocolVersion) -> Self
131 {
132 if value == ProtocolVersion::UNKNOWN
133 {
134 panic!("can not encode the unknown version");
135 }
136
137 return (value as u8) << 4;
138 }
139}
140
141impl ProtocolVersion
142{
143 pub(crate)
144 fn decode(raw: u8) -> Self
145 {
146 match raw >> 4
147 {
148 1 => return Self::V1,
149 2 => return Self::V2,
150 _ => return Self::UNKNOWN,
151 }
152 }
153}
154
155bitflags! {
156 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
158 pub struct PP2TlvClient: u8
159 {
160 const PP2_CLIENT_SSL = 0x01;
162
163 const PP2_CLIENT_CERT_CONN = 0x02;
165
166 const PP2_CLIENT_CERT_SESS = 0x04;
169 }
170}
171
172#[derive(Clone, Debug, PartialEq, Eq)]
174pub struct PP2TlvsTypeSsl<'zc>
175{
176 pub(crate) client: PP2TlvClient,
178
179 pub(crate) verify: u32,
182
183 pub(crate) sub_tlv: Vec<PP2Tlvs<'zc>>
185}
186
187impl<'zc> fmt::Display for PP2TlvsTypeSsl<'zc>
188{
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
190 {
191 write!(f, "CLIENT: {:?}, VERIFY: {}, TLVs: {}",
192 self.client, self.verify,
193 self.sub_tlv.iter().map(|t| t.to_string()).collect::<Vec<String>>().join(", "))
194 }
195}
196
197#[repr(u8)]
208#[derive(Clone, Debug, PartialEq, Eq)]
209pub enum PP2Tlvs<'zc>
210{
211 TypeAlpn(Cow<'zc, [Cow<'zc, [u8]>]>) = PP2Tlvs::TYPE_ALPN,
213
214 TypeAuthority(Cow<'zc, str>) = PP2Tlvs::TYPE_AUTHORITY,
217
218 TypeCrc32c(u32) = PP2Tlvs::TYPE_CRC32C,
220
221 TypeNoop = PP2Tlvs::TYPE_NOOP,
225
226 TypeUniqId(Cow<'zc, [u8]>) = PP2Tlvs::TYPE_UNIQID,
229
230 TypeSsl
232 {
233 client: PP2TlvClient,
234 verify: u32,
235 } = PP2Tlvs::TYPE_SSL,
236
237 TypeSubtypeSslVersion(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_VERSION,
239
240 TypeSubtypeSslCn(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_CN,
244
245 TypeSubtypeSslCipher(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_CIPHER,
247
248 TypeSubtypeSslSigAlg(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_SIGALG,
252
253 TypeSubtypeSslKeyAlg(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_KEYALG,
257
258 TypeSubTypeSslGroup(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_GROUP,
261
262 TypeSubTypeSslSigScheme(Cow<'zc, str>) = PP2Tlvs::TYPE_SUBTYPE_SSL_SIG_SCHEME,
265
266 TypeNetNs(Cow<'zc, str>) = PP2Tlvs::TYPE_NETNS,
268}
269
270impl<'zc> fmt::Display for PP2Tlvs<'zc>
271{
272 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
273 {
274 let id: u8 = self.into();
275
276 match self
277 {
278 Self::TypeAlpn(alpns) =>
279 {
280 let alpns_dec =
281 alpns
282 .iter()
283 .map(
284 |a|
285 std
286 ::str
287 ::from_utf8(a)
288 .map_err(|e| map_error!(MalformedData, "{}", e))
289 )
290 .collect::<HaProxRes<Vec<&str>>>()
291 .map_err(|_e| fmt::Error)?
292 .join(",");
293
294 write!(f, "ALPNS({:02X}): {}", id, alpns_dec)
295 },
296 Self::TypeAuthority(sni) =>
297 write!(f, "SNI({:02X}): {}", id, sni),
298 Self::TypeCrc32c(crc) =>
299 write!(f, "CRC({:02X}): {}", id, crc),
300 Self::TypeNoop =>
301 write!(f, "NOOP({:02X})", id),
302 Self::TypeUniqId(items) =>
303 write!(f, "UNIQID({:02X}): {:02X?}", id, items),
304 Self::TypeSsl{client, verify} =>
305 write!(f, "SSL({:02X}): client: {:?}, verify: {}", id, client, verify),
306 Self::TypeSubtypeSslVersion(ver) =>
307 write!(f, "SSL VERSION({:02X}): {}", id, ver),
308 Self::TypeSubtypeSslCn(cn) =>
309 write!(f, "SSL CN({:02X}): {}", id, cn),
310 Self::TypeSubtypeSslCipher(c) =>
311 write!(f, "SSL CIPHER({:02X}): {}", id, c),
312 Self::TypeSubtypeSslSigAlg(sa) =>
313 write!(f, "SSL SIGALG({:02X}): {}", id, sa),
314 Self::TypeSubtypeSslKeyAlg(ka) =>
315 write!(f, "SSL KEYALG({:02X}): {}", id, ka),
316 Self::TypeSubTypeSslGroup(group) =>
317 write!(f, "SSL GROUP({:02X}): {}", id, group),
318 Self::TypeSubTypeSslSigScheme(sig) =>
319 write!(f, "SSL SIG_SCHEME({:02X}): {}", id, sig),
320 Self::TypeNetNs(ns) =>
321 write!(f, "NETNS({:02X}): {}", id, ns),
322 }
323 }
324}
325
326impl<'zc> From<PP2Tlvs<'zc>> for u8
327{
328 fn from(value: PP2Tlvs<'zc>) -> Self
329 {
330 return (&value).into();
331 }
332}
333
334impl<'zc> From<&PP2Tlvs<'zc>> for u8
335{
336 fn from(value: &PP2Tlvs) -> Self
337 {
338 return unsafe { *<*const _>::from(value).cast::<Self>() };
339 }
340}
341
342
343
344impl<'zc> PP2Tlvs<'zc>
345{
346 pub const TLV_TYPE_MAIN_RANGES: &'static [RangeInclusive<u8>] =
348 &[
349 Self::TYPE_ALPN..=Self::TYPE_SSL,
350 Self::TYPE_NETNS ..= Self::TYPE_NETNS
351 ];
352
353 pub const TLV_TYPE_SSL_SUB_RANGE: &'static [RangeInclusive<u8>] =
355 &[Self::TYPE_SUBTYPE_SSL_VERSION ..= Self::TYPE_SUBTYPE_SSL_SIG_SCHEME];
356
357 pub const TYPE_ALPN: u8 = 0x01;
358
359 pub const TYPE_AUTHORITY: u8 = 0x02;
360
361 pub const TYPE_CRC32C: u8 = 0x03;
362
363 pub const TYPE_NOOP: u8 = 0x04;
364
365 pub const TYPE_UNIQID: u8 = 0x05;
366
367 pub const TYPE_SSL: u8 = 0x20;
368
369 pub const TYPE_SUBTYPE_SSL_VERSION: u8 = 0x21;
370
371 pub const TYPE_SUBTYPE_SSL_CN: u8 = 0x22;
372
373 pub const TYPE_SUBTYPE_SSL_CIPHER: u8 = 0x23;
374
375 pub const TYPE_SUBTYPE_SSL_SIGALG: u8 = 0x24;
376
377 pub const TYPE_SUBTYPE_SSL_KEYALG: u8 = 0x25;
378
379 pub const TYPE_SUBTYPE_SSL_GROUP: u8 = 0x26;
381
382 pub const TYPE_SUBTYPE_SSL_SIG_SCHEME: u8 = 0x27;
383
384
385 pub const TYPE_NETNS: u8 = 0x30;
386
387 pub
388 fn contains_subtype(&self) -> bool
389 {
390 let Self::TypeSsl{ .. } = self else { return false };
391
392 return true;
393 }
394
395 pub
396 fn conntains_subtype_discr(discr: u8) -> bool
397 {
398 return discr == Self::TYPE_SSL;
399 }
400
401 pub(crate)
402 fn is_in_range(tlv_type: u8, tlv_parent_type: Option<u8>) -> bool
403 {
404 if let Some(p_tlv) = tlv_parent_type
405 {
406 if p_tlv == Self::TYPE_SSL
407 {
408 return Self::TLV_TYPE_SSL_SUB_RANGE.iter().any(|tlv| tlv.contains(&tlv_type));
409 }
410 else
411 {
412 return false;
413 }
414 }
415
416 return Self::TLV_TYPE_MAIN_RANGES.iter().any(|tlv| tlv.contains(&tlv_type));
417 }
418
419 pub(crate)
420 fn restore_copying(tlv_type: u8, cur: &mut Cursor<&'zc [u8]>) -> HaProxRes<Self>
421 {
422 let tlv_len = cur.get_ref().len();
423
424 match tlv_type
425 {
426 Self::TYPE_ALPN =>
427 {
428 let mut alpns: Vec<Cow<'zc, [u8]>> = Vec::with_capacity(2);
429
430 while let Some(alpn_len) = cur.read_u16::<BigEndian>().ok()
431 {
432 let mut alpn: Vec<u8> = vec![0_u8; alpn_len as usize];
433
434 cur.read_exact(&mut alpn).map_err(common::map_io_err)?;
435
436 alpns.push(alpn.into());
437 }
438
439 return Ok(Self::TypeAlpn(alpns.into()));
440 },
441 Self::TYPE_AUTHORITY =>
442 {
443 let mut authority: Vec<u8> = vec![0_u8; tlv_len];
444
445 cur.read_exact(&mut authority).map_err(common::map_io_err)?;
446
447 return Ok(
448 Self::TypeAuthority(
449 String::from_utf8(authority)
450 .map_err(|e|
451 map_error!(MalformedData, "TLV TYPE_AUTHORITY restore error: '{}'", e)
452 )?
453 .into()
454 )
455 );
456 },
457 Self::TYPE_CRC32C =>
458 {
459 let crc = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
460
461 return Ok(Self::TypeCrc32c(crc));
462 },
463 Self::TYPE_NOOP =>
464 {
465 return Ok(Self::TypeNoop);
466 },
467 Self::TYPE_UNIQID =>
468 {
469 let mut authority: Vec<u8> = vec![0_u8; tlv_len];
470
471 cur.read_exact(&mut authority).map_err(common::map_io_err)?;
472
473 return Ok(
474 Self::TypeUniqId(authority.into())
475 );
476 },
477 Self::TYPE_SSL =>
478 {
479 let client_bits = cur.read_u8().map_err(common::map_io_err)?;
480
481 let client =
482 PP2TlvClient::from_bits(client_bits)
483 .ok_or_else(|| map_error!(ProtocolUnknownData, "TLV TYPE_SSL unknown client bits: {}", client_bits))?;
484
485 let verify = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
486
487 return Ok(
488 Self::TypeSsl{ client: client, verify: verify }
489 );
490 },
491 Self::TYPE_SUBTYPE_SSL_VERSION =>
492 {
493 let mut ssl_version: Vec<u8> = vec![0_u8; tlv_len];
494
495 cur.read_exact(&mut ssl_version).map_err(common::map_io_err)?;
496
497 let ssl_version_str =
498 String::from_utf8(ssl_version)
499 .map_err(|e|
500 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
501 )
502 .and_then(|v|
503 common::is_printable_ascii_nowp(&v, "ssl_version")
504 .and(Ok(v))
505 )?;
506
507 return Ok(
508 Self::TypeSubtypeSslVersion(Cow::Owned(ssl_version_str))
509 );
510 },
511 Self::TYPE_SUBTYPE_SSL_CN =>
512 {
513 let mut ssl_cn: Vec<u8> = vec![0_u8; tlv_len];
514
515 cur.read_exact(&mut ssl_cn).map_err(common::map_io_err)?;
516
517 let ssl_cn =
518 String::from_utf8(ssl_cn)
519 .map_err(|e|
520 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
521 )?;
522
523 return Ok(
524 Self::TypeSubtypeSslCn(Cow::Owned(ssl_cn))
525 );
526 },
527 Self::TYPE_SUBTYPE_SSL_CIPHER =>
528 {
529 let mut ssl_cipher: Vec<u8> = vec![0_u8; tlv_len];
530
531 cur.read_exact(&mut ssl_cipher).map_err(common::map_io_err)?;
532
533 let ssl_cipher =
534 String::from_utf8(ssl_cipher)
535 .map_err(|e|
536 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
537 )
538 .and_then(|v|
539 common::is_printable_ascii_nowp(&v, "cipher")
540 .and(Ok(v))
541 )?;
542
543 return Ok(
544 Self::TypeSubtypeSslCipher(Cow::Owned(ssl_cipher))
545 );
546 },
547 Self::TYPE_SUBTYPE_SSL_SIGALG =>
548 {
549 let mut ssl_sigalg: Vec<u8> = vec![0_u8; tlv_len];
550
551 cur.read_exact(&mut ssl_sigalg).map_err(common::map_io_err)?;
552
553 let ssl_sigalg =
554 String::from_utf8(ssl_sigalg)
555 .map_err(|e|
556 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
557 )
558 .and_then(|v|
559 common::is_printable_ascii_nowp(&v, "sig_alg")
560 .and(Ok(v))
561 )?;
562
563 return Ok(
564 Self::TypeSubtypeSslSigAlg(Cow::Owned(ssl_sigalg))
565 );
566 },
567 Self::TYPE_SUBTYPE_SSL_KEYALG =>
568 {
569 let mut ssl_keyalg: Vec<u8> = vec![0_u8; tlv_len];
570
571 cur.read_exact(&mut ssl_keyalg).map_err(common::map_io_err)?;
572
573 let ssl_keyalg =
574 String::from_utf8(ssl_keyalg)
575 .map_err(|e|
576 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
577 )
578 .and_then(|v|
579 common::is_printable_ascii_nowp(&v, "key_alg")
580 .and(Ok(v))
581 )?;
582
583 return Ok(
584 Self::TypeSubtypeSslKeyAlg(Cow::Owned(ssl_keyalg))
585 );
586 },
587 Self::TYPE_SUBTYPE_SSL_GROUP =>
588 {
589 let mut ssl_group: Vec<u8> = vec![0_u8; tlv_len];
590
591 cur.read_exact(&mut ssl_group).map_err(common::map_io_err)?;
592
593 let ssl_group =
594 String::from_utf8(ssl_group)
595 .map_err(|e|
596 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
597 )
598 .and_then(|v|
599 common::is_printable_ascii_nowp(&v, "ssl_group")
600 .and(Ok(v))
601 )?;
602
603 return Ok(
604 Self::TypeSubTypeSslGroup(Cow::Owned(ssl_group))
605 );
606 },
607 Self::TYPE_SUBTYPE_SSL_SIG_SCHEME =>
608 {
609 let mut ssl_sig_scheme: Vec<u8> = vec![0_u8; tlv_len];
610
611 cur.read_exact(&mut ssl_sig_scheme).map_err(common::map_io_err)?;
612
613 let ssl_sig_scheme =
614 String::from_utf8(ssl_sig_scheme)
615 .map_err(|e|
616 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
617 )
618 .and_then(|v|
619 common::is_printable_ascii_nowp(&v, "ssl_sig_scheme")
620 .and(Ok(v))
621 )?;
622
623 return Ok(
624 Self::TypeSubTypeSslSigScheme(Cow::Owned(ssl_sig_scheme))
625 );
626 },
627 Self::TYPE_NETNS =>
628 {
629 let mut netns: Vec<u8> = vec![0_u8; tlv_len];
630
631 cur.read_exact(&mut netns).map_err(common::map_io_err)?;
632
633 let netns =
634 String::from_utf8(netns)
635 .map_err(|e|
636 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
637 )
638 .and_then(|v|
639 common::is_printable_ascii_nowp(&v, "netns")
640 .and(Ok(v))
641 )?;
642
643 return Ok(
644 Self::TypeNetNs(netns.into())
645 );
646 },
647 _ =>
648 return_error!(ProtocolUnknownData, "unknown TLV type: {}", tlv_type)
649 }
650 }
651
652 pub(crate)
653 fn restore_zerocopy(tlv_type: u8, cur: &mut Cursor<&'zc [u8]>) -> HaProxRes<Self>
654 {
655 let tlv_len = cur.get_ref().len();
656
657 match tlv_type
658 {
659 Self::TYPE_ALPN =>
660 {
661 let mut alpns: Vec<Cow<'zc, [u8]>> = Vec::with_capacity(2);
662
663 while let Some(alpn_len) = cur.read_u16::<BigEndian>().ok()
664 {
665 let alpn =
666 cur.borrow_exact(alpn_len as usize).map_err(common::map_io_err)?;
667
668 alpns.push(Cow::Borrowed(alpn));
669 }
670
671 return Ok(Self::TypeAlpn(alpns.into()));
672 },
673 Self::TYPE_AUTHORITY =>
674 {
675 let authority =
676 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
677
678 return Ok(
679 Self::TypeAuthority(
680 Cow::Borrowed(
681 str::from_utf8(authority)
682 .map_err(|e|
683 map_error!(MalformedData, "TLV TYPE_AUTHORITY restore error: '{}'", e)
684 )?
685 )
686 )
687 );
688 },
689 Self::TYPE_CRC32C =>
690 {
691 let crc = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
692
693 return Ok(Self::TypeCrc32c(crc));
694 },
695 Self::TYPE_NOOP =>
696 {
697 return Ok(Self::TypeNoop);
698 },
699 Self::TYPE_UNIQID =>
700 {
701 let uniq_id =
702 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
703
704 return Ok(
705 Self::TypeUniqId(Cow::Borrowed(uniq_id))
706 );
707 },
708 Self::TYPE_SSL =>
709 {
710 let client_bits = cur.read_u8().map_err(common::map_io_err)?;
711
712 let client =
713 PP2TlvClient::from_bits(client_bits)
714 .ok_or_else(|| map_error!(ProtocolUnknownData, "TLV TYPE_SSL unknown client bits: {}", client_bits))?;
715
716 let verify = cur.read_u32::<BigEndian>().map_err(common::map_io_err)?;
717
718 return Ok(
719 Self::TypeSsl{ client: client, verify: verify }
720 );
721 },
722 Self::TYPE_SUBTYPE_SSL_VERSION =>
723 {
724 let ssl_version =
725 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
726
727 let ssl_version_str =
728 str::from_utf8(ssl_version)
729 .map_err(|e|
730 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
731 )
732 .and_then(|v|
733 common::is_printable_ascii_nowp(&v, "ssl_version")
734 .and(Ok(v))
735 )?;
736
737 return Ok(
738 Self::TypeSubtypeSslVersion(Cow::Borrowed(ssl_version_str))
739 );
740 },
741 Self::TYPE_SUBTYPE_SSL_CN =>
742 {
743 let ssl_cn =
744 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
745
746 let ssl_cn =
747 str::from_utf8(ssl_cn)
748 .map_err(|e|
749 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
750 )?;
751
752 return Ok(
753 Self::TypeSubtypeSslCn(Cow::Borrowed(ssl_cn))
754 );
755 },
756 Self::TYPE_SUBTYPE_SSL_CIPHER =>
757 {
758 let ssl_cipher =
759 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
760
761 let ssl_cipher =
762 str::from_utf8(ssl_cipher)
763 .map_err(|e|
764 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
765 )
766 .and_then(|v|
767 common::is_printable_ascii_nowp(&v, "cipher")
768 .and(Ok(v))
769 )?;
770
771 return Ok(
772 Self::TypeSubtypeSslCipher(Cow::Borrowed(ssl_cipher))
773 );
774 },
775 Self::TYPE_SUBTYPE_SSL_SIGALG =>
776 {
777 let ssl_sigalg =
778 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
779
780 let ssl_sigalg =
781 str::from_utf8(ssl_sigalg)
782 .map_err(|e|
783 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
784 )
785 .and_then(|v|
786 common::is_printable_ascii_nowp(&v, "sig_alg")
787 .and(Ok(v))
788 )?;
789
790 return Ok(
791 Self::TypeSubtypeSslSigAlg(Cow::Borrowed(ssl_sigalg))
792 );
793 },
794 Self::TYPE_SUBTYPE_SSL_KEYALG =>
795 {
796 let ssl_keyalg =
797 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
798
799 let ssl_keyalg =
800 str::from_utf8(ssl_keyalg)
801 .map_err(|e|
802 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
803 )
804 .and_then(|v|
805 common::is_printable_ascii_nowp(&v, "key_alg")
806 .and(Ok(v))
807 )?;
808
809 return Ok(
810 Self::TypeSubtypeSslKeyAlg(Cow::Borrowed(ssl_keyalg))
811 );
812 },
813 Self::TYPE_SUBTYPE_SSL_GROUP =>
814 {
815 let ssl_group =
816 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
817
818 let ssl_group =
819 str::from_utf8(ssl_group)
820 .map_err(|e|
821 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
822 )
823 .and_then(|v|
824 common::is_printable_ascii_nowp(&v, "ssl_group")
825 .and(Ok(v))
826 )?;
827
828 return Ok(
829 Self::TypeSubTypeSslGroup(Cow::Borrowed(ssl_group))
830 );
831 },
832 Self::TYPE_SUBTYPE_SSL_SIG_SCHEME =>
833 {
834 let ssl_sig_scheme =
835 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
836
837 let ssl_sig_scheme =
838 str::from_utf8(ssl_sig_scheme)
839 .map_err(|e|
840 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
841 )
842 .and_then(|v|
843 common::is_printable_ascii_nowp(&v, "ssl_sig_scheme")
844 .and(Ok(v))
845 )?;
846
847 return Ok(
848 Self::TypeSubTypeSslSigScheme(Cow::Borrowed(ssl_sig_scheme))
849 );
850 },
851 Self::TYPE_NETNS =>
852 {
853 let netns =
854 cur.borrow_exact(tlv_len as usize).map_err(common::map_io_err)?;
855
856 let netns =
857 str::from_utf8(netns)
858 .map_err(|e|
859 map_error!(MalformedData, "TLV TYPE_SUBTYPE_SSL_VERSION restore error: '{}'", e)
860 )
861 .and_then(|v|
862 common::is_printable_ascii_nowp(&v, "netns")
863 .and(Ok(v))
864 )?;
865
866 return Ok(
867 Self::TypeNetNs(Cow::Borrowed(netns))
868 );
869 },
870 _ =>
871 return_error!(ProtocolUnknownData, "unknown TLV type: {}", tlv_type)
872 }
873 }
874}
875
876#[repr(u8)]
880#[derive(Clone, Copy, Debug, PartialEq, Eq)]
881pub enum ProxyV2AddrType
882{
883 AfUnspec = 0x00,
890
891 AfInet = 0x01,
896
897 AfInet6 = 0x02,
902
903 AfUnix = 0x03,
907}
908
909impl From<ProxyV2AddrType> for u8
910{
911 fn from(value: ProxyV2AddrType) -> Self
912 {
913 return value as u8;
914 }
915}
916
917impl ProxyV2AddrType
918{
919 pub const DEF_IPV4_ADDR_LEN: u16 = 12;
920 pub const DEF_IPV6_ADDR_LEN: u16 = 36;
921 pub const DEF_UNIX_ADDR_LEN: u16 = 216;
922
923 pub(crate)
924 fn decode(raw: u8) -> HaProxRes<Self>
925 {
926 match raw >> 4
927 {
928 r if r == ProxyV2AddrType::AfUnspec.into() =>
929 return Ok(Self::AfUnspec),
930 r if r == ProxyV2AddrType::AfInet.into() =>
931 return Ok(Self::AfInet),
932 r if r == ProxyV2AddrType::AfInet6.into() =>
933 return Ok(Self::AfInet6),
934 r if r == ProxyV2AddrType::AfUnix.into() =>
935 return Ok(Self::AfUnix),
936 r =>
937 return_error!(ProtocolUnknownData, "can not decode address type: '{:02X}'", r),
938 }
939 }
940
941 pub
942 fn get_size_by_addr_family(&self) -> Option<u16>
943 {
944 match self
945 {
946 Self::AfUnspec =>
947 return None,
948 Self::AfInet =>
949 return Some(Self::DEF_IPV4_ADDR_LEN),
950 Self::AfInet6 =>
951 return Some(Self::DEF_IPV6_ADDR_LEN),
952 Self::AfUnix =>
953 return Some(Self::DEF_UNIX_ADDR_LEN),
954 }
955 }
956}
957
958
959#[derive(Clone, Debug)]
969pub enum ProxyV2Addr
970{
971 Ip
973 {
974 src: SocketAddr,
975 dst: SocketAddr,
976 },
977
978 Unix
980 {
981 src: net::SocketAddr,
982 dst: net::SocketAddr,
983 }
984}
985
986impl Eq for ProxyV2Addr {}
987
988impl PartialEq for ProxyV2Addr
989{
990 fn eq(&self, other: &Self) -> bool
991 {
992 match (self, other)
993 {
994 (
995 Self::Ip { src: l_src, dst: l_dst },
996 Self::Ip { src: r_src, dst: r_dst }
997 ) =>
998 l_src == r_src && l_dst == r_dst,
999
1000 (
1001 Self::Unix { src: l_src, dst: l_dst },
1002 Self::Unix { src: r_src, dst: r_dst }
1003 ) =>
1004 l_src.as_pathname() == r_src.as_pathname() && l_dst.as_pathname() == r_dst.as_pathname(),
1005 _ => false,
1006 }
1007 }
1008}
1009
1010impl fmt::Display for ProxyV2Addr
1011{
1012 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1013 {
1014 match self
1015 {
1016 ProxyV2Addr::Ip{ src, dst } =>
1017 write!(f, "SRC: {}, DST: {}", src, dst),
1018 ProxyV2Addr::Unix{ src, dst } =>
1019 write!(f, "SRC: {:?}, DST: {:?}", src, dst)
1020 }
1021 }
1022}
1023
1024impl TryFrom<(IpAddr, u16, IpAddr, u16)> for ProxyV2Addr
1025{
1026 type Error = HaProxErr;
1027
1028 fn try_from(value: (IpAddr, u16, IpAddr, u16)) -> Result<Self, Self::Error>
1038 {
1039 let src = SocketAddr::new(value.0, value.1);
1040 let dst = SocketAddr::new(value.2, value.3);
1041
1042 return Ok(Self::Ip{ src: src, dst: dst });
1043 }
1044}
1045
1046impl TryFrom<(SocketAddr, SocketAddr)> for ProxyV2Addr
1047{
1048 type Error = HaProxErr;
1049
1050 fn try_from(value: (SocketAddr, SocketAddr)) -> Result<Self, Self::Error>
1056 {
1057 return Ok(Self::Ip{ src: value.0, dst: value.1 });
1058 }
1059}
1060
1061impl TryFrom<(net::SocketAddr, net::SocketAddr)> for ProxyV2Addr
1063{
1064 type Error = HaProxErr;
1065
1066 fn try_from(value: (net::SocketAddr, net::SocketAddr)) -> Result<Self, Self::Error>
1072 {
1073 return Ok(Self::Unix{ src: value.0, dst: value.1 });
1074 }
1075}
1076
1077impl TryFrom<(&str, &str)> for ProxyV2Addr
1079{
1080 type Error = HaProxErr;
1081
1082 fn try_from(value: (&str, &str)) -> Result<Self, Self::Error>
1088 {
1089 if let Ok(src) = SocketAddr::from_str(value.0)
1090 {
1091 let Ok(dst) = SocketAddr::from_str(value.1)
1092 else
1093 {
1094 return_error!(ArgumentEinval, "can not convert '{}' to SocketAddr",
1095 common::sanitize_str_unicode(value.1));
1096 };
1097
1098 return Ok(Self::Ip{ src: src, dst: dst });
1099 }
1100 else if let Ok(src) = net::SocketAddr::from_pathname(value.0)
1101 {
1102 let Ok(dst) = net::SocketAddr::from_pathname(value.1)
1103 else
1104 {
1105 return_error!(ArgumentEinval, "can not convert '{}' to net::SocketAddr",
1106 common::sanitize_str_unicode(value.1));
1107 };
1108
1109 return Ok(Self::Unix{ src: src, dst: dst });
1110 }
1111 else
1112 {
1113 return_error!(ArgumentEinval, "can not convert '{}' to either SocketAddr or net::SocketAddr",
1114 common::sanitize_str_unicode(value.0));
1115 }
1116 }
1117}
1118
1119impl ProxyV2Addr
1120{
1121 #[inline]
1124 pub
1125 fn get_len(&self) -> u16
1126 {
1127 return self.as_addr_family().get_size_by_addr_family().unwrap();
1128 }
1129
1130 #[inline]
1132 pub
1133 fn as_addr_family(&self) -> ProxyV2AddrType
1134 {
1135 match self
1136 {
1137 ProxyV2Addr::Ip{ src, .. } =>
1138 {
1139 if src.is_ipv4() == true
1140 {
1141 return ProxyV2AddrType::AfInet;
1142 }
1143 else
1144 {
1145 return ProxyV2AddrType::AfInet6;
1146 }
1147 }
1148 ProxyV2Addr::Unix{ .. } =>
1149 return ProxyV2AddrType::AfUnix
1150 }
1151 }
1152
1153 pub
1162 fn read(addr_fam: ProxyV2AddrType, cur: &mut Cursor<&[u8]>) -> HaProxRes<Option<Self>>
1163 {
1164 match addr_fam
1165 {
1166 ProxyV2AddrType::AfUnspec => Ok(None),
1167 ProxyV2AddrType::AfInet =>
1168 {
1169 let src = IpAddr::from(Ipv4Addr::from_bits(cur.read_u32::<BigEndian>().map_err(common::map_io_err)?));
1170 let dst = IpAddr::from(Ipv4Addr::from_bits(cur.read_u32::<BigEndian>().map_err(common::map_io_err)?));
1171 let src_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
1172 let dst_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
1173
1174 return Ok(Some(Self::try_from((src, src_port, dst, dst_port))?));
1175 },
1176 ProxyV2AddrType::AfInet6 =>
1177 {
1178 let src = IpAddr::from(Ipv6Addr::from_bits(cur.read_u128::<BigEndian>().map_err(common::map_io_err)?));
1179 let dst = IpAddr::from(Ipv6Addr::from_bits(cur.read_u128::<BigEndian>().map_err(common::map_io_err)?));
1180 let src_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
1181 let dst_port = cur.read_u16::<BigEndian>().map_err(common::map_io_err)?;
1182
1183 return Ok(Some(Self::try_from((src, src_port, dst, dst_port))?));
1184 },
1185 ProxyV2AddrType::AfUnix =>
1186 {
1187 let mut n_src: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
1188 cur.read(&mut n_src).map_err(common::map_io_err)?;
1189
1190 let mut n_dst: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
1191 cur.read(&mut n_dst).map_err(common::map_io_err)?;
1192
1193 let src_s =
1194 net::SocketAddr::from_pathname(
1195 CStr::from_bytes_until_nul(&n_src)
1196 .map_err(|e|
1197 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1198 )?
1199 .to_str()
1200 .map_err(|e|
1201 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1202 )?
1203 )
1204 .map_err(|e|
1205 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1206 )?;
1207
1208 let dst_s =
1209 net::SocketAddr::from_pathname(
1210 CStr::from_bytes_until_nul(&n_dst)
1211 .map_err(|e|
1212 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1213 )?
1214 .to_str()
1215 .map_err(|e|
1216 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1217 )?
1218 )
1219 .map_err(|e|
1220 map_error!(MalformedData, "cannot read unix path, error: {}", e)
1221 )?;
1222
1223 return Ok(Some(Self::try_from((src_s, dst_s))?));
1224 },
1225 }
1226 }
1227
1228 pub
1232 fn write(&self, cur: &mut Cursor<Vec<u8>>) -> HaProxRes<()>
1233 {
1234 match self
1235 {
1236 ProxyV2Addr::Ip{ src, dst } =>
1237 {
1238 match src.ip()
1239 {
1240 IpAddr::V4(ipv4_addr) =>
1241 cur.write_u32::<BigEndian>(ipv4_addr.to_bits()).map_err(common::map_io_err)?,
1242 IpAddr::V6(ipv6_addr) =>
1243 cur.write_u128::<BigEndian>(ipv6_addr.to_bits()).map_err(common::map_io_err)?,
1244 }
1245
1246 match dst.ip()
1247 {
1248 IpAddr::V4(ipv4_addr) =>
1249 cur.write_u32::<BigEndian>(ipv4_addr.to_bits()).map_err(common::map_io_err)?,
1250 IpAddr::V6(ipv6_addr) =>
1251 cur.write_u128::<BigEndian>(ipv6_addr.to_bits()).map_err(common::map_io_err)?,
1252 }
1253
1254 cur.write_u16::<BigEndian>(src.port()).map_err(common::map_io_err)?;
1255 cur.write_u16::<BigEndian>(dst.port()).map_err(common::map_io_err)?;
1256 },
1257 ProxyV2Addr::Unix { src, dst } =>
1258 {
1259 let src_p =
1260 src.as_pathname().ok_or_else(|| map_error!(ArgumentEinval, "UNIX src socket addr is not path"))?;
1261 let dst_p =
1262 dst.as_pathname().ok_or_else(|| map_error!(ArgumentEinval, "UNIX src socket addr is not path"))?;
1263
1264 let src_b = src_p.as_os_str().as_bytes();
1265 let dst_b = dst_p.as_os_str().as_bytes();
1266
1267 if src_b.len() > HEADER_UNIX_ADDR_LEN
1268 {
1269 return_error!(ArgumentEinval, "socket path: '{}' longer than: '{}'",
1270 src_p.display(), HEADER_UNIX_ADDR_LEN);
1271 }
1272 else if dst_b.len() > HEADER_UNIX_ADDR_LEN
1273 {
1274 return_error!(ArgumentEinval, "socket path: '{}' longer than: '{}'",
1275 dst_p.display(), HEADER_UNIX_ADDR_LEN);
1276 }
1277
1278
1279 let mut n_src: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
1280 n_src[0..src_b.len()].copy_from_slice(src_b);
1281
1282 cur.write_all(&n_src).map_err(common::map_io_err)?;
1283
1284 let mut n_dst: [u8; HEADER_UNIX_ADDR_LEN] = [0_u8; HEADER_UNIX_ADDR_LEN];
1285 n_dst[0..dst_b.len()].copy_from_slice(dst_b);
1286
1287 cur.write_all(&n_dst).map_err(common::map_io_err)?;
1288 }
1289 }
1290
1291 return Ok(());
1292 }
1293}
1294
1295#[repr(u8)]
1299#[derive(Clone, Debug, PartialEq, Eq)]
1300pub enum ProxyTransportFam
1301{
1302 UNSPEC = 0x00,
1308
1309 STREAM,
1314
1315 DGRAM,
1320}
1321
1322impl fmt::Display for ProxyTransportFam
1323{
1324 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
1325 {
1326 match self
1327 {
1328 Self::UNSPEC => write!(f, "UNSPEC"),
1329 Self::STREAM => write!(f, "STREAM"),
1330 Self::DGRAM => write!(f, "DGRAM"),
1331 }
1332 }
1333}
1334
1335impl From<ProxyTransportFam> for u8
1336{
1337 fn from(value: ProxyTransportFam) -> Self
1338 {
1339 return value as u8;
1340 }
1341}
1342
1343impl From<&ProxyTransportFam> for u8
1344{
1345 fn from(value: &ProxyTransportFam) -> Self
1346 {
1347 return unsafe { *<*const _>::from(value).cast::<Self>() };
1348 }
1349}
1350
1351impl ProxyTransportFam
1352{
1353 pub(crate)
1354 fn decode(value: u8) -> HaProxRes<Self>
1355 {
1356 match value & protocol_raw::ProxyHdrV2::TRANSPT_MASK
1357 {
1358 v if ProxyTransportFam::UNSPEC as u8 == v =>
1359 return Ok(Self::UNSPEC),
1360 v if ProxyTransportFam::STREAM as u8 == v =>
1361 return Ok(Self::STREAM),
1362 v if ProxyTransportFam::DGRAM as u8 == v =>
1363 return Ok(Self::DGRAM),
1364 _ =>
1365 return_error!(ProtocolUnknownData, "unknown transport {:02X}", value)
1366 }
1367 }
1368}
1369
1370#[cfg(test)]
1371mod tests
1372{
1373 use core::fmt;
1374 use std::{slice, time::Instant};
1375
1376 use crate::{protocol_raw::{self, HEADER_MAGIC_V2, HEADER_MAGINC_LEN}, protocol_v2::{PP2TlvUniqId, protocol::{PP2TlvClient, ProxyTransportFam, ProxyV2Addr}, protocol_composer::{HdrV2OpLocal, HdrV2OpProxy, ProxyHdrV2}}};
1377 #[test]
1378 fn test_hdr1()
1379 {
1380
1381 for _ in 0..10
1382 {
1383 let s = Instant::now();
1384 let _local = ProxyHdrV2::<HdrV2OpLocal>::new();
1385
1386 let e = s.elapsed();
1387
1388 println!("{:?}", e);
1389 }
1390
1391 let buf = ProxyHdrV2::<HdrV2OpLocal>::new();
1392
1393
1394
1395 let mut sign: [u8; HEADER_MAGINC_LEN] = [0_u8; HEADER_MAGINC_LEN];
1396 sign.copy_from_slice(HEADER_MAGIC_V2);
1397 let ctrl =
1398 vec![
1399 protocol_raw::ProxyHdrV2
1400 {
1401 signature: sign,
1402 ver_cmd: 0x20,
1403 fam: 0,
1404 len: 0,
1405 address: [],
1406 }
1407 ];
1408
1409 println!("{} {}", buf.len(), size_of::<protocol_raw::ProxyHdrV2>());
1410 let ctrl_buf = unsafe { slice::from_raw_parts(ctrl.as_ptr() as *const _ as *const u8, size_of::<protocol_raw::ProxyHdrV2>()) };
1411
1412 assert_eq!(buf.as_slice(), ctrl_buf);
1413 }
1414
1415 #[test]
1416 fn test_proxy_compose()
1417 {
1418 struct UniqIdHolder;
1419 impl UniqIdHolder
1420 {
1421 const ID: &'static [u8] = b"ABCD12345678901234567890";
1422 }
1423 impl fmt::Display for UniqIdHolder
1424 {
1425 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
1426 {
1427 write!(f, "")
1428 }
1429 }
1430 impl PP2TlvUniqId for UniqIdHolder
1431 {
1432 fn into_bytes(&self) -> Vec<u8>
1433 {
1434 Self::ID.to_vec()
1435 }
1436
1437 fn as_slice<'a>(&'a self) -> &'a [u8]
1438 {
1439 Self::ID
1440 }
1441
1442 fn get_len(&self) -> u16
1443 {
1444 Self::ID.len() as u16
1445 }
1446 }
1447 for _ in 0..10
1448 {
1449 let addr: ProxyV2Addr = ProxyV2Addr::try_from(("127.0.0.1:4567", "127.0.0.1:443")).unwrap();
1450 let id = UniqIdHolder;
1451
1452 let s = Instant::now();
1453 let mut proxy =
1454 ProxyHdrV2::<HdrV2OpProxy>::new(ProxyTransportFam::STREAM, addr).unwrap();
1455
1456 let mut plts = proxy.set_plts();
1457 plts.add_crc32().unwrap();
1458 plts.add_authority("www.example.com").unwrap();
1459 plts.add_uniq_id(id).unwrap();
1460 drop(plts);
1461
1462 let e = s.elapsed();
1463
1464 println!("prep: {:?}", e);
1465
1466 let s = Instant::now();
1467 let _buf: Vec<u8> = proxy.try_into().unwrap();
1468 let e = s.elapsed();
1469
1470 println!("{:?}", e);
1471 }
1472
1473 return;
1475 }
1476
1477 #[test]
1478 fn test_hdr2()
1479 {
1480 let addr: ProxyV2Addr = ProxyV2Addr::try_from(("127.0.0.1:39754", "127.0.0.67:11883")).unwrap();
1481
1482 let s = Instant::now();
1483 let mut proxy =
1484 ProxyHdrV2::<HdrV2OpProxy>::new(ProxyTransportFam::STREAM, addr).unwrap();
1485
1486 let plts = proxy.set_plts();
1487
1488 let mut sub_ssl = plts.add_ssl(PP2TlvClient::PP2_CLIENT_SSL, 0).unwrap();
1489
1490 sub_ssl.add_ssl_sub_version("TLSv1.2").unwrap();
1491
1492 sub_ssl.done().unwrap();
1493
1494
1495 let e = s.elapsed();
1496
1497 println!("prep: {:?}", e);
1498
1499 let s = Instant::now();
1500 let buf: Vec<u8> = proxy.try_into().unwrap();
1501 let e = s.elapsed();
1502
1503 println!("{:?}", e);
1504
1505
1506 let reference =
1507 b"\x0d\x0a\x0d\x0a\x00\x0d\x0a\x51\x55\x49\x54\x0a\x21\x11\x00\x1e\
1508 \x7f\x00\x00\x01\x7f\x00\x00\x43\x9b\x4a\x2e\x6b\x20\x00\x0f\x01\
1509 \x00\x00\x00\x00\x21\x00\x07\x54\x4c\x53\x76\x31\x2e\x32";
1510
1511 assert_eq!(buf.as_slice(), reference.as_slice());
1514 }
1515}