Use standard C99 (and Qt) types for 64-bit integers
[novacoin.git] / src / net.h
index 0026e40..9f99f47 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -5,12 +5,14 @@
 #ifndef BITCOIN_NET_H
 #define BITCOIN_NET_H
 
+#include <stdint.h>
+
 #include <deque>
 #include <boost/array.hpp>
 #include <boost/foreach.hpp>
 #include <openssl/rand.h>
 
-#ifndef __WXMSW__
+#ifndef WIN32
 #include <arpa/inet.h>
 #endif
 
@@ -33,14 +35,13 @@ bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout
 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);
-bool AddAddress(CAddress addr, int64 nTimePenalty=0, CAddrDB *pAddrDB=NULL);
+bool AddAddress(CAddress addr, int64_t nTimePenalty=0, CAddrDB *pAddrDB=NULL);
 void AddressCurrentlyConnected(const CAddress& addr);
 CNode* FindNode(unsigned int ip);
-CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0);
+CNode* ConnectNode(CAddress addrConnect, int64_t nTimeout=0);
 void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1);
 bool AnySubscribed(unsigned int nChannel);
 void MapPort(bool fMapPort);
-void DNSAddressSeed();
 bool BindListenPort(std::string& strError=REF(std::string()));
 void StartNode(void* parg);
 bool StopNode();
@@ -75,9 +76,9 @@ public:
 
 extern bool fClient;
 extern bool fAllowDNS;
-extern uint64 nLocalServices;
+extern uint64_t nLocalServices;
 extern CAddress addrLocalHost;
-extern uint64 nLocalHostNonce;
+extern uint64_t nLocalHostNonce;
 extern boost::array<int, 10> vnThreadsRunning;
 
 extern std::vector<CNode*> vNodes;
@@ -85,9 +86,9 @@ extern CCriticalSection cs_vNodes;
 extern std::map<std::vector<unsigned char>, CAddress> mapAddresses;
 extern CCriticalSection cs_mapAddresses;
 extern std::map<CInv, CDataStream> mapRelay;
-extern std::deque<std::pair<int64, CInv> > vRelayExpiration;
+extern std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
 extern CCriticalSection cs_mapRelay;
-extern std::map<CInv, int64> mapAlreadyAskedFor;
+extern std::map<CInv, int64_t> mapAlreadyAskedFor;
 
 // Settings
 extern int fUseProxy;
@@ -102,16 +103,16 @@ class CNode
 {
 public:
     // socket
-    uint64 nServices;
+    uint64_t nServices;
     SOCKET hSocket;
     CDataStream vSend;
     CDataStream vRecv;
     CCriticalSection cs_vSend;
     CCriticalSection cs_vRecv;
-    int64 nLastSend;
-    int64 nLastRecv;
-    int64 nLastSendEmpty;
-    int64 nTimeConnected;
+    int64_t nLastSend;
+    int64_t nLastRecv;
+    int64_t nLastSendEmpty;
+    int64_t nTimeConnected;
     unsigned int nHeaderStart;
     unsigned int nMessageStart;
     CAddress addr;
@@ -124,8 +125,15 @@ public:
     bool fDisconnect;
 protected:
     int nRefCount;
+
+    // Denial-of-service detection/prevention
+    // Key is ip address, value is banned-until-time
+    static std::map<unsigned int, int64_t> setBanned;
+    static CCriticalSection cs_setBanned;
+    int nMisbehavior;
+
 public:
-    int64 nReleaseTime;
+    int64_t nReleaseTime;
     std::map<uint256, CRequestTracker> mapRequests;
     CCriticalSection cs_mapRequests;
     uint256 hashContinue;
@@ -143,12 +151,11 @@ public:
     std::set<CInv> setInventoryKnown;
     std::vector<CInv> vInventoryToSend;
     CCriticalSection cs_inventory;
-    std::multimap<int64, CInv> mapAskFor;
+    std::multimap<int64_t, CInv> mapAskFor;
 
     // publish and subscription
     std::vector<char> vfSubscribe;
 
-
     CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false)
     {
         nServices = 0;
@@ -185,6 +192,7 @@ public:
         nStartingHeight = -1;
         fGetAddr = false;
         vfSubscribe.assign(256, false);
+        nMisbehavior = 0;
 
         // Be shy and don't send version until we hear
         if (!fInbound)
@@ -211,7 +219,7 @@ public:
         return std::max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
     }
 
-    CNode* AddRef(int64 nTimeout=0)
+    CNode* AddRef(int64_t nTimeout=0)
     {
         if (nTimeout != 0)
             nReleaseTime = std::max(nReleaseTime, GetTime() + nTimeout);
@@ -259,12 +267,12 @@ public:
     {
         // We're using mapAskFor as a priority queue,
         // the key is the earliest time the request can be sent
-        int64& nRequestTime = mapAlreadyAskedFor[inv];
+        int64_t& nRequestTime = mapAlreadyAskedFor[inv];
         printf("askfor %s   %"PRI64d"\n", inv.ToString().c_str(), nRequestTime);
 
         // Make sure not to reuse time indexes to keep things in the same order
-        int64 nNow = (GetTime() - 1) * 1000000;
-        static int64 nLastTime;
+        int64_t nNow = (GetTime() - 1) * 1000000;
+        static int64_t nLastTime;
         nLastTime = nNow = std::max(nNow, ++nLastTime);
 
         // Each retry is 2 minutes after the last
@@ -349,18 +357,8 @@ public:
 
 
 
-    void PushVersion()
-    {
-        /// when NTP implemented, change to just nTime = GetAdjustedTime()
-        int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
-        CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
-        CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
-        RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
-        PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
-                    nLocalHostNonce, std::string(pszSubVer), nBestHeight);
-    }
-
 
+    void PushVersion();
 
 
     void PushMessage(const char* pszCommand)
@@ -568,6 +566,25 @@ public:
     void CancelSubscribe(unsigned int nChannel);
     void CloseSocketDisconnect();
     void Cleanup();
+
+
+    // Denial-of-service detection/prevention
+    // The idea is to detect peers that are behaving
+    // badly and disconnect/ban them, but do it in a
+    // one-coding-mistake-won't-shatter-the-entire-network
+    // way.
+    // IMPORTANT:  There should be nothing I can give a
+    // node that it will forward on that will make that
+    // node's peers drop it. If there is, an attacker
+    // can isolate a node and/or try to split the network.
+    // Dropping a node for sending stuff that is invalid
+    // now but might be valid in a later version is also
+    // dangerous, because it can cause a network split
+    // between nodes running old code and nodes running
+    // new code.
+    static void ClearBanned(); // needed for unit testing
+    static bool IsBanned(unsigned int ip);
+    bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
 };