X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fnet.h;h=5666805d58acde309d40f08adc1d55ccf26c22fd;hb=a93ab877877925c60b2dbf56bdde8aa46b6b7391;hp=66f3949b86e15d8f597a1cdbf1d7e5a65bb9b923;hpb=33e28c9948336784324cf5c7248ce608b93dbfde;p=novacoin.git diff --git a/src/net.h b/src/net.h index 66f3949..5666805 100644 --- a/src/net.h +++ b/src/net.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NET_H @@ -10,14 +10,13 @@ #include #include -#ifndef __WXMSW__ +#ifndef WIN32 #include #endif #include "protocol.h" class CAddrDB; -class CInv; class CRequestTracker; class CNode; class CBlockIndex; @@ -41,7 +40,6 @@ CNode* ConnectNode(CAddress addrConnect, int64 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(); @@ -52,85 +50,6 @@ enum MSG_BLOCK, }; -static const char* ppszTypeName[] = -{ - "ERROR", - "tx", - "block", -}; - -class CInv -{ -public: - int type; - uint256 hash; - - CInv() - { - type = 0; - hash = 0; - } - - CInv(int typeIn, const uint256& hashIn) - { - type = typeIn; - hash = hashIn; - } - - CInv(const std::string& strType, const uint256& hashIn) - { - int i; - for (i = 1; i < ARRAYLEN(ppszTypeName); i++) - { - if (strType == ppszTypeName[i]) - { - type = i; - break; - } - } - if (i == ARRAYLEN(ppszTypeName)) - throw std::out_of_range(strprintf("CInv::CInv(string, uint256) : unknown type '%s'", strType.c_str())); - hash = hashIn; - } - - IMPLEMENT_SERIALIZE - ( - READWRITE(type); - READWRITE(hash); - ) - - friend inline bool operator<(const CInv& a, const CInv& b) - { - return (a.type < b.type || (a.type == b.type && a.hash < b.hash)); - } - - bool IsKnownType() const - { - return (type >= 1 && type < ARRAYLEN(ppszTypeName)); - } - - const char* GetCommand() const - { - if (!IsKnownType()) - throw std::out_of_range(strprintf("CInv::GetCommand() : type=%d unknown type", type)); - return ppszTypeName[type]; - } - - std::string ToString() const - { - return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str()); - } - - void print() const - { - printf("CInv(%s)\n", ToString().c_str()); - } -}; - - - - - class CRequestTracker { public: @@ -192,7 +111,7 @@ public: int64 nLastRecv; int64 nLastSendEmpty; int64 nTimeConnected; - unsigned int nHeaderStart; + signed int nHeaderStart; unsigned int nMessageStart; CAddress addr; int nVersion; @@ -204,6 +123,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; @@ -228,7 +154,6 @@ public: // publish and subscription std::vector vfSubscribe; - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) { nServices = 0; @@ -265,6 +190,7 @@ public: nStartingHeight = -1; fGetAddr = false; vfSubscribe.assign(256, false); + nMisbehavior = 0; // Be shy and don't send version until we hear if (!fInbound) @@ -345,7 +271,9 @@ public: // Make sure not to reuse time indexes to keep things in the same order int64 nNow = (GetTime() - 1) * 1000000; static int64 nLastTime; - nLastTime = nNow = std::max(nNow, ++nLastTime); + ++nLastTime; + nNow = std::max(nNow, nLastTime); + nLastTime = nNow; // Each retry is 2 minutes after the last nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow); @@ -356,15 +284,16 @@ 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(); vSend << CMessageHeader(pszCommand, 0); nMessageStart = vSend.size(); - if (fDebug) + if (fDebug) { printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); - printf("sending: %s ", pszCommand); + printf("sending: %s ", pszCommand); + } } void AbortMessage() @@ -374,8 +303,10 @@ public: vSend.resize(nHeaderStart); nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); - printf("(aborted)\n"); + LEAVE_CRITICAL_SECTION(cs_vSend); + + if (fDebug) + printf("(aborted)\n"); } void EndMessage() @@ -404,12 +335,13 @@ public: memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nChecksum), &nChecksum, sizeof(nChecksum)); } - printf("(%d bytes) ", nSize); - printf("\n"); + if (fDebug) { + printf("(%d bytes)\n", nSize); + } nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); + LEAVE_CRITICAL_SECTION(cs_vSend); } void EndMessageAbortIfEmpty() @@ -430,7 +362,7 @@ public: /// 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); + 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); @@ -644,6 +576,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 };