mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-11 15:48:05 +00:00
Merge pull request #300 from sipa/connecttimeout
non-blocking connect (by phantomcircuit)
This commit is contained in:
commit
ce148944c7
@ -151,6 +151,7 @@ bool AppInit2(int argc, char* argv[])
|
||||
" -gen=0 \t\t " + _("Don't generate coins\n") +
|
||||
" -min \t\t " + _("Start minimized\n") +
|
||||
" -datadir=<dir> \t\t " + _("Specify data directory\n") +
|
||||
" -timeout=<n> \t " + _("Specify connection timeout (in milliseconds)\n") +
|
||||
" -proxy=<ip:port> \t " + _("Connect through socks4 proxy\n") +
|
||||
" -dns \t " + _("Allow DNS lookups for addnode and connect\n") +
|
||||
" -addnode=<ip> \t " + _("Add a node to connect to\n") +
|
||||
@ -414,6 +415,13 @@ bool AppInit2(int argc, char* argv[])
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-timeout"))
|
||||
{
|
||||
int nNewTimeout = GetArg("-timeout", 5000);
|
||||
if (nNewTimeout > 0 && nNewTimeout < 600000)
|
||||
nConnectTimeout = nNewTimeout;
|
||||
}
|
||||
|
||||
if (mapArgs.count("-printblock"))
|
||||
{
|
||||
string strMatch = mapArgs["-printblock"];
|
||||
|
@ -79,7 +79,6 @@ extern int fUseUPnP;
|
||||
|
||||
|
||||
|
||||
|
||||
bool CheckDiskSpace(uint64 nAdditionalBytes=0);
|
||||
FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb");
|
||||
FILE* AppendBlockFile(unsigned int& nFileRet);
|
||||
|
82
src/net.cpp
82
src/net.cpp
@ -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)
|
||||
|
||||
|
||||
|
||||
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)
|
||||
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;
|
||||
|
@ -19,6 +19,7 @@ class CRequestTracker;
|
||||
class CNode;
|
||||
class CBlockIndex;
|
||||
extern int nBestHeight;
|
||||
extern int nConnectTimeout;
|
||||
|
||||
|
||||
|
||||
@ -32,7 +33,7 @@ enum
|
||||
|
||||
|
||||
|
||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet);
|
||||
bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout);
|
||||
bool Lookup(const char *pszName, std::vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
|
||||
bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup = false, int portDefault = 0, bool fAllowPort = false);
|
||||
bool GetMyExternalIP(unsigned int& ipRet);
|
||||
|
@ -105,6 +105,8 @@ T* alignup(T* p)
|
||||
typedef int socklen_t;
|
||||
#else
|
||||
#define WSAGetLastError() errno
|
||||
#define WSAEINVAL EINVAL
|
||||
#define WSAEALREADY EALREADY
|
||||
#define WSAEWOULDBLOCK EWOULDBLOCK
|
||||
#define WSAEMSGSIZE EMSGSIZE
|
||||
#define WSAEINTR EINTR
|
||||
|
Loading…
Reference in New Issue
Block a user