aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp73
1 files changed, 55 insertions, 18 deletions
diff --git a/src/net.cpp b/src/net.cpp
index e18e8d0e2..e0d96a2dc 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -36,6 +36,8 @@
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
+#include <math.h>
+
// Dump addresses to peers.dat every 15 minutes (900s)
#define DUMP_ADDRESSES_INTERVAL 900
@@ -67,6 +69,8 @@ namespace {
};
}
+const static std::string NET_MESSAGE_COMMAND_OTHER = "*other*";
+
//
// Global state variables
//
@@ -216,6 +220,7 @@ void AdvertizeLocal(CNode *pnode)
}
if (addrLocal.IsRoutable())
{
+ LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal.ToString());
pnode->PushAddress(addrLocal);
}
}
@@ -262,6 +267,14 @@ bool AddLocal(const CNetAddr &addr, int nScore)
return AddLocal(CService(addr, GetListenPort()), nScore);
}
+bool RemoveLocal(const CService& addr)
+{
+ LOCK(cs_mapLocalHost);
+ LogPrintf("RemoveLocal(%s)\n", addr.ToString());
+ mapLocalHost.erase(addr);
+ return true;
+}
+
/** Make a particular network entirely off-limits (no automatic connects to it) */
void SetLimited(enum Network net, bool fLimited)
{
@@ -450,8 +463,8 @@ void CNode::PushVersion()
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), addrYou.ToString(), id);
else
LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString(), id);
- PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, strSubVersion, nBestHeight, true);
+ PushMessage(NetMsgType::VERSION, PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
+ nLocalHostNonce, strSubVersion, nBestHeight, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY));
}
@@ -512,12 +525,11 @@ void CNode::Ban(const CSubNet& subNet, const BanReason &banReason, int64_t banti
banEntry.banReason = banReason;
if (bantimeoffset <= 0)
{
- bantimeoffset = GetArg("-bantime", 60*60*24); // Default 24-hour ban
+ bantimeoffset = GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME);
sinceUnixEpoch = false;
}
banEntry.nBanUntil = (sinceUnixEpoch ? 0 : GetTime() )+bantimeoffset;
-
LOCK(cs_setBanned);
if (setBanned[subNet].nBanUntil < banEntry.nBanUntil)
setBanned[subNet] = banEntry;
@@ -608,6 +620,7 @@ void CNode::copyStats(CNodeStats &stats)
{
stats.nodeid = this->GetId();
X(nServices);
+ X(fRelayTxes);
X(nLastSend);
X(nLastRecv);
X(nTimeConnected);
@@ -618,7 +631,9 @@ void CNode::copyStats(CNodeStats &stats)
X(fInbound);
X(nStartingHeight);
X(nSendBytes);
+ X(mapSendBytesPerMsgCmd);
X(nRecvBytes);
+ X(mapRecvBytesPerMsgCmd);
X(fWhitelisted);
// It is common for nodes with good ping times to suddenly become lagged,
@@ -673,6 +688,15 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
nBytes -= handled;
if (msg.complete()) {
+
+ //store received bytes per message command
+ //to prevent a memory DOS, only allow valid commands
+ mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.hdr.pchCommand);
+ if (i == mapRecvBytesPerMsgCmd.end())
+ i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
+ assert(i != mapRecvBytesPerMsgCmd.end());
+ i->second += msg.hdr.nMessageSize + CMessageHeader::HEADER_SIZE;
+
msg.nTime = GetTimeMicros();
messageHandlerCondition.notify_one();
}
@@ -1404,7 +1428,7 @@ void ThreadDNSAddressSeed()
{
// goal: only query DNS seeds if address need is acute
if ((addrman.size() > 0) &&
- (!GetBoolArg("-forcednsseed", false))) {
+ (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED))) {
MilliSleep(11 * 1000);
LOCK(cs_vNodes);
@@ -1711,11 +1735,6 @@ void ThreadMessageHandler()
}
}
- // Poll the connected nodes for messages
- CNode* pnodeTrickle = NULL;
- if (!vNodesCopy.empty())
- pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
-
bool fSleep = true;
BOOST_FOREACH(CNode* pnode, vNodesCopy)
@@ -1746,7 +1765,7 @@ void ThreadMessageHandler()
{
TRY_LOCK(pnode->cs_vSend, lockSend);
if (lockSend)
- g_signals.SendMessages(pnode, pnode == pnodeTrickle || pnode->fWhitelisted);
+ g_signals.SendMessages(pnode);
}
boost::this_thread::interruption_point();
}
@@ -2108,8 +2127,8 @@ void CNode::SetMaxOutboundTarget(uint64_t limit)
uint64_t recommendedMinimum = (nMaxOutboundTimeframe / 600) * MAX_BLOCK_SIZE;
nMaxOutboundLimit = limit;
- if (limit < recommendedMinimum)
- LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit, recommendedMinimum);
+ if (limit > 0 && limit < recommendedMinimum)
+ LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit, recommendedMinimum);
}
uint64_t CNode::GetMaxOutboundTarget()
@@ -2327,13 +2346,13 @@ bool CAddrDB::Read(CAddrMan& addr)
return true;
}
-unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
-unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
+unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); }
+unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); }
CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNameIn, bool fInboundIn) :
ssSend(SER_NETWORK, INIT_PROTO_VERSION),
addrKnown(5000, 0.001),
- setInventoryKnown(SendBufferSize() / 1000)
+ filterInventoryKnown(50000, 0.000001)
{
nServices = 0;
hSocket = hSocketIn;
@@ -2360,7 +2379,11 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nSendOffset = 0;
hashContinue = uint256();
nStartingHeight = -1;
+ filterInventoryKnown.reset();
fGetAddr = false;
+ nNextLocalAddrSend = 0;
+ nNextAddrSend = 0;
+ nNextInvSend = 0;
fRelayTxes = false;
pfilter = new CBloomFilter();
nPingNonceSent = 0;
@@ -2368,6 +2391,9 @@ CNode::CNode(SOCKET hSocketIn, const CAddress& addrIn, const std::string& addrNa
nPingUsecTime = 0;
fPingQueued = false;
nMinPingUsecTime = std::numeric_limits<int64_t>::max();
+ BOOST_FOREACH(const std::string &msg, getAllNetMessageTypes())
+ mapRecvBytesPerMsgCmd[msg] = 0;
+ mapRecvBytesPerMsgCmd[NET_MESSAGE_COMMAND_OTHER] = 0;
{
LOCK(cs_nLastNodeId);
@@ -2398,8 +2424,12 @@ CNode::~CNode()
void CNode::AskFor(const CInv& inv)
{
- if (mapAskFor.size() > MAPASKFOR_MAX_SZ)
+ if (mapAskFor.size() > MAPASKFOR_MAX_SZ || setAskFor.size() > SETASKFOR_MAX_SZ)
+ return;
+ // a peer may not have multiple non-responded queue positions for a single inv item
+ if (!setAskFor.insert(inv.hash).second)
return;
+
// We're using mapAskFor as a priority queue,
// the key is the earliest time the request can be sent
int64_t nRequestTime;
@@ -2443,7 +2473,7 @@ void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
LogPrint("net", "(aborted)\n");
}
-void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
+void CNode::EndMessage(const char* pszCommand) UNLOCK_FUNCTION(cs_vSend)
{
// The -*messagestest options are intentionally not documented in the help message,
// since they are only used during development to debug the networking code and are
@@ -2466,6 +2496,9 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
+ //log total amount of bytes per command
+ mapSendBytesPerMsgCmd[std::string(pszCommand)] += nSize + CMessageHeader::HEADER_SIZE;
+
// Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
unsigned int nChecksum = 0;
@@ -2601,3 +2634,7 @@ void DumpBanlist()
LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
banmap.size(), GetTimeMillis() - nStart);
}
+
+int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
+ return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
+}