8 #if defined(HAVE_CONFIG_H)
33 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS
42 #include <unordered_map>
47 #define DUMP_ADDRESSES_INTERVAL 900
50 #define FEELER_SLEEP_WINDOW 1
52 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
53 #define MSG_NOSIGNAL 0
59 #ifndef PROTECTION_LEVEL_UNRESTRICTED
60 #define PROTECTION_LEVEL_UNRESTRICTED 10
62 #ifndef IPV6_PROTECTION_LEVEL
63 #define IPV6_PROTECTION_LEVEL 23
77 static const uint64_t SELECT_TIMEOUT_MILLISECONDS = 50;
79 const static std::string NET_MESSAGE_COMMAND_OTHER =
"*other*";
84 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
85 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
93 static bool vfLimited[
NET_MAX] = {};
116 int nBestReachability = -1;
120 int nScore = entry.second.nScore;
121 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
122 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
123 addr =
CService(entry.first, entry.second.nPort);
124 nBestReachability = nReachability;
129 return nBestScore >= 0;
133 static std::vector<CAddress> ConvertSeeds(
const std::vector<uint8_t> &vSeedsIn)
139 const int64_t nOneWeek = 7 * 24 * 60 * 60;
140 std::vector<CAddress> vSeedsOut;
149 vSeedsOut.push_back(addr);
163 ret =
CAddress(addr, nLocalServices);
199 LogPrintf(
"%s: advertising address %s\n", __func__, addrLocal.
ToString());
217 LogPrintf(
"AddLocal(%s,%i)\n", addr.
ToString(), nScore);
223 if (!fAlready || nScore >= info.
nScore) {
224 info.
nScore = nScore + (fAlready ? 1 : 0);
240 LogPrintf(
"RemoveLocal(%s)\n", addr.
ToString());
250 vfLimited[net] = !reachable;
256 return !vfLimited[net];
327 if (pnode->
addr == addr)
346 if (pszDest ==
nullptr) {
348 LogPrintf(
"%s: cannot connect to local node\n", __func__);
355 LogPrintf(
"Failed to open new connection, already connected\n");
362 pszDest ? pszDest : addrConnect.
ToString(),
368 std::vector<CService> resolved;
379 bool connected =
false;
383 bool proxyConnectionFailed =
false;
399 if (!proxyConnectionFailed) {
410 int port = default_port;
445 if (bandb.
Write(banmap)) {
466 if (nVersionIn < nVersionRequired) {
467 LogPrintf(
"%s : peer=%d using obsolete version %i; disconnecting\n", __func__,
id, nVersionIn);
502 banmap_t::iterator i =
setBanned.find(subnet);
515 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
522 if (bantimeoffset <= 0)
524 bantimeoffset =
gArgs.
GetArg(
"-bantime", DEFAULT_MISBEHAVING_BANTIME);
525 sinceUnixEpoch =
false;
554 return Unban(subNet);
590 bool notifyUI =
false;
593 banmap_t::iterator it =
setBanned.begin();
631 if (subnet.Match(addr))
664 #define X(name) stats.name = name
709 int64_t nPingUsecWait = 0;
716 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
744 handled = msg.
readData(pch, nBytes);
767 msg.
nTime = nTimeMicros;
783 error(
"Send version already set for node: %i. Refusing to change from %i to %i",
id,
nSendVersion, nVersionIn);
795 error(
"Requesting unset send version for node: %i. Using %i",
id, INIT_PROTO_VERSION);
796 return INIT_PROTO_VERSION;
804 unsigned int nRemaining = 24 -
nHdrPos;
805 unsigned int nCopy = std::min(nRemaining, nBytes);
817 }
catch (
const std::exception&) {
834 unsigned int nCopy = std::min(nRemaining, nBytes);
860 size_t nSentSize = 0;
862 while (it != pnode->
vSendMsg.end()) {
863 const auto& data = *it;
910 int nConnections = 0;
921 static std::set<CNetAddr> setOffsetDisconnectedPeers;
922 setOffsetDisconnectedPeers.insert(
ip);
925 setOffsetDisconnectedPeers.clear();
927 std::string strWarn1 =
_(
"Peers are being disconnected due time differences.");
928 std::string strWarn2 =
strprintf(
_(
"Please check that your computer's date and time are correct! If your clock is wrong %s will not work properly."),
PACKAGE_NAME);
930 LogPrintf(
"*** Warning: %s %s\n", strWarn1, strWarn2);
932 static int64_t nLastGUINotif = 0;
934 if (nLastGUINotif + 40 < now) {
974 std::vector<NodeEvictionCandidate> vEvictionCandidates;
979 if (node->fWhitelisted)
983 if (node->fDisconnect)
993 if (node->fFirstMessageReceived && !node->fFirstMessageIsMNAUTH) {
998 if (!node->verifiedProRegTxHash.IsNull()) {
1007 vEvictionCandidates.push_back(candidate);
1011 if (vEvictionCandidates.empty())
return false;
1017 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
1018 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1020 if (vEvictionCandidates.empty())
return false;
1024 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
1025 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8,
static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1027 if (vEvictionCandidates.empty())
return false;
1031 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
1032 vEvictionCandidates.erase(vEvictionCandidates.end() -
static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
1034 if (vEvictionCandidates.empty())
return false;
1038 uint64_t naMostConnections;
1039 unsigned int nMostConnections = 0;
1040 int64_t nMostConnectionsTime = 0;
1041 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapAddrCounts;
1043 mapAddrCounts[node.nKeyedNetGroup].push_back(node);
1044 int64_t grouptime = mapAddrCounts[node.nKeyedNetGroup][0].nTimeConnected;
1045 size_t groupsize = mapAddrCounts[node.nKeyedNetGroup].size();
1046 if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
1047 nMostConnections = groupsize;
1048 nMostConnectionsTime = grouptime;
1049 naMostConnections = node.nKeyedNetGroup;
1054 vEvictionCandidates = std::move(mapAddrCounts[naMostConnections]);
1057 if (vEvictionCandidates.size() <= 1)
1059 if (!fPreferNewConnection)
1063 NodeId evicted = vEvictionCandidates.front().id;
1066 if (pnode->
GetId() == evicted) {
1075 struct sockaddr_storage sockaddr;
1076 socklen_t len =
sizeof(sockaddr);
1077 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1080 int nVerifiedInboundMasternodes = 0;
1083 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr))
1084 LogPrintf(
"Warning: Unknown socket family\n");
1093 nVerifiedInboundMasternodes++;
1107 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1112 if (!IsSelectableSocket(hSocket)) {
1113 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1122 if (
IsBanned(addr) && !whitelisted)
1124 LogPrintf(
"connection from %s dropped (banned)\n", addr.
ToString());
1135 while (nInbound - nVerifiedInboundMasternodes >=
nMaxConnections - MAX_OUTBOUND_CONNECTIONS) {
1138 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1180 std::vector<CNode*> vNodesCopy =
vNodes;
1181 for (
CNode* pnode : vNodesCopy) {
1201 for (
CNode* pnode : vNodesDisconnectedCopy) {
1204 bool fDelete =
false;
1228 vNodesSize =
vNodes.size();
1244 }
else if (nTime - pnode->
nLastSend > TIMEOUT_INTERVAL) {
1245 LogPrintf(
"socket sending timeout: %is\n", nTime - pnode->
nLastSend);
1247 }
else if (nTime - pnode->
nLastRecv > TIMEOUT_INTERVAL) {
1248 LogPrintf(
"socket receive timeout: %is\n", nTime - pnode->
nLastRecv);
1263 recv_set.insert(hListenSocket.socket);
1284 select_send = !pnode->
vSendMsg.empty();
1291 error_set.insert(pnode->
hSocket);
1293 send_set.insert(pnode->
hSocket);
1297 recv_set.insert(pnode->
hSocket);
1302 #ifdef USE_WAKEUP_PIPE
1311 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1315 void CConnman::SocketEvents(std::set<SOCKET>& recv_set, std::set<SOCKET>& send_set, std::set<SOCKET>& error_set)
1317 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1323 std::unordered_map<SOCKET, struct pollfd> pollfds;
1324 for (
SOCKET socket_id : recv_select_set) {
1325 pollfds[socket_id].fd = socket_id;
1326 pollfds[socket_id].events |= POLLIN;
1329 for (
SOCKET socket_id : send_select_set) {
1330 pollfds[socket_id].fd = socket_id;
1331 pollfds[socket_id].events |= POLLOUT;
1334 for (
SOCKET socket_id : error_select_set) {
1335 pollfds[socket_id].fd = socket_id;
1337 pollfds[socket_id].events |= POLLERR|POLLHUP;
1340 std::vector<struct pollfd> vpollfds;
1341 vpollfds.reserve(pollfds.size());
1342 for (
auto it : pollfds) {
1343 vpollfds.push_back(std::move(it.second));
1347 int r = poll(vpollfds.data(), vpollfds.size(), SELECT_TIMEOUT_MILLISECONDS);
1355 for (
struct pollfd pollfd_entry : vpollfds) {
1356 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1357 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1358 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1364 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1373 struct timeval timeout;
1375 timeout.tv_usec = SELECT_TIMEOUT_MILLISECONDS * 1000;
1380 FD_ZERO(&fdsetRecv);
1381 FD_ZERO(&fdsetSend);
1382 FD_ZERO(&fdsetError);
1385 for (
SOCKET hSocket : recv_select_set) {
1386 FD_SET(hSocket, &fdsetRecv);
1387 hSocketMax = std::max(hSocketMax, hSocket);
1390 for (
SOCKET hSocket : send_select_set) {
1391 FD_SET(hSocket, &fdsetSend);
1392 hSocketMax = std::max(hSocketMax, hSocket);
1395 for (
SOCKET hSocket : error_select_set) {
1396 FD_SET(hSocket, &fdsetError);
1397 hSocketMax = std::max(hSocketMax, hSocket);
1401 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1410 for (
unsigned int i = 0; i <= hSocketMax; i++)
1411 FD_SET(i, &fdsetRecv);
1412 FD_ZERO(&fdsetSend);
1413 FD_ZERO(&fdsetError);
1418 for (
SOCKET hSocket : recv_select_set) {
1419 if (FD_ISSET(hSocket, &fdsetRecv)) {
1420 recv_set.insert(hSocket);
1424 for (
SOCKET hSocket : send_select_set) {
1425 if (FD_ISSET(hSocket, &fdsetSend)) {
1426 send_set.insert(hSocket);
1430 for (
SOCKET hSocket : error_select_set) {
1431 if (FD_ISSET(hSocket, &fdsetError)) {
1432 error_set.insert(hSocket);
1440 std::set<SOCKET> recv_set, send_set, error_set;
1443 #ifdef USE_WAKEUP_PIPE
1449 int r = read(
wakeupPipe[0], buf,
sizeof(buf));
1463 if (hListenSocket.socket !=
INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0) {
1473 for (
CNode* pnode : vNodesCopy) {
1480 bool recvSet =
false;
1481 bool sendSet =
false;
1482 bool errorSet =
false;
1487 recvSet = recv_set.count(pnode->
hSocket) > 0;
1488 sendSet = send_set.count(pnode->
hSocket) > 0;
1489 errorSet = error_set.count(pnode->
hSocket) > 0;
1491 if (recvSet || errorSet) {
1493 char pchBuf[0x10000];
1499 nBytes = recv(pnode->
hSocket, pchBuf,
sizeof(pchBuf), MSG_DONTWAIT);
1502 bool notify =
false;
1507 size_t nSizeAdded = 0;
1509 for (; it != pnode->
vRecvMsg.end(); ++it) {
1510 if (!it->complete())
1522 }
else if (nBytes == 0) {
1527 }
else if (nBytes < 0) {
1573 #ifdef USE_WAKEUP_PIPE
1597 return strprintf(
"x%x.%s", *requiredServiceBits, data.
host);
1611 for (
auto pnode :
vNodes) {
1614 if (nRelevant >= 2) {
1615 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1623 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1632 std::vector<CNetAddr> vIPs;
1633 std::vector<CAddress> vAdd;
1635 std::string host = GetDNSHost(seed, &requiredServiceBits);
1642 int nOneDay = 24*3600;
1645 vAdd.push_back(addr);
1653 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1686 std::string strDest;
1704 if (!connect.empty()) {
1705 for (int64_t nLoop = 0;; nLoop++) {
1707 for (
const std::string& strAddr : connect) {
1710 for (
int i = 0; i < 10 && i < nLoop; i++) {
1724 int64_t nNextFeeler =
PoissonNextSend(nStart * 1000 * 1000, FEELER_INTERVAL);
1737 static bool done =
false;
1739 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1755 std::set<std::vector<unsigned char> > setConnected;
1783 bool fFeeler =
false;
1786 if (nTime > nNextFeeler) {
1802 if (!fFeeler || !addr.
IsValid()) {
1827 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1831 if (nANow - addr.
nLastTry < 600 && nTries < 30)
1835 if (addr.
GetPort() !=
Params().GetDefaultPort() && nTries < 50)
1858 std::vector<AddedNodeInfo> ret;
1860 std::list<std::string> lAddresses(0);
1863 ret.reserve(vAddedNodes.size());
1864 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1869 std::map<CService, bool> mapConnected;
1870 std::map<std::string, std::pair<bool, CService> > mapConnectedByName;
1878 if (!addrName.empty()) {
1879 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->
fInbound,
static_cast<const CService&
>(pnode->
addr));
1884 for (
const std::string& strAddNode : lAddresses) {
1889 auto it = mapConnected.find(service);
1890 if (it != mapConnected.end()) {
1891 addedNode.resolvedAddress = service;
1892 addedNode.fConnected =
true;
1893 addedNode.fInbound = it->second;
1897 auto it = mapConnectedByName.find(strAddNode);
1898 if (it != mapConnectedByName.end()) {
1899 addedNode.resolvedAddress = it->second.second;
1900 addedNode.fConnected =
true;
1901 addedNode.fInbound = it->second.first;
1904 ret.emplace_back(std::move(addedNode));
1917 if (!info.fConnected) {
1975 if (masternode_connection)
1977 if (masternode_probe_connection)
1989 int64_t nLastSendMessagesTimeMasternodes = 0;
1994 bool fMoreWork =
false;
1997 bool fSkipSendMessagesForMasternodes =
true;
1998 if (
GetTimeMillis() - nLastSendMessagesTimeMasternodes >= 100) {
1999 fSkipSendMessagesForMasternodes =
false;
2003 for (
CNode* pnode : vNodesCopy) {
2009 fMoreWork |= (fMoreNodeWork && !pnode->
fPauseSend);
2028 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this] {
return fMsgProcWake; });
2040 struct sockaddr_storage sockaddr;
2041 socklen_t len =
sizeof(sockaddr);
2042 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len)) {
2043 strError =
strprintf(
"Error: Bind address family for %s not supported", addrBind.
ToString());
2044 LogPrintf(
"%s\n", strError);
2051 LogPrintf(
"%s\n", strError);
2058 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
void*)&nOne,
sizeof(
int));
2065 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2068 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2069 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2073 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR) {
2079 LogPrintf(
"%s\n", strError);
2083 LogPrintf(
"Bound to %s\n", addrBind.
ToString());
2086 if (listen(hListenSocket, SOMAXCONN) ==
SOCKET_ERROR) {
2088 LogPrintf(
"%s\n", strError);
2108 char pszHostName[256] =
"";
2109 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR) {
2110 std::vector<CNetAddr> vaddr;
2111 if (
LookupHost(pszHostName, vaddr, 0,
true)) {
2112 for (
const CNetAddr& addr : vaddr) {
2114 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.
ToString());
2118 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS)
2120 struct ifaddrs* myaddrs;
2121 if (getifaddrs(&myaddrs) == 0) {
2122 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next) {
2123 if (ifa->ifa_addr ==
nullptr)
continue;
2124 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2125 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2126 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2127 if (ifa->ifa_addr->sa_family == AF_INET) {
2128 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2131 LogPrintf(
"%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.
ToString());
2132 }
else if (ifa->ifa_addr->sa_family == AF_INET6) {
2133 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2136 LogPrintf(
"%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.
ToString());
2139 freeifaddrs(myaddrs);
2175 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2181 std::string strError;
2192 bool fBound =
false;
2193 for (
const auto& addrBind : binds) {
2196 for (
const auto& addrBind : whiteBinds) {
2199 if (binds.empty() && whiteBinds.empty()) {
2200 struct in_addr inaddr_any;
2201 inaddr_any.s_addr = INADDR_ANY;
2214 nTotalBytesRecv = 0;
2218 nTotalBytesSent = 0;
2224 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2230 for (
const auto& strDest : connOptions.
vSeedNodes) {
2245 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2255 if (bandb.
Read(banmap)) {
2263 LogPrintf(
"Invalid or missing banlist.dat; recreating\n");
2270 srand(time(
nullptr));
2296 #ifdef USE_WAKEUP_PIPE
2301 int fFlags = fcntl(
wakeupPipe[0], F_GETFL, 0);
2302 if (fcntl(
wakeupPipe[0], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2306 if (fcntl(
wakeupPipe[1], F_SETFL, fFlags | O_NONBLOCK) == -1) {
2316 LogPrintf(
"DNS seeding disabled\n");
2333 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2441 #ifdef USE_WAKEUP_PIPE
2451 bool fUpdateConnectionTime =
false;
2453 if (fUpdateConnectionTime) {
2482 return addrman.
Add(vAddr, addrFrom, nTimePenalty);
2493 for (
const std::string& it : vAddedNodes) {
2494 if (strNode == it)
return false;
2497 vAddedNodes.push_back(strNode);
2504 for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2505 if (strNode == *it) {
2506 vAddedNodes.erase(it);
2525 for (
const auto& pnode :
vNodes) {
2538 vstats.reserve(
vNodes.size());
2540 vstats.emplace_back();
2559 if (
id == pnode->
GetId()) {
2574 if (pnode->
nVersion >= minProtoVersion)
2584 for (
const auto& pnode :
vNodes) {
2600 nTotalBytesRecv += bytes;
2606 nTotalBytesSent += bytes;
2612 return nTotalBytesRecv;
2618 return nTotalBytesSent;
2628 nBestHeight.store(height, std::memory_order_release);
2633 return nBestHeight.load(std::memory_order_acquire);
2642 fInbound(fInboundIn),
2643 nKeyedNetGroup(nKeyedNetGroupIn),
2644 addrKnown(5000, 0.001),
2645 filterInventoryKnown(50000, 0.000001),
2647 nLocalHostNonce(nLocalHostNonceIn),
2648 nLocalServices(nLocalServicesIn),
2649 nMyStartingHeight(nMyStartingHeightIn),
2681 pfilter = std::make_unique<CBloomFilter>();
2717 int64_t nRequestTime;
2720 nRequestTime = it->second;
2727 static int64_t nLastTime;
2729 nNow = std::max(nNow, nLastTime);
2733 nRequestTime = std::max(nRequestTime + doubleRequestDelay, nNow);
2738 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2745 if (it->second.hash == invHash) {
2760 size_t nMessageSize = msg.data.size();
2764 std::vector<unsigned char> serializedHeader;
2766 uint256 hash =
Hash(msg.data.data(), msg.data.data() + nMessageSize);
2772 size_t nBytesSent = 0;
2775 bool hasPendingData = !pnode->
vSendMsg.empty();
2776 bool optimisticSend(allowOptimisticSend && pnode->
vSendMsg.empty());
2784 pnode->
vSendMsg.push_back(std::move(serializedHeader));
2786 pnode->
vSendMsg.push_back(std::move(msg.data));
2789 if (optimisticSend ==
true)
2801 CNode* found =
nullptr;
2803 for (
auto&& pnode :
vNodes) {
2804 if(pnode->
GetId() ==
id) {
2814 CNode* found =
nullptr;
2816 for (
auto&& pnode :
vNodes) {
2822 return found !=
nullptr && cond(found) && func(found);
2832 return ConnectNode(addrConnect,
nullptr,
true,
true);
2847 return nNow + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
2852 std::vector<CNode*> vecNodesCopy;
2854 for (
size_t i = 0; i <
vNodes.size(); ++i) {
2859 vecNodesCopy.push_back(pnode);
2861 return vecNodesCopy;
2871 for (
size_t i = 0; i < vecNodes.size(); ++i) {
2872 CNode* pnode = vecNodes[i];
std::map< CSubNet, CBanEntry > banmap_t
const CChainParams & Params()
Return the currently selected parameters.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
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.
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions.
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
void SetServices(const CService &addr, ServiceFlags nServices)
std::vector< bool > m_asmap
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, Optional< Network > network)
Return all or many randomly selected addresses, optionally by network.
A CService with information about it as peer.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
uint32_t nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
Access to the banlist database (banlist.dat)
bool Write(const banmap_t &banSet)
bool Read(banmap_t &banSet)
void resize(size_type n, value_type c=0)
int GetDefaultPort() const
const std::vector< CDNSSeedData > & DNSSeeds() const
bool IsRegTestNet() const
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
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 SweepBanned()
clean unused entries (if bantime has expired)
std::thread threadMessageHandler
void ThreadOpenAddedConnections()
int GetBestHeight() const
void ReleaseNodeVector(const std::vector< CNode * > &vecNodes)
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
void DeleteNode(CNode *pnode)
bool AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
std::unique_ptr< TierTwoConnMan > m_tiertwo_conn_man
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)
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void AddNewAddress(const CAddress &addr, const CAddress &addrFrom, int64_t nTimePenalty=0)
CThreadInterrupt interruptNet
std::unique_ptr< CSemaphore > semAddnode
std::atomic< NodeId > nLastNodeId
void SetServices(const CService &addr, ServiceFlags nServices)
void RecordBytesSent(uint64_t bytes)
std::thread threadDNSAddressSeed
bool Unban(const CNetAddr &ip)
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, Optional< Network > network)
Return all or many randomly selected addresses, optionally by network.
std::deque< std::string > vOneShots
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=nullptr, const char *strDest=nullptr, bool fOneShot=false, bool fFeeler=false, bool fAddnode=false, bool masternode_connection=false, bool masternode_probe_connection=false)
unsigned int nPrevNodeCount
void NotifyNumConnectionsChanged()
void SetBannedSetDirty(bool dirty=true)
set the "dirty" flag for the banlist
ServiceFlags GetLocalServices() const
bool DisconnectNode(const std::string &node)
size_t SocketSendData(CNode *pnode)
ServiceFlags nRelevantServices
Services this instance cares about.
std::vector< CNode * > CopyNodeVector()
std::vector< ListenSocket > vhListenSocket
void ThreadOpenConnections(const std::vector< std::string > connect)
size_t GetMaxOutboundNodeCount()
CClientUIInterface * clientInterface
void GetBanned(banmap_t &banmap)
std::unique_ptr< CSemaphore > semOutbound
void ThreadSocketHandler()
RecursiveMutex cs_totalBytesSent
std::thread threadOpenConnections
RecursiveMutex cs_vOneShots
bool fMsgProcWake
flag for waking the message processor.
CNode * FindNode(const CNetAddr &ip)
void Init(const Options &connOptions)
constexpr static const CAllNodes AllNodes
unsigned int GetSendBufferSize() const
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg, bool allowOptimisticSend=DEFAULT_ALLOW_OPTIMISTIC_SEND)
void MarkAddressGood(const CAddress &addr)
void RelayInv(CInv &inv, int minProtoVersion=ActiveProtocol())
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
unsigned int nReceiveFloodSize
std::atomic< bool > wakeupSelectNeeded
RecursiveMutex cs_totalBytesRecv
static bool NodeFullyConnected(const CNode *pnode)
void WakeMessageHandler()
void SetNetworkActive(bool active)
bool IsBanned(CNetAddr ip)
bool AttemptToEvictConnection(bool fPreferNewConnection)
Try to find a connection to evict when the node is full.
bool Start(CScheduler &scheduler, const Options &options)
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
bool Bind(const CService &addr, unsigned int flags)
bool IsNodeConnected(const CAddress &addr)
void ThreadDNSAddressSeed()
int wakeupPipe[2]
a pipe which is added to select() calls to wakeup before the timeout
std::vector< CSubNet > vWhitelistedRange
void ThreadMessageHandler()
bool fAddressesInitialized
uint64_t GetTotalBytesSent()
void WakeSelect()
Interrupt the select/poll system call.
RecursiveMutex cs_vAddedNodes
std::thread threadOpenAddedConnections
CSipHasher GetDeterministicRandomizer(uint64_t id)
Get a unique deterministic randomizer.
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
bool BannedSetIsDirty()
check is the banlist has unwritten changes
void InactivityCheck(CNode *pnode)
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)
constexpr static const CFullyConnectedOnly FullyConnectedOnly
bool InitBinds(const std::vector< CService > &binds, const std::vector< CService > &whiteBinds)
std::vector< CNode * > vNodes
unsigned int nSendBufferMaxSize
void RemoveAskFor(const uint256 &invHash, int invType)
NetEventsInterface * m_msgproc
void UpdateQuorumRelayMemberIfNeeded(CNode *pnode)
Update the node to be a iqr member if needed.
void SetBanned(const banmap_t &banmap)
std::atomic< bool > fNetworkActive
RecursiveMutex cs_setBanned
CConnman(uint64_t seed0, uint64_t seed1)
bool AddNode(const std::string &node)
std::thread threadSocketHandler
uint64_t CalculateKeyedNetGroup(const CAddress &ad)
bool RemoveAddedNode(const std::string &node)
void AddOneShot(const std::string &strDest)
CNode * ConnectNode(const CAddress &addrConnect)
bool IsWhitelistedRange(const CNetAddr &addr)
void AcceptConnection(const ListenSocket &hListenSocket)
static void callCleanup()
CHash256 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
std::string ToString() const
bool IsMasterNodeType() const
std::string ToStringIP() const
void SetIP(const CNetAddr &ip)
std::string ToString() const
bool SetInternal(const std::string &name)
Transform an arbitrary string into a non-routable ipv6 address.
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
uint32_t GetMappedAS(const std::vector< bool > &asmap) 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.
RecursiveMutex cs_vProcessMsg
std::atomic< int64_t > nLastSend
CRollingBloomFilter filterInventoryKnown
std::atomic< int > nVersion
void SetSendVersion(int nVersionIn)
std::atomic< bool > m_masternode_connection
std::deque< std::vector< unsigned char > > vSendMsg
std::atomic_bool fPauseRecv
std::atomic< int64_t > nTimeOffset
RecursiveMutex cs_sendProcessing
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
RecursiveMutex cs_inventory
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.
void AskForInvReceived(const uint256 &invHash)
std::atomic_bool fSuccessfullyConnected
ServiceFlags nServicesExpected
bool DisconnectOldProtocol(int nVersionIn, int nVersionRequired)
uint64_t GetLocalNonce() const
std::atomic< ServiceFlags > nServices
uint256 verifiedProRegTxHash
RecursiveMutex cs_addrLocal
CSemaphoreGrant grantOutbound
const int64_t nTimeConnected
std::string GetAddrName() const
uint256 verifiedPubKeyHash
mapMsgCmdSize mapSendBytesPerMsgCmd
std::atomic< int > nRefCount
void AskFor(const CInv &inv, int64_t doubleRequestDelay=2 *60 *1000000)
RecursiveMutex cs_addrName
void CloseSocketDisconnect()
std::atomic< int > nStartingHeight
std::atomic_bool fPauseSend
std::multimap< int64_t, CInv > mapAskFor
std::unique_ptr< CBloomFilter > pfilter
void PushInventory(const CInv &inv)
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
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 > nMinPingUsecTime
std::atomic< uint64_t > nPingNonceSent
RecursiveMutex cs_hSocket
std::set< uint256 > setAskFor
std::atomic< int64_t > nPingUsecStart
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::atomic< bool > m_masternode_probe_connection
std::list< CNetMessage > vProcessMsg
std::atomic< bool > m_masternode_iqr_connection
std::atomic_bool fDisconnect
CService GetAddrLocal() const
std::atomic< int > nRecvVersion
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
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
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)
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
virtual void InitializeNode(CNode *pnode)=0
virtual bool SendMessages(CNode *pnode, std::atomic< bool > &interrupt) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
virtual void FinalizeNode(NodeId id, bool &update_connection_time)=0
STL-like map container that only keeps the N elements with the highest value.
std::map< K, V >::const_iterator const_iterator
#define WSAGetLastError()
void * memcpy(void *a, const void *b, size_t c)
CClientUIInterface uiInterface
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
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)
bool IsLocal(const CService &addr)
check whether a given address is potentially local
#define DUMP_ADDRESSES_INTERVAL
BindFlags
Used to pass flags to the Bind() function.
limitedmap< CInv, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
RecursiveMutex cs_mapLocalHost
class CNetCleanup instance_of_cnetcleanup
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 SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
bool validateMasternodeIP(const std::string &addrStr)
bool AddLocal(const CService &addr, int nScore)
#define FEELER_SLEEP_WINDOW
void CheckOffsetDisconnectedPeers(const CNetAddr &ip)
bool IsReachable(enum Network net)
bool SeenLocal(const CService &addr)
vote for a local address
int GetnScore(const CService &addr)
#define ENOUGH_CONNECTIONS
Disconnected peers are added to setOffsetDisconnectedPeers only if node has less than ENOUGH_CONNECTI...
#define MAX_TIMEOFFSET_DISCONNECTIONS
Maximum number of peers added to setOffsetDisconnectedPeers before triggering a warning.
@ NET_MAX
Dummy value to indicate the number of NET_* constants.
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
bool GetNameProxy(proxyType &nameProxyOut)
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
bool SetSocketNoDelay(SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
CService LookupNumeric(const std::string &name, int portDefault)
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, int port, const SOCKET &hSocket, int nTimeout, bool *outProxyConnectionFailed)
void InterruptSocks5(bool interrupt)
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, int nTimeout, bool manual_connection)
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
SOCKET CreateSocket(const CService &addrConnect)
boost::optional< T > Optional
Substitute for C++17 std::optional.
const std::vector< std::string > & getAllNetMessageTypes()
ServiceFlags
nServices flags
uint64_t GetRand(uint64_t nMax) noexcept
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
int GetRandInt(int nMax) noexcept
std::vector< std::string > m_specified_outgoing
NetEventsInterface * m_msgproc
std::vector< CService > vWhiteBinds
std::vector< CService > vBinds
std::vector< std::string > vSeedNodes
bool m_use_addrman_outgoing
bool supportsServiceBitsFiltering
bool m_has_specified_outgoing
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define TRY_LOCK(cs, name)
std::atomic< bool > fMasterNode
bool error(const char *fmt, const Args &... args)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
void TraceThread(const std::string name, Callable func)
int64_t GetAdjustedTime()
const uint256 UINT256_ZERO
constant uint256 instances
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
int64_t GetTimeMicros()
Returns the system time (not mockable)
int64_t GetTimeMillis()
Returns the system time (not mockable)
int64_t GetSystemTimeInSeconds()
Returns the system time (not mockable)
std::string FormatISO8601Time(int64_t nTime)
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)