mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
netbase: Make InterruptibleRecv return an error code instead of bool
This commit is contained in:
parent
36f9d3ae6d
commit
13f608582c
@ -198,6 +198,14 @@ struct timeval MillisToTimeval(int64_t nTimeout)
|
|||||||
return timeout;
|
return timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class IntrRecvError {
|
||||||
|
OK,
|
||||||
|
Timeout,
|
||||||
|
Disconnected,
|
||||||
|
NetworkError,
|
||||||
|
Interrupted
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read bytes from socket. This will either read the full number of bytes requested
|
* Read bytes from socket. This will either read the full number of bytes requested
|
||||||
* or return False on error or timeout.
|
* or return False on error or timeout.
|
||||||
@ -209,7 +217,7 @@ struct timeval MillisToTimeval(int64_t nTimeout)
|
|||||||
*
|
*
|
||||||
* @note This function requires that hSocket is in non-blocking mode.
|
* @note This function requires that hSocket is in non-blocking mode.
|
||||||
*/
|
*/
|
||||||
bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket)
|
static IntrRecvError InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSocket)
|
||||||
{
|
{
|
||||||
int64_t curTime = GetTimeMillis();
|
int64_t curTime = GetTimeMillis();
|
||||||
int64_t endTime = curTime + timeout;
|
int64_t endTime = curTime + timeout;
|
||||||
@ -222,12 +230,12 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock
|
|||||||
len -= ret;
|
len -= ret;
|
||||||
data += ret;
|
data += ret;
|
||||||
} else if (ret == 0) { // Unexpected disconnection
|
} else if (ret == 0) { // Unexpected disconnection
|
||||||
return false;
|
return IntrRecvError::Disconnected;
|
||||||
} else { // Other error or blocking
|
} else { // Other error or blocking
|
||||||
int nErr = WSAGetLastError();
|
int nErr = WSAGetLastError();
|
||||||
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
|
if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) {
|
||||||
if (!IsSelectableSocket(hSocket)) {
|
if (!IsSelectableSocket(hSocket)) {
|
||||||
return false;
|
return IntrRecvError::NetworkError;
|
||||||
}
|
}
|
||||||
struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
|
struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait));
|
||||||
fd_set fdset;
|
fd_set fdset;
|
||||||
@ -235,17 +243,17 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock
|
|||||||
FD_SET(hSocket, &fdset);
|
FD_SET(hSocket, &fdset);
|
||||||
int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval);
|
int nRet = select(hSocket + 1, &fdset, NULL, NULL, &tval);
|
||||||
if (nRet == SOCKET_ERROR) {
|
if (nRet == SOCKET_ERROR) {
|
||||||
return false;
|
return IntrRecvError::NetworkError;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return IntrRecvError::NetworkError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (interruptSocks5Recv)
|
if (interruptSocks5Recv)
|
||||||
return false;
|
return IntrRecvError::Interrupted;
|
||||||
curTime = GetTimeMillis();
|
curTime = GetTimeMillis();
|
||||||
}
|
}
|
||||||
return len == 0;
|
return len == 0 ? IntrRecvError::OK : IntrRecvError::Timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProxyCredentials
|
struct ProxyCredentials
|
||||||
@ -272,6 +280,7 @@ std::string Socks5ErrorString(int err)
|
|||||||
/** Connect using SOCKS5 (as described in RFC1928) */
|
/** Connect using SOCKS5 (as described in RFC1928) */
|
||||||
static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket)
|
static bool Socks5(const std::string& strDest, int port, const ProxyCredentials *auth, SOCKET& hSocket)
|
||||||
{
|
{
|
||||||
|
IntrRecvError recvr;
|
||||||
LogPrint("net", "SOCKS5 connecting %s\n", strDest);
|
LogPrint("net", "SOCKS5 connecting %s\n", strDest);
|
||||||
if (strDest.size() > 255) {
|
if (strDest.size() > 255) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
@ -294,7 +303,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
return error("Error sending to proxy");
|
return error("Error sending to proxy");
|
||||||
}
|
}
|
||||||
char pchRet1[2];
|
char pchRet1[2];
|
||||||
if (!InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
if ((recvr = InterruptibleRecv(pchRet1, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
|
LogPrintf("Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure\n", strDest, port);
|
||||||
return false;
|
return false;
|
||||||
@ -320,7 +329,7 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
}
|
}
|
||||||
LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
|
LogPrint("proxy", "SOCKS5 sending proxy authentication %s:%s\n", auth->username, auth->password);
|
||||||
char pchRetA[2];
|
char pchRetA[2];
|
||||||
if (!InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
if ((recvr = InterruptibleRecv(pchRetA, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("Error reading proxy authentication response");
|
return error("Error reading proxy authentication response");
|
||||||
}
|
}
|
||||||
@ -349,9 +358,9 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
return error("Error sending to proxy");
|
return error("Error sending to proxy");
|
||||||
}
|
}
|
||||||
char pchRet2[4];
|
char pchRet2[4];
|
||||||
if (!InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
if ((recvr = InterruptibleRecv(pchRet2, 4, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("Error reading proxy response");
|
return error("Error while reading proxy response");
|
||||||
}
|
}
|
||||||
if (pchRet2[0] != 0x05) {
|
if (pchRet2[0] != 0x05) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
@ -370,26 +379,26 @@ static bool Socks5(const std::string& strDest, int port, const ProxyCredentials
|
|||||||
char pchRet3[256];
|
char pchRet3[256];
|
||||||
switch (pchRet2[3])
|
switch (pchRet2[3])
|
||||||
{
|
{
|
||||||
case 0x01: ret = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
|
case 0x01: recvr = InterruptibleRecv(pchRet3, 4, SOCKS5_RECV_TIMEOUT, hSocket); break;
|
||||||
case 0x04: ret = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
|
case 0x04: recvr = InterruptibleRecv(pchRet3, 16, SOCKS5_RECV_TIMEOUT, hSocket); break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
{
|
{
|
||||||
ret = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
|
recvr = InterruptibleRecv(pchRet3, 1, SOCKS5_RECV_TIMEOUT, hSocket);
|
||||||
if (!ret) {
|
if (recvr != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("Error reading from proxy");
|
return error("Error reading from proxy");
|
||||||
}
|
}
|
||||||
int nRecv = pchRet3[0];
|
int nRecv = pchRet3[0];
|
||||||
ret = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
|
recvr = InterruptibleRecv(pchRet3, nRecv, SOCKS5_RECV_TIMEOUT, hSocket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: CloseSocket(hSocket); return error("Error: malformed proxy response");
|
default: CloseSocket(hSocket); return error("Error: malformed proxy response");
|
||||||
}
|
}
|
||||||
if (!ret) {
|
if (recvr != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("Error reading from proxy");
|
return error("Error reading from proxy");
|
||||||
}
|
}
|
||||||
if (!InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) {
|
if ((recvr = InterruptibleRecv(pchRet3, 2, SOCKS5_RECV_TIMEOUT, hSocket)) != IntrRecvError::OK) {
|
||||||
CloseSocket(hSocket);
|
CloseSocket(hSocket);
|
||||||
return error("Error reading from proxy");
|
return error("Error reading from proxy");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user