#include "db.h"
#include "net.h"
#include "init.h"
-#include "strlcpy.h"
#include "addrman.h"
#include "ui_interface.h"
-
-#ifdef WIN32
-#include <string.h>
-#endif
-
-#ifdef USE_UPNP
-#include <miniupnpc/miniwget.h>
-#include <miniupnpc/miniupnpc.h>
-#include <miniupnpc/upnpcommands.h>
-#include <miniupnpc/upnperrors.h>
-#endif
+#include "miner.h"
+#include "ntp.h"
using namespace std;
-using namespace boost;
static const int MAX_OUTBOUND_CONNECTIONS = 16;
void ThreadSocketHandler2(void* parg);
void ThreadOpenConnections2(void* parg);
void ThreadOpenAddedConnections2(void* parg);
-#ifdef USE_UPNP
-void ThreadMapPort2(void* parg);
-#endif
void ThreadDNSAddressSeed2(void* parg);
+// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
+// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
+#ifdef WIN32
+#ifndef PROTECTION_LEVEL_UNRESTRICTED
+#define PROTECTION_LEVEL_UNRESTRICTED 10
+#endif
+#ifndef IPV6_PROTECTION_LEVEL
+#define IPV6_PROTECTION_LEVEL 23
+#endif
+#endif
+
struct LocalServiceInfo {
int nScore;
- int nPort;
+ uint16_t nPort;
};
//
//
bool fClient = false;
bool fDiscover = true;
-bool fUseUPnP = false;
uint64_t nLocalServices = (fClient ? 0 : NODE_NETWORK);
static CCriticalSection cs_mapLocalHost;
static map<CNetAddr, LocalServiceInfo> mapLocalHost;
static bool vfLimited[NET_MAX] = {};
static CNode* pnodeLocalHost = NULL;
static CNode* pnodeSync = NULL;
-CAddress addrSeenByPeer(CService("0.0.0.0", 0), nLocalServices);
+CAddress addrSeenByPeer(CService("0.0.0.0", nPortZero), nLocalServices);
uint64_t nLocalHostNonce = 0;
-boost::array<int, THREAD_MAX> vnThreadsRunning;
-static std::vector<SOCKET> vhListenSocket;
+array<int, THREAD_MAX> vnThreadsRunning;
+static vector<SOCKET> vhListenSocket;
CAddrMan addrman;
vector<CNode*> vNodes;
set<CNetAddr> setservAddNodeAddresses;
CCriticalSection cs_setservAddNodeAddresses;
-vector<std::string> vAddedNodes;
+vector<string> vAddedNodes;
CCriticalSection cs_vAddedNodes;
static CSemaphore *semOutbound = NULL;
vOneShots.push_back(strDest);
}
-unsigned short GetListenPort()
+uint16_t GetListenPort()
{
- return (unsigned short)(GetArg("-port", GetDefaultPort()));
+ return static_cast<uint16_t>(GetArg("-port", GetDefaultPort()));
}
void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
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);
// get best local address for a particular peer as a CAddress
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
{
- CAddress ret(CService("0.0.0.0",0),0);
+ CAddress ret(CService("0.0.0.0", nPortZero), 0);
CService addr;
if (GetLocal(addr, paddrPeer))
{
bool RecvLine(SOCKET hSocket, string& strLine)
{
- strLine = "";
- while (true)
+ strLine.clear();
+ for ( ; ; )
{
char c;
int nBytes = recv(hSocket, &c, 1, 0);
void static AdvertizeLocal()
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for(CNode* pnode : vNodes)
{
if (pnode->fSuccessfullyConnected)
{
- CAddress addrLocal = GetLocalAddress(&pnode->addr);
- if (addrLocal.IsRoutable() && (CService)addrLocal != (CService)pnode->addrLocal)
+ auto addrLocal = GetLocalAddress(&pnode->addr);
+ if (addrLocal.IsRoutable() && (CService)addrLocal != pnode->addrLocal)
{
pnode->PushAddress(addrLocal);
pnode->addrLocal = addrLocal;
vfReachable[NET_IPV4] = true;
}
+int GetnScore(const CService& addr)
+{
+ LOCK(cs_mapLocalHost);
+ if (mapLocalHost.count(addr) == LOCAL_NONE)
+ return 0;
+ return mapLocalHost[addr].nScore;
+}
+
+
+// Is our peer's addrLocal potentially useful as an external IP source?
+bool IsPeerAddrLocalGood(CNode *pnode)
+{
+ return fDiscover && pnode->addr.IsRoutable() && pnode->addrLocal.IsRoutable() &&
+ !IsLimited(pnode->addrLocal.GetNetwork());
+}
+
+// pushes our own address to a peer
+void AdvertiseLocal(CNode *pnode)
+{
+ if (!fNoListen && pnode->fSuccessfullyConnected)
+ {
+ auto addrLocal = GetLocalAddress(&pnode->addr);
+ // If discovery is enabled, sometimes give our peer the address it
+ // tells us that it sees us as in case it has a better idea of our
+ // address than we do.
+ if (IsPeerAddrLocalGood(pnode) && (!addrLocal.IsRoutable() ||
+ GetRand((GetnScore(addrLocal) > LOCAL_MANUAL) ? 8:2) == 0))
+ {
+ addrLocal.SetIP(pnode->addrLocal);
+ }
+ if (addrLocal.IsRoutable())
+ {
+ printf("AdvertiseLocal: advertising address %s\n", addrLocal.ToString().c_str());
+ pnode->PushAddress(addrLocal);
+ }
+ }
+}
+
// learn a new local address
bool AddLocal(const CService& addr, int nScore)
{
// We now get our external IP from the IRC server first and only use this as a backup
bool GetMyExternalIP(CNetAddr& ipRet)
{
- struct sockaddr_in mapped;
- uint64_t rnd = GetRand(~0LL);
+ struct sockaddr_in mapped = {};
+ auto rnd = GetRand(numeric_limits<uint64_t>::max());
const char *srv;
int rc = GetExternalIPbySTUN(rnd, &mapped, &srv);
if(rc >= 0) {
ipRet = CNetAddr(mapped.sin_addr);
- printf("GetExternalIPbySTUN(%" PRIu64 ") returned %s in attempt %d; Server=%s\n", rnd, ipRet.ToStringIP().c_str(), rc, srv);
+ if (fDebugNet) {
+ printf("GetExternalIPbySTUN(%" PRIu64 ") returned %s in attempt %d; Server=%s\n", rnd, ipRet.ToStringIP().c_str(), rc, srv);
+ }
return true;
}
return false;
}
}
-
-
-
-
void AddressCurrentlyConnected(const CService& addr)
{
addrman.Connected(addr);
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)
+CNode* FindNode(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;
}
}
+CNode::CNode(SOCKET hSocketIn, CAddress addrIn, string addrNameIn, bool fInboundIn) : vSend(SER_NETWORK, MIN_PROTO_VERSION), vRecv(SER_NETWORK, MIN_PROTO_VERSION)
+{
+ nServices = 0;
+ hSocket = hSocketIn;
+ nLastSend = 0;
+ nLastRecv = 0;
+ nSendBytes = 0;
+ nRecvBytes = 0;
+ nLastSendEmpty = GetTime();
+ nTimeConnected = GetTime();
+ nHeaderStart = -1;
+ nMessageStart = numeric_limits<uint32_t>::max();
+ addr = addrIn;
+ addrName = addrNameIn.empty() ? addr.ToStringIPPort() : addrNameIn;
+ nVersion = 0;
+ strSubVer.clear();
+ fOneShot = false;
+ fClient = false; // set by version message
+ fInbound = fInboundIn;
+ fNetworkNode = false;
+ fSuccessfullyConnected = false;
+ fDisconnect = false;
+ nRefCount = 0;
+ nReleaseTime = 0;
+ hashContinue = 0;
+ pindexLastGetBlocksBegin = 0;
+ hashLastGetBlocksEnd = 0;
+ nStartingHeight = -1;
+ nNextLocalAddrSend = 0;
+ nNextAddrSend = 0;
+ nNextInvSend = 0;
+ fStartSync = false;
+ fGetAddr = false;
+ nMisbehavior = 0;
+ hashCheckpointKnown = 0;
+ setInventoryKnown.max_size((size_t)SendBufferSize() / 1000);
+
+ // Be shy and don't send version until we hear
+ if (hSocket != INVALID_SOCKET && !fInbound)
+ PushVersion();
+}
+
+CNode::~CNode()
+{
+ if (hSocket != INVALID_SOCKET)
+ {
+ CloseSocket(hSocket);
+ }
+}
+
+int CNode::GetRefCount()
+{
+ return max(nRefCount, 0) + (GetTime() < nReleaseTime ? 1 : 0);
+}
+
+CNode* CNode::AddRef(int64_t nTimeout)
+{
+ if (nTimeout != 0)
+ nReleaseTime = max(nReleaseTime, GetTime() + nTimeout);
+ else
+ nRefCount++;
+ return this;
+}
+
+void CNode::Release()
+{
+ nRefCount--;
+}
+
+void CNode::AddAddressKnown(const CAddress& addr)
+{
+ setAddrKnown.insert(addr);
+}
+
+void CNode::PushAddress(const CAddress& addr)
+{
+ // Known checking here is only to save space from duplicates.
+ // SendMessages will filter it again for knowns that were added
+ // after addresses were pushed.
+ if (addr.IsValid() && !setAddrKnown.count(addr))
+ vAddrToSend.push_back(addr);
+}
+
+void CNode::AddInventoryKnown(const CInv& inv)
+{
+ {
+ LOCK(cs_inventory);
+ setInventoryKnown.insert(inv);
+ }
+}
+
+void CNode::PushInventory(const CInv& inv)
+{
+ {
+ LOCK(cs_inventory);
+ if (!setInventoryKnown.count(inv))
+ vInventoryToSend.push_back(inv);
+ }
+}
+
+void CNode::AskFor(const CInv& inv)
+{
+ // We're using mapAskFor as a priority queue,
+ // the key is the earliest time the request can be sent
+ int64_t& nRequestTime = mapAlreadyAskedFor[inv];
+ if (fDebugNet)
+ printf("askfor %s %" PRId64 " (%s)\n", inv.ToString().c_str(), nRequestTime, DateTimeStrFormat("%H:%M:%S", nRequestTime/1000000).c_str());
+
+ // Make sure not to reuse time indexes to keep things in the same order
+ int64_t nNow = (GetTime() - 1) * 1000000;
+ static int64_t nLastTime;
+ ++nLastTime;
+ nNow = max(nNow, nLastTime);
+ nLastTime = nNow;
+
+ // Each retry is 2 minutes after the last
+ nRequestTime = max(nRequestTime + 2 * 60 * 1000000, nNow);
+ mapAskFor.insert({ nRequestTime, inv });
+}
+
+void CNode::BeginMessage(const char* pszCommand)
+{
+ ENTER_CRITICAL_SECTION(cs_vSend);
+ if (nHeaderStart != -1)
+ AbortMessage();
+ nHeaderStart = (int32_t)vSend.size();
+ vSend << CMessageHeader(pszCommand, 0);
+ nMessageStart = (uint32_t)vSend.size();
+ if (fDebug)
+ printf("sending: %s ", pszCommand);
+}
+
+void CNode::AbortMessage()
+{
+ if (nHeaderStart < 0)
+ return;
+ vSend.resize(nHeaderStart);
+ nHeaderStart = -1;
+ nMessageStart = numeric_limits<uint32_t>::max();
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+
+ if (fDebug)
+ printf("(aborted)\n");
+}
+
+void CNode::EndMessage()
+{
+ if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
+ {
+ printf("dropmessages DROPPING SEND MESSAGE\n");
+ AbortMessage();
+ return;
+ }
+
+ if (nHeaderStart < 0)
+ 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
+ auto 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 = numeric_limits<uint32_t>::max();
+ LEAVE_CRITICAL_SECTION(cs_vSend);
+}
+
+void CNode::EndMessageAbortIfEmpty()
+{
+ if (nHeaderStart < 0)
+ return;
+ int nSize = (int) vSend.size() - nMessageStart;
+ if (nSize > 0)
+ EndMessage();
+ else
+ AbortMessage();
+}
+
void CNode::CloseSocketDisconnect()
{
fDisconnect = true;
if (hSocket != INVALID_SOCKET)
{
printf("disconnecting node %s\n", addrName.c_str());
- closesocket(hSocket);
- hSocket = INVALID_SOCKET;
+ CloseSocket(hSocket);
vRecv.clear();
}
void CNode::PushVersion()
{
- /// when NTP implemented, change to just nTime = GetAdjustedTime()
- int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
- CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
- CAddress addrMe = GetLocalAddress(&addr);
+ auto nTime = GetAdjustedTime();
+ CAddress addrYou, addrMe;
+
+ bool fHidden = false;
+ if (addr.IsTor()) {
+ if (mapArgs.count("-torname")) {
+ // Our hidden service address
+ CService addrTorName(mapArgs["-torname"], GetListenPort());
+
+ if (addrTorName.IsValid()) {
+ addrYou = addr;
+ addrMe = CAddress(addrTorName);
+ fHidden = true;
+ }
+ }
+ }
+
+ if (!fHidden) {
+ addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0", nPortZero)));
+ 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());
PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
- nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>()), nBestHeight);
+ nLocalHostNonce, FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, vector<string>()), nBestHeight);
}
-std::map<CNetAddr, int64_t> CNode::setBanned;
+map<CNetAddr, int64_t> CNode::setBanned;
CCriticalSection CNode::cs_setBanned;
void CNode::ClearBanned()
bool fResult = false;
{
LOCK(cs_setBanned);
- std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
+ auto i = setBanned.find(ip);
if (i != setBanned.end())
{
- int64_t t = (*i).second;
+ auto t = (*i).second;
if (GetTime() < t)
fResult = true;
}
}
nMisbehavior += howmuch;
- if (nMisbehavior >= GetArg("-banscore", 100))
+ if (nMisbehavior >= GetArgInt("-banscore", 100))
{
- int64_t banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
+ auto banTime = GetTime()+GetArg("-bantime", nOneDay); // Default 24-hour ban
printf("Misbehaving: %s (%d -> %d) DISCONNECTING\n", addr.ToString().c_str(), nMisbehavior-howmuch, nMisbehavior);
{
LOCK(cs_setBanned);
}
#undef X
-
-
-
-
+void Release(CNode* node) {
+ node->Release();
+}
ThreadSocketHandler2(parg);
vnThreadsRunning[THREAD_SOCKETHANDLER]--;
}
- catch (std::exception& e) {
+ catch (exception& e) {
vnThreadsRunning[THREAD_SOCKETHANDLER]--;
PrintException(&e, "ThreadSocketHandler()");
} catch (...) {
printf("ThreadSocketHandler exited\n");
}
+static list<CNode*> vNodesDisconnected;
+
void ThreadSocketHandler2(void* parg)
{
printf("ThreadSocketHandler started\n");
- list<CNode*> vNodesDisconnected;
- unsigned int nPrevNodeCount = 0;
-
- while (true)
+ size_t nPrevNodeCount = 0;
+ for ( ; ; )
{
//
// Disconnect nodes
LOCK(cs_vNodes);
// Disconnect unused nodes
vector<CNode*> vNodesCopy = vNodes;
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ for(CNode* pnode : vNodesCopy)
{
if (pnode->fDisconnect ||
(pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
// Delete disconnected nodes
list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
- BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
+ for(CNode* pnode : vNodesDisconnectedCopy)
{
// wait until threads are done using it
if (pnode->GetRefCount() <= 0)
SOCKET hSocketMax = 0;
bool have_fds = false;
- BOOST_FOREACH(SOCKET hListenSocket, vhListenSocket) {
+ for(SOCKET hListenSocket : vhListenSocket) {
FD_SET(hListenSocket, &fdsetRecv);
hSocketMax = max(hSocketMax, hListenSocket);
have_fds = true;
}
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
+ for(CNode* pnode : vNodes)
{
if (pnode->hSocket == INVALID_SOCKET)
continue;
//
// 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++;
}
if (nErr != WSAEWOULDBLOCK)
printf("socket error accept failed: %d\n", nErr);
}
- else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
+ else if (nInbound >= GetArgInt("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
{
{
LOCK(cs_setservAddNodeAddresses);
if (!setservAddNodeAddresses.count(addr))
- closesocket(hSocket);
+ CloseSocket(hSocket);
}
}
else if (CNode::IsBanned(addr))
{
printf("connection from %s dropped (banned)\n", addr.ToString().c_str());
- closesocket(hSocket);
+ CloseSocket(hSocket);
}
else
{
{
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;
}
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
- pnode->Release();
+ for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
}
Sleep(10);
}
}
-
-
-
-
-
-
-
-
-#ifdef USE_UPNP
-void ThreadMapPort(void* parg)
-{
- // Make this thread recognisable as the UPnP thread
- RenameThread("novacoin-UPnP");
-
- try
- {
- vnThreadsRunning[THREAD_UPNP]++;
- ThreadMapPort2(parg);
- vnThreadsRunning[THREAD_UPNP]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[THREAD_UPNP]--;
- PrintException(&e, "ThreadMapPort()");
- } catch (...) {
- vnThreadsRunning[THREAD_UPNP]--;
- PrintException(NULL, "ThreadMapPort()");
- }
- printf("ThreadMapPort exited\n");
-}
-
-void ThreadMapPort2(void* parg)
-{
- printf("ThreadMapPort started\n");
-
- std::string port = strprintf("%u", GetListenPort());
- const char * multicastif = 0;
- const char * minissdpdpath = 0;
- struct UPNPDev * devlist = 0;
- char lanaddr[64];
-
-#ifndef UPNPDISCOVER_SUCCESS
- /* miniupnpc 1.5 */
- devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
-#else
- /* miniupnpc 1.6 */
- int error = 0;
- devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
-#endif
-
- struct UPNPUrls urls;
- struct IGDdatas data;
- int r;
-
- r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
- if (r == 1)
- {
- if (fDiscover) {
- char externalIPAddress[40];
- r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
- if(r != UPNPCOMMAND_SUCCESS)
- printf("UPnP: GetExternalIPAddress() returned %d\n", r);
- else
- {
- if(externalIPAddress[0])
- {
- printf("UPnP: ExternalIPAddress = %s\n", externalIPAddress);
- AddLocal(CNetAddr(externalIPAddress), LOCAL_UPNP);
- }
- else
- printf("UPnP: GetExternalIPAddress failed.\n");
- }
- }
-
- string strDesc = "NovaCoin " + FormatFullVersion();
-#ifndef UPNPDISCOVER_SUCCESS
- /* miniupnpc 1.5 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
-#else
- /* miniupnpc 1.6 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
-#endif
-
- if(r!=UPNPCOMMAND_SUCCESS)
- printf("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");
- int i = 1;
- while (true)
- {
- if (fShutdown || !fUseUPnP)
- {
- r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0);
- printf("UPNP_DeletePortMapping() returned : %d\n", r);
- freeUPNPDevlist(devlist); devlist = 0;
- FreeUPNPUrls(&urls);
- return;
- }
- if (i % 600 == 0) // Refresh every 20 minutes
- {
-#ifndef UPNPDISCOVER_SUCCESS
- /* miniupnpc 1.5 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0);
-#else
- /* miniupnpc 1.6 */
- r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
- port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0");
-#endif
-
- if(r!=UPNPCOMMAND_SUCCESS)
- printf("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");;
- }
- Sleep(2000);
- i++;
- }
- } else {
- printf("No valid UPnP IGDs found\n");
- freeUPNPDevlist(devlist); devlist = 0;
- if (r != 0)
- FreeUPNPUrls(&urls);
- while (true)
- {
- if (fShutdown || !fUseUPnP)
- return;
- Sleep(2000);
- }
- }
-}
-
-void MapPort()
-{
- if (fUseUPnP && vnThreadsRunning[THREAD_UPNP] < 1)
- {
- if (!NewThread(ThreadMapPort, NULL))
- printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
- }
-}
-#else
-void MapPort()
-{
- // Intentionally left blank.
-}
-#endif
-
-
-
-
-
-
-
-
-
-// DNS seeds
-// Each pair gives a source name and a seed name.
-// The first name is used as information source for addrman.
-// The second name should resolve to a list of seed addresses.
-static const char *strDNSSeed[][2] = {
- {"novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro"},
- {"novacoin.su", "dnsseed.novacoin.su"},
- {"novacoin.ru", "dnsseed.novacoin.ru"},
- {"novacoin.ru", "testseed.novacoin.ru"},
- {"novaco.in", "dnsseed.novaco.in"},
-};
-
void ThreadDNSAddressSeed(void* parg)
{
// Make this thread recognisable as the DNS seeding thread
ThreadDNSAddressSeed2(parg);
vnThreadsRunning[THREAD_DNSSEED]--;
}
- catch (std::exception& e) {
+ catch (exception& e) {
vnThreadsRunning[THREAD_DNSSEED]--;
PrintException(&e, "ThreadDNSAddressSeed()");
} catch (...) {
if (!fTestNet)
{
+ // DNS seeds
+ // Each pair gives a source name and a seed name.
+ // The first name is used as information source for addrman.
+ // The second name should resolve to a list of seed addresses.
+ static const vector<pair <string, string> > vstrDNSSeed = {
+ { "node.novacoin.karelia.pro", "dnsseed.novacoin.karelia.pro" },
+ { "novacoin.ru", "dnsseed.novacoin.ru" },
+ { "novacoin.ru", "testseed.novacoin.ru" },
+ { "novaco.in", "dnsseed.novaco.in" },
+ };
printf("Loading addresses from DNS seeds (could take a while)\n");
- for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
+ for (unsigned int seed_idx = 0; seed_idx < vstrDNSSeed.size(); seed_idx++) {
if (HaveNameProxy()) {
- AddOneShot(strDNSSeed[seed_idx][1]);
+ AddOneShot(vstrDNSSeed[seed_idx].second);
} else {
vector<CNetAddr> vaddr;
vector<CAddress> vAdd;
- if (LookupHost(strDNSSeed[seed_idx][1], vaddr))
+ if (LookupHost(vstrDNSSeed[seed_idx].second, vaddr))
{
- BOOST_FOREACH(CNetAddr& ip, vaddr)
+ for(CNetAddr& ip : vaddr)
{
- int nOneDay = 24*3600;
- CAddress addr = CAddress(CService(ip, GetDefaultPort()));
+ auto addr = CAddress(CService(ip, GetDefaultPort()));
addr.nTime = GetTime() - 3*nOneDay - GetRand(4*nOneDay); // use a random age between 3 and 7 days old
vAdd.push_back(addr);
found++;
}
}
- addrman.Add(vAdd, CNetAddr(strDNSSeed[seed_idx][0], true));
+ addrman.Add(vAdd, CNetAddr(vstrDNSSeed[seed_idx].first, true));
}
}
}
printf("%d addresses found from DNS seeds\n", found);
}
-
-
-
-
-
-
-
-
-
-
-
-uint32_t pnSeed[] =
-{
- 0x5360a653, 0x6c47bb25, 0x52568c5f, 0xc6f5c851, 0x6f17f3a2, 0x1d52a9d5, 0x2c1544c1, 0xb8748368,
- 0x055d6ac1, 0x2490bb25, 0x614488d5, 0xa463f8a2, 0xc54c1256, 0xf72d9252, 0x548432c6, 0xade08368,
- 0x02bf8f55, 0x79f81c48, 0xeb44a26d, 0x802c0856, 0xe3a8d772, 0xc661c852, 0xde30d4b0, 0x1044d079,
- 0xa1e1485d, 0x269d5e02, 0x65ec8b5b, 0x4b78a605, 0xac9a1f5f, 0x307c7db0, 0xb75d4880, 0x31aaef53,
- 0xe9433eb0, 0x8ce0861f, 0x1874695f, 0x6baef986, 0x06cfbf2e, 0x6c2e0082, 0x15e024b0, 0x0d0986bc,
- 0xe7002d48, 0x064b2d05, 0xba568c5f, 0x3c93fa18, 0xfae6234d, 0xb06f5d02, 0x34e25d02, 0x559425b0,
- 0x308eae6e, 0x48e15d02, 0x87fee36d, 0x647f5e02, 0xcbfe61bc, 0x3bf377d4, 0x1543075b, 0x3ee84980,
- 0xde26482e, 0x66a65e02, 0x60cf0fb0, 0xf74c8e4f, 0x88d39a5e, 0x1c385e02, 0x62c4f460, 0x5b26df48,
- 0x5249515d, 0x2b353f7d, 0xb6e34980, 0x5e7cd23e, 0x5ecc5e02, 0x9349515d, 0x31abbf2e, 0xa8675cb6,
- 0xa8ce4762, 0x09e5d4b0, 0x6db26805, 0xb4f45d02, 0xfe07e555, 0xb6ab40bc, 0x8be25d02, 0x92bd345f,
- 0x7122306c, 0x9254c248, 0x8dcc5e02, 0x0d1d5d02, 0x35a2805f, 0x404ef986, 0x5dab696d, 0xf153ad2e,
- 0xc5c7a988, 0xfafd6d4a, 0xf172a7be, 0x09627bd9, 0x747d695f, 0xaa4a5d02, 0x4d226805, 0x6bb40ab9,
- 0x67d61352,
-};
-
void DumpAddresses()
{
- int64_t nStart = GetTimeMillis();
+ auto nStart = GetTimeMillis();
CAddrDB adb;
adb.Write(addrman);
void ThreadDumpAddress2(void* parg)
{
+ printf("ThreadDumpAddress started\n");
+
vnThreadsRunning[THREAD_DUMPADDRESS]++;
while (!fShutdown)
{
{
ThreadDumpAddress2(parg);
}
- catch (std::exception& e) {
+ catch (exception& e) {
PrintException(&e, "ThreadDumpAddress()");
}
printf("ThreadDumpAddress exited\n");
ThreadOpenConnections2(parg);
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
}
- catch (std::exception& e) {
+ catch (exception& e) {
vnThreadsRunning[THREAD_OPENCONNECTIONS]--;
PrintException(&e, "ThreadOpenConnections()");
} catch (...) {
}
}
-// ppcoin: stake minter thread
-void static ThreadStakeMinter(void* parg)
-{
- printf("ThreadStakeMinter started\n");
- CWallet* pwallet = (CWallet*)parg;
- try
- {
- vnThreadsRunning[THREAD_MINTER]++;
- StakeMiner(pwallet);
- vnThreadsRunning[THREAD_MINTER]--;
- }
- catch (std::exception& e) {
- vnThreadsRunning[THREAD_MINTER]--;
- PrintException(&e, "ThreadStakeMinter()");
- } catch (...) {
- vnThreadsRunning[THREAD_MINTER]--;
- PrintException(NULL, "ThreadStakeMinter()");
- }
- printf("ThreadStakeMinter exiting, %d threads remaining\n", vnThreadsRunning[THREAD_MINTER]);
-}
-
void ThreadOpenConnections2(void* parg)
{
printf("ThreadOpenConnections started\n");
for (int64_t nLoop = 0;; nLoop++)
{
ProcessOneShot();
- BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
+ for(string strAddr : mapMultiArgs["-connect"])
{
CAddress addr;
OpenNetworkConnection(addr, NULL, strAddr.c_str());
}
// Initiate network connections
- int64_t nStart = GetTime();
- while (true)
+ auto nStart = GetTime();
+ for ( ; ; )
{
ProcessOneShot();
return;
// Add seed nodes if IRC isn't working
- if (addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
+ if (!IsLimited(NET_IPV4) && addrman.size()==0 && (GetTime() - nStart > 60) && !fTestNet)
{
- std::vector<CAddress> vAdd;
- for (unsigned int i = 0; i < ARRAYLEN(pnSeed); i++)
+ vector<uint32_t> vnSeed =
+ {
+ 0x1c542868, 0x3859dd6f, 0x203c2e68, 0xf145a6bc, 0x638a545f, 0x325da346, 0x385da346, 0xfb2b8d5f,
+ 0x52568c5f, 0xa979e65b, 0x8de6485d, 0x9f79e65b, 0x048a861f, 0x3388b55f, 0x6ff0b45e, 0x17e81f5f,
+ 0x6c47bb25, 0x1ecdc852, 0x28263db9, 0x47824e5d, 0x36f1c851, 0x2bf913b2, 0x95923cb3, 0x84e63eb2,
+ 0xefdeedbf, 0x65200092, 0xf36f6805, 0x42692d05, 0x772c1955, 0xb6bf1b4e, 0x7abb5f5d, 0xdb2fa6bc,
+ 0x90e911bf, 0x82de565f, 0x694416b2, 0x0ab600bc, 0xfcecbe6d, 0x24ed9fb2, 0x1bb618c2, 0xc64765bb,
+ 0x4e3d62c3, 0xdba24baa, 0x4b7109b0, 0x12a12cc2, 0xfc01864f, 0x0b69e85b, 0x33922c1f, 0xac611bc6,
+ 0x2a257155, 0x991d5fc0, 0xbfdabcb1, 0x9b73ee55, 0x5bc2b95d, 0xdef0762e, 0x6ab7c936, 0x9c4416b2,
+ 0xd60d864f, 0x03671f1f, 0x3b5da346, 0xc6f5c851, 0x5411b2d4, 0xe7c25702, 0x63474fb0, 0x7e11c854,
+ 0x52381d5f, 0x72fdfe59, 0x51599a05, 0xfb12b2d4, 0xaee4f15e, 0xd0e3f15e, 0x2aa2805f, 0xa1caf15e,
+ 0x34fe425e, 0x46e1f15e, 0xd7c71955, 0xaeeff15e, 0x47c2af55, 0x563d89b2, 0x67980fd9, 0xc9def15e,
+ 0x9cc51eb9, 0xdaa7aa6b, 0x78e6871f, 0x0d5d2cb2, 0x7aedf15e, 0x9bcaf15e, 0xe5f7f15e, 0x501c1759,
+ 0xdfbc4980, 0xa7397f2e, 0x31ea1a02, 0x3a27655e, 0xaa86f05c, 0xdcddf15e, 0x64689cb2, 0xd4bf62d4,
+ 0xf093eab2, 0x98def15e, 0xb6c5f15e, 0x81e8f15e, 0xe5d2fe59, 0xa312786d, 0x4cf9fe59, 0x8a922c1f,
+ 0x00c7fe59, 0x1ade565f, 0x9e4116b2, 0x2c36983e, 0x68f8f15e, 0x51b7eab2, 0x76c51eb9, 0x9edd4980,
+ 0x90ef565f, 0x0dd80857, 0xd513fb94, 0xf5bdeab2, 0xa95277b0, 0x2cf2f15e, 0x1897eab2, 0x924416b2,
+ 0x985c9b59, 0x30aa43d8, 0xf9c6745f, 0xaf862e5f, 0xe0ceeab2, 0xb9b3eab2, 0x6da4eab2, 0xa4fdeab2,
+ 0x0fa6c125, 0xe38bbd05, 0x5d922c1f, 0x9bd0eab2, 0x73025e02, 0xc4fd794d, 0x8435b35f, 0x2d01bc2e,
+ 0xaa2a14d4, 0xa22b07cb, 0xebda6f4f, 0xddc6514e, 0xf23feab2, 0xea1e5256, 0x6147b45e, 0x47d21e4f,
+ 0x67c41c1f, 0x53ec1a02, 0x352e786d, 0x6bec1a02, 0x78fb4abe, 0xd3014c5d, 0x9fbbeab2, 0x1fc51eb9,
+ 0x720eeab2, 0x2db5eab2, 0xe8baf65c, 0x521b459e, 0x65c4955f, 0x0e7b915f, 0xa8f37e6d, 0x6d0b465f,
+ 0xfab8ff5c, 0xf7c27e6d, 0x7345a846, 0x4fd1a7d5, 0xdfc97e6d, 0x26c27e6d, 0xa9de36b2, 0xc615344d,
+ 0x28ceb95d, 0xa52d895e, 0x18c17e6d, 0x13ec1a02, 0x0ba37125, 0x6c3d344d, 0xb3922c1f, 0x506bbeb0,
+ 0x4d04994e, 0xa1bbe56d, 0xf62c344d, 0x0847d048, 0x4bdc6451, 0xc95b9a05, 0xbcd3a7d5, 0x29b57125,
+ 0x0c4d2cb2, 0xf2b8eab2, 0xc2d5b95d, 0x0185ef59, 0x30adeab2, 0xcaf0e92e, 0x756c344d, 0xfd9e252e,
+ 0xbe5ef3bc, 0x4689344d, 0xb223895e, 0xfcebeaad, 0xb7c0e92e, 0x993c1760, 0xe1e171b0, 0xb857e75b,
+ 0xbf10002e, 0xb55b2cb2, 0xa90e2cb2, 0x13d6f15e, 0xf8be9225, 0x14ddf15e, 0x06e90305, 0x82472cb2,
+ };
+ vector<CAddress> vAdd;
+ for (unsigned int i = 0; i < vnSeed.size(); i++)
{
// It'll only connect to one or two seed nodes because once it connects,
// it'll get a pile of addresses with newer timestamps.
// Seed nodes are given a random 'last seen time' of between one and two
// weeks ago.
- const int64_t nOneWeek = 7*24*60*60;
struct in_addr ip;
- memcpy(&ip, &pnSeed[i], sizeof(ip));
+ memcpy(&ip, &vnSeed[i], sizeof(ip));
CAddress addr(CService(ip, GetDefaultPort()));
addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
vAdd.push_back(addr);
addrman.Add(vAdd, CNetAddr("127.0.0.1"));
}
+ // Add Tor nodes if we have connection with onion router
+ if (mapArgs.count("-tor"))
+ {
+ const vector<string> vstrTorSeed =
+ {
+ "seedp4knqnoei57u.onion",
+ "seedr3hhlepyi7fd.onion",
+ "seed3uuomkclbiz4.onion",
+ "seedeh7qck3ouff5.onion",
+ "5rg3vq4jagckeckf.onion",
+ "seedt3sraf53ajiy.onion",
+ "seedg4qyccsg42oq.onion",
+ "novaqrtoywpg7jly.onion",
+ "seed3d5wolqbgrcb.onion",
+ "seed24u5dwph3qw4.onion",
+ "mj26ulzbs2oskgym.onion",
+ "eqon4usunavt76m7.onion",
+ "seedd3aldwpslzl3.onion"
+ };
+ vector<CAddress> vAdd;
+ for (unsigned int i = 0; i < vstrTorSeed.size(); i++)
+ {
+ CAddress addr(CService(vstrTorSeed[i], GetDefaultPort()));
+ addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
+ vAdd.push_back(addr);
+ }
+ addrman.Add(vAdd, CNetAddr("dummyaddress.onion"));
+ }
+
//
// Choose an address to connect to based on most recently seen
//
set<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++;
}
}
- int64_t nANow = GetAdjustedTime();
+ auto nANow = GetAdjustedTime();
int nTries = 0;
- while (true)
+ for ( ; ; )
{
// use an nUnkBias between 10 (no outgoing connections) and 90 (8 outgoing connections)
- CAddress addr = addrman.Select(10 + min(nOutbound,8)*10);
+ auto addr = addrman.Select(10 + min(nOutbound,8)*10);
// if we selected an invalid address, restart
if (!addr.IsValid() || setConnected.count(addr.GetGroup()) || IsLocal(addr))
ThreadOpenAddedConnections2(parg);
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
}
- catch (std::exception& e) {
+ catch (exception& e) {
vnThreadsRunning[THREAD_ADDEDCONNECTIONS]--;
PrintException(&e, "ThreadOpenAddedConnections()");
} catch (...) {
list<string> lAddresses(0);
{
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ for(string& strAddNode : vAddedNodes)
lAddresses.push_back(strAddNode);
}
- BOOST_FOREACH(string& strAddNode, lAddresses) {
+ for(string& strAddNode : lAddresses) {
CAddress addr;
CSemaphoreGrant grant(*semOutbound);
OpenNetworkConnection(addr, &grant, strAddNode.c_str());
list<string> lAddresses(0);
{
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ for(string& strAddNode : vAddedNodes)
lAddresses.push_back(strAddNode);
}
list<vector<CService> > lservAddressesToAdd(0);
- BOOST_FOREACH(string& strAddNode, lAddresses)
+ for(string& strAddNode : lAddresses)
{
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++)
- {
- BOOST_FOREACH(CService& addrNode, *(it))
+ for(CNode* pnode : vNodes)
+ for (auto it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
+ {
+ for(CService& addrNode : *(it))
if (pnode->addr == addrNode)
{
it = lservAddressesToAdd.erase(it);
break;
}
}
- BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
+ for(vector<CService>& vserv : lservAddressesToAdd)
{
if (vserv.size() == 0)
continue;
// for now, use a very simple selection metric: the node from which we received
// most recently
-double static NodeSyncScore(const CNode *pnode) {
- return -pnode->nLastRecv;
+static int64_t NodeSyncScore(const CNode *pnode) {
+ return pnode->nLastRecv;
}
void static StartSync(const vector<CNode*> &vNodes) {
CNode *pnodeNewSync = NULL;
- double dBestScore = 0;
+ 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 &&
(pnode->nStartingHeight > (nBestHeight - 144)) &&
(pnode->nVersion < NOBLKS_VERSION_START || pnode->nVersion >= NOBLKS_VERSION_END)) {
// if ok, compare node's score with the best so far
- double dScore = NodeSyncScore(pnode);
- if (pnodeNewSync == NULL || dScore > dBestScore) {
+ int64_t nScore = NodeSyncScore(pnode);
+ if (pnodeNewSync == NULL || nScore > nBestScore) {
pnodeNewSync = pnode;
- dBestScore = dScore;
+ nBestScore = nScore;
}
}
}
ThreadMessageHandler2(parg);
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
}
- catch (std::exception& e) {
+ catch (exception& e) {
vnThreadsRunning[THREAD_MESSAGEHANDLER]--;
PrintException(&e, "ThreadMessageHandler()");
} catch (...) {
{
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
- CNode* pnodeTrickle = NULL;
- if (!vNodesCopy.empty())
- pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
+ for(CNode* pnode : vNodesCopy)
{
// Receive messages
{
{
TRY_LOCK(pnode->cs_vSend, lockSend);
if (lockSend)
- SendMessages(pnode, pnode == pnodeTrickle);
+ SendMessages(pnode);
}
if (fShutdown)
return;
{
LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodesCopy)
- pnode->Release();
+ for_each(vNodesCopy.begin(), vNodesCopy.end(), Release);
}
// Wait and allow messages to bunch up.
bool BindListenPort(const CService &addrBind, string& strError)
{
- strError = "";
+ strError.clear();
int nOne = 1;
-#ifdef WIN32
- // Initialize Windows Sockets
- WSADATA wsadata;
- int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
- if (ret != NO_ERROR)
- {
- strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
- printf("%s\n", strError.c_str());
- return false;
- }
-#endif
-
// Create socket for listening for incoming connections
#ifdef USE_IPV6
struct sockaddr_storage sockaddr;
return false;
}
+#ifndef WIN32
#ifdef SO_NOSIGPIPE
// Different way of disabling SIGPIPE on BSD
- setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
+ if (setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int)) == SOCKET_ERROR)
+ {
+ printf("WARNING: setsockopt failed\n");
+ //TODO: work around problem - may be add CloseSocket and return false?
+ }
#endif
-
-#ifndef WIN32
// Allow binding if the port is still in TIME_WAIT state after
- // the program was closed and restarted. Not an issue on windows.
- setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
+ // the program was closed and restarted. Not an issue on windows!
+ if (setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int)) == SOCKET_ERROR)
+ {
+ printf("WARNING: setsockopt failed\n");
+ //TODO: work around problem - may be add CloseSocket and return false?
+ }
#endif
-
#ifdef WIN32
// Set to non-blocking, incoming connections will also inherit this
if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
{
strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
printf("%s\n", strError.c_str());
+ CloseSocket(hSocket);
return false;
}
if (addrBind.IsIPv6()) {
#ifdef IPV6_V6ONLY
#ifdef WIN32
- setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int));
+ if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&nOne, sizeof(int)) == SOCKET_ERROR)
+ {
+ printf("WARNING: setsockopt failed\n");
+ //TODO: work around problem - may be add CloseSocket and return false?
+ }
#else
- setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int));
+ if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&nOne, sizeof(int)) == SOCKET_ERROR)
+ {
+ printf("WARNING: setsockopt failed\n");
+ //TODO: work around problem - may be add CloseSocket and return false?
+ }
#endif
#endif
#ifdef WIN32
- int nProtLevel = 10 /* PROTECTION_LEVEL_UNRESTRICTED */;
- int nParameterId = 23 /* IPV6_PROTECTION_LEVEl */;
- // this call is allowed to fail
- setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (const char*)&nProtLevel, sizeof(int));
+ int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
+ if (setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (const char*)&nProtLevel, sizeof(int)) == SOCKET_ERROR)
+ {
+ printf("WARNING: setsockopt failed\n");
+ //TODO: work around problem - may be add CloseSocket and return false?
+ }
#endif
}
#endif
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());
+ CloseSocket(hListenSocket);
return false;
}
printf("Bound to %s\n", addrBind.ToString().c_str());
{
strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
printf("%s\n", strError.c_str());
+ CloseSocket(hListenSocket);
return false;
}
vector<CNetAddr> vaddr;
if (LookupHost(pszHostName, vaddr))
{
- BOOST_FOREACH (const CNetAddr &addr, vaddr)
+ for(const auto &addr : vaddr)
{
AddLocal(addr, LOCAL_IF);
}
if (semOutbound == NULL) {
// initialize semaphore
- int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, (int)GetArg("-maxconnections", 125));
+ int nMaxOutbound = min(MAX_OUTBOUND_CONNECTIONS, GetArgInt("-maxconnections", 125));
semOutbound = new CSemaphore(nMaxOutbound);
}
if (pnodeLocalHost == NULL)
- pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", 0), nLocalServices));
+ pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress(CService("127.0.0.1", nPortZero), nLocalServices));
Discover();
if (!NewThread(ThreadDNSAddressSeed, NULL))
printf("Error: NewThread(ThreadDNSAddressSeed) failed\n");
- // Map ports with UPnP
- if (fUseUPnP)
- MapPort();
-
// Get addresses from IRC and advertise ours
- if (!NewThread(ThreadIRCSeed, NULL))
- printf("Error: NewThread(ThreadIRCSeed) failed\n");
+ if (!GetBoolArg("-irc", true))
+ printf("IRC seeding disabled\n");
+ else
+ if (!NewThread(ThreadIRCSeed, NULL))
+ printf("Error: NewThread(ThreadIRCSeed) failed\n");
// Send and receive from sockets, accept connections
if (!NewThread(ThreadSocketHandler, NULL))
if (!NewThread(ThreadDumpAddress, NULL))
printf("Error; NewThread(ThreadDumpAddress) failed\n");
- // ppcoin: mint proof-of-stake blocks in the background
- if (!NewThread(ThreadStakeMinter, pwalletMain))
- printf("Error: NewThread(ThreadStakeMinter) failed\n");
+ // Mine proof-of-stake blocks in the background
+ if (!NewThread(ThreadStakeMiner, pwalletMain))
+ printf("Error: NewThread(ThreadStakeMiner) failed\n");
+
+ // Trusted NTP server, it's localhost by default.
+ strTrustedUpstream = GetArg("-ntp", "localhost");
+
+ // Start periodical NTP sampling thread
+ NewThread(ThreadNtpSamples, NULL);
+
}
bool StopNode()
printf("StopNode()\n");
fShutdown = true;
nTransactionsUpdated++;
- int64_t nStart = GetTime();
+ auto nStart = GetTime();
{
LOCK(cs_main);
ThreadScriptCheckQuit();
if (semOutbound)
for (int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
semOutbound->post();
- do
+ for ( ; ; )
{
int nThreadsRunning = 0;
for (int n = 0; n < THREAD_MAX; n++)
if (GetTime() - nStart > 20)
break;
Sleep(20);
- } while(true);
+ };
if (vnThreadsRunning[THREAD_SOCKETHANDLER] > 0) printf("ThreadSocketHandler still running\n");
if (vnThreadsRunning[THREAD_OPENCONNECTIONS] > 0) printf("ThreadOpenConnections still running\n");
if (vnThreadsRunning[THREAD_MESSAGEHANDLER] > 0) printf("ThreadMessageHandler still running\n");
if (vnThreadsRunning[THREAD_RPCLISTENER] > 0) printf("ThreadRPCListener still running\n");
if (vnThreadsRunning[THREAD_RPCHANDLER] > 0) printf("ThreadsRPCServer still running\n");
-#ifdef USE_UPNP
- if (vnThreadsRunning[THREAD_UPNP] > 0) printf("ThreadMapPort still running\n");
-#endif
if (vnThreadsRunning[THREAD_DNSSEED] > 0) printf("ThreadDNSAddressSeed still running\n");
if (vnThreadsRunning[THREAD_ADDEDCONNECTIONS] > 0) printf("ThreadOpenAddedConnections still running\n");
if (vnThreadsRunning[THREAD_DUMPADDRESS] > 0) printf("ThreadDumpAddresses still running\n");
Sleep(20);
Sleep(50);
DumpAddresses();
+
return true;
}
~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)
+ CloseSocket(pnode->hSocket);
+ for(SOCKET hListenSocket : vhListenSocket)
if (hListenSocket != INVALID_SOCKET)
- if (closesocket(hListenSocket) == SOCKET_ERROR)
- printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+ if (!CloseSocket(hListenSocket))
+ printf("CloseSocket(hListenSocket) failed with error %d\n", WSAGetLastError());
+
+ // clean up some globals (to help leak detection)
+ for(CNode *pnode : vNodes)
+ delete pnode;
+ for(CNode *pnode : vNodesDisconnected)
+ delete pnode;
+ vNodes.clear();
+ vNodesDisconnected.clear();
+ delete semOutbound;
+ semOutbound = NULL;
+ delete pnodeLocalHost;
+ pnodeLocalHost = NULL;
#ifdef WIN32
// Shutdown Windows Sockets
}
instance_of_cnetcleanup;
+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 RelayTransaction(const CTransaction& tx, const uint256& hash)
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
}
// Save original serialized message so newer versions are preserved
- mapRelay.insert(std::make_pair(inv, ss));
- vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv));
+ mapRelay.insert({inv, ss});
+ vRelayExpiration.push_back({GetTime() + 15 * 60, inv});
}
RelayInventory(inv);
LOCK(cs_totalBytesSent);
return nTotalBytesSent;
}
+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);
+}