* Read bytes from socket. This will either read the full number of bytes requested * or return False on error or timeout. * This function can be interrupted by boost thread interrupt. * * @param data Buffer to receive into * @param len Length of data to receive * @param timeout Timeout in milliseconds for receive operation * * @note This function requires that hSocket is in non-blocking
| 258 | * @note This function requires that hSocket is in non-blocking mode. |
| 259 | */ |
| 260 | bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket) |
| 261 | { |
| 262 | int64_t curTime = GetTimeMillis(); |
| 263 | int64_t endTime = curTime + timeout; |
| 264 | // Maximum time to wait in one select call. It will take up until this time (in millis) |
| 265 | // to break off in case of an interruption. |
| 266 | const int64_t maxWait = 1000; |
| 267 | while (len > 0 && curTime < endTime) { |
| 268 | ssize_t ret = recv(hSocket, data, len, 0); // Optimistically try the recv first |
| 269 | if (ret > 0) { |
| 270 | len -= ret; |
| 271 | data += ret; |
| 272 | } else if (ret == 0) { // Unexpected disconnection |
| 273 | return false; |
| 274 | } else { // Other error or blocking |
| 275 | int nErr = WSAGetLastError(); |
| 276 | if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { |
| 277 | if (!IsSelectableSocket(hSocket)) { |
| 278 | return false; |
| 279 | } |
| 280 | struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); |
| 281 | fd_set fdset; |
| 282 | FD_ZERO(&fdset); |
| 283 | FD_SET(hSocket, &fdset); |
| 284 | int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval); |
| 285 | if (nRet == SOCKET_ERROR) { |
| 286 | return false; |
| 287 | } |
| 288 | } else { |
| 289 | return false; |
| 290 | } |
| 291 | } |
| 292 | boost::this_thread::interruption_point(); |
| 293 | curTime = GetTimeMillis(); |
| 294 | } |
| 295 | return len == 0; |
| 296 | } |
| 297 | |
| 298 | bool static Socks5(string strDest, int port, SOCKET& hSocket) |
| 299 | { |
no test coverage detected