10 #if defined(HAVE_CONFIG_H)
29 #include <arpa/inet.h>
32 #include <boost/foreach.hpp>
33 #include <boost/signals2/signal.hpp>
34 #include <openssl/rand.h>
46 static const int PING_INTERVAL = 2 * 60;
48 static const int TIMEOUT_INTERVAL = 20 * 60;
50 static const unsigned int MAX_INV_SZ = 50000;
52 static const size_t MAPASKFOR_MAX_SZ = MAX_INV_SZ;
68 bool BindListenNativeI2P();
69 bool BindListenNativeI2P(
SOCKET& hSocket);
71 void StartNode(boost::thread_group& threadGroup);
120 std::string FormatI2PNativeFullVersion();
121 bool IsDarknetOnly();
125 bool IsBehindDarknet();
126 #endif // ENABLE_I2PSAM
135 extern int nI2PNodeCount;
138 extern std::vector<CNode*>
vNodes;
140 extern std::map<CInv, CDataStream>
mapRelay;
194 CNetMessage(
int nTypeIn,
int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
214 int readHeader(
const char *pch,
unsigned int nBytes);
215 int readData(
const char *pch,
unsigned int nBytes);
278 void Fuzz(
int nChance);
311 , nSendStreamType(
SER_NETWORK | (((addrIn.nServices & NODE_I2P) || addrIn.IsNativeI2P()) ? 0 : SER_IPADDRONLY))
312 , nRecvStreamType(
SER_NETWORK | (((addrIn.nServices & NODE_I2P) || addrIn.IsNativeI2P()) ? 0 : SER_IPADDRONLY))
317 nRecvVersion = INIT_PROTO_VERSION;
329 fInbound = fInboundIn;
330 fNetworkNode =
false;
331 fSuccessfullyConnected =
false;
337 pindexLastGetBlocksBegin = 0;
338 hashLastGetBlocksEnd = 0;
339 nStartingHeight = -1;
351 LOCK(cs_nLastNodeId);
390 void SetSendStreamType(
int nType) {
391 nSendStreamType = nType;
392 ssSend.
SetType(nSendStreamType);
395 void SetRecvStreamType(
int nType) {
396 nRecvStreamType = nType;
397 for (std::deque<CNetMessage>::iterator it = vRecvMsg.begin(), end = vRecvMsg.end(); it != end; ++it) {
398 it->hdrbuf.SetType(nRecvStreamType);
399 it->vRecv.SetType(nRecvStreamType);
403 int GetSendStreamType()
const {
return nSendStreamType; }
404 int GetRecvStreamType()
const {
return nRecvStreamType; }
405 #endif // ENABLE_I2PSAM
413 assert(nRefCount >= 0);
420 unsigned int total = 0;
432 nRecvVersion = nVersionIn;
452 setAddrKnown.
insert(addr);
461 vAddrToSend.push_back(addr);
469 setInventoryKnown.
insert(inv);
477 if (!setInventoryKnown.
count(inv))
478 vInventoryToSend.push_back(inv);
484 if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
489 int64_t nRequestTime;
491 if (it != mapAlreadyAskedFor.
end())
492 nRequestTime = it->second;
495 LogPrint(
"net",
"askfor %s %d (%s)\n", inv.
ToString().c_str(), nRequestTime,
DateTimeStrFormat(
"%H:%M:%S", nRequestTime/1000000).c_str());
499 static int64_t nLastTime;
501 nNow = std::max(nNow, nLastTime);
505 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
506 if (it != mapAlreadyAskedFor.
end())
507 mapAlreadyAskedFor.
update(it, nRequestTime);
509 mapAlreadyAskedFor.
insert(std::make_pair(inv, nRequestTime));
510 mapAskFor.insert(std::make_pair(nRequestTime, inv));
519 assert(ssSend.
size() == 0);
521 LogPrint(
"net",
"sending: %s ", pszCommand);
531 LogPrint(
"net",
"(aborted)\n");
542 LogPrint(
"net",
"dropmessages DROPPING SEND MESSAGE\n");
546 if (
mapArgs.count(
"-fuzzmessagestest"))
549 if (ssSend.
size() == 0)
553 unsigned int nSize = ssSend.
size() - CMessageHeader::HEADER_SIZE;
554 memcpy((
char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize,
sizeof(nSize));
558 unsigned int nChecksum = 0;
559 memcpy(&nChecksum, &hash,
sizeof(nChecksum));
560 assert(ssSend.
size () >= CMessageHeader::CHECKSUM_OFFSET +
sizeof(nChecksum));
561 memcpy((
char*)&ssSend[CMessageHeader::CHECKSUM_OFFSET], &nChecksum,
sizeof(nChecksum));
563 LogPrint(
"net",
"(%d bytes)\n", nSize);
565 std::deque<CSerializeData>::iterator it = vSendMsg.insert(vSendMsg.end(),
CSerializeData());
567 nSendSize += (*it).size();
570 if (it == vSendMsg.begin())
593 template<
typename T1>
609 template<
typename T1,
typename T2>
610 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2)
625 template<
typename T1,
typename T2,
typename T3>
626 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3)
631 ssSend << a1 << a2 << a3;
641 template<
typename T1,
typename T2,
typename T3,
typename T4>
642 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4)
647 ssSend << a1 << a2 << a3 << a4;
657 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5>
658 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5)
663 ssSend << a1 << a2 << a3 << a4 << a5;
673 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
674 void PushMessage(
const char* pszCommand,
const T1& a1,
const T2& a2,
const T3& a3,
const T4& a4,
const T5& a5,
const T6& a6)
679 ssSend << a1 << a2 << a3 << a4 << a5 << a6;
689 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7>
690 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)
695 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7;
705 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8>
706 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)
711 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8;
721 template<
typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6,
typename T7,
typename T8,
typename T9>
722 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)
727 ssSend << a1 << a2 << a3 << a4 << a5 << a6 << a7 << a8 << a9;
738 void Subscribe(
unsigned int nChannel,
unsigned int nHops=0);
788 #endif // ANONCOIN_NET_H
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
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
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)
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)
#define LEAVE_CRITICAL_SECTION(cs)
void RelayTransaction(const CTransaction &tx, const uint256 &hash)
CCriticalSection cs_nLastNodeId
static uint64_t nTotalBytesRecv
mruset< CAddress > setAddrKnown
unsigned int ReceiveFloodSize()
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
bool fDiscover
Specific functions we need to implement I2P functionality.
static uint64_t nTotalBytesSent
void AbortMessage() UNLOCK_FUNCTION(cs_vSend)
void copyStats(CNodeStats &stats)
boost::signals2::signal< void(NodeId, const CNode *)> InitializeNode
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)