| 225 | } |
| 226 | |
| 227 | int ProxyProtocolHandler::ParseProxyHeaderV2(const ProxyHdr & hdr, int read_size) { |
| 228 | int size = 16 + ntohs(hdr.len); |
| 229 | if (read_size < size) { // truncated or too large header |
| 230 | return -__LINE__; |
| 231 | } |
| 232 | switch (hdr.ver_cmd & 0xF) { |
| 233 | case PP2_CMD_PROXY: |
| 234 | switch (hdr.fam) { |
| 235 | case PP2_FAM_TCP4: |
| 236 | src_addr_.ss_family = AF_INET; |
| 237 | ((struct sockaddr_in *) &src_addr_)->sin_addr.s_addr = hdr.addr.ip4.src_addr; |
| 238 | ((struct sockaddr_in *) &src_addr_)->sin_port = hdr.addr.ip4.src_port; |
| 239 | dst_addr_.ss_family = AF_INET; |
| 240 | ((struct sockaddr_in *) &dst_addr_)->sin_addr.s_addr = hdr.addr.ip4.dst_addr; |
| 241 | ((struct sockaddr_in *) &dst_addr_)->sin_port = hdr.addr.ip4.dst_port; |
| 242 | return size; |
| 243 | case PP2_FAM_TCP6: |
| 244 | src_addr_.ss_family = AF_INET6; |
| 245 | memcpy(&((struct sockaddr_in6 *) &src_addr_)->sin6_addr, hdr.addr.ip6.src_addr, 16); |
| 246 | ((struct sockaddr_in6 *) &src_addr_)->sin6_port = hdr.addr.ip6.src_port; |
| 247 | dst_addr_.ss_family = AF_INET6; |
| 248 | memcpy(&((struct sockaddr_in6 *) &dst_addr_)->sin6_addr, hdr.addr.ip6.dst_addr, 16); |
| 249 | ((struct sockaddr_in6 *) &dst_addr_)->sin6_port = hdr.addr.ip6.dst_port; |
| 250 | return size; |
| 251 | case PP2_FAM_UNSPEC: |
| 252 | return size; // unknown protocol, keep local connection address |
| 253 | default: |
| 254 | return -__LINE__; // unsupport protocol |
| 255 | } |
| 256 | case PP2_CMD_LOCAL: |
| 257 | return size; // keep local connection address for LOCAL |
| 258 | default: |
| 259 | return -__LINE__; // unsupport command |
| 260 | } |
| 261 | return -__LINE__; |
| 262 | } |
| 263 | |
| 264 | int ProxyProtocolHandler::SendProxyHeader(int fd) { |
| 265 | int ret = 0; |
nothing calls this directly
no outgoing calls
no test coverage detected