Merge branch '0.4.x' into 0.5.0.x
authorLuke Dashjr <luke-jr+git@utopios.org>
Fri, 17 Feb 2012 14:15:21 +0000 (09:15 -0500)
committerLuke Dashjr <luke-jr+git@utopios.org>
Fri, 17 Feb 2012 14:15:21 +0000 (09:15 -0500)
1  2 
src/net.cpp

diff --combined src/net.cpp
@@@ -10,7 -10,7 +10,7 @@@
  #include "init.h"
  #include "strlcpy.h"
  
 -#ifdef __WXMSW__
 +#ifdef WIN32
  #include <string.h>
  #endif
  
@@@ -103,7 -103,7 +103,7 @@@ bool ConnectSocket(const CAddress& addr
      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
                  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)
                  return false;
              }
          }
 -#ifdef __WXMSW__
 +#ifdef WIN32
          else if (WSAGetLastError() != WSAEISCONN)
  #else
          else
      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
@@@ -679,7 -679,7 +679,7 @@@ CNode* ConnectNode(CAddress addrConnect
          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());
@@@ -731,52 -731,6 +731,52 @@@ void CNode::Cleanup(
  }
  
  
 +std::map<unsigned int, int64> 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<unsigned int, int64>::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;
 +}
 +
  
  
  
@@@ -931,13 -885,17 +931,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)
              {
                  closesocket(hSocket);
              }
 +            else if (CNode::IsBanned(addr.ip))
 +            {
 +                printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
 +                closesocket(hSocket);
 +            }
              else
              {
                  printf("accepted connection %s\n", addr.ToString().c_str());
@@@ -1478,9 -1431,13 +1482,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;
              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;
  
              BOOST_FOREACH(CNode* pnode, vNodes)
                  setConnected.insert(pnode->addr.ip & 0x0000ffff);
  
 +        int64 nANow = GetAdjustedTime();
 +
          CRITICAL_BLOCK(cs_mapAddresses)
          {
              BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
                  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);
@@@ -1608,8 -1562,7 +1615,8 @@@ bool OpenNetworkConnection(const CAddre
      //
      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]--;
@@@ -1713,7 -1666,7 +1720,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);
      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
@@@ -1792,7 -1745,7 +1799,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)
@@@ -1895,7 -1848,7 +1902,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
@@@ -1935,7 -1888,7 +1942,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