| 142 | } |
| 143 | |
| 144 | int ProxyProtocolHandler::ProcessProxyHeader(int fd) { |
| 145 | int ret = GetAddrFromFD(fd); |
| 146 | if (ret < 0) { |
| 147 | return ret; |
| 148 | } |
| 149 | |
| 150 | ret = IsProxyHeaderNeed(); |
| 151 | if (ret <= 0) { |
| 152 | return ret; |
| 153 | } |
| 154 | |
| 155 | union { |
| 156 | char v1[108]; |
| 157 | ProxyHdr v2; |
| 158 | } hdr; |
| 159 | |
| 160 | int hdr_size = RoutinePeekWithTimeout(fd, (char *) &hdr, sizeof(hdr), config_->ProxyProtocolTimeoutMs()); |
| 161 | if (hdr_size < 0) { |
| 162 | LOG_ERR("read proxy header from fd [%d] failed, ret %d", fd, hdr_size); |
| 163 | return -__LINE__; |
| 164 | } |
| 165 | |
| 166 | if (hdr_size >= 16 && memcmp(&hdr.v2, PP2_SIGNATURE, 12) == 0 && (hdr.v2.ver_cmd & 0xF0) == PP2_VERSION) { |
| 167 | hdr_size = ParseProxyHeaderV2(hdr.v2, hdr_size); |
| 168 | } else if (hdr_size >= 8 && memcmp(hdr.v1, "PROXY ", 6) == 0) { |
| 169 | hdr_size = ParseProxyHeaderV1(hdr.v1, hdr_size); |
| 170 | } else { |
| 171 | return -__LINE__; |
| 172 | } |
| 173 | |
| 174 | if (hdr_size > 0) { |
| 175 | ret = read(fd, &hdr, hdr_size); |
| 176 | if (ret != hdr_size) { |
| 177 | LOG_ERR("flush fd [%d] failed, ret %d hdr size %d", fd, ret, hdr_size); |
| 178 | return -__LINE__; |
| 179 | } |
| 180 | } |
| 181 | |
| 182 | return hdr_size; |
| 183 | } |
| 184 | |
| 185 | int ProxyProtocolHandler::ParseProxyHeaderV1(const char * hdr, int read_size) { |
| 186 | const char * end = (const char *) memchr(hdr, '\r', read_size - 1); |
no test coverage detected