Try to parse proxy header. https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt Whenever this function is called, client is connecting, and we have have pre-read 4 bytes (NET_HEADER_SIZE) from the network already. These 4 bytes did not match MySQL packet header, and (unless the client is buggy), those bytes must be proxy header. @param[in] net - vio and already preread byte
| 177 | @return 0 in case of success, -1 if error. |
| 178 | */ |
| 179 | int parse_proxy_protocol_header(NET *net, proxy_peer_info *peer_info) |
| 180 | { |
| 181 | uchar hdr[MAX_PROXY_HEADER_LEN]; |
| 182 | size_t pos= 0; |
| 183 | |
| 184 | DBUG_ASSERT(!net->compress); |
| 185 | const uchar *preread_bytes= net->buff + net->where_b; |
| 186 | bool have_v1_header= !memcmp(preread_bytes, PROXY_PROTOCOL_V1_SIGNATURE, NET_HEADER_SIZE); |
| 187 | bool have_v2_header= |
| 188 | !have_v1_header && !memcmp(preread_bytes, PROXY_PROTOCOL_V2_SIGNATURE, NET_HEADER_SIZE); |
| 189 | if (!have_v1_header && !have_v2_header) |
| 190 | { |
| 191 | // not a proxy protocol header |
| 192 | return -1; |
| 193 | } |
| 194 | memcpy(hdr, preread_bytes, NET_HEADER_SIZE); |
| 195 | pos= NET_HEADER_SIZE; |
| 196 | Vio *vio= net->vio; |
| 197 | memset(peer_info, 0, sizeof (*peer_info)); |
| 198 | |
| 199 | if (have_v1_header) |
| 200 | { |
| 201 | /* Read until end of header (newline character)*/ |
| 202 | while(pos < sizeof(hdr) - 1) |
| 203 | { |
| 204 | long len= (long)vio_read(vio, hdr + pos, 1); |
| 205 | if (len < 0) |
| 206 | return -1; |
| 207 | pos++; |
| 208 | if (hdr[pos-1] == '\n') |
| 209 | break; |
| 210 | } |
| 211 | DBUG_ASSERT(pos < sizeof(hdr)); |
| 212 | hdr[pos]= 0; |
| 213 | |
| 214 | if (parse_v1_header((char *)hdr, pos, peer_info)) |
| 215 | return -1; |
| 216 | } |
| 217 | else // if (have_v2_header) |
| 218 | { |
| 219 | #define PROXY_V2_HEADER_LEN 16 |
| 220 | /* read off 16 bytes of the header.*/ |
| 221 | ssize_t len= vio_read(vio, hdr + pos, PROXY_V2_HEADER_LEN - pos); |
| 222 | if (len < 0) |
| 223 | return -1; |
| 224 | // 2 last bytes are the length in network byte order of the part following header |
| 225 | ushort trail_len= ((ushort)hdr[PROXY_V2_HEADER_LEN-2] << 8) + hdr[PROXY_V2_HEADER_LEN-1]; |
| 226 | if (trail_len > sizeof(hdr) - PROXY_V2_HEADER_LEN) |
| 227 | return -1; |
| 228 | if (trail_len > 0) |
| 229 | { |
| 230 | len= vio_read(vio, hdr + PROXY_V2_HEADER_LEN, trail_len); |
| 231 | if (len < 0) |
| 232 | return -1; |
| 233 | } |
| 234 | pos= PROXY_V2_HEADER_LEN + trail_len; |
| 235 | if (parse_v2_header(hdr, pos, peer_info)) |
| 236 | return -1; |
no test coverage detected