X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=blobdiff_plain;f=src%2Fnet.h;fp=src%2Fnet.h;h=c0cda53f2c3ec548fb53fcecc3702b66fd510eda;hp=c2f0aad2405de3d909d6654e1394a9307594448c;hb=0561bbd1c69263dceb24ffacf850788e6e961a13;hpb=34b67676bb113a79f5f3784dd41541ea1d174729 diff --git a/src/net.h b/src/net.h index c2f0aad..c0cda53 100644 --- a/src/net.h +++ b/src/net.h @@ -1,8 +1,8 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers +// Copyright (c) 2009-2012 The Bitcoin developers // Copyright (c) 2012 The PPCoin developers // Distributed under the MIT/X11 software license, see the accompanying -// file license.txt or http://www.opensource.org/licenses/mit-license.php. +// file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NET_H #define BITCOIN_NET_H @@ -15,31 +15,28 @@ #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; inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } 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); void MapPort(bool fMapPort); bool BindListenPort(std::string& strError=REF(std::string())); void StartNode(void* parg); @@ -70,8 +67,21 @@ 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; @@ -79,26 +89,22 @@ extern uint64 nLocalServices; extern CAddress addrLocalHost; extern CAddress addrSeenByPeer; 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: @@ -113,7 +119,7 @@ public: int64 nLastRecv; int64 nLastSendEmpty; int64 nTimeConnected; - unsigned int nHeaderStart; + int nHeaderStart; unsigned int nMessageStart; CAddress addr; int nVersion; @@ -123,12 +129,13 @@ public: bool fNetworkNode; bool fSuccessfullyConnected; bool fDisconnect; + bool fHasGrant; // whether to call semOutbound.post() at disconnect protected: int nRefCount; // Denial-of-service detection/prevention // Key is ip address, value is banned-until-time - static std::map setBanned; + static std::map setBanned; static CCriticalSection cs_setBanned; int nMisbehavior; @@ -149,28 +156,15 @@ public: uint256 hashCheckpointKnown; // ppcoin: known sent sync-checkpoint // inventory based relay - std::set setInventoryKnown; + mruset setInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; std::multimap mapAskFor; - // publish and subscription - std::vector vfSubscribe; - - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) + CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) { 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); - } nLastSend = 0; nLastRecv = 0; nLastSendEmpty = GetTime(); @@ -181,6 +175,7 @@ public: nVersion = 0; strSubVer = ""; fClient = false; // set by version message + fHasGrant = false; fInbound = fInboundIn; fNetworkNode = false; fSuccessfullyConnected = false; @@ -192,9 +187,9 @@ public: hashLastGetBlocksEnd = 0; nStartingHeight = -1; fGetAddr = false; - vfSubscribe.assign(256, false); nMisbehavior = 0; hashCheckpointKnown = 0; + setInventoryKnown.max_size(SendBufferSize() / 1000); // Be shy and don't send version until we hear if (!fInbound) @@ -254,15 +249,19 @@ public: void AddInventoryKnown(const CInv& inv) { - CRITICAL_BLOCK(cs_inventory) + { + LOCK(cs_inventory); setInventoryKnown.insert(inv); + } } void PushInventory(const CInv& inv) { - CRITICAL_BLOCK(cs_inventory) + { + LOCK(cs_inventory); if (!setInventoryKnown.count(inv)) vInventoryToSend.push_back(inv); + } } void AskFor(const CInv& inv) @@ -275,7 +274,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); @@ -286,7 +287,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(); @@ -300,12 +301,12 @@ public: void AbortMessage() { - if (nHeaderStart == -1) + if (nHeaderStart < 0) return; vSend.resize(nHeaderStart); nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); + LEAVE_CRITICAL_SECTION(cs_vSend); if (fDebug) printf("(aborted)\n"); @@ -320,7 +321,7 @@ public: return; } - if (nHeaderStart == -1) + if (nHeaderStart < 0) return; // Set the size @@ -328,14 +329,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); @@ -343,12 +341,12 @@ public: nHeaderStart = -1; nMessageStart = -1; - cs_vSend.Leave(); + LEAVE_CRITICAL_SECTION(cs_vSend); } void EndMessageAbortIfEmpty() { - if (nHeaderStart == -1) + if (nHeaderStart < 0) return; int nSize = vSend.size() - nMessageStart; if (nSize > 0) @@ -359,18 +357,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 ? 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) @@ -538,8 +525,10 @@ public: uint256 hashReply; RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); - CRITICAL_BLOCK(cs_mapRequests) + { + LOCK(cs_mapRequests); mapRequests[hashReply] = CRequestTracker(fn, param1); + } PushMessage(pszCommand, hashReply); } @@ -551,8 +540,10 @@ public: uint256 hashReply; RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); - CRITICAL_BLOCK(cs_mapRequests) + { + LOCK(cs_mapRequests); mapRequests[hashReply] = CRequestTracker(fn, param1); + } PushMessage(pszCommand, hashReply, a1); } @@ -564,8 +555,10 @@ public: uint256 hashReply; RAND_bytes((unsigned char*)&hashReply, sizeof(hashReply)); - CRITICAL_BLOCK(cs_mapRequests) + { + LOCK(cs_mapRequests); mapRequests[hashReply] = CRequestTracker(fn, param1); + } PushMessage(pszCommand, hashReply, a1, a2); } @@ -595,7 +588,7 @@ public: // between nodes running old code and nodes running // new code. static void ClearBanned(); // needed for unit testing - static bool IsBanned(unsigned int ip); + static bool IsBanned(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot }; @@ -611,15 +604,17 @@ public: inline void RelayInventory(const CInv& inv) { // Put on lists to offer to the other nodes - CRITICAL_BLOCK(cs_vNodes) + { + LOCK(cs_vNodes); BOOST_FOREACH(CNode* pnode, vNodes) pnode->PushInventory(inv); + } } template void RelayMessage(const CInv& inv, const T& a) { - CDataStream ss(SER_NETWORK); + CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss.reserve(10000); ss << a; RelayMessage(inv, ss); @@ -628,8 +623,8 @@ void RelayMessage(const CInv& inv, const T& a) template<> inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) { - CRITICAL_BLOCK(cs_mapRelay) { + LOCK(cs_mapRelay); // Expire old relay messages while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) { @@ -638,7 +633,7 @@ inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) } // Save original serialized message so newer versions are preserved - mapRelay[inv] = ss; + mapRelay.insert(std::make_pair(inv, ss)); vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); } @@ -646,58 +641,4 @@ inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) } - - - - - - -// -// Templates for the publish and subscription system. -// The object being published as T& obj needs to have: -// a set setSources member -// specializations of AdvertInsert and AdvertErase -// Currently implemented for CTable and CProduct. -// - -template -void AdvertStartPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) -{ - // Add to sources - obj.setSources.insert(pfrom->addr.ip); - - if (!AdvertInsert(obj)) - return; - - // Relay - CRITICAL_BLOCK(cs_vNodes) - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) - pnode->PushMessage("publish", nChannel, nHops, obj); -} - -template -void AdvertStopPublish(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) -{ - uint256 hash = obj.GetHash(); - - CRITICAL_BLOCK(cs_vNodes) - BOOST_FOREACH(CNode* pnode, vNodes) - if (pnode != pfrom && (nHops < PUBLISH_HOPS || pnode->IsSubscribed(nChannel))) - pnode->PushMessage("pub-cancel", nChannel, nHops, hash); - - AdvertErase(obj); -} - -template -void AdvertRemoveSource(CNode* pfrom, unsigned int nChannel, unsigned int nHops, T& obj) -{ - // Remove a source - obj.setSources.erase(pfrom->addr.ip); - - // If no longer supported by any sources, cancel it - if (obj.setSources.empty()) - AdvertStopPublish(pfrom, nChannel, nHops, obj); -} - #endif