MCPcopy Index your code
hub / github.com/ermak-dev/cloudpub / build_proxy_v2_header

Function build_proxy_v2_header

common/src/proxy_protocol.rs:35–108  ·  view source on GitHub ↗

Builds a PROXY protocol v2 header for TCP connections # Arguments `client_addr` - The original client's socket address `server_addr` - The server's socket address (destination) # Returns A byte vector containing the complete PROXY v2 header

(client_addr: &SocketAddr, server_addr: &SocketAddr)

Source from the content-addressed store, hash-verified

33/// # Returns
34/// A byte vector containing the complete PROXY v2 header
35pub fn build_proxy_v2_header(client_addr: &SocketAddr, server_addr: &SocketAddr) -> Vec<u8> {
36 let mut header = Vec::with_capacity(52); // Max size for IPv6
37
38 // 1. Signature (12 bytes)
39 header.extend_from_slice(&PROXY_V2_SIGNATURE);
40
41 // Determine address family and protocol
42 let (af_proto, addr_len, addr_data) = match (client_addr.ip(), server_addr.ip()) {
43 (IpAddr::V4(src_ip), IpAddr::V4(dst_ip)) => {
44 // IPv4 + TCP
45 let af_proto = AF_INET | STREAM;
46 let mut data = Vec::with_capacity(12);
47 data.extend_from_slice(&src_ip.octets()); // 4 bytes src addr
48 data.extend_from_slice(&dst_ip.octets()); // 4 bytes dst addr
49 data.extend_from_slice(&client_addr.port().to_be_bytes()); // 2 bytes src port
50 data.extend_from_slice(&server_addr.port().to_be_bytes()); // 2 bytes dst port
51 (af_proto, 12u16, data)
52 }
53 (IpAddr::V6(src_ip), IpAddr::V6(dst_ip)) => {
54 // IPv6 + TCP
55 let af_proto = AF_INET6 | STREAM;
56 let mut data = Vec::with_capacity(36);
57 data.extend_from_slice(&src_ip.octets()); // 16 bytes src addr
58 data.extend_from_slice(&dst_ip.octets()); // 16 bytes dst addr
59 data.extend_from_slice(&client_addr.port().to_be_bytes()); // 2 bytes src port
60 data.extend_from_slice(&server_addr.port().to_be_bytes()); // 2 bytes dst port
61 (af_proto, 36u16, data)
62 }
63 (IpAddr::V4(src_ip), IpAddr::V6(_)) => {
64 // Mixed: convert IPv4 to IPv6-mapped address
65 let src_v6 = src_ip.to_ipv6_mapped();
66 let dst_v6 = match server_addr.ip() {
67 IpAddr::V6(ip) => ip,
68 _ => unreachable!(),
69 };
70 let af_proto = AF_INET6 | STREAM;
71 let mut data = Vec::with_capacity(36);
72 data.extend_from_slice(&src_v6.octets());
73 data.extend_from_slice(&dst_v6.octets());
74 data.extend_from_slice(&client_addr.port().to_be_bytes());
75 data.extend_from_slice(&server_addr.port().to_be_bytes());
76 (af_proto, 36u16, data)
77 }
78 (IpAddr::V6(_), IpAddr::V4(dst_ip)) => {
79 // Mixed: convert IPv4 to IPv6-mapped address
80 let src_v6 = match client_addr.ip() {
81 IpAddr::V6(ip) => ip,
82 _ => unreachable!(),
83 };
84 let dst_v6 = dst_ip.to_ipv6_mapped();
85 let af_proto = AF_INET6 | STREAM;
86 let mut data = Vec::with_capacity(36);
87 data.extend_from_slice(&src_v6.octets());
88 data.extend_from_slice(&dst_v6.octets());
89 data.extend_from_slice(&client_addr.port().to_be_bytes());
90 data.extend_from_slice(&server_addr.port().to_be_bytes());
91 (af_proto, 36u16, data)
92 }

Callers 2

Calls 1

portMethod · 0.80

Tested by 2