6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
32 #include <miniupnpc/miniupnpc.h>
33 #include <miniupnpc/miniwget.h>
34 #include <miniupnpc/upnpcommands.h>
35 #include <miniupnpc/upnperrors.h>
42 #define DUMP_ADDRESSES_INTERVAL 900
45 #define FEELER_SLEEP_WINDOW 1
47 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
48 #define MSG_NOSIGNAL 0
54 #ifndef PROTECTION_LEVEL_UNRESTRICTED
55 #define PROTECTION_LEVEL_UNRESTRICTED 10
57 #ifndef IPV6_PROTECTION_LEVEL
58 #define IPV6_PROTECTION_LEVEL 23
62 const static std::string NET_MESSAGE_COMMAND_OTHER =
"*other*";
64 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
65 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
74 static bool vfLimited[
NET_MAX] = {};
91 return (
unsigned short)(
GetArg(
"-port",
Params().GetDefaultPort()));
101 int nBestReachability = -1;
106 int nScore = (*it).second.nScore;
107 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
108 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
110 addr =
CService((*it).first, (*it).second.nPort);
111 nBestReachability = nReachability;
116 return nBestScore >= 0;
120 static std::vector<CAddress> convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
126 const int64_t nOneWeek = 7*24*60*60;
127 std::vector<CAddress> vSeedsOut;
128 vSeedsOut.reserve(vSeedsIn.size());
129 for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
132 memcpy(&ip, i->addr,
sizeof(ip));
135 vSeedsOut.push_back(addr);
150 ret =
CAddress(addr, nLocalServices);
188 LogPrint(
"net",
"AdvertiseLocal: advertising address %s\n", addrLocal.
ToString());
213 if (!fAlready || nScore >= info.
nScore) {
214 info.
nScore = nScore + (fAlready ? 1 : 0);
241 vfLimited[net] = fLimited;
247 return vfLimited[net];
279 return !vfLimited[net];
340 if (pszDest == NULL) {
348 LogPrintf(
"Failed to open new connection, already connected\n");
354 LogPrint(
"net",
"trying connection %s lastseen=%.1fhrs\n",
355 pszDest ? pszDest : addrConnect.
ToString(),
360 bool proxyConnectionFailed =
false;
364 if (!IsSelectableSocket(hSocket)) {
365 LogPrintf(
"Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
370 if (pszDest && addrConnect.
IsValid()) {
381 LogPrintf(
"Failed to open new connection, already connected\n");
396 }
else if (!proxyConnectionFailed) {
417 if (bandb.
Write(banmap)) {
421 LogPrint(
"net",
"Flushed %d banned node ips/subnets to banlist.dat %dms\n",
431 LogPrint(
"net",
"disconnecting peer=%d\n",
id);
450 bool fResult =
false;
467 bool fResult =
false;
470 banmap_t::iterator i =
setBanned.find(subnet);
483 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
489 if (bantimeoffset <= 0)
491 bantimeoffset =
GetArg(
"-bantime", DEFAULT_MISBEHAVING_BANTIME);
492 sinceUnixEpoch =
false;
520 return Unban(subNet);
556 banmap_t::iterator it =
setBanned.begin();
565 LogPrint(
"net",
"%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.
ToString());
588 if (subnet.
Match(addr))
627 #define X(name) stats.name = name
668 int64_t nPingUsecWait = 0;
676 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
705 handled = msg.
readData(pch, nBytes);
711 LogPrint(
"net",
"Oversized message from peer=%i, disconnecting\n",
GetId());
728 msg.
nTime = nTimeMicros;
744 error(
"Send version already set for node: %i. Refusing to change from %i to %i",
id,
nSendVersion, nVersionIn);
756 error(
"Requesting unset send version for node: %i. Using %i",
id, INIT_PROTO_VERSION);
757 return INIT_PROTO_VERSION;
766 unsigned int nRemaining = 24 -
nHdrPos;
767 unsigned int nCopy = std::min(nRemaining, nBytes);
780 catch (
const std::exception&) {
797 unsigned int nCopy = std::min(nRemaining, nBytes);
831 size_t nSentSize = 0;
833 while (it != pnode->
vSendMsg.end()) {
834 const auto &data = *it;
935 std::vector<NodeEvictionCandidate> vEvictionCandidates;
950 vEvictionCandidates.push_back(candidate);
954 if (vEvictionCandidates.empty())
return false;
960 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
961 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
963 if (vEvictionCandidates.empty())
return false;
967 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
968 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
970 if (vEvictionCandidates.empty())
return false;
974 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime);
975 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
977 if (vEvictionCandidates.empty())
return false;
981 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime);
982 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
984 if (vEvictionCandidates.empty())
return false;
988 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
989 vEvictionCandidates.erase(vEvictionCandidates.end() -
static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
991 if (vEvictionCandidates.empty())
return false;
995 uint64_t naMostConnections;
996 unsigned int nMostConnections = 0;
997 int64_t nMostConnectionsTime = 0;
998 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1001 int64_t grouptime = mapNetGroupNodes[node.
nKeyedNetGroup][0].nTimeConnected;
1004 if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
1005 nMostConnections = groupsize;
1006 nMostConnectionsTime = grouptime;
1012 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1015 NodeId evicted = vEvictionCandidates.front().id;
1017 for(std::vector<CNode*>::const_iterator it(
vNodes.begin()); it !=
vNodes.end(); ++it) {
1018 if ((*it)->GetId() == evicted) {
1019 (*it)->fDisconnect =
true;
1027 struct sockaddr_storage sockaddr;
1028 socklen_t len =
sizeof(sockaddr);
1029 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1035 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr))
1036 LogPrintf(
"Warning: Unknown socket family\n");
1055 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1060 if (!IsSelectableSocket(hSocket))
1062 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1071 setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (
const char*)&set,
sizeof(
int));
1073 setsockopt(hSocket, IPPROTO_TCP, TCP_NODELAY, (
void*)&set,
sizeof(
int));
1076 if (
IsBanned(addr) && !whitelisted)
1083 if (nInbound >= nMaxInbound)
1087 LogPrint(
"net",
"failed to find an eviction candidate - connection dropped (full)\n");
1111 unsigned int nPrevNodeCount = 0;
1120 std::vector<CNode*> vNodesCopy =
vNodes;
1121 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1143 BOOST_FOREACH(
CNode* pnode, vNodesDisconnectedCopy)
1147 bool fDelete =
false;
1167 vNodesSize =
vNodes.size();
1169 if(vNodesSize != nPrevNodeCount) {
1170 nPrevNodeCount = vNodesSize;
1178 struct timeval timeout;
1180 timeout.tv_usec = 50000;
1185 FD_ZERO(&fdsetRecv);
1186 FD_ZERO(&fdsetSend);
1187 FD_ZERO(&fdsetError);
1189 bool have_fds =
false;
1192 FD_SET(hListenSocket.
socket, &fdsetRecv);
1193 hSocketMax = std::max(hSocketMax, hListenSocket.
socket);
1216 select_send = !pnode->
vSendMsg.empty();
1223 FD_SET(pnode->
hSocket, &fdsetError);
1224 hSocketMax = std::max(hSocketMax, pnode->
hSocket);
1228 FD_SET(pnode->
hSocket, &fdsetSend);
1232 FD_SET(pnode->
hSocket, &fdsetRecv);
1237 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1238 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1248 for (
unsigned int i = 0; i <= hSocketMax; i++)
1249 FD_SET(i, &fdsetRecv);
1251 FD_ZERO(&fdsetSend);
1252 FD_ZERO(&fdsetError);
1271 std::vector<CNode*> vNodesCopy;
1275 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1278 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1286 bool recvSet =
false;
1287 bool sendSet =
false;
1288 bool errorSet =
false;
1293 recvSet = FD_ISSET(pnode->
hSocket, &fdsetRecv);
1294 sendSet = FD_ISSET(pnode->
hSocket, &fdsetSend);
1295 errorSet = FD_ISSET(pnode->
hSocket, &fdsetError);
1297 if (recvSet || errorSet)
1302 char pchBuf[0x10000];
1308 nBytes = recv(pnode->
hSocket, pchBuf,
sizeof(pchBuf), MSG_DONTWAIT);
1312 bool notify =
false;
1317 size_t nSizeAdded = 0;
1319 for (; it != pnode->
vRecvMsg.end(); ++it) {
1320 if (!it->complete())
1333 else if (nBytes == 0)
1337 LogPrint(
"net",
"socket closed\n");
1340 else if (nBytes < 0)
1378 else if (nTime - pnode->
nLastSend > TIMEOUT_INTERVAL)
1383 else if (nTime - pnode->
nLastRecv > (pnode->
nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1395 LogPrintf(
"version handshake timeout from %d\n", pnode->
id);
1402 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1423 void ThreadMapPort()
1426 const char * multicastif = 0;
1427 const char * minissdpdpath = 0;
1428 struct UPNPDev * devlist = 0;
1431 #ifndef UPNPDISCOVER_SUCCESS
1433 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1434 #elif MINIUPNPC_API_VERSION < 14
1437 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &
error);
1441 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &
error);
1444 struct UPNPUrls urls;
1445 struct IGDdatas data;
1448 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1452 char externalIPAddress[40];
1453 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1454 if(r != UPNPCOMMAND_SUCCESS)
1455 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1458 if(externalIPAddress[0])
1461 if(
LookupHost(externalIPAddress, resolved,
false)) {
1467 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1475 #ifndef UPNPDISCOVER_SUCCESS
1477 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1478 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0);
1481 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1482 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1485 if(r!=UPNPCOMMAND_SUCCESS)
1486 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1487 port, port, lanaddr, r, strupnperror(r));
1489 LogPrintf(
"UPnP Port Mapping successful.\n");
1494 catch (
const boost::thread_interrupted&)
1496 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1497 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1498 freeUPNPDevlist(devlist); devlist = 0;
1499 FreeUPNPUrls(&urls);
1503 LogPrintf(
"No valid UPnP IGDs found\n");
1504 freeUPNPDevlist(devlist); devlist = 0;
1506 FreeUPNPUrls(&urls);
1512 static boost::thread* upnp_thread = NULL;
1517 upnp_thread->interrupt();
1518 upnp_thread->join();
1521 upnp_thread =
new boost::thread(boost::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort));
1523 else if (upnp_thread) {
1524 upnp_thread->interrupt();
1525 upnp_thread->join();
1552 return strprintf(
"x%x.%s", *requiredServiceBits, data.
host);
1563 (!
GetBoolArg(
"-forcednsseed", DEFAULT_FORCEDNSSEED))) {
1569 for (
auto pnode :
vNodes) {
1572 if (nRelevant >= 2) {
1573 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1581 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1590 std::vector<CNetAddr> vIPs;
1591 std::vector<CAddress> vAdd;
1593 if (
LookupHost(GetDNSHost(seed, &requiredServiceBits).c_str(), vIPs, 0,
true))
1595 BOOST_FOREACH(
const CNetAddr& ip, vIPs)
1597 int nOneDay = 24*3600;
1600 vAdd.push_back(addr);
1611 if (!vIPs.empty()) {
1613 Lookup(seed.
name.c_str(), seedSource, 0,
true);
1619 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1640 LogPrint(
"net",
"Flushed %d addresses to peers.dat %dms\n",
1652 std::string strDest;
1673 for (int64_t nLoop = 0;; nLoop++)
1676 BOOST_FOREACH(
const std::string& strAddr,
mapMultiArgs.at(
"-connect"))
1680 for (
int i = 0; i < 10 && i < nLoop; i++)
1695 int64_t nNextFeeler =
PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1709 static bool done =
false;
1711 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1727 int nOutboundRelevant = 0;
1728 std::set<std::vector<unsigned char> > setConnected;
1736 nOutboundRelevant++;
1761 bool fFeeler =
false;
1764 if (nTime > nNextFeeler) {
1793 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1797 if (nANow - addr.
nLastTry < 600 && nTries < 30)
1803 nRequiredServices = REQUIRED_SERVICES;
1806 if ((addr.
nServices & nRequiredServices) != nRequiredServices) {
1811 if (addr.
GetPort() !=
Params().GetDefaultPort() && nTries < 50)
1818 addrConnect.
nServices = REQUIRED_SERVICES;
1820 addrConnect.
nServices = nRequiredServices;
1832 LogPrint(
"net",
"Making feeler connection to %s\n", addrConnect.
ToString());
1842 std::vector<AddedNodeInfo> ret;
1844 std::list<std::string> lAddresses(0);
1848 BOOST_FOREACH(
const std::string& strAddNode,
vAddedNodes)
1849 lAddresses.push_back(strAddNode);
1854 std::map<CService, bool> mapConnected;
1855 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1859 if (pnode->addr.IsValid()) {
1860 mapConnected[pnode->addr] = pnode->fInbound;
1862 std::string addrName = pnode->GetAddrName();
1863 if (!addrName.empty()) {
1864 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound,
static_cast<const CService&
>(pnode->addr));
1869 BOOST_FOREACH(
const std::string& strAddNode, lAddresses) {
1873 auto it = mapConnected.find(service);
1874 if (it != mapConnected.end()) {
1875 ret.push_back(
AddedNodeInfo{strAddNode, service,
true, it->second});
1881 auto it = mapConnectedByName.find(strAddNode);
1882 if (it != mapConnectedByName.end()) {
1883 ret.push_back(
AddedNodeInfo{strAddNode, it->second.second,
true, it->second.first});
1907 if (!info.fConnected) {
1943 FindNode(addrConnect.ToStringIPPort()))
1945 }
else if (
FindNode(std::string(pszDest)))
1974 std::vector<CNode*> vNodesCopy;
1978 BOOST_FOREACH(
CNode* pnode, vNodesCopy) {
1983 bool fMoreWork =
false;
1985 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1992 fMoreWork |= (fMoreNodeWork && !pnode->
fPauseSend);
2007 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
2013 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this] {
return fMsgProcWake; });
2030 struct sockaddr_storage sockaddr;
2031 socklen_t len =
sizeof(sockaddr);
2032 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2034 strError =
strprintf(
"Error: Bind address family for %s not supported", addrBind.
ToString());
2039 SOCKET hListenSocket = socket(((
struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
2046 if (!IsSelectableSocket(hListenSocket))
2048 strError =
"Error: Couldn't create a listenable socket for incoming connections";
2057 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&nOne,
sizeof(
int));
2061 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
void*)&nOne,
sizeof(
int));
2063 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
void*)&nOne,
sizeof(
int));
2065 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
const char*)&nOne,
sizeof(
int));
2066 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
const char*)&nOne,
sizeof(
int));
2081 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
const char*)&nOne,
sizeof(
int));
2083 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
void*)&nOne,
sizeof(
int));
2087 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2088 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2092 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2096 strError =
strprintf(
_(
"Unable to bind to %s on this computer. %s is probably already running."), addrBind.
ToString(),
_(PACKAGE_NAME));
2129 char pszHostName[256] =
"";
2130 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2132 std::vector<CNetAddr> vaddr;
2135 BOOST_FOREACH (
const CNetAddr &addr, vaddr)
2144 struct ifaddrs* myaddrs;
2145 if (getifaddrs(&myaddrs) == 0)
2147 for (
struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
2149 if (ifa->ifa_addr == NULL)
continue;
2150 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2151 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2152 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2153 if (ifa->ifa_addr->sa_family == AF_INET)
2155 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2160 else if (ifa->ifa_addr->sa_family == AF_INET6)
2162 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2168 freeifaddrs(myaddrs);
2176 LogPrint(
"net",
"SetNetworkActive: %s\n", active);
2214 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2250 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2260 if (bandb.
Read(banmap)) {
2265 LogPrint(
"net",
"Loaded %d banned node ips/subnets from banlist.dat %dms\n",
2268 LogPrintf(
"Invalid or missing banlist.dat; recreating\n");
2407 bool fUpdateConnectionTime =
false;
2409 if(fUpdateConnectionTime)
2466 if (strNode == *it) {
2481 for(std::vector<CNode*>::const_iterator it =
vNodes.begin(); it !=
vNodes.end(); ++it)
2492 vstats.reserve(
vNodes.size());
2493 for(std::vector<CNode*>::iterator it =
vNodes.begin(); it !=
vNodes.end(); ++it) {
2495 vstats.emplace_back();
2504 pnode->fDisconnect =
true;
2513 if (
id == pnode->id) {
2514 pnode->fDisconnect =
true;
2573 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2594 if (historicalBlockServingLimit)
2598 uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE;
2636 nBestHeight.store(height, std::memory_order_release);
2641 return nBestHeight.load(std::memory_order_acquire);
2650 fInbound(fInboundIn),
2652 nKeyedNetGroup(nKeyedNetGroupIn),
2653 addrKnown(5000, 0.001),
2654 filterInventoryKnown(50000, 0.000001),
2655 nLocalHostNonce(nLocalHostNonceIn),
2656 nLocalServices(nLocalServicesIn),
2657 nMyStartingHeight(nMyStartingHeightIn),
2715 LogPrint(
"net",
"Added connection peer=%d\n",
id);
2736 int64_t nRequestTime;
2739 nRequestTime = it->second;
2746 static int64_t nLastTime;
2748 nNow = std::max(nNow, nLastTime);
2752 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2757 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2767 size_t nMessageSize = msg.data.size();
2771 std::vector<unsigned char> serializedHeader;
2773 uint256 hash =
Hash(msg.data.data(), msg.data.data() + nMessageSize);
2779 size_t nBytesSent = 0;
2782 bool optimisticSend(pnode->
vSendMsg.empty());
2790 pnode->
vSendMsg.push_back(std::move(serializedHeader));
2792 pnode->
vSendMsg.push_back(std::move(msg.data));
2795 if (optimisticSend ==
true)
2804 CNode* found =
nullptr;
2806 for (
auto&& pnode :
vNodes) {
2807 if(pnode->
id ==
id) {
2816 return nNow + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
2826 std::vector<unsigned char> vchNetGroup(ad.
GetGroup());
std::map< CSubNet, CBanEntry > banmap_t
const CChainParams & Params()
Return the currently selected parameters.
Access to the (IP) address database (peers.dat)
bool Write(const CAddrMan &addr)
bool Read(CAddrMan &addr)
Extended statistics about a CAddress.
int64_t nLastTry
last try whatsoever by us (memory only)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
size_t size() const
Return the number of (unique) addresses in all tables.
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
void SetServices(const CService &addr, ServiceFlags nServices)
A CService with information about it as peer.
Access to the banlist database (banlist.dat)
bool Write(const banmap_t &banSet)
bool Read(banmap_t &banSet)
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
const std::vector< CDNSSeedData > & DNSSeeds() const
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
boost::signals2::signal< void(bool networkActive)> NotifyNetworkActiveChanged
Network activity state changed.
std::condition_variable condMsgProc
void AddWhitelistedRange(const CSubNet &subnet)
uint64_t nMaxOutboundLimit
void SweepBanned()
clean unused entries (if bantime has expired)
std::thread threadMessageHandler
void ThreadOpenAddedConnections()
int GetBestHeight() const
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
size_t SocketSendData(CNode *pnode) const
CCriticalSection cs_vNodes
void DeleteNode(CNode *pnode)
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
ServiceFlags nLocalServices
Services this instance offers.
size_t GetNodeCount(NumConnections num)
std::atomic< bool > flagInterruptMsgProc
unsigned int GetReceiveFloodSize() const
std::list< CNode * > vNodesDisconnected
uint64_t GetTotalBytesRecv()
void SetBestHeight(int height)
CCriticalSection cs_totalBytesRecv
void AddNewAddress(const CAddress &addr, const CAddress &addrFrom, int64_t nTimePenalty=0)
CThreadInterrupt interruptNet
uint64_t GetMaxOutboundTimeframe()
std::atomic< NodeId > nLastNodeId
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
void SetServices(const CService &addr, ServiceFlags nServices)
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle
size_t GetAddressCount() const
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
void RecordBytesSent(uint64_t bytes)
bool OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=NULL, const char *strDest=NULL, bool fOneShot=false, bool fFeeler=false, bool fAddnode=false)
std::vector< CAddress > GetAddresses()
std::thread threadDNSAddressSeed
bool Unban(const CNetAddr &ip)
CCriticalSection cs_totalBytesSent
std::deque< std::string > vOneShots
void SetBannedSetDirty(bool dirty=true)
set the "dirty" flag for the banlist
ServiceFlags GetLocalServices() const
bool DisconnectNode(const std::string &node)
uint64_t nMaxOutboundTimeframe
ServiceFlags nRelevantServices
Services this instance cares about.
std::vector< ListenSocket > vhListenSocket
CClientUIInterface * clientInterface
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
void GetBanned(banmap_t &banmap)
CCriticalSection cs_setBanned
void ThreadSocketHandler()
std::thread threadOpenConnections
bool fMsgProcWake
flag for waking the message processor.
CNode * FindNode(const CNetAddr &ip)
bool Start(CScheduler &scheduler, std::string &strNodeError, Options options)
unsigned int GetSendBufferSize() const
void MarkAddressGood(const CAddress &addr)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
unsigned int nReceiveFloodSize
uint64_t nMaxOutboundTotalBytesSentInCycle
uint64_t nMaxOutboundCycleStartTime
static bool NodeFullyConnected(const CNode *pnode)
void SetMaxOutboundTarget(uint64_t limit)
set the max outbound target in bytes
void WakeMessageHandler()
void SetNetworkActive(bool active)
uint64_t GetMaxOutboundTarget()
bool IsBanned(CNetAddr ip)
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached
void ThreadDNSAddressSeed()
std::vector< CSubNet > vWhitelistedRange
void ThreadMessageHandler()
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
bool fAddressesInitialized
uint64_t GetTotalBytesSent()
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle
std::thread threadOpenAddedConnections
void ThreadOpenConnections()
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
bool BannedSetIsDirty()
check is the banlist has unwritten changes
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
std::atomic< int > nBestHeight
bool CheckIncomingNonce(uint64_t nonce)
bool BindListenPort(const CService &bindAddr, std::string &strError, bool fWhitelisted=false)
void RecordBytesRecv(uint64_t bytes)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
void GetNodeStats(std::vector< CNodeStats > &vstats)
std::vector< std::string > vAddedNodes
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
std::vector< CNode * > vNodes
CCriticalSection cs_vWhitelistedRange
unsigned int nSendBufferMaxSize
void SetBanned(const banmap_t &banmap)
std::atomic< bool > fNetworkActive
CConnman(uint64_t seed0, uint64_t seed1)
CCriticalSection cs_vOneShots
CCriticalSection cs_vAddedNodes
bool AddNode(const std::string &node)
std::thread threadSocketHandler
bool RemoveAddedNode(const std::string &node)
void AddOneShot(const std::string &strDest)
bool IsWhitelistedRange(const CNetAddr &addr)
void AcceptConnection(const ListenSocket &hListenSocket)
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
void resize(size_type n, value_type c=0)
CHash256 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
std::string ToString() const
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
void SetIP(const CNetAddr &ip)
std::string ToString() const
std::vector< unsigned char > GetGroup() const
enum Network GetNetwork() const
int readHeader(const char *pch, unsigned int nBytes)
const uint256 & GetMessageHash() const
int readData(const char *pch, unsigned int nBytes)
Information about a peer.
std::atomic< int64_t > nLastSend
CCriticalSection cs_sendProcessing
CRollingBloomFilter filterInventoryKnown
std::atomic< int > nVersion
void SetSendVersion(int nVersionIn)
std::deque< std::vector< unsigned char > > vSendMsg
CCriticalSection cs_vRecv
std::atomic_bool fPauseRecv
std::atomic< int64_t > nTimeOffset
CCriticalSection cs_inventory
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
std::atomic< bool > fPingQueued
int GetSendVersion() const
std::list< CNetMessage > vRecvMsg
mapMsgCmdSize mapRecvBytesPerMsgCmd
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
std::atomic_bool fSuccessfullyConnected
ServiceFlags nServicesExpected
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
CCriticalSection cs_hSocket
CSemaphoreGrant grantOutbound
const int64_t nTimeConnected
std::string GetAddrName() const
mapMsgCmdSize mapSendBytesPerMsgCmd
const uint64_t nKeyedNetGroup
std::atomic< int > nRefCount
void CloseSocketDisconnect()
CCriticalSection cs_filter
CCriticalSection cs_addrName
std::atomic< int > nStartingHeight
std::atomic_bool fPauseSend
std::multimap< int64_t, CInv > mapAskFor
CCriticalSection cs_vSend
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
CCriticalSection cs_vProcessMsg
CCriticalSection cs_addrLocal
int64_t nextSendTimeFeeFilter
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
std::atomic< int64_t > timeLastMempoolReq
std::atomic< int64_t > nLastRecv
std::atomic< int64_t > nLastTXTime
std::atomic< int64_t > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
std::set< uint256 > setAskFor
CAmount lastSentFeeFilter
std::atomic< int64_t > nPingUsecStart
void copyStats(CNodeStats &stats)
ServiceFlags GetLocalServices() const
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const std::string &addrNameIn="", bool fInboundIn=false)
std::atomic< int64_t > nPingUsecTime
std::list< CNetMessage > vProcessMsg
CCriticalSection cs_SubVer
std::atomic< int64_t > nLastBlockTime
std::atomic_bool fDisconnect
void AskFor(const CInv &inv)
CService GetAddrLocal() const
std::atomic< int > nRecvVersion
int64_t nNextLocalAddrSend
void scheduleEvery(Function f, int64_t deltaSeconds)
RAII-style semaphore lock.
void MoveTo(CSemaphoreGrant &grant)
A combination of a network address (CNetAddr) and a (TCP) port.
std::string ToStringIPPort() const
std::string ToString() const
unsigned short GetPort() const
bool SetSockAddr(const struct sockaddr *paddr)
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
std::string ToString() const
bool Match(const CNetAddr &addr) const
bool sleep_for(std::chrono::milliseconds rel_time)
STL-like map container that only keeps the N elements with the highest value.
std::map< K, V >::const_iterator const_iterator
std::string FormatFullVersion()
#define WSAGetLastError()
void * memcpy(void *a, const void *b, size_t c)
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
bool RemoveLocal(const CService &addr)
bool IsPeerAddrLocalGood(CNode *pnode)
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
void AdvertiseLocal(CNode *pnode)
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool IsLocal(const CService &addr)
check whether a given address is potentially local
#define DUMP_ADDRESSES_INTERVAL
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
CNodeSignals & GetNodeSignals()
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
class CNetCleanup instance_of_cnetcleanup
CCriticalSection cs_mapLocalHost
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void Discover(boost::thread_group &threadGroup)
bool IsLimited(enum Network net)
bool AddLocal(const CService &addr, int nScore)
#define FEELER_SLEEP_WINDOW
unsigned short GetListenPort()
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
bool SeenLocal(const CService &addr)
vote for a local address
int GetnScore(const CService &addr)
bool ConnectSocket(const CService &addrDest, SOCKET &hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
bool ConnectSocketByName(CService &addr, SOCKET &hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
bool SetSocketNonBlocking(SOCKET &hSocket, bool fNonBlocking)
Disable or enable blocking-mode for a socket.
CService LookupNumeric(const char *pszName, int portDefault)
void InterruptSocks5(bool interrupt)
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
const std::vector< std::string > & getAllNetMessageTypes()
ServiceFlags
nServices flags
uint64_t GetRand(uint64_t nMax)
unsigned int nReceiveFloodSize
uint64_t nMaxOutboundLimit
CClientUIInterface * uiInterface
uint64_t nMaxOutboundTimeframe
ServiceFlags nLocalServices
ServiceFlags nRelevantServices
unsigned int nSendBufferMaxSize
bool supportsServiceBitsFiltering
boost::signals2::signal< void(CNode *, CConnman &)> InitializeNode
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > ProcessMessages
boost::signals2::signal< bool(CNode *, CConnman &, std::atomic< bool > &), CombinerAll > SendMessages
boost::signals2::signal< void(NodeId, bool &)> FinalizeNode
#define TRY_LOCK(cs, name)
int64_t GetAdjustedTime()
CClientUIInterface uiInterface
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
const map< string, vector< string > > & mapMultiArgs
#define LogPrint(category,...)
bool error(const char *fmt, const Args &... args)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
void TraceThread(const char *name, Callable func)
string SanitizeString(const string &str, int rule)
int64_t GetSystemTimeInSeconds()
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units.
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
void MilliSleep(int64_t n)