diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2015-07-09 18:23:27 -0400 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-07-20 16:57:37 +0200 |
commit | 0095b9a1ff6a5d8d2b6662f7706c191534709b90 (patch) | |
tree | b84d23ce2fce00cd2c04bd9dfa9752354a210006 | |
parent | ea5b5ddd7c790c54393aa0c02f34b2db7be4983f (diff) | |
download | bitcoin-0095b9a1ff6a5d8d2b6662f7706c191534709b90.tar.xz |
Test whether created sockets are select()able
Conflicts:
src/net.cpp
Rebased-From: d422f9b1fdb42a51aadaa1bbc157542dca2feb17
-rw-r--r-- | src/compat.h | 8 | ||||
-rw-r--r-- | src/net.cpp | 19 | ||||
-rw-r--r-- | src/netbase.cpp | 3 |
3 files changed, 30 insertions, 0 deletions
diff --git a/src/compat.h b/src/compat.h index 7a5438a11e..f88b6ce36e 100644 --- a/src/compat.h +++ b/src/compat.h @@ -92,4 +92,12 @@ typedef u_int SOCKET; size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN +bool static inline IsSelectableSocket(SOCKET s) { +#ifdef WIN32 + return true; +#else + return (s >= 0 && s < FD_SETSIZE); +#endif +} + #endif // BITCOIN_COMPAT_H diff --git a/src/net.cpp b/src/net.cpp index 3908be6824..abccdf257b 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -376,6 +376,12 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest) if (pszDest ? ConnectSocketByName(addrConnect, hSocket, pszDest, Params().GetDefaultPort(), nConnectTimeout, &proxyConnectionFailed) : ConnectSocket(addrConnect, hSocket, nConnectTimeout, &proxyConnectionFailed)) { + if (!IsSelectableSocket(hSocket)) { + LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n"); + CloseSocket(hSocket); + return NULL; + } + addrman.Attempt(addrConnect); // Add node @@ -846,8 +852,14 @@ void ThreadSocketHandler() if (nErr != WSAEWOULDBLOCK) LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr)); } + else if (!IsSelectableSocket(hSocket)) + { + LogPrintf("connection from %s dropped: non-selectable socket\n", addr.ToString()); + CloseSocket(hSocket); + } else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS) { + LogPrint("net", "connection from %s dropped (full)\n", addr.ToString()); CloseSocket(hSocket); } else if (CNode::IsBanned(addr) && !whitelisted) @@ -1476,6 +1488,13 @@ bool BindListenPort(const CService &addrBind, string& strError, bool fWhiteliste LogPrintf("%s\n", strError); return false; } + if (!IsSelectableSocket(hListenSocket)) + { + strError = "Error: Couldn't create a listenable socket for incoming connections"; + LogPrintf("%s\n", strError); + return false; + } + #ifndef WIN32 #ifdef SO_NOSIGPIPE diff --git a/src/netbase.cpp b/src/netbase.cpp index e3cb4e706f..bbdc11d46b 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -266,6 +266,9 @@ bool static InterruptibleRecv(char* data, size_t len, int timeout, SOCKET& hSock } else { // Other error or blocking int nErr = WSAGetLastError(); if (nErr == WSAEINPROGRESS || nErr == WSAEWOULDBLOCK || nErr == WSAEINVAL) { + if (!IsSelectableSocket(hSocket)) { + return false; + } struct timeval tval = MillisToTimeval(std::min(endTime - curTime, maxWait)); fd_set fdset; FD_ZERO(&fdset); |