aboutsummaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp258
1 files changed, 179 insertions, 79 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 02b99fd04..954fe5947 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -1,5 +1,5 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
-// Copyright (c) 2009-2012 The Bitcoin developers
+// Copyright (c) 2009-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,32 +7,34 @@
#include "bitcoin-config.h"
#endif
-#include "chainparams.h"
-#include "db.h"
#include "net.h"
-#include "core.h"
+
#include "addrman.h"
+#include "chainparams.h"
+#include "core.h"
+#include "db.h"
#include "ui_interface.h"
-#include "script.h"
+
+#include <inttypes.h>
+#include <stdint.h>
#ifdef WIN32
#include <string.h>
-#endif
-
-#ifndef WIN32
+#else
#include <fcntl.h>
#endif
#ifdef USE_UPNP
-#include <miniupnpc/miniwget.h>
#include <miniupnpc/miniupnpc.h>
+#include <miniupnpc/miniwget.h>
#include <miniupnpc/upnpcommands.h>
#include <miniupnpc/upnperrors.h>
#endif
// Dump addresses to peers.dat every 15 minutes (900s)
#define DUMP_ADDRESSES_INTERVAL 900
-#if !defined(HAVE_MSG_NOSIGNAL)
+
+#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
#endif
@@ -53,14 +55,14 @@ struct LocalServiceInfo {
// Global state variables
//
bool fDiscover = true;
-uint64 nLocalServices = NODE_NETWORK;
+uint64_t nLocalServices = NODE_NETWORK;
static CCriticalSection cs_mapLocalHost;
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
static CNode* pnodeSync = NULL;
-uint64 nLocalHostNonce = 0;
+uint64_t nLocalHostNonce = 0;
static std::vector<SOCKET> vhListenSocket;
CAddrMan addrman;
int nMaxConnections = 125;
@@ -68,9 +70,9 @@ int nMaxConnections = 125;
vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
map<CInv, CDataStream> mapRelay;
-deque<pair<int64, CInv> > vRelayExpiration;
+deque<pair<int64_t, CInv> > vRelayExpiration;
CCriticalSection cs_mapRelay;
-limitedmap<CInv, int64> mapAlreadyAskedFor(MAX_INV_SZ);
+limitedmap<CInv, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
static deque<string> vOneShots;
CCriticalSection cs_vOneShots;
@@ -173,14 +175,14 @@ bool RecvLine(SOCKET hSocket, string& strLine)
if (nBytes == 0)
{
// socket closed
- printf("socket closed\n");
+ LogPrint("net", "socket closed\n");
return false;
}
else
{
// socket error
int nErr = WSAGetLastError();
- printf("recv failed: %d\n", nErr);
+ LogPrint("net", "recv failed: %d\n", nErr);
return false;
}
}
@@ -226,7 +228,7 @@ bool AddLocal(const CService& addr, int nScore)
if (IsLimited(addr))
return false;
- printf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
+ LogPrintf("AddLocal(%s,%i)\n", addr.ToString().c_str(), nScore);
{
LOCK(cs_mapLocalHost);
@@ -334,7 +336,7 @@ bool GetMyExternalIP2(const CService& addrConnect, const char* pszGet, const cha
while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
strLine.resize(strLine.size()-1);
CService addr(strLine,0,true);
- printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
+ LogPrintf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
if (!addr.IsValid() || !addr.IsRoutable())
return false;
ipRet.SetIP(addr);
@@ -409,7 +411,7 @@ void ThreadGetMyExternalIP()
CNetAddr addrLocalHost;
if (GetMyExternalIP(addrLocalHost))
{
- printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
+ LogPrintf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
AddLocal(addrLocalHost, LOCAL_HTTP);
}
}
@@ -426,8 +428,10 @@ void AddressCurrentlyConnected(const CService& addr)
-
-
+uint64_t CNode::nTotalBytesRecv = 0;
+uint64_t CNode::nTotalBytesSent = 0;
+CCriticalSection CNode::cs_totalBytesRecv;
+CCriticalSection CNode::cs_totalBytesSent;
CNode* FindNode(const CNetAddr& ip)
{
@@ -473,7 +477,7 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
/// debug print
- printf("trying connection %s lastseen=%.1fhrs\n",
+ LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
pszDest ? pszDest : addrConnect.ToString().c_str(),
pszDest ? 0 : (double)(GetAdjustedTime() - addrConnect.nTime)/3600.0);
@@ -483,17 +487,16 @@ CNode* ConnectNode(CAddress addrConnect, const char *pszDest)
{
addrman.Attempt(addrConnect);
- /// debug print
- printf("connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
+ LogPrint("net", "connected %s\n", pszDest ? pszDest : addrConnect.ToString().c_str());
// Set to non-blocking
#ifdef WIN32
u_long nOne = 1;
if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
- printf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
+ LogPrintf("ConnectSocket() : ioctlsocket non-blocking setting failed, error %d\n", WSAGetLastError());
#else
if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
- printf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
+ LogPrintf("ConnectSocket() : fcntl non-blocking setting failed, error %d\n", errno);
#endif
// Add node
@@ -519,7 +522,7 @@ void CNode::CloseSocketDisconnect()
fDisconnect = true;
if (hSocket != INVALID_SOCKET)
{
- printf("disconnecting node %s\n", addrName.c_str());
+ LogPrint("net", "disconnecting node %s\n", addrName.c_str());
closesocket(hSocket);
hSocket = INVALID_SOCKET;
}
@@ -541,12 +544,14 @@ void CNode::Cleanup()
void CNode::PushVersion()
{
+ int nBestHeight = g_signals.GetHeight().get_value_or(0);
+
/// when NTP implemented, change to just nTime = GetAdjustedTime()
- int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
+ int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
CAddress addrMe = GetLocalAddress(&addr);
RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
- printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
+ LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight, true);
}
@@ -555,7 +560,7 @@ void CNode::PushVersion()
-std::map<CNetAddr, int64> CNode::setBanned;
+std::map<CNetAddr, int64_t> CNode::setBanned;
CCriticalSection CNode::cs_setBanned;
void CNode::ClearBanned()
@@ -568,10 +573,10 @@ bool CNode::IsBanned(CNetAddr ip)
bool fResult = false;
{
LOCK(cs_setBanned);
- std::map<CNetAddr, int64>::iterator i = setBanned.find(ip);
+ std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
if (i != setBanned.end())
{
- int64 t = (*i).second;
+ int64_t t = (*i).second;
if (GetTime() < t)
fResult = true;
}
@@ -583,15 +588,15 @@ bool CNode::Misbehaving(int howmuch)
{
if (addr.IsLocal())
{
- printf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
+ LogPrintf("Warning: Local node %s misbehaving (delta: %d)!\n", addrName.c_str(), howmuch);
return false;
}
nMisbehavior += howmuch;
if (nMisbehavior >= GetArg("-banscore", 100))
{
- int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
- printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
+ int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
+ LogPrintf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
{
LOCK(cs_setBanned);
if (setBanned[addr] < banTime)
@@ -600,7 +605,7 @@ bool CNode::Misbehaving(int howmuch)
CloseSocketDisconnect();
return true;
} else
- printf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
+ LogPrintf("Misbehaving: %s (%d -> %d)\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
return false;
}
@@ -621,6 +626,24 @@ void CNode::copyStats(CNodeStats &stats)
X(nSendBytes);
X(nRecvBytes);
stats.fSyncNode = (this == pnodeSync);
+
+ // It is common for nodes with good ping times to suddenly become lagged,
+ // due to a new block arriving or other large transfer.
+ // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
+ // since pingtime does not update until the ping is complete, which might take a while.
+ // So, if a ping is taking an unusually long time in flight,
+ // the caller can immediately detect that this is happening.
+ int64_t nPingUsecWait = 0;
+ if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
+ nPingUsecWait = GetTimeMicros() - nPingUsecStart;
+ }
+
+ // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
+ stats.dPingTime = (((double)nPingUsecTime) / 1e6);
+ stats.dPingWait = (((double)nPingUsecWait) / 1e6);
+
+ // Leave string empty if addrLocal invalid (not filled in yet)
+ stats.addrLocal = addrLocal.IsValid() ? addrLocal.ToString() : "";
}
#undef X
@@ -717,6 +740,7 @@ void SocketSendData(CNode *pnode)
pnode->nLastSend = GetTime();
pnode->nSendBytes += nBytes;
pnode->nSendOffset += nBytes;
+ pnode->RecordBytesSent(nBytes);
if (pnode->nSendOffset == data.size()) {
pnode->nSendOffset = 0;
pnode->nSendSize -= data.size();
@@ -731,7 +755,7 @@ void SocketSendData(CNode *pnode)
int nErr = WSAGetLastError();
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
- printf("socket send error %d\n", nErr);
+ LogPrintf("socket send error %d\n", nErr);
pnode->CloseSocketDisconnect();
}
}
@@ -782,7 +806,8 @@ void ThreadSocketHandler()
vNodesDisconnected.push_back(pnode);
}
}
-
+ }
+ {
// Delete disconnected nodes
list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
@@ -812,10 +837,9 @@ void ThreadSocketHandler()
}
}
}
- if (vNodes.size() != nPrevNodeCount)
- {
+ if(vNodes.size() != nPrevNodeCount) {
nPrevNodeCount = vNodes.size();
- uiInterface.NotifyNumConnectionsChanged(vNodes.size());
+ uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
}
@@ -891,7 +915,7 @@ void ThreadSocketHandler()
if (have_fds)
{
int nErr = WSAGetLastError();
- printf("socket select error %d\n", nErr);
+ LogPrintf("socket select error %d\n", nErr);
for (unsigned int i = 0; i <= hSocketMax; i++)
FD_SET(i, &fdsetRecv);
}
@@ -919,7 +943,7 @@ void ThreadSocketHandler()
if (hSocket != INVALID_SOCKET)
if (!addr.SetSockAddr((const struct sockaddr*)&sockaddr))
- printf("Warning: Unknown socket family\n");
+ LogPrintf("Warning: Unknown socket family\n");
{
LOCK(cs_vNodes);
@@ -932,7 +956,7 @@ void ThreadSocketHandler()
{
int nErr = WSAGetLastError();
if (nErr != WSAEWOULDBLOCK)
- printf("socket error accept failed: %d\n", nErr);
+ LogPrintf("socket error accept failed: %d\n", nErr);
}
else if (nInbound >= nMaxConnections - MAX_OUTBOUND_CONNECTIONS)
{
@@ -944,12 +968,12 @@ void ThreadSocketHandler()
}
else if (CNode::IsBanned(addr))
{
- printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
+ LogPrintf("connection from %s dropped (banned)\n", addr.ToString().c_str());
closesocket(hSocket);
}
else
{
- printf("accepted connection %s\n", addr.ToString().c_str());
+ LogPrint("net", "accepted connection %s\n", addr.ToString().c_str());
CNode* pnode = new CNode(hSocket, addr, "", true);
pnode->AddRef();
{
@@ -994,12 +1018,13 @@ void ThreadSocketHandler()
pnode->CloseSocketDisconnect();
pnode->nLastRecv = GetTime();
pnode->nRecvBytes += nBytes;
+ pnode->RecordBytesRecv(nBytes);
}
else if (nBytes == 0)
{
// socket closed gracefully
if (!pnode->fDisconnect)
- printf("socket closed\n");
+ LogPrint("net", "socket closed\n");
pnode->CloseSocketDisconnect();
}
else if (nBytes < 0)
@@ -1009,7 +1034,7 @@ void ThreadSocketHandler()
if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
{
if (!pnode->fDisconnect)
- printf("socket recv error %d\n", nErr);
+ LogPrintf("socket recv error %d\n", nErr);
pnode->CloseSocketDisconnect();
}
}
@@ -1038,17 +1063,17 @@ void ThreadSocketHandler()
{
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
{
- printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
+ LogPrint("net", "socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
pnode->fDisconnect = true;
}
else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
{
- printf("socket not sending\n");
+ LogPrintf("socket not sending\n");
pnode->fDisconnect = true;
}
else if (GetTime() - pnode->nLastRecv > 90*60)
{
- printf("socket inactivity timeout\n");
+ LogPrintf("socket inactivity timeout\n");
pnode->fDisconnect = true;
}
}
@@ -1100,16 +1125,16 @@ void ThreadMapPort()
char externalIPAddress[40];
r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
if(r != UPNPCOMMAND_SUCCESS)
- printf("UPnP: GetExternalIPAddress() returned %d\n", r);
+ LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r);
else
{
if(externalIPAddress[0])
{
- printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
+ LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
}
else
- printf("UPnP: GetExternalIPAddress failed.\n");
+ LogPrintf("UPnP: GetExternalIPAddress failed.\n");
}
}
@@ -1128,10 +1153,10 @@ void ThreadMapPort()
#endif
if(r!=UPNPCOMMAND_SUCCESS)
- printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
+ LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
port.c_str(), port.c_str(), lanaddr, r, strupnperror(r));
else
- printf("UPnP Port Mapping successful.\n");;
+ LogPrintf("UPnP Port Mapping successful.\n");;
MilliSleep(20*60*1000); // Refresh every 20 minutes
}
@@ -1139,13 +1164,13 @@ void ThreadMapPort()
catch (boost::thread_interrupted)
{
r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
- printf("UPNP_DeletePortMapping() returned : %d\n", r);
+ LogPrintf("UPNP_DeletePortMapping() returned : %d\n", r);
freeUPNPDevlist(devlist); devlist = 0;
FreeUPNPUrls(&urls);
throw;
}
} else {
- printf("No valid UPnP IGDs found\n");
+ LogPrintf("No valid UPnP IGDs found\n");
freeUPNPDevlist(devlist); devlist = 0;
if (r != 0)
FreeUPNPUrls(&urls);
@@ -1190,7 +1215,7 @@ void ThreadDNSAddressSeed()
const vector<CDNSSeedData> &vSeeds = Params().DNSSeeds();
int found = 0;
- printf("Loading addresses from DNS seeds (could take a while)\n");
+ LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
BOOST_FOREACH(const CDNSSeedData &seed, vSeeds) {
if (HaveNameProxy()) {
@@ -1213,7 +1238,7 @@ void ThreadDNSAddressSeed()
}
}
- printf("%d addresses found from DNS seeds\n", found);
+ LogPrintf("%d addresses found from DNS seeds\n", found);
}
@@ -1229,12 +1254,12 @@ void ThreadDNSAddressSeed()
void DumpAddresses()
{
- int64 nStart = GetTimeMillis();
+ int64_t nStart = GetTimeMillis();
CAddrDB adb;
adb.Write(addrman);
- printf("Flushed %d addresses to peers.dat %"PRI64d"ms\n",
+ LogPrint("net", "Flushed %d addresses to peers.dat %"PRId64"ms\n",
addrman.size(), GetTimeMillis() - nStart);
}
@@ -1261,7 +1286,7 @@ void ThreadOpenConnections()
// Connect to specific addresses
if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0)
{
- for (int64 nLoop = 0;; nLoop++)
+ for (int64_t nLoop = 0;; nLoop++)
{
ProcessOneShot();
BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
@@ -1278,7 +1303,7 @@ void ThreadOpenConnections()
}
// Initiate network connections
- int64 nStart = GetTime();
+ int64_t nStart = GetTime();
while (true)
{
ProcessOneShot();
@@ -1292,7 +1317,7 @@ void ThreadOpenConnections()
if (addrman.size() == 0 && (GetTime() - nStart > 60)) {
static bool done = false;
if (!done) {
- printf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
+ LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
addrman.Add(Params().FixedSeeds(), CNetAddr("127.0.0.1"));
done = true;
}
@@ -1317,7 +1342,7 @@ void ThreadOpenConnections()
}
}
- int64 nANow = GetAdjustedTime();
+ int64_t nANow = GetAdjustedTime();
int nTries = 0;
while (true)
@@ -1468,6 +1493,8 @@ void static StartSync(const vector<CNode*> &vNodes) {
CNode *pnodeNewSync = NULL;
double dBestScore = 0;
+ int nBestHeight = g_signals.GetHeight().get_value_or(0);
+
// Iterate over all nodes
BOOST_FOREACH(CNode* pnode, vNodes) {
// check preconditions for allowing a sync
@@ -1515,6 +1542,9 @@ void ThreadMessageHandler()
CNode* pnodeTrickle = NULL;
if (!vNodesCopy.empty())
pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
+
+ bool fSleep = true;
+
BOOST_FOREACH(CNode* pnode, vNodesCopy)
{
if (pnode->fDisconnect)
@@ -1524,8 +1554,18 @@ void ThreadMessageHandler()
{
TRY_LOCK(pnode->cs_vRecvMsg, lockRecv);
if (lockRecv)
+ {
if (!g_signals.ProcessMessages(pnode))
pnode->CloseSocketDisconnect();
+
+ if (pnode->nSendSize < SendBufferSize())
+ {
+ if (!pnode->vRecvGetData.empty() || (!pnode->vRecvMsg.empty() && pnode->vRecvMsg[0].complete()))
+ {
+ fSleep = false;
+ }
+ }
+ }
}
boost::this_thread::interruption_point();
@@ -1543,8 +1583,9 @@ void ThreadMessageHandler()
BOOST_FOREACH(CNode* pnode, vNodesCopy)
pnode->Release();
}
-
- MilliSleep(100);
+
+ if (fSleep)
+ MilliSleep(100);
}
}
@@ -1568,7 +1609,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
if (!addrBind.GetSockAddr((struct sockaddr*)&sockaddr, &len))
{
strError = strprintf("Error: bind address family for %s not supported", addrBind.ToString().c_str());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1576,7 +1617,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
if (hListenSocket == INVALID_SOCKET)
{
strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1600,7 +1641,7 @@ bool BindListenPort(const CService &addrBind, string& strError)
#endif
{
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1631,16 +1672,16 @@ bool BindListenPort(const CService &addrBind, string& strError)
strError = strprintf(_("Unable to bind to %s on this computer. Bitcoin is probably already running."), addrBind.ToString().c_str());
else
strError = strprintf(_("Unable to bind to %s on this computer (bind returned error %d, %s)"), addrBind.ToString().c_str(), nErr, strerror(nErr));
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
- printf("Bound to %s\n", addrBind.ToString().c_str());
+ LogPrintf("Bound to %s\n", addrBind.ToString().c_str());
// Listen for incoming connections
if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
{
strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
- printf("%s\n", strError.c_str());
+ LogPrintf("%s\n", strError.c_str());
return false;
}
@@ -1687,7 +1728,7 @@ void static Discover()
struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
CNetAddr addr(s4->sin_addr);
if (AddLocal(addr, LOCAL_IF))
- printf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
+ LogPrintf("IPv4 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
#ifdef USE_IPV6
else if (ifa->ifa_addr->sa_family == AF_INET6)
@@ -1695,7 +1736,7 @@ void static Discover()
struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
CNetAddr addr(s6->sin6_addr);
if (AddLocal(addr, LOCAL_IF))
- printf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
+ LogPrintf("IPv6 %s: %s\n", ifa->ifa_name, addr.ToString().c_str());
}
#endif
}
@@ -1726,7 +1767,7 @@ void StartNode(boost::thread_group& threadGroup)
//
if (!GetBoolArg("-dnsseed", true))
- printf("DNS seeding disabled\n");
+ LogPrintf("DNS seeding disabled\n");
else
threadGroup.create_thread(boost::bind(&TraceThread<void (*)()>, "dnsseed", &ThreadDNSAddressSeed));
@@ -1753,7 +1794,7 @@ void StartNode(boost::thread_group& threadGroup)
bool StopNode()
{
- printf("StopNode()\n");
+ LogPrintf("StopNode()\n");
MapPort(false);
if (semOutbound)
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
@@ -1779,7 +1820,7 @@ public:
BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
if (hListenSocket != INVALID_SOCKET)
if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+ LogPrintf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
// clean up some globals (to help leak detection)
BOOST_FOREACH(CNode *pnode, vNodes)
@@ -1845,3 +1886,62 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
pnode->PushInventory(inv);
}
}
+
+void CNode::RecordBytesRecv(uint64_t bytes)
+{
+ LOCK(cs_totalBytesRecv);
+ nTotalBytesRecv += bytes;
+}
+
+void CNode::RecordBytesSent(uint64_t bytes)
+{
+ LOCK(cs_totalBytesSent);
+ nTotalBytesSent += bytes;
+}
+
+uint64_t CNode::GetTotalBytesRecv()
+{
+ LOCK(cs_totalBytesRecv);
+ return nTotalBytesRecv;
+}
+
+uint64_t CNode::GetTotalBytesSent()
+{
+ LOCK(cs_totalBytesSent);
+ return nTotalBytesSent;
+}
+
+void CNode::Fuzz(int nChance)
+{
+ if (!fSuccessfullyConnected) return; // Don't fuzz initial handshake
+ if (GetRand(nChance) != 0) return; // Fuzz 1 of every nChance messages
+
+ switch (GetRand(3))
+ {
+ case 0:
+ // xor a random byte with a random value:
+ if (!ssSend.empty()) {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ ssSend[pos] ^= (unsigned char)(GetRand(256));
+ }
+ break;
+ case 1:
+ // delete a random byte:
+ if (!ssSend.empty()) {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ ssSend.erase(ssSend.begin()+pos);
+ }
+ break;
+ case 2:
+ // insert a random byte at a random position
+ {
+ CDataStream::size_type pos = GetRand(ssSend.size());
+ char ch = (char)GetRand(256);
+ ssSend.insert(ssSend.begin()+pos, ch);
+ }
+ break;
+ }
+ // Chance of more than one change half the time:
+ // (more changes exponentially less likely):
+ Fuzz(2);
+}