1use std::fmt;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
22pub enum ProxyMode {
23 #[default]
25 Off,
26 Required {
28 versions: ProxyVersions,
30 },
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Eq)]
39pub enum ProxyVersions {
40 V1,
42 V2,
44 Both,
46}
47
48#[derive(Clone, Copy)]
55pub struct ProxyFacts {
56 alpn: [u8; 32],
57 alpn_len: u8,
58 authority: [u8; 255],
59 authority_len: u8,
60 unique_id: [u8; 128],
61 unique_id_len: u8,
62 ssl_client: Option<u8>,
63}
64
65impl Default for ProxyFacts {
66 fn default() -> ProxyFacts {
67 ProxyFacts {
68 alpn: [0; 32],
69 alpn_len: 0,
70 authority: [0; 255],
71 authority_len: 0,
72 unique_id: [0; 128],
73 unique_id_len: 0,
74 ssl_client: None,
75 }
76 }
77}
78
79impl ProxyFacts {
80 #[must_use]
82 pub fn alpn(&self) -> Option<&[u8]> {
83 (self.alpn_len > 0).then(|| &self.alpn[..usize::from(self.alpn_len)])
84 }
85
86 #[must_use]
88 pub fn authority(&self) -> Option<&str> {
89 if self.authority_len == 0 {
90 return None;
91 }
92 std::str::from_utf8(&self.authority[..usize::from(self.authority_len)]).ok()
93 }
94
95 #[must_use]
97 pub fn unique_id(&self) -> Option<&[u8]> {
98 (self.unique_id_len > 0).then(|| &self.unique_id[..usize::from(self.unique_id_len)])
99 }
100
101 #[must_use]
103 pub fn ssl_client(&self) -> Option<u8> {
104 self.ssl_client
105 }
106}
107
108impl fmt::Debug for ProxyFacts {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 f.debug_struct("ProxyFacts")
111 .field("alpn", &self.alpn().map(String::from_utf8_lossy))
112 .field("authority", &self.authority())
113 .field("unique_id_len", &self.unique_id_len)
114 .field("ssl_client", &self.ssl_client)
115 .finish()
116 }
117}
118
119#[non_exhaustive]
125#[derive(Clone, Copy, Debug, PartialEq, Eq)]
126pub enum ProxyError {
127 OutputTooSmall {
129 need: usize,
131 },
132 NotProxy,
134 V1TooLong,
136 V1Syntax {
138 at: u8,
140 },
141 V1BadAddress,
143 V1BadPort,
145 V2BadVersion,
147 V2BadCommand,
149 V2BadFamily,
151 V2LengthTooLarge {
153 declared: u16,
155 max: u16,
157 },
158 V2AddressTooShort,
160 V2TlvOverrun,
162 V2CrcMismatch,
164 V2UniqueIdTooLong,
166 V2SslMalformed,
168 FamilyMismatch,
170}
171
172impl fmt::Display for ProxyError {
173 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174 match self {
175 ProxyError::OutputTooSmall { need } => {
176 write!(f, "output buffer too small ({need} bytes needed)")
177 }
178 ProxyError::NotProxy => f.write_str("the connection did not start with a PROXY header"),
179 ProxyError::V1TooLong => f.write_str("v1 header longer than 107 bytes"),
180 ProxyError::V1Syntax { at } => write!(f, "v1 header syntax error at byte {at}"),
181 ProxyError::V1BadAddress => f.write_str("v1 header with an invalid address"),
182 ProxyError::V1BadPort => f.write_str("v1 header with an invalid port"),
183 ProxyError::V2BadVersion => f.write_str("v2 header with an unknown version"),
184 ProxyError::V2BadCommand => f.write_str("v2 header with an unknown command"),
185 ProxyError::V2BadFamily => f.write_str("v2 header with an unknown address family"),
186 ProxyError::V2LengthTooLarge { declared, max } => {
187 write!(
188 f,
189 "v2 header declares {declared} bytes, above the maximum of {max}"
190 )
191 }
192 ProxyError::V2AddressTooShort => {
193 f.write_str("v2 address block too short for its family")
194 }
195 ProxyError::V2TlvOverrun => f.write_str("v2 TLV runs past the declared length"),
196 ProxyError::V2CrcMismatch => f.write_str("v2 header checksum does not match"),
197 ProxyError::V2UniqueIdTooLong => f.write_str("v2 unique id longer than 128 bytes"),
198 ProxyError::V2SslMalformed => f.write_str("v2 SSL TLV is malformed"),
199 ProxyError::FamilyMismatch => f.write_str("addresses do not match the declared family"),
200 }
201 }
202}
203
204impl std::error::Error for ProxyError {}