6 #if defined(HAVE_CONFIG_H) 36 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS 49 #include <unordered_map> 82 #define FEELER_SLEEP_WINDOW 1 118 m_addr_fetches.push_back(strDest);
133 int nBestReachability = -1;
136 for (
const auto& entry : mapLocalHost)
138 int nScore = entry.second.nScore;
139 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
140 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
142 addr =
CService(entry.first, entry.second.nPort);
143 nBestReachability = nReachability;
148 return nBestScore >= 0;
152 static std::vector<CAddress>
ConvertSeeds(
const std::vector<uint8_t> &vSeedsIn)
158 const int64_t nOneWeek = 7*24*60*60;
159 std::vector<CAddress> vSeedsOut;
168 vSeedsOut.push_back(addr);
183 ret =
CAddress(addr, nLocalServices);
192 if (mapLocalHost.count(addr) == 0)
return 0;
193 return mapLocalHost[addr].nScore;
245 bool fAlready = mapLocalHost.count(addr) > 0;
247 if (!fAlready || nScore >= info.
nScore) {
248 info.
nScore = nScore + (fAlready ? 1 : 0);
265 mapLocalHost.erase(addr);
273 vfLimited[net] = !reachable;
279 return !vfLimited[net];
292 if (mapLocalHost.count(addr) == 0)
294 mapLocalHost[addr].nScore++;
304 return mapLocalHost.count(addr) > 0;
310 for (
CNode* pnode : vNodes) {
311 if (static_cast<CNetAddr>(pnode->addr) == ip) {
321 for (
CNode* pnode : vNodes) {
322 if (subNet.
Match(static_cast<CNetAddr>(pnode->addr))) {
332 for (
CNode* pnode : vNodes) {
333 if (pnode->GetAddrName() == addrName) {
343 for (
CNode* pnode : vNodes) {
344 if (static_cast<CService>(pnode->addr) == addr) {
359 for (
const CNode* pnode : vNodes) {
360 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
370 struct sockaddr_storage sockaddr_bind;
371 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
373 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
374 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
386 if (pszDest ==
nullptr) {
394 LogPrintf(
"Failed to open new connection, already connected\n");
401 pszDest ? pszDest : addrConnect.
ToString(),
408 std::vector<CService> resolved;
424 LogPrintf(
"Failed to open new connection, already connected\n");
431 bool connected =
false;
432 std::unique_ptr<Sock> sock;
438 bool proxyConnectionFailed =
false;
444 sock = std::move(conn.
sock);
463 if (!proxyConnectionFailed) {
474 uint16_t port{default_port};
476 bool proxyConnectionFailed;
478 proxyConnectionFailed);
526 return "outbound-full-relay";
528 return "block-relay-only";
543 if (addrName.empty()) {
544 addrName = addrNameIn;
555 if (addrLocal.IsValid()) {
556 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
558 addrLocal = addrLocalIn;
568 #define X(name) stats.name = name 600 X(mapSendBytesPerMsgCmd);
605 X(mapRecvBytesPerMsgCmd);
629 const auto time = GetTime<std::chrono::microseconds>();
631 nLastRecv = std::chrono::duration_cast<std::chrono::seconds>(time).
count();
632 nRecvBytes += msg_bytes.
size();
633 while (msg_bytes.
size() > 0) {
643 uint32_t out_err_raw_size{0};
644 std::optional<CNetMessage> result{
m_deserializer->GetMessage(time, out_err_raw_size)};
654 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(result->m_command);
655 if (i == mapRecvBytesPerMsgCmd.end())
657 assert(i != mapRecvBytesPerMsgCmd.end());
658 i->second += result->m_raw_message_size;
661 vRecvMsg.push_back(std::move(*result));
674 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
687 catch (
const std::exception&) {
713 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
738 std::optional<CNetMessage> msg(std::move(
vRecv));
753 LogPrint(
BCLog::NET,
"Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
758 out_err_raw_size = msg->m_raw_message_size;
763 out_err_raw_size = msg->m_raw_message_size;
787 auto it =
node.vSendMsg.begin();
788 size_t nSentSize = 0;
790 while (it !=
node.vSendMsg.end()) {
791 const auto& data = *it;
802 node.nSendBytes += nBytes;
803 node.nSendOffset += nBytes;
805 if (
node.nSendOffset == data.size()) {
806 node.nSendOffset = 0;
807 node.nSendSize -= data.size();
820 node.CloseSocketDisconnect();
828 if (it ==
node.vSendMsg.end()) {
832 node.vSendMsg.erase(
node.vSendMsg.begin(), it);
897 template <
typename T,
typename Comparator>
899 std::vector<T>& elements, Comparator comparator,
size_t k,
902 std::sort(elements.begin(), elements.end(), comparator);
903 size_t eraseSize = std::min(k, elements.size());
904 elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
915 const size_t initial_size = eviction_candidates.size();
916 const size_t total_protect_size{initial_size / 2};
920 struct Net {
bool is_local;
Network id;
size_t count; };
921 std::array<Net, 3> networks{
925 for (Net& n : networks) {
926 n.count = std::count_if(eviction_candidates.cbegin(), eviction_candidates.cend(),
933 std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) {
return a.count < b.count; });
936 const size_t max_protect_by_network{total_protect_size / 2};
937 size_t num_protected{0};
939 while (num_protected < max_protect_by_network) {
941 auto num_networks = std::count_if(networks.begin(), networks.end(), [](
const Net& n) {
return n.count; });
942 if (num_networks == 0) {
945 const size_t disadvantaged_to_protect{max_protect_by_network - num_protected};
946 const size_t protect_per_network{std::max(disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
948 bool protected_at_least_one{
false};
950 for (Net& n : networks) {
951 if (n.count == 0)
continue;
952 const size_t before = eviction_candidates.size();
955 return n.is_local ? c.m_is_local : c.m_network == n.id;
957 const size_t after = eviction_candidates.size();
958 if (before > after) {
959 protected_at_least_one =
true;
960 const size_t delta{before - after};
961 num_protected += delta;
962 if (num_protected >= max_protect_by_network) {
968 if (!protected_at_least_one) {
975 assert(num_protected == initial_size - eviction_candidates.size());
976 const size_t remaining_to_protect{total_protect_size - num_protected};
980 [[nodiscard]] std::optional<NodeId>
SelectNodeToEvict(std::vector<NodeEvictionCandidate>&& vEvictionCandidates)
1005 if (vEvictionCandidates.empty())
return std::nullopt;
1011 vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
1017 uint64_t naMostConnections;
1018 unsigned int nMostConnections = 0;
1019 int64_t nMostConnectionsTime = 0;
1020 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1022 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[
node.nKeyedNetGroup];
1023 group.push_back(
node);
1024 const int64_t grouptime = group[0].nTimeConnected;
1026 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1027 nMostConnections = group.size();
1028 nMostConnectionsTime = grouptime;
1029 naMostConnections =
node.nKeyedNetGroup;
1034 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1037 return vEvictionCandidates.front().id;
1050 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1057 if (!
node->IsInboundConn())
1059 if (
node->fDisconnect)
1061 bool peer_relay_txes =
false;
1062 bool peer_filter_not_null =
false;
1063 if (
node->m_tx_relay !=
nullptr) {
1065 peer_relay_txes =
node->m_tx_relay->fRelayTxes;
1066 peer_filter_not_null =
node->m_tx_relay->pfilter !=
nullptr;
1069 node->nLastBlockTime,
node->nLastTXTime,
1071 peer_relay_txes, peer_filter_not_null,
node->nKeyedNetGroup,
1072 node->m_prefer_evict,
node->addr.IsLocal(),
1073 node->ConnectedThroughNetwork()};
1074 vEvictionCandidates.push_back(candidate);
1077 const std::optional<NodeId> node_id_to_evict =
SelectNodeToEvict(std::move(vEvictionCandidates));
1078 if (!node_id_to_evict) {
1082 for (
CNode* pnode : vNodes) {
1083 if (pnode->GetId() == *node_id_to_evict) {
1084 LogPrint(
BCLog::NET,
"selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
1085 pnode->fDisconnect =
true;
1093 struct sockaddr_storage sockaddr;
1094 socklen_t len =
sizeof(sockaddr);
1095 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1106 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1107 LogPrintf(
"Warning: Unknown socket family\n");
1137 for (
const CNode* pnode : vNodes) {
1138 if (pnode->IsInboundConn()) nInbound++;
1150 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1177 if (nInbound >= nMaxInbound)
1181 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1206 vNodes.push_back(pnode);
1215 std::optional<int> max_connections;
1216 switch (conn_type) {
1234 return std::count_if(vNodes.begin(), vNodes.end(), [conn_type](
CNode*
node) {
return node->m_conn_type == conn_type; }););
1237 if (max_connections != std::nullopt && existing_connections >= max_connections)
return false;
1241 if (!grant)
return false;
1254 for (
CNode* pnode : vNodes) {
1255 if (!pnode->fDisconnect) {
1257 pnode->fDisconnect =
true;
1263 std::vector<CNode*> vNodesCopy = vNodes;
1264 for (
CNode* pnode : vNodesCopy)
1266 if (pnode->fDisconnect)
1269 vNodes.erase(
remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1272 pnode->grantOutbound.Release();
1275 pnode->CloseSocketDisconnect();
1286 for (
CNode* pnode : vNodesDisconnectedCopy)
1289 if (pnode->GetRefCount() <= 0) {
1302 vNodesSize = vNodes.size();
1325 if (
node.nLastRecv == 0 ||
node.nLastSend == 0) {
1340 if (!
node.fSuccessfullyConnected) {
1351 recv_set.insert(hListenSocket.socket);
1356 for (
CNode* pnode : vNodes)
1369 bool select_recv = !pnode->fPauseRecv;
1372 LOCK(pnode->cs_vSend);
1373 select_send = !pnode->vSendMsg.empty();
1376 LOCK(pnode->cs_hSocket);
1380 error_set.insert(pnode->hSocket);
1382 send_set.insert(pnode->hSocket);
1386 recv_set.insert(pnode->hSocket);
1391 return !recv_set.empty() || !send_set.empty() || !error_set.empty();
1395 void CConnman::SocketEvents(std::set<SOCKET> &recv_set, std::set<SOCKET> &send_set, std::set<SOCKET> &error_set)
1397 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1403 std::unordered_map<SOCKET, struct pollfd> pollfds;
1404 for (
SOCKET socket_id : recv_select_set) {
1405 pollfds[socket_id].fd = socket_id;
1406 pollfds[socket_id].events |= POLLIN;
1409 for (
SOCKET socket_id : send_select_set) {
1410 pollfds[socket_id].fd = socket_id;
1411 pollfds[socket_id].events |= POLLOUT;
1414 for (
SOCKET socket_id : error_select_set) {
1415 pollfds[socket_id].fd = socket_id;
1417 pollfds[socket_id].events |= POLLERR|POLLHUP;
1420 std::vector<struct pollfd> vpollfds;
1421 vpollfds.reserve(pollfds.size());
1422 for (
auto it : pollfds) {
1423 vpollfds.push_back(std::move(it.second));
1430 for (
struct pollfd pollfd_entry : vpollfds) {
1431 if (pollfd_entry.revents & POLLIN) recv_set.insert(pollfd_entry.fd);
1432 if (pollfd_entry.revents & POLLOUT) send_set.insert(pollfd_entry.fd);
1433 if (pollfd_entry.revents & (POLLERR|POLLHUP)) error_set.insert(pollfd_entry.fd);
1439 std::set<SOCKET> recv_select_set, send_select_set, error_select_set;
1448 struct timeval timeout;
1455 FD_ZERO(&fdsetRecv);
1456 FD_ZERO(&fdsetSend);
1457 FD_ZERO(&fdsetError);
1460 for (
SOCKET hSocket : recv_select_set) {
1461 FD_SET(hSocket, &fdsetRecv);
1462 hSocketMax = std::max(hSocketMax, hSocket);
1465 for (
SOCKET hSocket : send_select_set) {
1466 FD_SET(hSocket, &fdsetSend);
1467 hSocketMax = std::max(hSocketMax, hSocket);
1470 for (
SOCKET hSocket : error_select_set) {
1471 FD_SET(hSocket, &fdsetError);
1472 hSocketMax = std::max(hSocketMax, hSocket);
1475 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1484 for (
unsigned int i = 0; i <= hSocketMax; i++)
1485 FD_SET(i, &fdsetRecv);
1486 FD_ZERO(&fdsetSend);
1487 FD_ZERO(&fdsetError);
1492 for (
SOCKET hSocket : recv_select_set) {
1493 if (FD_ISSET(hSocket, &fdsetRecv)) {
1494 recv_set.insert(hSocket);
1498 for (
SOCKET hSocket : send_select_set) {
1499 if (FD_ISSET(hSocket, &fdsetSend)) {
1500 send_set.insert(hSocket);
1504 for (
SOCKET hSocket : error_select_set) {
1505 if (FD_ISSET(hSocket, &fdsetError)) {
1506 error_set.insert(hSocket);
1514 std::set<SOCKET> recv_set, send_set, error_set;
1524 if (hListenSocket.socket !=
INVALID_SOCKET && recv_set.count(hListenSocket.socket) > 0)
1533 std::vector<CNode*> vNodesCopy;
1536 vNodesCopy = vNodes;
1537 for (
CNode* pnode : vNodesCopy)
1540 for (
CNode* pnode : vNodesCopy)
1548 bool recvSet =
false;
1549 bool sendSet =
false;
1550 bool errorSet =
false;
1552 LOCK(pnode->cs_hSocket);
1555 recvSet = recv_set.count(pnode->hSocket) > 0;
1556 sendSet = send_set.count(pnode->hSocket) > 0;
1557 errorSet = error_set.count(pnode->hSocket) > 0;
1559 if (recvSet || errorSet)
1562 uint8_t pchBuf[0x10000];
1565 LOCK(pnode->cs_hSocket);
1568 nBytes = recv(pnode->hSocket, (
char*)pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1572 bool notify =
false;
1574 pnode->CloseSocketDisconnect();
1577 size_t nSizeAdded = 0;
1578 auto it(pnode->vRecvMsg.begin());
1579 for (; it != pnode->vRecvMsg.end(); ++it) {
1582 nSizeAdded += it->m_raw_message_size;
1585 LOCK(pnode->cs_vProcessMsg);
1586 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1587 pnode->nProcessQueueSize += nSizeAdded;
1593 else if (nBytes == 0)
1596 if (!pnode->fDisconnect) {
1599 pnode->CloseSocketDisconnect();
1601 else if (nBytes < 0)
1607 if (!pnode->fDisconnect) {
1610 pnode->CloseSocketDisconnect();
1625 for (
CNode* pnode : vNodesCopy)
1644 fMsgProcWake =
true;
1653 Shuffle(seeds.begin(), seeds.end(), rng);
1654 int seeds_right_now = 0;
1659 seeds_right_now = seeds.size();
1664 seeds_right_now = seeds.size();
1681 for (
const std::string& seed : seeds) {
1682 if (seeds_right_now == 0) {
1686 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
1687 std::chrono::seconds to_wait = seeds_wait_time;
1688 while (to_wait.count() > 0) {
1699 for (
const CNode* pnode : vNodes) {
1700 if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
1703 if (nRelevant >= 2) {
1705 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1706 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
1708 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1720 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
1726 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
1730 std::vector<CNetAddr> vIPs;
1731 std::vector<CAddress> vAdd;
1733 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1738 unsigned int nMaxIPs = 256;
1741 int nOneDay = 24*3600;
1744 vAdd.push_back(addr);
1756 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1772 std::string strDest;
1775 if (m_addr_fetches.empty())
1777 strDest = m_addr_fetches.front();
1778 m_addr_fetches.pop_front();
1795 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1806 int full_outbound_peers = 0;
1809 for (
const CNode* pnode : vNodes) {
1810 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
1811 ++full_outbound_peers;
1820 int block_relay_peers = 0;
1823 for (
const CNode* pnode : vNodes) {
1824 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
1825 ++block_relay_peers;
1835 if (!connect.empty())
1837 for (int64_t nLoop = 0;; nLoop++)
1840 for (
const std::string& strAddr : connect)
1844 for (
int i = 0; i < 10 && i < nLoop; i++)
1856 auto start = GetTime<std::chrono::microseconds>();
1864 if (!add_fixed_seeds) {
1865 LogPrintf(
"Fixed seeds are disabled\n");
1884 bool add_fixed_seeds_now =
false;
1886 if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
1887 add_fixed_seeds_now =
true;
1888 LogPrintf(
"Adding fixed seeds as 60 seconds have passed and addrman is empty\n");
1892 if (!add_fixed_seeds_now && !dnsseed) {
1894 if (m_addr_fetches.empty() && vAddedNodes.empty()) {
1895 add_fixed_seeds_now =
true;
1896 LogPrintf(
"Adding fixed seeds as -dnsseed=0, -addnode is not provided and all -seednode(s) attempted\n");
1900 if (add_fixed_seeds_now) {
1904 add_fixed_seeds =
false;
1914 int nOutboundFullRelay = 0;
1915 int nOutboundBlockRelay = 0;
1916 std::set<std::vector<unsigned char> > setConnected;
1920 for (
const CNode* pnode : vNodes) {
1921 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
1922 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
1929 switch (pnode->m_conn_type) {
1943 auto now = GetTime<std::chrono::microseconds>();
1944 bool anchor =
false;
1945 bool fFeeler =
false;
1991 }
else if (now > next_feeler) {
2064 if (nANow - addr.
nLastTry < 600 && nTries < 30)
2106 std::vector<CAddress> ret;
2108 for (
const CNode* pnode : vNodes) {
2109 if (pnode->IsBlockOnlyConn()) {
2110 ret.push_back(pnode->addr);
2119 std::vector<AddedNodeInfo> ret;
2121 std::list<std::string> lAddresses(0);
2124 ret.reserve(vAddedNodes.size());
2125 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
2130 std::map<CService, bool> mapConnected;
2131 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2134 for (
const CNode* pnode : vNodes) {
2135 if (pnode->addr.IsValid()) {
2136 mapConnected[pnode->addr] = pnode->IsInboundConn();
2138 std::string addrName = pnode->GetAddrName();
2139 if (!addrName.empty()) {
2140 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
2145 for (
const std::string& strAddNode : lAddresses) {
2150 auto it = mapConnected.find(service);
2151 if (it != mapConnected.end()) {
2152 addedNode.resolvedAddress = service;
2153 addedNode.fConnected =
true;
2154 addedNode.fInbound = it->second;
2158 auto it = mapConnectedByName.find(strAddNode);
2159 if (it != mapConnectedByName.end()) {
2160 addedNode.resolvedAddress = it->second.second;
2161 addedNode.fConnected =
true;
2162 addedNode.fInbound = it->second.first;
2165 ret.emplace_back(std::move(addedNode));
2179 if (!info.fConnected) {
2217 }
else if (
FindNode(std::string(pszDest)))
2220 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, conn_type);
2230 vNodes.push_back(pnode);
2239 std::vector<CNode*> vNodesCopy;
2242 vNodesCopy = vNodes;
2243 for (
CNode* pnode : vNodesCopy) {
2248 bool fMoreWork =
false;
2253 Shuffle(vNodesCopy.begin(), vNodesCopy.end(), rng);
2255 for (
CNode* pnode : vNodesCopy)
2257 if (pnode->fDisconnect)
2262 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2267 LOCK(pnode->cs_sendProcessing);
2277 for (
CNode* pnode : vNodesCopy)
2285 fMsgProcWake =
false;
2291 static constexpr
auto err_wait_begin = 1s;
2292 static constexpr
auto err_wait_cap = 5min;
2293 auto err_wait = err_wait_begin;
2295 bool advertising_listen_addr =
false;
2301 if (advertising_listen_addr && conn.
me.
IsValid()) {
2303 advertising_listen_addr =
false;
2307 if (err_wait < err_wait_cap) {
2314 if (!advertising_listen_addr) {
2316 advertising_listen_addr =
true;
2333 struct sockaddr_storage sockaddr;
2334 socklen_t len =
sizeof(sockaddr);
2335 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2342 std::unique_ptr<Sock> sock =
CreateSock(addrBind);
2351 setsockopt(sock->Get(), SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2357 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2360 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2361 setsockopt(sock->Get(), IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2365 if (::bind(sock->Get(), (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2396 char pszHostName[256] =
"";
2397 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2399 std::vector<CNetAddr> vaddr;
2405 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2409 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) 2411 struct ifaddrs* myaddrs;
2412 if (getifaddrs(&myaddrs) == 0)
2414 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2416 if (ifa->ifa_addr ==
nullptr)
continue;
2417 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2418 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2419 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2420 if (ifa->ifa_addr->sa_family == AF_INET)
2422 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2427 else if (ifa->ifa_addr->sa_family == AF_INET6)
2429 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2435 freeifaddrs(myaddrs);
2442 LogPrintf(
"%s: %s\n", __func__, active);
2454 : addrman(addrman_in), nSeed0(nSeed0In), nSeed1(nSeed1In)
2465 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2490 bool fBound =
false;
2491 for (
const auto& addrBind : options.
vBinds) {
2494 for (
const auto& addrBind : options.
vWhiteBinds) {
2497 for (
const auto& addr_bind : options.
onion_binds) {
2501 struct in_addr inaddr_any;
2502 inaddr_any.s_addr = htonl(INADDR_ANY);
2503 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2517 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2529 for (
const auto& strDest : connOptions.
vSeedNodes) {
2555 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
2558 uiInterface.InitMessage(
_(
"Starting network threads…").translated);
2581 fMsgProcWake =
false;
2598 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2696 std::vector<CNode*> nodes;
2698 for (
CNode* pnode : nodes) {
2699 pnode->CloseSocketDisconnect();
2736 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct, network);
2738 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
2750 .Write(local_socket_bytes.data(), local_socket_bytes.size())
2752 const auto current_time = GetTime<std::chrono::microseconds>();
2789 for (
const std::string& it : vAddedNodes) {
2790 if (strNode == it)
return false;
2793 vAddedNodes.push_back(strNode);
2800 for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2801 if (strNode == *it) {
2802 vAddedNodes.erase(it);
2813 return vNodes.size();
2816 for (
const auto& pnode : vNodes) {
2829 vstats.reserve(vNodes.size());
2830 for (
CNode* pnode : vNodes) {
2831 vstats.emplace_back();
2841 pnode->fDisconnect =
true;
2849 bool disconnected =
false;
2851 for (
CNode* pnode : vNodes) {
2852 if (subnet.
Match(pnode->addr)) {
2854 pnode->fDisconnect =
true;
2855 disconnected =
true;
2858 return disconnected;
2869 for(
CNode* pnode : vNodes) {
2870 if (
id == pnode->GetId()) {
2872 pnode->fDisconnect =
true;
2882 nTotalBytesRecv += bytes;
2888 nTotalBytesSent += bytes;
2890 const auto now = GetTime<std::chrono::seconds>();
2894 nMaxOutboundCycleStartTime = now;
2895 nMaxOutboundTotalBytesSentInCycle = 0;
2899 nMaxOutboundTotalBytesSentInCycle += bytes;
2905 return nMaxOutboundLimit;
2916 if (nMaxOutboundLimit == 0)
2919 if (nMaxOutboundCycleStartTime.count() == 0)
2923 const auto now = GetTime<std::chrono::seconds>();
2924 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
2930 if (nMaxOutboundLimit == 0)
2933 if (historicalBlockServingLimit)
2938 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2941 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2950 if (nMaxOutboundLimit == 0)
2953 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2959 return nTotalBytesRecv;
2965 return nTotalBytesSent;
2978 addrBind(addrBindIn),
2979 m_inbound_onion(inbound_onion),
2980 nKeyedNetGroup(nKeyedNetGroupIn),
2982 nLocalHostNonce(nLocalHostNonceIn),
2983 m_conn_type(conn_type_in),
2984 nLocalServices(nLocalServicesIn)
2987 hSocket = hSocketIn;
2994 mapRecvBytesPerMsgCmd[msg] = 0;
3019 size_t nMessageSize = msg.data.size();
3026 std::vector<unsigned char> serializedHeader;
3027 pnode->
m_serializer->prepareForTransport(msg, serializedHeader);
3028 size_t nTotalSize = nMessageSize + serializedHeader.size();
3030 size_t nBytesSent = 0;
3033 bool optimisticSend(pnode->vSendMsg.empty());
3036 pnode->mapSendBytesPerMsgCmd[msg.m_type] += nTotalSize;
3037 pnode->nSendSize += nTotalSize;
3040 pnode->vSendMsg.push_back(std::move(serializedHeader));
3041 if (nMessageSize) pnode->vSendMsg.push_back(std::move(msg.data));
3051 CNode* found =
nullptr;
3053 for (
auto&& pnode : vNodes) {
3054 if(pnode->
GetId() == id) {
3073 std::chrono::microseconds
PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
3075 double unscaled = -log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 );
3076 return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
3097 auto now = GetTime<std::chrono::microseconds>();
3100 std::string clean_addr = addr.
ToString();
3101 std::replace(clean_addr.begin(), clean_addr.end(),
':',
'_');
3104 fs::create_directories(base_path);
3106 fs::path path = base_path / (is_incoming ?
"msgs_recv.dat" :
"msgs_sent.dat");
3110 f.
write(msg_type.data(), msg_type.length());
3114 uint32_t size = data.
size();
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
std::vector< CService > vBinds
std::atomic< bool > flagInterruptMsgProc
void copyStats(CNodeStats &stats, const std::vector< bool > &m_asmap)
std::vector< CAddress > m_addrs_response_cache
std::vector< unsigned char > GetGroup(const std::vector< bool > &asmap) const
Get the canonical identifier of our network group.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::chrono::microseconds m_min_ping_time
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
void MoveTo(CSemaphoreGrant &grant)
std::atomic_bool fPauseSend
Access to the (IP) address database (peers.dat)
uint64_t GetRand(uint64_t nMax) noexcept
Generate a uniform random integer in the range [0..range).
void ThreadOpenAddedConnections()
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
bool sleep_for(std::chrono::milliseconds rel_time)
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
bool m_i2p_accept_incoming
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const
returns the time left in the current max outbound cycle in case of no limit, it will always return 0 ...
std::atomic< bool > fNetworkActive
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
void Finalize(Span< unsigned char > output)
std::unique_ptr< TransportSerializer > m_serializer
#define LogPrint(category,...)
int readData(Span< const uint8_t > msg_bytes)
bool AddLocal(const CService &addr, int nScore)
FILE * fopen(const fs::path &p, const char *mode)
A set of addresses that represent the hash of a string or FQDN.
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
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 ...
CAddrInfo SelectTriedCollision() EXCLUSIVE_LOCKS_REQUIRED(!cs)
Randomly select an address in tried that another address is attempting to evict.
Dummy value to indicate the number of NET_* constants.
void scheduleEvery(Function f, std::chrono::milliseconds delta)
Repeat f until the scheduler is stopped.
static bool IsSelectableSocket(const SOCKET &s)
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
uint64_t GetOutboundTargetBytesLeft() const
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
void ser_writedata64(Stream &s, uint64_t obj)
void SocketEvents(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
int64_t GetTimeMillis()
Returns the system time (not mockable)
static const bool DEFAULT_FORCEDNSSEED
int64_t GetTimeSeconds()
Returns the system time (not mockable)
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
std::vector< unsigned char > data
const ConnectionType m_conn_type
uint64_t GetTotalBytesRecv() const
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::vector< NetWhitelistPermissions > vWhitelistedRange
constexpr auto GetRandMillis
int m_max_outbound_full_relay
void resize(size_type n, value_type c=0)
bool GetNameProxy(proxyType &nameProxyOut)
std::vector< CService > m_onion_binds
A vector of -bind=<address>:<port>=onion arguments each of which is an address and port that are desi...
void ser_writedata32(Stream &s, uint32_t obj)
static constexpr std::chrono::seconds MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
constexpr std::size_t size() const noexcept
bool LookupHost(const std::string &name, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
void AddWhitelistPermissionFlags(NetPermissionFlags &flags, const CNetAddr &addr) const
#define FEELER_SLEEP_WINDOW
RAII-style semaphore lock.
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
CService me
Our I2P address.
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
RecursiveMutex cs_addrName
NetEventsInterface * m_msgproc
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
void CreateNodeFromAcceptedSocket(SOCKET hSocket, NetPermissionFlags permissionFlags, const CAddress &addr_bind, const CAddress &addr)
Create a CNode object from a socket that has just been accepted and add the node to the vNodes member...
int m_max_outbound_block_relay
Double ended buffer combining vector and stream-like interfaces.
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!cs)
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SetTryNewOutboundPeer(bool flag)
std::string ToString() const
std::unique_ptr< TransportDeserializer > m_deserializer
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
bool SeenLocal(const CService &addr)
vote for a local address
void ThreadSocketHandler()
An established connection with another peer.
static bool CompareNodeBlockTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Network GetNetClass() const
static bool CompareNodeBlockRelayOnlyTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
CService LookupNumeric(const std::string &name, uint16_t portDefault, DNSLookupFn dns_lookup_function)
Resolve a service string with a numeric IP to its first corresponding service.
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
static const int TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network) const
Return all or many randomly selected addresses, optionally by network.
void GetNodeStats(std::vector< CNodeStats > &vstats) const
bool Lookup(const std::string &name, std::vector< CService > &vAddr, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
#define WSAGetLastError()
bool operator()(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) const
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, uint16_t port, const Sock &sock, int nTimeout, bool &outProxyConnectionFailed)
Connect to a specified destination service through a SOCKS5 proxy by first connecting to the SOCKS5 p...
static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
std::list< CNetMessage > vRecvMsg
bool GetTryNewOutboundPeer() const
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
void DumpAnchors(const fs::path &anchors_db_path, const std::vector< CAddress > &anchors)
Dump the anchor IP address database (anchors.dat)
void NotifyNumConnectionsChanged()
enum Network GetNetwork() const
void RecordBytesSent(uint64_t bytes)
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
std::atomic< ServiceFlags > nServices
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
void write(const char *pch, size_t nSize)
uint32_t GetMappedAS(const std::vector< bool > &asmap) const
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
uint16_t GetDefaultPort() const
ServiceFlags nLocalServices
Services this instance offers.
RecursiveMutex cs_mapLocalHost
bool DisconnectNode(const std::string &node)
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
Stochastical (IP) address manager.
int GetExtraBlockRelayCount() const
std::atomic< int64_t > nLastSend
static constexpr int ADDRV2_FORMAT
A flag that is ORed into the protocol version to designate that addresses should be serialized in (un...
void RecordBytesRecv(uint64_t bytes)
bool IsDiscouraged(const CNetAddr &net_addr)
Return whether net_addr is discouraged.
std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
Attempts to obfuscate tx time through exponentially distributed emitting.
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
std::thread threadI2PAcceptIncoming
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return all or many randomly selected addresses, optionally by network.
Extended statistics about a CAddress.
ServiceFlags GetLocalServices() const
static CAddress GetBindAddress(SOCKET sock)
Get the bind address for a socket as CAddress.
void TraceThread(const char *thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
void CloseSocketDisconnect()
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
CAddrInfo Select(bool newOnly=false) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Choose an address to connect to.
Sort eviction candidates by network/localhost and connection uptime.
bool Write(const CAddrMan &addr)
std::chrono::microseconds m_cache_entry_expiration
void AddAddrFetch(const std::string &strDest)
static bool NodeFullyConnected(const CNode *pnode)
unsigned int nPrevNodeCount
static const uint64_t RANDOMIZER_ID_NETGROUP
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
bool AddNode(const std::string &node)
std::condition_variable condMsgProc
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
RecursiveMutex cs_vAddedNodes
CService GetAddrLocal() const
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Add a single address.
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound, const char *strDest, ConnectionType conn_type)
size_t SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
std::atomic< int64_t > nLastRecv
std::optional< CAddress > GetLocalAddrForPeer(CNode *pnode)
Returns a local address that we should advertise to this peer.
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
static bool HasAllDesirableServiceFlags(ServiceFlags services)
A shortcut for (services & GetDesirableServiceFlags(services)) == GetDesirableServiceFlags(services)...
std::thread threadOpenAddedConnections
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
std::string ToStringIP() const
CNode * FindNode(const CNetAddr &ip)
void ResolveCollisions() EXCLUSIVE_LOCKS_REQUIRED(!cs)
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection. ...
RecursiveMutex m_addr_fetches_mutex
bilingual_str _(const char *psz)
Translation function.
bool IsPeerAddrLocalGood(CNode *pnode)
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
CConnman(uint64_t seed0, uint64_t seed1, CAddrMan &addrman, bool network_active=true)
static constexpr int DNSSEEDS_TO_QUERY_AT_ONCE
Number of DNS seeds to query when the number of connections is low.
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< std::string > vSeedNodes
std::vector< std::string > m_specified_outgoing
int64_t m_peer_connect_timeout
std::unique_ptr< CSemaphore > semOutbound
void ThreadOpenConnections(std::vector< std::string > connect)
std::thread threadMessageHandler
void CaptureMessage(const CAddress &addr, const std::string &msg_type, const Span< const unsigned char > &data, bool is_incoming)
Dump binary message to file, with timestamp.
const uint256 & GetMessageHash() const
virtual void FinalizeNode(const CNode &node)=0
Handle removal of a peer (clear state)
int GetExtraFullOutboundCount() const
A CService with information about it as peer.
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
bool Start(CScheduler &scheduler, const Options &options)
static int GetnScore(const CService &addr)
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
const std::vector< std::string > & getAllNetMessageTypes()
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete)
Receive bytes from the buffer and deserialize them into messages.
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections, to prevent gossiping them over the network.
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of m_max_outbound_full_relay This t...
const CMessageHeader::MessageStartChars & MessageStart() const
bool InitBinds(const Options &options)
void SetNetworkActive(bool active)
#define WAIT_LOCK(cs, name)
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
std::atomic< bool > m_bip152_highbandwidth_to
CClientUIInterface * clientInterface
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
std::optional< CNetMessage > GetMessage(std::chrono::microseconds time, uint32_t &out_err_raw_size) override
static constexpr std::chrono::minutes DNSSEEDS_DELAY_MANY_PEERS
const bool m_inbound_onion
Whether this peer is an inbound onion, i.e. connected via our Tor onion service.
std::atomic_bool fDisconnect
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void prepareForTransport(CSerializedNetMsg &msg, std::vector< unsigned char > &header) override
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
std::optional< NodeId > SelectNodeToEvict(std::vector< NodeEvictionCandidate > &&vEvictionCandidates)
Select an inbound peer to evict after filtering out (protecting) peers having distinct, difficult-to-forge characteristics.
const std::string NET_MESSAGE_COMMAND_OTHER
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB...
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
unsigned int GetReceiveFloodSize() const
Inbound connections are those initiated by a peer.
void DeleteNode(CNode *pnode)
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
bool CheckIncomingNonce(uint64_t nonce)
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion)
bool Complete() const override
static const bool DEFAULT_DNSSEED
bool Match(const CNetAddr &addr) const
const int64_t nTimeConnected
Unix epoch time at peer connection, in seconds.
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
std::list< CNode * > vNodesDisconnected
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type)
std::vector< CService > onion_binds
size_t GetNodeCount(ConnectionDirection) const
bool IsReachable(enum Network net)
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
ServiceFlags nServices
Serialized as uint64_t in V1, and as CompactSize in V2.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
bool ShouldRunInactivityChecks(const CNode &node, std::optional< int64_t > now=std::nullopt) const
Return true if we should disconnect the peer for failing an inactivity check.
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
std::string ToString() const
BanMan * m_banman
Pointer to this node's banman.
std::atomic< int64_t > nLastTXTime
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e...
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
ConnectionType
Different types of connections to a peer.
int readHeader(Span< const uint8_t > msg_bytes)
constexpr C * data() const noexcept
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
const CChainParams & m_chain_params
size_t size() const EXCLUSIVE_LOCKS_REQUIRED(!cs)
Return the number of (unique) addresses in all tables.
static const int PROTOCOL_VERSION
network protocol versioning
Feeler connections are short-lived connections made to check that a node is alive.
std::vector< AddedNodeInfo > GetAddedNodeInfo() const
NetPermissionFlags m_permissionFlags
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool fAddressesInitialized
std::thread threadDNSAddressSeed
int64_t GetAdjustedTime()
std::string ToStringIPPort() const
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
std::vector< ListenSocket > vhListenSocket
std::chrono::seconds GetMaxOutboundTimeframe() const
static const uint64_t RANDOMIZER_ID_ADDRCACHE
static uint32_t ReadLE32(const unsigned char *ptr)
std::atomic< int64_t > nTimeOffset
std::atomic_bool fSuccessfullyConnected
fSuccessfullyConnected is set to true on receiving VERACK from the peer.
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
void ThreadMessageHandler()
These are the default connections that we use to connect with the network.
bool OutboundTargetReached(bool historicalBlockServingLimit) const
check if the outbound target is reached if param historicalBlockServingLimit is set true...
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
std::atomic< int > nVersion
static void EraseLastKElements(std::vector< T > &elements, Comparator comparator, size_t k, std::function< bool(const NodeEvictionCandidate &)> predicate=[](const NodeEvictionCandidate &n) { return true;})
Sort an array by the specified comparator, then erase the last K elements where predicate is true...
void InterruptSocks5(bool interrupt)
unsigned int nSendBufferMaxSize
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
std::vector< bool > m_asmap
std::string ToString() const
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(cs_mapLocalHost)
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
std::atomic< bool > m_bip152_highbandwidth_from
void ThreadI2PAcceptIncoming()
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
bool AddConnection(const std::string &address, ConnectionType conn_type)
Attempts to open a connection.
bool IsBanned(const CNetAddr &net_addr)
Return whether net_addr is banned.
BindFlags
Used to pass flags to the Bind() function.
bool GenerateSelectSet(std::set< SOCKET > &recv_set, std::set< SOCKET > &send_set, std::set< SOCKET > &error_set)
void AcceptConnection(const ListenSocket &hListenSocket)
A Span is an object that can refer to a contiguous sequence of objects.
CClientUIInterface uiInterface
static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
uint64_t GetMaxOutboundTarget() const
Information about a peer.
static CNetCleanup instance_of_cnetcleanup
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime()) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Mark an entry as connection attempted to.
bool SetSockAddr(const struct sockaddr *paddr)
std::thread threadSocketHandler
Simple class for background tasks that should be run periodically or once "after a while"...
We use block-relay-only connections to help prevent against partition attacks.
RecursiveMutex cs_totalBytesRecv
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Network ConnectedThroughNetwork() const
Get network the peer connected through.
virtual void InitializeNode(CNode *pnode)=0
Initialize a peer (setup state, queue any initial messages)
std::string GetAddrName() const
RecursiveMutex cs_addrLocal
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
AddrFetch connections are short lived connections used to solicit addresses from peers.
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime()) EXCLUSIVE_LOCKS_REQUIRED(!cs)
Mark an entry as accessible.
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
int64_t GetTime()
Return system time (or mocked time, if set)
uint64_t GetTotalBytesSent() const
std::unique_ptr< CSemaphore > semAddnode
std::atomic< std::chrono::microseconds > m_next_send_inv_to_incoming
std::unique_ptr< Sock > sock
Connected socket.
void Init(const Options &connOptions)
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
int GetRandInt(int nMax) noexcept
CService peer
The peer's I2P address.
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
bool IsInboundConn() const
bool m_use_addrman_outgoing
std::vector< NetWhitebindPermissions > vWhiteBinds
std::atomic< int64_t > nLastBlockTime
UNIX epoch time of the last block received from this peer that we had not yet seen (e...
bool error(const char *fmt, const Args &... args)
uint32_t nTime
Always included in serialization, except in the network format on INIT_PROTO_VERSION.
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
CHash256 & Write(Span< const unsigned char > input)
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
bool Read(CAddrMan &addr)
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0...
void ProtectEvictionCandidatesByRatio(std::vector< NodeEvictionCandidate > &eviction_candidates)
Protect desirable or disadvantaged inbound peers from eviction by ratio.
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
Non-refcounted RAII wrapper for FILE*.
bool m_use_addrman_outgoing
Cache responses to addr requests to minimize privacy leak.
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Process protocol messages received from a given node.
std::vector< unsigned char > GetAddrBytes() const
int64_t nLastTry
last try whatsoever by us (memory only)
void RemoveLocal(const CService &addr)
bool IsLocal(const CService &addr)
check whether a given address is potentially local
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
RecursiveMutex cs_totalBytesSent
unsigned int nReceiveFloodSize
std::unique_ptr< TxRelay > m_tx_relay
virtual bool SendMessages(CNode *pnode) EXCLUSIVE_LOCKS_REQUIRED(pnode -> cs_sendProcessing)=0
Send queued protocol messages to a given node.
CompareNodeNetworkTime(bool is_local, Network network)
void ThreadDNSAddressSeed()
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
Addresses from these networks are not publicly routable on the global Internet.
static const bool DEFAULT_FIXEDSEEDS