Parse proxy protocol V2 (binary) header */
| 96 | Parse proxy protocol V2 (binary) header |
| 97 | */ |
| 98 | static int parse_v2_header(uchar *hdr, size_t len,proxy_peer_info *peer_info) |
| 99 | { |
| 100 | /* V2 Signature */ |
| 101 | if (memcmp(hdr, PROXY_PROTOCOL_V2_SIGNATURE, 12)) |
| 102 | return -1; |
| 103 | |
| 104 | /* version + command */ |
| 105 | uint8 ver= (hdr[12] & 0xF0); |
| 106 | if (ver != 0x20) |
| 107 | return -1; /* Wrong version*/ |
| 108 | |
| 109 | uint cmd= (hdr[12] & 0xF); |
| 110 | |
| 111 | /* Address family */ |
| 112 | uchar fam= hdr[13]; |
| 113 | |
| 114 | if (cmd == 0) |
| 115 | { |
| 116 | /* LOCAL command*/ |
| 117 | peer_info->is_local_command= true; |
| 118 | return 0; |
| 119 | } |
| 120 | |
| 121 | if (cmd != 0x01) |
| 122 | { |
| 123 | /* Not PROXY COMMAND */ |
| 124 | return -1; |
| 125 | } |
| 126 | |
| 127 | struct sockaddr_in *sin= (struct sockaddr_in *)(&peer_info->peer_addr); |
| 128 | struct sockaddr_in6 *sin6= (struct sockaddr_in6 *)(&peer_info->peer_addr); |
| 129 | switch (fam) |
| 130 | { |
| 131 | case 0x11: /* TCPv4 */ |
| 132 | if (len < 25) |
| 133 | return -1; |
| 134 | sin->sin_family= AF_INET; |
| 135 | memcpy(&(sin->sin_addr), hdr + 16, 4); |
| 136 | peer_info->port= (hdr[24] << 8) + hdr[25]; |
| 137 | break; |
| 138 | case 0x21: /* TCPv6 */ |
| 139 | if (len < 49) |
| 140 | return -1; |
| 141 | sin6->sin6_family= AF_INET6; |
| 142 | memcpy(&(sin6->sin6_addr), hdr + 16, 16); |
| 143 | peer_info->port= (hdr[48] << 8) + hdr[49]; |
| 144 | break; |
| 145 | case 0x31: /* AF_UNIX, stream */ |
| 146 | peer_info->peer_addr.ss_family= AF_UNIX; |
| 147 | break; |
| 148 | default: |
| 149 | return -1; |
| 150 | } |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | |
| 155 | bool has_proxy_protocol_header(NET *net) |
no outgoing calls
no test coverage detected