1use std::fmt;
16use std::net::{IpAddr, SocketAddr};
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20#[non_exhaustive]
21pub enum ProxyAddress {
22 Inet(SocketAddr),
24 Unix(Vec<u8>),
26}
27
28impl ProxyAddress {
29 pub fn as_inet(&self) -> Option<SocketAddr> {
31 match self {
32 Self::Inet(addr) => Some(*addr),
33 _ => None,
34 }
35 }
36
37 pub fn as_unix(&self) -> Option<&[u8]> {
39 match self {
40 Self::Unix(path) => Some(path),
41 _ => None,
42 }
43 }
44
45 pub fn ip(&self) -> Option<IpAddr> {
47 self.as_inet().map(|a| a.ip())
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Hash)]
53pub struct ProxyInfo {
54 pub version: Version,
56
57 pub command: Command,
59
60 pub transport: Option<Transport>,
63
64 pub source: Option<ProxyAddress>,
66
67 pub destination: Option<ProxyAddress>,
69
70 pub tlvs: Tlvs,
72}
73
74impl ProxyInfo {
75 pub fn source_inet(&self) -> Option<SocketAddr> {
77 self.source.as_ref().and_then(ProxyAddress::as_inet)
78 }
79
80 pub fn destination_inet(&self) -> Option<SocketAddr> {
82 self.destination.as_ref().and_then(ProxyAddress::as_inet)
83 }
84
85 pub fn source_ip(&self) -> Option<IpAddr> {
87 self.source.as_ref().and_then(ProxyAddress::ip)
88 }
89
90 pub fn destination_ip(&self) -> Option<IpAddr> {
92 self.destination.as_ref().and_then(ProxyAddress::ip)
93 }
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
97#[non_exhaustive]
98pub enum Version {
99 V1,
100 V2,
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
104#[non_exhaustive]
105pub enum Command {
106 Local,
107 Proxy,
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
111pub struct Transport {
112 pub family: AddressFamily,
113 pub protocol: TransportProtocol,
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117#[non_exhaustive]
118pub enum AddressFamily {
119 Inet,
120 Inet6,
121 Unix,
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
125#[non_exhaustive]
126pub enum TransportProtocol {
127 Stream,
128 Datagram,
129}
130
131#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
133pub struct Tlvs {
134 pub alpn: Option<Vec<u8>>,
136
137 pub authority: Option<String>,
139
140 pub crc32c: Option<u32>,
142
143 pub unique_id: Option<Vec<u8>>,
145
146 pub netns: Option<String>,
148
149 pub ssl: Option<SslInfo>,
151
152 pub raw: Vec<(u8, Vec<u8>)>,
155}
156
157#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
159pub struct SslInfo {
160 pub client_flags: SslClientFlags,
162
163 pub verified: bool,
165
166 pub version: Option<String>,
168
169 pub cipher: Option<String>,
171
172 pub sig_alg: Option<String>,
174
175 pub key_alg: Option<String>,
177
178 pub cn: Option<String>,
180
181 pub group: Option<String>,
183
184 pub sig_scheme: Option<String>,
186
187 pub client_cert: Option<Vec<u8>>,
189}
190
191bitflags::bitflags! {
192 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
194 pub struct SslClientFlags: u8 {
195 const SSL = 0x01;
197 const CERT_CONN = 0x02;
199 const CERT_SESS = 0x04;
201 }
202}
203
204impl fmt::Display for ProxyAddress {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 match self {
207 Self::Inet(addr) => write!(f, "{addr}"),
208 Self::Unix(path) => match std::str::from_utf8(path) {
209 Ok(s) => write!(f, "{s}"),
210 Err(_) => write!(f, "<unix:{} bytes>", path.len()),
211 },
212 }
213 }
214}
215
216impl From<SocketAddr> for ProxyAddress {
217 fn from(addr: SocketAddr) -> Self {
218 Self::Inet(addr)
219 }
220}
221
222impl From<std::net::SocketAddrV4> for ProxyAddress {
223 fn from(addr: std::net::SocketAddrV4) -> Self {
224 Self::Inet(SocketAddr::V4(addr))
225 }
226}
227
228impl From<std::net::SocketAddrV6> for ProxyAddress {
229 fn from(addr: std::net::SocketAddrV6) -> Self {
230 Self::Inet(SocketAddr::V6(addr))
231 }
232}
233
234impl fmt::Display for Version {
235 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236 match self {
237 Self::V1 => write!(f, "v1"),
238 Self::V2 => write!(f, "v2"),
239 }
240 }
241}
242
243impl fmt::Display for Command {
244 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245 match self {
246 Self::Local => write!(f, "LOCAL"),
247 Self::Proxy => write!(f, "PROXY"),
248 }
249 }
250}
251
252impl fmt::Display for AddressFamily {
253 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254 match self {
255 Self::Inet => write!(f, "IPv4"),
256 Self::Inet6 => write!(f, "IPv6"),
257 Self::Unix => write!(f, "Unix"),
258 }
259 }
260}
261
262impl fmt::Display for TransportProtocol {
263 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
264 match self {
265 Self::Stream => write!(f, "stream"),
266 Self::Datagram => write!(f, "datagram"),
267 }
268 }
269}