X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=blobdiff_plain;f=src%2Fnet.h;h=f071ac734936a9ce48be27a3dcca19c3c79d66bb;hp=cf0661601054c126fb9d4210ec9ad6efa7e6417c;hb=1c1980bccd1bcccdb03c69ebbe03ad51e08f343a;hpb=83e34b29071b58d6578b197430d12c55d277a515 diff --git a/src/net.h b/src/net.h index cf06616..f071ac7 100644 --- a/src/net.h +++ b/src/net.h @@ -1,15 +1,16 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin developers -// Copyright (c) 2012 The PPCoin developers -// Copyright (c) 2012-2013 The NovaCoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_NET_H #define BITCOIN_NET_H +#include #include +#ifndef Q_MOC_RUN #include #include +#endif #include #ifndef WIN32 @@ -18,35 +19,64 @@ #include "mruset.h" #include "netbase.h" -#include "protocol.h" #include "addrman.h" +#include "hash.h" -class CAddrDB; class CRequestTracker; class CNode; class CBlockIndex; extern int nBestHeight; +const uint16_t nSocksDefault = 9050; +const uint16_t nPortZero = 0; -inline unsigned int ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 10*1000); } -inline unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 10*1000); } +inline uint64_t ReceiveBufferSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); } +inline uint64_t SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); } +void AddOneShot(std::string strDest); 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 MapPort(bool fMapPort); -bool BindListenPort(std::string& strError=REF(std::string())); +CNode* ConnectNode(CAddress addrConnect, const char *strDest = NULL, int64_t nTimeout=0); +bool OpenNetworkConnection(const CAddress& addrConnect, CSemaphoreGrant *grantOutbound = NULL, const char *strDest = NULL, bool fOneShot = false); +void MapPort(); +unsigned short GetListenPort(); +bool BindListenPort(const CService &bindAddr, std::string& strError=REF(std::string())); void StartNode(void* parg); bool StopNode(); enum { + LOCAL_NONE, // unknown + LOCAL_IF, // address a local interface listens on + LOCAL_BIND, // address explicit bound to + LOCAL_IRC, // address reported by IRC (deprecated) + LOCAL_HTTP, // address reported by whatismyip.com and similar + LOCAL_MANUAL, // address explicitly specified (-externalip=) + + LOCAL_MAX +}; + +void SetLimited(enum Network net, bool fLimited = true); +bool IsLimited(enum Network net); +bool IsLimited(const CNetAddr& addr); +bool AddLocal(const CService& addr, int nScore = LOCAL_NONE); +bool AddLocal(const CNetAddr& addr, int nScore = LOCAL_NONE); +bool SeenLocal(const CService& addr); +bool IsLocal(const CService& addr); +bool GetLocal(CService &addr, const CNetAddr *paddrPeer = NULL); +bool IsReachable(const CNetAddr &addr); +void SetReachable(enum Network net, bool fFlag = true); +CAddress GetLocalAddress(const CNetAddr *paddrPeer = NULL); + + +enum +{ MSG_TX = 1, - MSG_BLOCK, + MSG_BLOCK }; class CRequestTracker @@ -74,33 +104,57 @@ enum threadId THREAD_SOCKETHANDLER, THREAD_OPENCONNECTIONS, THREAD_MESSAGEHANDLER, - THREAD_MINER, - THREAD_RPCSERVER, - THREAD_UPNP, + THREAD_RPCLISTENER, THREAD_DNSSEED, THREAD_ADDEDCONNECTIONS, THREAD_DUMPADDRESS, + THREAD_RPCHANDLER, THREAD_MINTER, + THREAD_SCRIPTCHECK, + THREAD_NTP, + THREAD_IPCOLLECTOR, THREAD_MAX }; extern bool fClient; -extern bool fAllowDNS; -extern uint64 nLocalServices; -extern CAddress addrLocalHost; +extern bool fDiscover; +extern uint64_t nLocalServices; +extern uint64_t nLocalHostNonce; extern CAddress addrSeenByPeer; -extern uint64 nLocalHostNonce; extern boost::array vnThreadsRunning; extern CAddrMan addrman; extern std::vector vNodes; extern CCriticalSection cs_vNodes; +extern std::vector vAddedNodes; +extern CCriticalSection cs_vAddedNodes; extern std::map mapRelay; -extern std::deque > vRelayExpiration; +extern std::deque > vRelayExpiration; extern CCriticalSection cs_mapRelay; -extern std::map mapAlreadyAskedFor; +extern std::map mapAlreadyAskedFor; + + + +class CNodeStats +{ +public: + uint64_t nServices; + int64_t nLastSend; + int64_t nLastRecv; + int64_t nTimeConnected; + std::string addrName; + int32_t nVersion; + std::string strSubVer; + bool fInbound; + int64_t nReleaseTime; + int32_t nStartingHeight; + int32_t nMisbehavior; + uint64_t nSendBytes; + uint64_t nRecvBytes; + bool fSyncNode; +}; @@ -111,44 +165,50 @@ class CNode { public: // socket - uint64 nServices; + uint64_t nServices; SOCKET hSocket; CDataStream vSend; CDataStream vRecv; + uint64_t nSendBytes; + uint64_t nRecvBytes; CCriticalSection cs_vSend; CCriticalSection cs_vRecv; - int64 nLastSend; - int64 nLastRecv; - int64 nLastSendEmpty; - int64 nTimeConnected; - int nHeaderStart; - unsigned int nMessageStart; + int64_t nLastSend; + int64_t nLastRecv; + int64_t nLastSendEmpty; + int64_t nTimeConnected; + int32_t nHeaderStart; + uint32_t nMessageStart; CAddress addr; - int nVersion; + std::string addrName; + CService addrLocal; + int32_t nVersion; std::string strSubVer; + bool fOneShot; bool fClient; bool fInbound; bool fNetworkNode; bool fSuccessfullyConnected; bool fDisconnect; - bool fHasGrant; // whether to call semOutbound.post() at disconnect + CSemaphoreGrant grantOutbound; protected: int nRefCount; // Denial-of-service detection/prevention - // Key is ip address, value is banned-until-time - static std::map setBanned; + // Key is IP address, value is banned-until-time + static std::map setBanned; static CCriticalSection cs_setBanned; int nMisbehavior; public: - int64 nReleaseTime; + int64_t nReleaseTime; std::map mapRequests; CCriticalSection cs_mapRequests; uint256 hashContinue; CBlockIndex* pindexLastGetBlocksBegin; uint256 hashLastGetBlocksEnd; - int nStartingHeight; + int32_t nStartingHeight; + bool fStartSync; // flood relay std::vector vAddrToSend; @@ -161,23 +221,26 @@ public: mruset setInventoryKnown; std::vector vInventoryToSend; CCriticalSection cs_inventory; - std::multimap mapAskFor; + std::multimap mapAskFor; - CNode(SOCKET hSocketIn, CAddress addrIn, bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) + CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn = "", bool fInboundIn=false) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION) { nServices = 0; hSocket = hSocketIn; nLastSend = 0; nLastRecv = 0; + nSendBytes = 0; + nRecvBytes = 0; nLastSendEmpty = GetTime(); nTimeConnected = GetTime(); nHeaderStart = -1; - nMessageStart = -1; + nMessageStart = std::numeric_limits::max(); addr = addrIn; + addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn; nVersion = 0; - strSubVer = ""; + strSubVer.clear(); + fOneShot = false; fClient = false; // set by version message - fHasGrant = false; fInbound = fInboundIn; fNetworkNode = false; fSuccessfullyConnected = false; @@ -188,13 +251,14 @@ public: pindexLastGetBlocksBegin = 0; hashLastGetBlocksEnd = 0; nStartingHeight = -1; + fStartSync = false; fGetAddr = false; nMisbehavior = 0; hashCheckpointKnown = 0; - setInventoryKnown.max_size(SendBufferSize() / 1000); + setInventoryKnown.max_size((size_t)SendBufferSize() / 1000); // Be shy and don't send version until we hear - if (!fInbound) + if (hSocket != INVALID_SOCKET && !fInbound) PushVersion(); } @@ -202,12 +266,17 @@ public: { if (hSocket != INVALID_SOCKET) { - closesocket(hSocket); - hSocket = INVALID_SOCKET; + CloseSocket(hSocket); } } + private: + // Network usage totals + static CCriticalSection cs_totalBytesRecv; + static CCriticalSection cs_totalBytesSent; + static uint64_t nTotalBytesRecv; + static uint64_t nTotalBytesSent; CNode(const CNode&); void operator=(const CNode&); public: @@ -218,7 +287,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); @@ -270,12 +339,13 @@ public: { // We're using mapAskFor as a priority queue, // the key is the earliest time the request can be sent - int64& nRequestTime = mapAlreadyAskedFor[inv]; - printf("askfor %s %"PRI64d"\n", inv.ToString().c_str(), nRequestTime); + int64_t& nRequestTime = mapAlreadyAskedFor[inv]; + if (fDebugNet) + printf("askfor %s %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str()); // 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); nLastTime = nNow; @@ -292,13 +362,11 @@ public: ENTER_CRITICAL_SECTION(cs_vSend); if (nHeaderStart != -1) AbortMessage(); - nHeaderStart = vSend.size(); + nHeaderStart = (int32_t)vSend.size(); vSend << CMessageHeader(pszCommand, 0); - nMessageStart = vSend.size(); - if (fDebug) { - printf("%s ", DateTimeStrFormat(GetTime()).c_str()); + nMessageStart = (uint32_t)vSend.size(); + if (fDebug) printf("sending: %s ", pszCommand); - } } void AbortMessage() @@ -307,7 +375,7 @@ public: return; vSend.resize(nHeaderStart); nHeaderStart = -1; - nMessageStart = -1; + nMessageStart = std::numeric_limits::max(); LEAVE_CRITICAL_SECTION(cs_vSend); if (fDebug) @@ -327,22 +395,22 @@ public: return; // Set the size - unsigned int nSize = vSend.size() - nMessageStart; - memcpy((char*)&vSend[nHeaderStart] + offsetof(CMessageHeader, nMessageSize), &nSize, sizeof(nSize)); + uint32_t nSize = (uint32_t) vSend.size() - nMessageStart; + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize)); // Set the checksum uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end()); - unsigned int nChecksum = 0; + uint32_t 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)); + assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum)); + memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum)); if (fDebug) { printf("(%d bytes)\n", nSize); } nHeaderStart = -1; - nMessageStart = -1; + nMessageStart = std::numeric_limits::max(); LEAVE_CRITICAL_SECTION(cs_vSend); } @@ -350,7 +418,7 @@ public: { if (nHeaderStart < 0) return; - int nSize = vSend.size() - nMessageStart; + int nSize = (int) vSend.size() - nMessageStart; if (nSize > 0) EndMessage(); else @@ -592,16 +660,14 @@ public: static void ClearBanned(); // needed for unit testing static bool IsBanned(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot -}; - - - - - - - - + void copyStats(CNodeStats &stats); + // Network stats + static void RecordBytesRecv(uint64_t bytes); + static void RecordBytesSent(uint64_t bytes); + static uint64_t GetTotalBytesRecv(); + static uint64_t GetTotalBytesSent(); +}; inline void RelayInventory(const CInv& inv) { @@ -613,34 +679,9 @@ inline void RelayInventory(const CInv& inv) } } -template -void RelayMessage(const CInv& inv, const T& a) -{ - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss.reserve(10000); - ss << a; - RelayMessage(inv, ss); -} - -template<> -inline void RelayMessage<>(const CInv& inv, const CDataStream& ss) -{ - { - LOCK(cs_mapRelay); - // Expire old relay messages - while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime()) - { - mapRelay.erase(vRelayExpiration.front().second); - vRelayExpiration.pop_front(); - } - - // Save original serialized message so newer versions are preserved - mapRelay.insert(std::make_pair(inv, ss)); - vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv)); - } - - RelayInventory(inv); -} +class CTransaction; +void RelayTransaction(const CTransaction& tx, const uint256& hash); +void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss); #endif