diff options
Diffstat (limited to 'src/net.cpp')
| -rw-r--r-- | src/net.cpp | 258 |
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); +} |