24 #include <arpa/inet.h>
27 #include <boost/foreach.hpp>
28 #include <boost/signals2/signal.hpp>
29 #include <openssl/rand.h>
57 void StartNode(boost::thread_group& threadGroup);
108 extern std::vector<CNode*>
vNodes;
110 extern std::map<CInv, CDataStream>
mapRelay;
164 CNetMessage(
int nTypeIn,
int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
184 int readHeader(
const char *pch,
unsigned int nBytes);
185 int readData(
const char *pch,
unsigned int nBytes);
249 void Fuzz(
int nChance);
293 fInbound = fInboundIn;
294 fNetworkNode =
false;
295 fSuccessfullyConnected =
false;
301 pindexLastGetBlocksBegin = 0;
302 hashLastGetBlocksEnd = 0;
303 nStartingHeight = -1;
315 LOCK(cs_nLastNodeId);
356 assert(nRefCount >= 0);
363 unsigned int total = 0;
375 nRecvVersion = nVersionIn;
395 setAddrKnown.
insert(addr);
404 vAddrToSend.push_back(addr);
412 setInventoryKnown.
insert(inv);
420 if (!setInventoryKnown.
count(inv))
421 vInventoryToSend.push_back(inv);
432 int64_t nRequestTime;
434 if (it != mapAlreadyAskedFor.
end())
435 nRequestTime = it->second;
442 static int64_t nLastTime;
444 nNow = std::max(nNow, nLastTime);
448 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
449 if (it != mapAlreadyAskedFor.
end())
450 mapAlreadyAskedFor.
update(it, nRequestTime);
452 mapAlreadyAskedFor.
insert(std::make_pair(inv, nRequestTime));
453 mapAskFor.insert(std::make_pair(nRequestTime, inv));
462 assert(ssSend.
size() == 0);
464 LogPrint(
"net",
"sending: %s ", pszCommand);
485 LogPrint(
"net",
"dropmessages DROPPING SEND MESSAGE\n");
489 if (
mapArgs.count(
"-fuzzmessagestest"))
492 if (ssSend.
size() == 0)
496 unsigned int nSize = ssSend.
size() - CMessageHeader::HEADER_SIZE;
497 memcpy((
char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize,
sizeof(nSize));
501 unsigned int nChecksum = 0;
502 memcpy(&nChecksum, &hash,
sizeof(nChecksum));
503 assert(ssSend.
size () >= CMessageHeader::CHECKSUM_OFFSET +
sizeof(nChecksum));
504 memcpy((
char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum,
sizeof(nChecksum));
506 LogPrint(
"net",
"(%d bytes)\n", nSize);
508 std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(),
CSerializeData());
510 nSendSize += (*it).size();
513 if (it == vSendMsg.begin())
536 template<
typename T1>
552 template<
typename T1,
typename T2>
553 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2)
568 template<
typename T1,
typename T2,
typename T3>
569 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3)
574 ssSend << a1 << a2 << a3;
584 template<
typename T1,
typename T2,
typename T3,
typename T4>
585 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4)
590 ssSend << a1 << a2 << a3 << a4;
600 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
601 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5)
606 ssSend << a1 << a2 << a3 << a4 << a5;
616 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
617 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5,
const T6& a6)
622 ssSend << a1 << a2 << a3 << a4 << a5 << a6;
632 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
633 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5,
const T6& a6,
const T7& a7)
638 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
648 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8>
649 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5,
const T6& a6,
const T7& a7,
const T8& a8)
654 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
664 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
665 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5,
const T6& a6,
const T7& a7,
const T8& a8,
const T9& a9)
670 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
681 void Subscribe(
unsigned int nChannel,
unsigned int nHops=0);
std::map< K, V >::const_iterator const_iterator
CNetMessage(int nTypeIn, int nVersionIn)
void PushMessage(const char *pszCommand)
uint64_t GetRand(uint64_t nMax)
std::vector< CNode * > vNodes
static uint64_t GetTotalBytesRecv()
Access to the (IP) address database (peers.dat)
#define EXCLUSIVE_LOCK_FUNCTION(...)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer=NULL)
CNode(SOCKET hSocketIn, CAddress addrIn, std::string addrNameIn="", bool fInboundIn=false)
CCriticalSection cs_filter
const_iterator begin() const
void AddOneShot(std::string strDest)
STL-like map container that only keeps the N elements with the highest value.
void EndMessage() UNLOCK_FUNCTION(cs_vSend)
void GetAndClear(CSerializeData &data)
void insert(const value_type &x)
CCriticalSection cs_mapRelay
void PushMessage(const char *pszCommand, const T1 &a1)
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4, const T5 &a5, const T6 &a6, const T7 &a7, const T8 &a8, const T9 &a9)
void CancelSubscribe(unsigned int nChannel)
bool SeenLocal(const CService &addr)
vote for a local address
CCriticalSection cs_vNodes
static void ClearBanned()
void update(const_iterator itIn, const mapped_type &v)
bool IsSubscribed(unsigned int nChannel)
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4, const T5 &a5, const T6 &a6)
std::string ToStringIPPort() const
void resize(size_type n, value_type c=0)
std::pair< iterator, bool > insert(const key_type &x)
void AskFor(const CInv &inv)
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
RAII-style semaphore lock.
uint256 hashLastGetBlocksEnd
void SetVersion(int nVersionIn)
bool RecvLine(SOCKET hSocket, std::string &strLine)
size_type max_size() const
void MapPort(bool fUseUPnP)
Double ended buffer combining vector and stream-like interfaces.
CCriticalSection cs_inventory
std::vector< CAddress > vAddrToSend
CCriticalSection cs_vAddedNodes
void AddAddressKnown(const CAddress &addr)
static const size_t MAPASKFOR_MAX_SZ
The maximum number of entries in mapAskFor.
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4, const T5 &a5)
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
void SetRecvVersion(int nVersionIn)
static void RecordBytesRecv(uint64_t bytes)
CNode * ConnectNode(CAddress addrConnect, const char *strDest=NULL)
void PushInventory(const CInv &inv)
size_type count(const key_type &k) const
CAddress GetLocalAddress(const CNetAddr *paddrPeer=NULL)
std::deque< CInv > vRecvGetData
void BeginMessage(const char *pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSend)
#define UNLOCK_FUNCTION(...)
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4)
std::set< uint256 > setKnown
Stochastical (IP) address manager.
limitedmap< CInv, int64_t > mapAlreadyAskedFor
void AddressCurrentlyConnected(const CService &addr)
std::deque< CNetMessage > vRecvMsg
std::deque< std::pair< int64_t, CInv > > vRelayExpiration
unsigned int GetTotalRecvSize()
void CloseSocketDisconnect()
std::map< CInv, CDataStream > mapRelay
bool Write(const CAddrMan &addr)
bool IsReachable(const CNetAddr &addr)
check whether a given address is in a network we can probably connect to
#define LEAVE_CRITICAL_SECTION(cs)
static int LogPrint(const char *category, const char *format)
void RelayTransaction(const CTransaction &tx, const uint256 &hash)
CCriticalSection cs_nLastNodeId
static uint64_t nTotalBytesRecv
mruset< CAddress > setAddrKnown
unsigned int ReceiveFloodSize()
static const int INIT_PROTO_VERSION
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< char, zero_after_free_allocator< char > > CSerializeData
CBlockIndex * pindexLastGetBlocksBegin
static CCriticalSection cs_totalBytesRecv
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes)
mruset< CInv > setInventoryKnown
CNode * FindNode(const CNetAddr &ip)
A CService with information about it as peer.
unsigned int SendBufferSize()
bool fSuccessfullyConnected
bool GetMyExternalIP(CNetAddr &ipRet)
uint256 Hash(const T1 pbegin, const T1 pend)
const_iterator end() const
void SetLimited(enum Network net, bool fLimited=true)
Make a particular network entirely off-limits (no automatic connects to it)
static uint64_t GetTotalBytesSent()
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4, const T5 &a5, const T6 &a6, const T7 &a7, const T8 &a8)
boost::signals2::signal< bool(CNode *, bool)> SendMessages
static CCriticalSection cs_totalBytesSent
map< CNetAddr, LocalServiceInfo > mapLocalHost
boost::signals2::signal< bool(CNode *)> ProcessMessages
int readData(const char *pch, unsigned int nBytes)
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3, const T4 &a4, const T5 &a5, const T6 &a6, const T7 &a7)
boost::signals2::signal< int()> GetHeight
#define ENTER_CRITICAL_SECTION(cs)
void SocketSendData(CNode *pnode)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
static void RecordBytesSent(uint64_t bytes)
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2, const T3 &a3)
void StartNode(boost::thread_group &threadGroup)
void AddInventoryKnown(const CInv &inv)
CCriticalSection cs_vRecvMsg
The block chain is a tree shaped structure starting with the genesis block at the root...
CSemaphoreGrant grantOutbound
std::vector< CInv > vInventoryToSend
void * memcpy(void *a, const void *b, size_t c)
boost::filesystem::path pathAddr
static bool IsBanned(CNetAddr ip)
void SetReachable(enum Network net, bool fFlag=true)
static CCriticalSection cs_setBanned
void operator=(const CNode &)
static bool Ban(const CNetAddr &ip)
std::vector< std::string > vAddedNodes
void Subscribe(unsigned int nChannel, unsigned int nHops=0)
bool BindListenPort(const CService &bindAddr, std::string &strError=REF(std::string()))
void PushMessage(const char *pszCommand, const T1 &a1, const T2 &a2)
int readHeader(const char *pch, unsigned int nBytes)
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
The basic transaction that is broadcasted on the network and contained in blocks. ...
Information about a peer.
boost::signals2::signal< void(NodeId)> FinalizeNode
std::string ToString() const
CCriticalSection cs_vSend
static uint64_t nTotalBytesSent
void AbortMessage() UNLOCK_FUNCTION(cs_vSend)
void copyStats(CNodeStats &stats)
boost::signals2::signal< void(NodeId, const CNode *)> InitializeNode
static const unsigned int MAX_INV_SZ
The maximum number of entries in an 'inv' protocol message.
bool AddLocal(const CService &addr, int nScore=LOCAL_NONE)
CNodeSignals & GetNodeSignals()
bool IsLocal(const CService &addr)
check whether a given address is potentially local
std::multimap< int64_t, CInv > mapAskFor
CCriticalSection cs_mapLocalHost
bool Read(CAddrMan &addr)
const_iterator find(const key_type &k) const
static std::map< CNetAddr, int64_t > setBanned
unsigned short GetListenPort()
bool IsLimited(enum Network net)
map< string, string > mapArgs
std::deque< CSerializeData > vSendMsg
const_iterator end() const
void PushAddress(const CAddress &addr)