|
|
|
@ -51,6 +51,7 @@ map<CInv, int64> mapAlreadyAskedFor;
@@ -51,6 +51,7 @@ map<CInv, int64> mapAlreadyAskedFor;
|
|
|
|
|
|
|
|
|
|
// Settings
|
|
|
|
|
int fUseProxy = false; |
|
|
|
|
int nConnectTimeout = 5000; |
|
|
|
|
CAddress addrProxy("127.0.0.1",9050); |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -76,7 +77,7 @@ void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
@@ -76,7 +77,7 @@ void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet) |
|
|
|
|
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout) |
|
|
|
|
{ |
|
|
|
|
hSocketRet = INVALID_SOCKET; |
|
|
|
|
|
|
|
|
@ -91,7 +92,86 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
@@ -91,7 +92,86 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet)
|
|
|
|
|
bool fProxy = (fUseProxy && addrConnect.IsRoutable()); |
|
|
|
|
struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); |
|
|
|
|
|
|
|
|
|
#ifdef __WXMSW__ |
|
|
|
|
u_long fNonblock = 1; |
|
|
|
|
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) |
|
|
|
|
#else |
|
|
|
|
int fFlags = fcntl(hSocket, F_GETFL, 0); |
|
|
|
|
if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) |
|
|
|
|
{ |
|
|
|
|
// WSAEINVAL is here because some legacy version of winsock uses it
|
|
|
|
|
if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL) |
|
|
|
|
{ |
|
|
|
|
struct timeval timeout; |
|
|
|
|
timeout.tv_sec = nTimeout / 1000; |
|
|
|
|
timeout.tv_usec = (nTimeout % 1000) * 1000; |
|
|
|
|
|
|
|
|
|
fd_set fdset; |
|
|
|
|
FD_ZERO(&fdset); |
|
|
|
|
FD_SET(hSocket, &fdset); |
|
|
|
|
int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout); |
|
|
|
|
if (nRet == 0) |
|
|
|
|
{ |
|
|
|
|
printf("connection timeout\n"); |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (nRet == SOCKET_ERROR) |
|
|
|
|
{ |
|
|
|
|
printf("select() for connection failed: %i\n",WSAGetLastError()); |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
socklen_t nRetSize = sizeof(nRet); |
|
|
|
|
#ifdef __WXMSW__ |
|
|
|
|
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) |
|
|
|
|
#else |
|
|
|
|
if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
printf("getsockopt() for connection failed: %i\n",WSAGetLastError()); |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (nRet != 0) |
|
|
|
|
{ |
|
|
|
|
printf("connect() failed after select(): %i\n",nRet); |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#ifdef __WXMSW__ |
|
|
|
|
else if (WSAGetLastError() != WSAEISCONN) |
|
|
|
|
#else |
|
|
|
|
else |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
printf("connect() failed: %s\n",WSAGetLastError()); |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
this isn't even strictly necessary |
|
|
|
|
CNode::ConnectNode immediately turns the socket back to non-blocking |
|
|
|
|
but we'll turn it back to blocking just in case |
|
|
|
|
*/ |
|
|
|
|
#ifdef __WXMSW__ |
|
|
|
|
fNonblock = 0; |
|
|
|
|
if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) |
|
|
|
|
#else |
|
|
|
|
fFlags = fcntl(hSocket, F_GETFL, 0); |
|
|
|
|
if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
closesocket(hSocket); |
|
|
|
|
return false; |
|
|
|
|