#include "net.h"
#include "init.h"
#include "addrman.h"
-#include "ui_interface.h"
+#include "interface.h"
+#include "main.h"
#include "miner.h"
#include "ntp.h"
+#include "random.h"
#ifdef WIN32
#include <string.h>
#endif
-using namespace std;
-using namespace boost;
static const int MAX_OUTBOUND_CONNECTIONS = 16;
bool fDiscover = true;
uint64_t nLocalServices = (fClient ? 0 : NODE_NETWORK);
static CCriticalSection cs_mapLocalHost;
-static map<CNetAddr, LocalServiceInfo> mapLocalHost;
+static std::map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfReachable[NET_MAX] = {};
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
static CNode* pnodeSync = NULL;
CAddress addrSeenByPeer(CService("0.0.0.0", nPortZero), nLocalServices);
uint64_t nLocalHostNonce = 0;
-boost::array<int, THREAD_MAX> vnThreadsRunning;
+std::array<int, THREAD_MAX> vnThreadsRunning;
static std::vector<SOCKET> vhListenSocket;
CAddrMan addrman;
-vector<CNode*> vNodes;
+std::vector<CNode*> vNodes;
CCriticalSection cs_vNodes;
-map<CInv, CDataStream> mapRelay;
-deque<pair<int64_t, CInv> > vRelayExpiration;
+std::map<CInv, CDataStream> mapRelay;
+std::deque<std::pair<int64_t, CInv> > vRelayExpiration;
CCriticalSection cs_mapRelay;
-map<CInv, int64_t> mapAlreadyAskedFor;
+std::map<CInv, int64_t> mapAlreadyAskedFor;
-static deque<string> vOneShots;
+static std::deque<std::string> vOneShots;
CCriticalSection cs_vOneShots;
-set<CNetAddr> setservAddNodeAddresses;
+std::set<CNetAddr> setservAddNodeAddresses;
CCriticalSection cs_setservAddNodeAddresses;
-vector<std::string> vAddedNodes;
+std::vector<std::string> vAddedNodes;
CCriticalSection cs_vAddedNodes;
static CSemaphore *semOutbound = NULL;
-void AddOneShot(string strDest)
+inline void RelayInventory(const CInv& inv)
+{
+ // Put on lists to offer to the other nodes
+ {
+ LOCK(cs_vNodes);
+ for (CNode* pnode : vNodes)
+ pnode->PushInventory(inv);
+ }
+}
+
+void AddOneShot(std::string strDest)
{
LOCK(cs_vOneShots);
vOneShots.push_back(strDest);
int nBestReachability = -1;
{
LOCK(cs_mapLocalHost);
- for (map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
+ for (auto it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
{
int nScore = (*it).second.nScore;
int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
return ret;
}
-bool RecvLine(SOCKET hSocket, string& strLine)
+bool RecvLine(SOCKET hSocket, std::string& strLine)
{
strLine.clear();
for ( ; ; )
void static AdvertizeLocal()
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
{
if (pnode->fSuccessfullyConnected)
{
CNode* FindNode(const CNetAddr& ip)
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
if ((CNetAddr)pnode->addr == ip)
return (pnode);
return NULL;
CNode* FindNode(std::string addrName)
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
if (pnode->addrName == addrName)
return (pnode);
return NULL;
CNode* FindNode(const CService& addr)
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
if ((CService)pnode->addr == addr)
return (pnode);
return NULL;
{
}
+void CNode::EndMessage()
+{
+ if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
+ {
+ printf("dropmessages DROPPING SEND MESSAGE\n");
+ AbortMessage();
+ return;
+ }
+
+ if (nHeaderStart < 0) {
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+ return;
+ }
+
+ // Set the size
+ uint32_t nSize = (uint32_t) vSend.size() - nMessageStart;
+ memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::MESSAGE_SIZE_OFFSET, &nSize, sizeof(nSize));
+
+ // Set the checksum
+ uint256 hash = Hash(vSend.begin() + nMessageStart, vSend.end());
+ uint32_t nChecksum = 0;
+ memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ assert(nMessageStart - nHeaderStart >= CMessageHeader::CHECKSUM_OFFSET + sizeof(nChecksum));
+ memcpy((char*)&vSend[nHeaderStart] + CMessageHeader::CHECKSUM_OFFSET, &nChecksum, sizeof(nChecksum));
+
+ if (fDebug) {
+ printf("(%d bytes)\n", nSize);
+ }
+
+ nHeaderStart = -1;
+ nMessageStart = std::numeric_limits<uint32_t>::max();
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+}
void CNode::PushVersion()
{
addrMe = GetLocalAddress(&addr);
}
- RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+ GetRandBytes((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());
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
+ nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<std::string>()), nBestHeight);
}
printf("ThreadSocketHandler exited\n");
}
-static list<CNode*> vNodesDisconnected;
+static std::list<CNode*> vNodesDisconnected;
void ThreadSocketHandler2(void* parg)
{
{
LOCK(cs_vNodes);
// Disconnect unused nodes
- vector<CNode*> vNodesCopy = vNodes;
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ std::vector<CNode*> vNodesCopy = vNodes;
+ for (CNode* pnode : vNodesCopy)
{
if (pnode->fDisconnect ||
(pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
pnode->Cleanup();
// hold in disconnected pool until all refs are released
- pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
+ pnode->nReleaseTime = std::max(pnode->nReleaseTime, GetTime() + 15 * 60);
if (pnode->fNetworkNode || pnode->fInbound)
pnode->Release();
vNodesDisconnected.push_back(pnode);
}
// Delete disconnected nodes
- list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
- BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
+ std::list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
+ for (CNode* pnode : vNodesDisconnectedCopy)
{
// wait until threads are done using it
if (pnode->GetRefCount() <= 0)
TRY_LOCK(pnode->cs_vRecv, lockRecv);
if (lockRecv)
{
- TRY_LOCK(pnode->cs_mapRequests, lockReq);
- if (lockReq)
- {
- TRY_LOCK(pnode->cs_inventory, lockInv);
- if (lockInv)
- fDelete = true;
- }
+ TRY_LOCK(pnode->cs_inventory, lockInv);
+ if (lockInv)
+ fDelete = true;
}
}
}
SOCKET hSocketMax = 0;
bool have_fds = false;
- BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
+ for (SOCKET hListenSocket : vhListenSocket) {
FD_SET(hListenSocket, &fdsetRecv);
- hSocketMax = max(hSocketMax, hListenSocket);
+ hSocketMax = std::max(hSocketMax, hListenSocket);
have_fds = true;
}
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
{
if (pnode->hSocket == INVALID_SOCKET)
continue;
FD_SET(pnode->hSocket, &fdsetRecv);
FD_SET(pnode->hSocket, &fdsetError);
- hSocketMax = max(hSocketMax, pnode->hSocket);
+ hSocketMax = std::max(hSocketMax, pnode->hSocket);
have_fds = true;
{
TRY_LOCK(pnode->cs_vSend, lockSend);
//
// Accept new connections
//
- BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
+ for (SOCKET hListenSocket : vhListenSocket)
if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
{
#ifdef USE_IPV6
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
if (pnode->fInbound)
nInbound++;
}
//
// Service each socket
//
- vector<CNode*> vNodesCopy;
+ std::vector<CNode*> vNodesCopy;
{
LOCK(cs_vNodes);
vNodesCopy = vNodes;
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ for (CNode* pnode : vNodesCopy)
pnode->AddRef();
}
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ for (CNode* pnode : vNodesCopy)
{
if (fShutdown)
return;
if (HaveNameProxy()) {
AddOneShot(strDNSSeed[seed_idx][1]);
} else {
- vector<CNetAddr> vaddr;
- vector<CAddress> vAdd;
+ std::vector<CNetAddr> vaddr;
+ std::vector<CAddress> vAdd;
if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
{
- BOOST_FOREACH(CNetAddr& ip, vaddr)
+ for (CNetAddr& ip : vaddr)
{
CAddress addr = CAddress(CService(ip, GetDefaultPort()));
addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
void static ProcessOneShot()
{
- string strDest;
+ std::string strDest;
{
LOCK(cs_vOneShots);
if (vOneShots.empty())
for (int64_t nLoop = 0;; nLoop++)
{
ProcessOneShot();
- BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
+ for (std::string strAddr : mapMultiArgs["-connect"])
{
CAddress addr;
OpenNetworkConnection(addr, NULL, strAddr.c_str());
// Only connect out to one peer per network group (/16 for IPv4).
// Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
int nOutbound = 0;
- set<vector<unsigned char> > setConnected;
+ std::set<std::vector<unsigned char> > setConnected;
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes) {
+ for (CNode* pnode : vNodes) {
if (!pnode->fInbound) {
setConnected.insert(pnode->addr.GetGroup());
nOutbound++;
for ( ; ; )
{
// use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
- CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
+ CAddress addr = addrman.Select(10 + std::min(nOutbound,8)*10);
// if we selected an invalid address, restart
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
if (HaveNameProxy()) {
while(!fShutdown) {
- list<string> lAddresses(0);
+ std::list<std::string> lAddresses(0);
{
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ for (std::string& strAddNode : vAddedNodes)
lAddresses.push_back(strAddNode);
}
- BOOST_FOREACH(string& strAddNode, lAddresses) {
+ for (std::string& strAddNode : lAddresses) {
CAddress addr;
CSemaphoreGrant grant(*semOutbound);
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
for (uint32_t i = 0; true; i++)
{
- list<string> lAddresses(0);
+ std::list<std::string> lAddresses(0);
{
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ for (std::string& strAddNode : vAddedNodes)
lAddresses.push_back(strAddNode);
}
- list<vector<CService> > lservAddressesToAdd(0);
- BOOST_FOREACH(string& strAddNode, lAddresses)
+ std::list<std::vector<CService> > lservAddressesToAdd(0);
+ for (std::string& strAddNode : lAddresses)
{
- vector<CService> vservNode(0);
+ std::vector<CService> vservNode(0);
if (Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
{
lservAddressesToAdd.push_back(vservNode);
{
LOCK(cs_setservAddNodeAddresses);
- BOOST_FOREACH(CService& serv, vservNode)
+ for (CService& serv : vservNode)
setservAddNodeAddresses.insert(serv);
}
}
// (keeping in mind that addnode entries can have many IPs if fNameLookup)
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
+ for (CNode* pnode : vNodes)
+ for (auto it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
{
- BOOST_FOREACH(CService& addrNode, *(it))
+ for (CService& addrNode : *(it))
if (pnode->addr == addrNode)
{
it = lservAddressesToAdd.erase(it);
break;
}
}
- BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
+ for (std::vector<CService>& vserv : lservAddressesToAdd)
{
if (vserv.size() == 0)
continue;
return pnode->nLastRecv;
}
-void static StartSync(const vector<CNode*> &vNodes) {
+void static StartSync(const std::vector<CNode*> &vNodes) {
CNode *pnodeNewSync = NULL;
int64_t nBestScore = 0;
// Iterate over all nodes
- BOOST_FOREACH(CNode* pnode, vNodes) {
+ for (CNode* pnode : vNodes) {
// check preconditions for allowing a sync
if (!pnode->fClient && !pnode->fOneShot &&
!pnode->fDisconnect && pnode->fSuccessfullyConnected &&
while (!fShutdown)
{
bool fHaveSyncNode = false;
- vector<CNode*> vNodesCopy;
+ std::vector<CNode*> vNodesCopy;
{
LOCK(cs_vNodes);
vNodesCopy = vNodes;
- BOOST_FOREACH(CNode* pnode, vNodesCopy) {
+ for (CNode* pnode : vNodesCopy) {
pnode->AddRef();
if (pnode == pnodeSync)
fHaveSyncNode = true;
StartSync(vNodesCopy);
// Poll the connected nodes for messages
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ for (CNode* pnode : vNodesCopy)
{
// Receive messages
{
TRY_LOCK(pnode->cs_vRecv, lockRecv);
- if (lockRecv)
- ProcessMessages(pnode);
+ if (lockRecv) {
+ if (!ProcessMessages(pnode)) {
+ pnode->CloseSocketDisconnect();
+ if (pnode == pnodeSync)
+ fHaveSyncNode = false;
+ }
+ }
}
if (fShutdown)
return;
-bool BindListenPort(const CService &addrBind, string& strError)
+bool BindListenPort(const CService &addrBind, std::string& strError)
{
strError.clear();
int nOne = 1;
char pszHostName[1000] = "";
if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
{
- vector<CNetAddr> vaddr;
+ std::vector<CNetAddr> vaddr;
if (LookupHost(pszHostName, vaddr))
{
- BOOST_FOREACH (const CNetAddr &addr, vaddr)
+ for (const CNetAddr &addr : vaddr)
{
AddLocal(addr, LOCAL_IF);
}
if (semOutbound == NULL) {
// initialize semaphore
- int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
+ int nMaxOutbound = std::min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
semOutbound = new CSemaphore(nMaxOutbound);
}
~CNetCleanup()
{
// Close sockets
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for (CNode* pnode : vNodes)
if (pnode->hSocket != INVALID_SOCKET)
CloseSocket(pnode->hSocket);
- BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket)
+ for (SOCKET hListenSocket : vhListenSocket)
if (hListenSocket != INVALID_SOCKET)
if (!CloseSocket(hListenSocket))
printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
// clean up some globals (to help leak detection)
- BOOST_FOREACH(CNode *pnode, vNodes)
+ for (CNode *pnode : vNodes)
delete pnode;
- BOOST_FOREACH(CNode *pnode, vNodesDisconnected)
+ for (CNode *pnode : vNodesDisconnected)
delete pnode;
vNodes.clear();
vNodesDisconnected.clear();