MCPcopy Create free account
hub / github.com/apache/trafficserver / proxy_protocol_v2_parse

Function proxy_protocol_v2_parse

src/iocore/net/ProxyProtocol.cc:225–315  ·  view source on GitHub ↗

PROXY Protocol v2 Parser @return read length */

Source from the content-addressed store, hash-verified

223 @return read length
224 */
225size_t
226proxy_protocol_v2_parse(ProxyProtocol *pp_info, const swoc::TextView &msg)
227{
228 ink_release_assert(msg.size() >= PPv2_CONNECTION_HEADER_LEN);
229
230 const PPv2Hdr *hdr_v2 = reinterpret_cast<const PPv2Hdr *>(msg.data());
231
232 // Assuming PREFACE check is done
233
234 // length check
235 const uint16_t len = ntohs(hdr_v2->len);
236 const size_t total_len = PPv2_CONNECTION_HEADER_LEN + len;
237 uint16_t tlv_len = 0;
238
239 if (msg.size() < total_len) {
240 Dbg(dbg_ctl_proxyprotocol_v2, "The amount of available data is smaller than the expected size");
241 return 0;
242 }
243
244 // protocol version and command
245 switch (hdr_v2->ver_cmd) {
246 case PPv2_CMD_LOCAL: {
247 // protocol byte should be UNSPEC (\x00) with LOCAL command
248 if (hdr_v2->fam != PPv2_PROTO_UNSPEC) {
249 Dbg(dbg_ctl_proxyprotocol_v2, "UNSPEC is unexpected");
250 return 0;
251 }
252
253 pp_info->version = ProxyProtocolVersion::V2;
254 pp_info->ip_family = AF_UNSPEC;
255
256 return total_len;
257 }
258 case PPv2_CMD_PROXY: {
259 switch (hdr_v2->fam) {
260 case PPv2_PROTO_TCP4:
261 case PPv2_PROTO_UDP4:
262 if (len < PPv2_ADDR_LEN_INET) {
263 Dbg(dbg_ctl_proxyprotocol_v2, "There is not enough data left for IPv4 info");
264 return 0;
265 }
266 tlv_len = len - PPv2_ADDR_LEN_INET;
267
268 pp_info->set_ipv4_addrs(reinterpret_cast<in_addr_t>(hdr_v2->addr.ip4.src_addr), hdr_v2->addr.ip4.src_port,
269 reinterpret_cast<in_addr_t>(hdr_v2->addr.ip4.dst_addr), hdr_v2->addr.ip4.dst_port);
270 pp_info->type = hdr_v2->fam == PPv2_PROTO_TCP4 ? SOCK_STREAM : SOCK_DGRAM;
271 pp_info->version = ProxyProtocolVersion::V2;
272
273 break;
274 case PPv2_PROTO_TCP6:
275 case PPv2_PROTO_UDP6:
276 if (len < PPv2_ADDR_LEN_INET6) {
277 Dbg(dbg_ctl_proxyprotocol_v2, "There is not enough data left for IPv6 info");
278 return 0;
279 }
280 tlv_len = len - PPv2_ADDR_LEN_INET6;
281
282 pp_info->set_ipv6_addrs(reinterpret_cast<in6_addr const &>(hdr_v2->addr.ip6.src_addr), hdr_v2->addr.ip6.src_port,

Callers 1

proxy_protocol_parseFunction · 0.85

Calls 6

set_ipv4_addrsMethod · 0.80
set_ipv6_addrsMethod · 0.80
set_additional_dataMethod · 0.80
sizeMethod · 0.45
dataMethod · 0.45
substrMethod · 0.45

Tested by

no test coverage detected