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}