| 296 | } |
| 297 | |
| 298 | bool static Socks5(string strDest, int port, SOCKET& hSocket) |
| 299 | { |
| 300 | LogPrintf("SOCKS5 connecting %s\n", strDest); |
| 301 | if (strDest.size() > 255) { |
| 302 | CloseSocket(hSocket); |
| 303 | return error("Hostname too long"); |
| 304 | } |
| 305 | char pszSocks5Init[] = "\5\1\0"; |
| 306 | ssize_t nSize = sizeof(pszSocks5Init) - 1; |
| 307 | |
| 308 | ssize_t ret = send(hSocket, pszSocks5Init, nSize, MSG_NOSIGNAL); |
| 309 | if (ret != nSize) { |
| 310 | CloseSocket(hSocket); |
| 311 | return error("Error sending to proxy"); |
| 312 | } |
| 313 | char pchRet1[2]; |
| 314 | if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) { |
| 315 | CloseSocket(hSocket); |
| 316 | return error("Error reading proxy response"); |
| 317 | } |
| 318 | if (pchRet1[0] != 0x05 || pchRet1[1] != 0x00) { |
| 319 | CloseSocket(hSocket); |
| 320 | return error("Proxy failed to initialize"); |
| 321 | } |
| 322 | string strSocks5("\5\1"); |
| 323 | strSocks5 += '\000'; |
| 324 | strSocks5 += '\003'; |
| 325 | strSocks5 += static_cast<char>(std::min((int)strDest.size(), 255)); |
| 326 | strSocks5 += strDest; |
| 327 | strSocks5 += static_cast<char>((port >> 8) & 0xFF); |
| 328 | strSocks5 += static_cast<char>((port >> 0) & 0xFF); |
| 329 | ret = send(hSocket, strSocks5.data(), strSocks5.size(), MSG_NOSIGNAL); |
| 330 | if (ret != (ssize_t)strSocks5.size()) { |
| 331 | CloseSocket(hSocket); |
| 332 | return error("Error sending to proxy"); |
| 333 | } |
| 334 | char pchRet2[4]; |
| 335 | if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) { |
| 336 | CloseSocket(hSocket); |
| 337 | return error("Error reading proxy response"); |
| 338 | } |
| 339 | if (pchRet2[0] != 0x05) { |
| 340 | CloseSocket(hSocket); |
| 341 | return error("Proxy failed to accept request"); |
| 342 | } |
| 343 | if (pchRet2[1] != 0x00) { |
| 344 | CloseSocket(hSocket); |
| 345 | switch (pchRet2[1]) { |
| 346 | case 0x01: |
| 347 | return error("Proxy error: general failure"); |
| 348 | case 0x02: |
| 349 | return error("Proxy error: connection not allowed"); |
| 350 | case 0x03: |
| 351 | return error("Proxy error: network unreachable"); |
| 352 | case 0x04: |
| 353 | return error("Proxy error: host unreachable"); |
| 354 | case 0x05: |
| 355 | return error("Proxy error: connection refused"); |
no test coverage detected