actix_proxy_protocol/
lib.rs

1//! PROXY protocol.
2
3#![expect(dead_code)]
4#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
5#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
6
7pub mod tlv;
8pub mod v1;
9pub mod v2;
10
11/// PROXY Protocol Version.
12#[derive(Debug, Clone, Copy)]
13enum Version {
14    /// Human-readable header format (Version 1)
15    V1,
16
17    /// Binary header format (Version 2)
18    V2,
19}
20
21impl Version {
22    const fn signature(&self) -> &'static [u8] {
23        match self {
24            Version::V1 => v1::SIGNATURE.as_bytes(),
25            Version::V2 => v2::SIGNATURE.as_slice(),
26        }
27    }
28
29    const fn v2_hi(&self) -> u8 {
30        (match self {
31            Version::V1 => panic!("v1 not supported in PROXY v2"),
32            Version::V2 => 0x2,
33        }) << 4
34    }
35}
36
37/// Command
38///
39/// other values are unassigned and must not be emitted by senders. Receivers
40/// must drop connections presenting unexpected values here.
41#[derive(Debug, Clone, Copy)]
42pub enum Command {
43    /// \x0 : LOCAL : the connection was established on purpose by the proxy
44    /// without being relayed. The connection endpoints are the sender and the
45    /// receiver. Such connections exist when the proxy sends health-checks to the
46    /// server. The receiver must accept this connection as valid and must use the
47    /// real connection endpoints and discard the protocol block including the
48    /// family which is ignored.
49    Local,
50
51    /// \x1 : PROXY : the connection was established on behalf of another node,
52    /// and reflects the original connection endpoints. The receiver must then use
53    /// the information provided in the protocol block to get original the address.
54    Proxy,
55}
56
57impl Command {
58    const fn v2_lo(&self) -> u8 {
59        match self {
60            Command::Local => 0x0,
61            Command::Proxy => 0x1,
62        }
63    }
64}
65
66/// Address Family.
67///
68/// maps to the original socket family without necessarily
69/// matching the values internally used by the system.
70///
71/// other values are unspecified and must not be emitted in version 2 of this
72/// protocol and must be rejected as invalid by receivers.
73#[derive(Debug, Clone, Copy)]
74pub enum AddressFamily {
75    /// 0x0 : AF_UNSPEC : the connection is forwarded for an unknown, unspecified
76    /// or unsupported protocol. The sender should use this family when sending
77    /// LOCAL commands or when dealing with unsupported protocol families. The
78    /// receiver is free to accept the connection anyway and use the real endpoint
79    /// addresses or to reject it. The receiver should ignore address information.
80    Unspecified,
81
82    /// 0x1 : AF_INET : the forwarded connection uses the AF_INET address family
83    /// (IPv4). The addresses are exactly 4 bytes each in network byte order,
84    /// followed by transport protocol information (typically ports).
85    Inet,
86
87    /// 0x2 : AF_INET6 : the forwarded connection uses the AF_INET6 address family
88    /// (IPv6). The addresses are exactly 16 bytes each in network byte order,
89    /// followed by transport protocol information (typically ports).
90    Inet6,
91
92    /// 0x3 : AF_UNIX : the forwarded connection uses the AF_UNIX address family
93    /// (UNIX). The addresses are exactly 108 bytes each.
94    Unix,
95}
96
97impl AddressFamily {
98    pub(crate) fn v1_str(&self) -> &'static str {
99        match self {
100            AddressFamily::Inet => "TCP4",
101            AddressFamily::Inet6 => "TCP6",
102            af => panic!("{:?} is not supported in PROXY v1", af),
103        }
104    }
105
106    const fn v2_hi(&self) -> u8 {
107        (match self {
108            AddressFamily::Unspecified => 0x0,
109            AddressFamily::Inet => 0x1,
110            AddressFamily::Inet6 => 0x2,
111            AddressFamily::Unix => 0x3,
112        }) << 4
113    }
114}
115
116/// Transport Protocol.
117///
118/// other values are unspecified and must not be emitted in version 2 of this
119/// protocol and must be rejected as invalid by receivers.
120#[derive(Debug, Clone, Copy)]
121pub enum TransportProtocol {
122    /// 0x0 : UNSPEC : the connection is forwarded for an unknown, unspecified
123    /// or unsupported protocol. The sender should use this family when sending
124    /// LOCAL commands or when dealing with unsupported protocol families. The
125    /// receiver is free to accept the connection anyway and use the real endpoint
126    /// addresses or to reject it. The receiver should ignore address information.
127    Unspecified,
128
129    /// 0x1 : STREAM : the forwarded connection uses a SOCK_STREAM protocol (eg:
130    /// TCP or UNIX_STREAM). When used with AF_INET/AF_INET6 (TCP), the addresses
131    /// are followed by the source and destination ports represented on 2 bytes
132    /// each in network byte order.
133    Stream,
134
135    /// 0x2 : DGRAM : the forwarded connection uses a SOCK_DGRAM protocol (eg:
136    /// UDP or UNIX_DGRAM). When used with AF_INET/AF_INET6 (UDP), the addresses
137    /// are followed by the source and destination ports represented on 2 bytes
138    /// each in network byte order.
139    Datagram,
140}
141
142impl TransportProtocol {
143    const fn v2_lo(&self) -> u8 {
144        match self {
145            TransportProtocol::Unspecified => 0x0,
146            TransportProtocol::Stream => 0x1,
147            TransportProtocol::Datagram => 0x2,
148        }
149    }
150}
151
152#[derive(Debug)]
153enum ProxyProtocolHeader {
154    V1(v1::Header),
155    V2(v2::Header),
156}