X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fnet.cpp;h=e92c659a394bd95f8abae255ddf8889e5c92b1a1;hb=dfac636fd7e4f0168daade3b3095f3d5a60fd524;hp=83e7f28c6bc013215bf2759d0c23807847417a20;hpb=888ac4e7a326986945ca91668c47a3d8fa981d49;p=novacoin.git diff --git a/src/net.cpp b/src/net.cpp index 83e7f28..e92c659 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -10,8 +10,10 @@ #include "init.h" #include "strlcpy.h" -#ifdef __WXMSW__ +#ifdef WIN32 #include +#else +#include #endif #ifdef USE_UPNP @@ -103,7 +105,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout bool fProxy = (fUseProxy && addrConnect.IsRoutable()); struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr()); -#ifdef __WXMSW__ +#ifdef WIN32 u_long fNonblock = 1; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else @@ -142,7 +144,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout return false; } socklen_t nRetSize = sizeof(nRet); -#ifdef __WXMSW__ +#ifdef WIN32 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR) #else if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR) @@ -159,7 +161,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout return false; } } -#ifdef __WXMSW__ +#ifdef WIN32 else if (WSAGetLastError() != WSAEISCONN) #else else @@ -176,7 +178,7 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout CNode::ConnectNode immediately turns the socket back to non-blocking but we'll turn it back to blocking just in case */ -#ifdef __WXMSW__ +#ifdef WIN32 fNonblock = 0; if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR) #else @@ -316,14 +318,14 @@ bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const cha } if (pszKeyword == NULL) break; - if (strLine.find(pszKeyword) != -1) + if (strLine.find(pszKeyword) != string::npos) { strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword)); break; } } closesocket(hSocket); - if (strLine.find("<") != -1) + if (strLine.find("<") != string::npos) strLine = strLine.substr(0, strLine.find("<")); strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r")); while (strLine.size() > 0 && isspace(strLine[strLine.size()-1])) @@ -679,7 +681,7 @@ CNode* ConnectNode(CAddress addrConnect, int64 nTimeout) printf("connected %s\n", addrConnect.ToString().c_str()); // Set to nonblocking -#ifdef __WXMSW__ +#ifdef WIN32 u_long nOne = 1; if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR) printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError()); @@ -716,6 +718,7 @@ void CNode::CloseSocketDisconnect() printf("disconnecting node %s\n", addr.ToString().c_str()); closesocket(hSocket); hSocket = INVALID_SOCKET; + vRecv.clear(); } } @@ -731,6 +734,52 @@ void CNode::Cleanup() } +std::map CNode::setBanned; +CCriticalSection CNode::cs_setBanned; + +void CNode::ClearBanned() +{ + setBanned.clear(); +} + +bool CNode::IsBanned(unsigned int ip) +{ + bool fResult = false; + CRITICAL_BLOCK(cs_setBanned) + { + std::map::iterator i = setBanned.find(ip); + if (i != setBanned.end()) + { + int64 t = (*i).second; + if (GetTime() < t) + fResult = true; + } + } + return fResult; +} + +bool CNode::Misbehaving(int howmuch) +{ + if (addr.IsLocal()) + { + printf("Warning: local node %s misbehaving\n", addr.ToString().c_str()); + return false; + } + + nMisbehavior += howmuch; + if (nMisbehavior >= GetArg("-banscore", 100)) + { + int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban + CRITICAL_BLOCK(cs_setBanned) + if (setBanned[addr.ip] < banTime) + setBanned[addr.ip] = banTime; + CloseSocketDisconnect(); + printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior); + return true; + } + return false; +} + @@ -868,7 +917,7 @@ void ThreadSocketHandler2(void* parg) if (hSocketMax > -1) { printf("socket select error %d\n", nErr); - for (int i = 0; i <= hSocketMax; i++) + for (unsigned int i = 0; i <= hSocketMax; i++) FD_SET(i, &fdsetRecv); } FD_ZERO(&fdsetSend); @@ -885,13 +934,17 @@ void ThreadSocketHandler2(void* parg) struct sockaddr_in sockaddr; socklen_t len = sizeof(sockaddr); SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len); - CAddress addr(sockaddr); + CAddress addr; int nInbound = 0; + if (hSocket != INVALID_SOCKET) + addr = CAddress(sockaddr); + CRITICAL_BLOCK(cs_vNodes) BOOST_FOREACH(CNode* pnode, vNodes) if (pnode->fInbound) nInbound++; + if (hSocket == INVALID_SOCKET) { if (WSAGetLastError() != WSAEWOULDBLOCK) @@ -901,6 +954,11 @@ void ThreadSocketHandler2(void* parg) { closesocket(hSocket); } + else if (CNode::IsBanned(addr.ip)) + { + printf("connection from %s dropped (banned)\n", addr.ToString().c_str()); + closesocket(hSocket); + } else { printf("accepted connection %s\n", addr.ToString().c_str()); @@ -1247,7 +1305,7 @@ void ThreadDNSAddressSeed2(void* parg) { printf("Loading addresses from DNS seeds (could take a while)\n"); - for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { + for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { vector vaddr; if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true)) { @@ -1427,9 +1485,13 @@ void ThreadOpenConnections2(void* parg) int64 nStart = GetTime(); loop { - // Limit outbound connections vnThreadsRunning[1]--; Sleep(500); + vnThreadsRunning[1]++; + if (fShutdown) + return; + + // Limit outbound connections loop { int nOutbound = 0; @@ -1441,13 +1503,12 @@ void ThreadOpenConnections2(void* parg) nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125)); if (nOutbound < nMaxOutboundConnections) break; + vnThreadsRunning[1]--; Sleep(2000); + vnThreadsRunning[1]++; if (fShutdown) return; } - vnThreadsRunning[1]++; - if (fShutdown) - return; bool fAddSeeds = false; @@ -1461,7 +1522,7 @@ void ThreadOpenConnections2(void* parg) if (fAddSeeds) { - for (int i = 0; i < ARRAYLEN(pnSeed); i++) + for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++) { // It'll only connect to one or two seed nodes because once it connects, // it'll get a pile of addresses with newer timestamps. @@ -1488,6 +1549,8 @@ void ThreadOpenConnections2(void* parg) BOOST_FOREACH(CNode* pnode, vNodes) setConnected.insert(pnode->addr.ip & 0x0000ffff); + int64 nANow = GetAdjustedTime(); + CRITICAL_BLOCK(cs_mapAddresses) { BOOST_FOREACH(const PAIRTYPE(vector, CAddress)& item, mapAddresses) @@ -1495,8 +1558,8 @@ void ThreadOpenConnections2(void* parg) const CAddress& addr = item.second; if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff)) continue; - int64 nSinceLastSeen = GetAdjustedTime() - addr.nTime; - int64 nSinceLastTry = GetAdjustedTime() - addr.nLastTry; + int64 nSinceLastSeen = nANow - addr.nTime; + int64 nSinceLastTry = nANow - addr.nLastTry; // Randomize the order in a deterministic way, putting the standard port first int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60); @@ -1555,7 +1618,8 @@ bool OpenNetworkConnection(const CAddress& addrConnect) // if (fShutdown) return false; - if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || FindNode(addrConnect.ip)) + if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() || + FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip)) return false; vnThreadsRunning[1]--; @@ -1659,7 +1723,7 @@ bool BindListenPort(string& strError) int nOne = 1; addrLocalHost.port = htons(GetListenPort()); -#ifdef __WXMSW__ +#ifdef WIN32 // Initialize Windows Sockets WSADATA wsadata; int ret = WSAStartup(MAKEWORD(2,2), &wsadata); @@ -1685,13 +1749,13 @@ bool BindListenPort(string& strError) setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)); #endif -#ifndef __WXMSW__ +#ifndef WIN32 // Allow binding if the port is still in TIME_WAIT state after // the program was closed and restarted. Not an issue on windows. setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)); #endif -#ifdef __WXMSW__ +#ifdef WIN32 // Set to nonblocking, incoming connections will also inherit this if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR) #else @@ -1738,7 +1802,7 @@ void StartNode(void* parg) if (pnodeLocalHost == NULL) pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices)); -#ifdef __WXMSW__ +#ifdef WIN32 // Get local host ip char pszHostName[1000] = ""; if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR) @@ -1841,7 +1905,7 @@ bool StopNode() fShutdown = true; nTransactionsUpdated++; int64 nStart = GetTime(); - while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 + while (vnThreadsRunning[0] > 0 || vnThreadsRunning[1] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0 #ifdef USE_UPNP || vnThreadsRunning[5] > 0 #endif @@ -1881,7 +1945,7 @@ public: if (closesocket(hListenSocket) == SOCKET_ERROR) printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError()); -#ifdef __WXMSW__ +#ifdef WIN32 // Shutdown Windows Sockets WSACleanup(); #endif