X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fnet.h;h=82316917d2b49fce9769d41f7f98ef7860306511;hb=66116c3847eeb3f0619bc084d96f5add41a156c8;hp=d8b90222769ab1caf600703ee279a8ff2d78e7ab;hpb=888ac4e7a326986945ca91668c47a3d8fa981d49;p=novacoin.git diff --git a/src/net.h b/src/net.h index d8b9022..8231691 100644 --- a/src/net.h +++ b/src/net.h @@ -10,18 +10,20 @@ #include #include -#ifndef __WXMSW__ +#ifndef WIN32 #include #endif +#include "mruset.h" +#include "netbase.h" #include "protocol.h" +#include "addrman.h" class CAddrDB; class CRequestTracker; class CNode; class CBlockIndex; extern int nBestHeight; -extern int nConnectTimeout; @@ -29,13 +31,11 @@ inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer" inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } static const unsigned int PUBLISH_HOPS = 5; -bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout=nConnectTimeout); -bool Lookup(const char *pszName, std::vector& 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); -void AddressCurrentlyConnected(const CAddress& addr); -CNode* FindNode(unsigned int ip); +bool RecvLine(SOCKET hSocket, std::string& strLine); +bool GetMyExternalIP(CNetAddr& ipRet); +void AddressCurrentlyConnected(const CService& addr); +CNode* FindNode(const CNetAddr& ip); +CNode* FindNode(const CService& ip); CNode* ConnectNode(CAddress addrConnect, int64 nTimeout=0); void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1); bool AnySubscribed(unsigned int nChannel); @@ -69,34 +69,43 @@ public: }; - - +/** Thread types */ +enum threadId +{ + THREAD_SOCKETHANDLER, + THREAD_OPENCONNECTIONS, + THREAD_MESSAGEHANDLER, + THREAD_MINER, + THREAD_RPCSERVER, + THREAD_UPNP, + THREAD_DNSSEED, + THREAD_ADDEDCONNECTIONS, + THREAD_DUMPADDRESS, + + THREAD_MAX +}; extern bool fClient; extern bool fAllowDNS; extern uint64 nLocalServices; extern CAddress addrLocalHost; extern uint64 nLocalHostNonce; -extern boost::array vnThreadsRunning; +extern boost::array vnThreadsRunning; +extern CAddrMan addrman; extern std::vector vNodes; extern CCriticalSection cs_vNodes; -extern std::map, CAddress> mapAddresses; -extern CCriticalSection cs_mapAddresses; extern std::map mapRelay; extern std::deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; extern std::map mapAlreadyAskedFor; -// Settings -extern int fUseProxy; -extern CAddress addrProxy; - +/** Information about a peer */ class CNode { public: @@ -111,7 +120,7 @@ public: int64 nLastRecv; int64 nLastSendEmpty; int64 nTimeConnected; - unsigned int nHeaderStart; + signed int nHeaderStart; unsigned int nMessageStart; CAddress addr; int nVersion; @@ -123,6 +132,13 @@ public: bool fDisconnect; protected: int nRefCount; + + // Denial-of-service detection/prevention + // Key is ip address, value is banned-until-time + static std::map setBanned; + static CCriticalSection cs_setBanned; + int nMisbehavior; + public: int64 nReleaseTime; std::map mapRequests; @@ -139,7 +155,7 @@ public: std::set setKnown; // inventory based relay - std::set setInventoryKnown; + mruset setInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; std::multimap mapAskFor; @@ -147,21 +163,14 @@ public: // publish and subscription std::vector vfSubscribe; - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) { nServices = 0; hSocket = hSocketIn; vSend.SetType(SER_NETWORK); - vSend.SetVersion(0); vRecv.SetType(SER_NETWORK); - vRecv.SetVersion(0); - // Version 0.2 obsoletes 20 Feb 2012 - if (GetTime() > 1329696000) - { - vSend.SetVersion(209); - vRecv.SetVersion(209); - } + vSend.SetVersion(209); + vRecv.SetVersion(209); nLastSend = 0; nLastRecv = 0; nLastSendEmpty = GetTime(); @@ -184,6 +193,8 @@ public: nStartingHeight = -1; fGetAddr = false; vfSubscribe.assign(256, false); + nMisbehavior = 0; + setInventoryKnown.max_size(SendBufferSize() / 1000); // Be shy and don't send version until we hear if (!fInbound) @@ -277,7 +288,7 @@ public: void BeginMessage(const char* pszCommand) { - cs_vSend.Enter("cs_vSend", __FILE__, __LINE__); + ENTER_CRITICAL_SECTION(cs_vSend); if (nHeaderStart != -1) AbortMessage(); nHeaderStart = vSend.size(); @@ -296,7 +307,7 @@ public: vSend.resize(nHeaderStart); nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); + LEAVE_CRITICAL_SECTION(cs_vSend); if (fDebug) printf("(aborted)\n"); @@ -319,14 +330,11 @@ public: memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); // Set the checksum - if (vSend.GetVersion() >= 209) - { - uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); - unsigned int nChecksum = 0; - memcpy(&nChecksum, &hash, sizeof(nChecksum)); - assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum)); - memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); - } + uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); + unsigned int nChecksum = 0; + memcpy(&nChecksum, &hash, sizeof(nChecksum)); + assert(nMessageStart - nHeaderStart >= offsetof(CMessageHeader, nChecksum) + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); if (fDebug) { printf("(%d bytes)\n", nSize); @@ -334,7 +342,7 @@ public: nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); + LEAVE_CRITICAL_SECTION(cs_vSend); } void EndMessageAbortIfEmpty() @@ -350,18 +358,7 @@ 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 || !addrLocalHost.IsRoutable() ? 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) @@ -569,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(CNetAddr ip); + bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot };