6 #if defined(HAVE_CONFIG_H) 45 #if HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS 54 #include <unordered_map> 132 m_addr_fetches.push_back(strDest);
138 for (
const std::string& bind_arg :
gArgs.
GetArgs(
"-bind")) {
139 constexpr uint16_t dummy_port = 0;
141 const std::optional<CService> bind_addr{
Lookup(bind_arg, dummy_port,
false)};
142 if (bind_addr.has_value() && bind_addr->GetPort() != dummy_port)
return bind_addr->GetPort();
147 for (
const std::string& whitebind_arg :
gArgs.
GetArgs(
"-whitebind")) {
164 if (!
fListen)
return std::nullopt;
166 std::optional<CService> addr;
168 int nBestReachability = -1;
171 for (
const auto& [local_addr, local_service_info] : mapLocalHost) {
179 const int nScore{local_service_info.nScore};
180 const int nReachability{local_addr.GetReachabilityFrom(peer.
addr)};
181 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore)) {
182 addr.emplace(
CService{local_addr, local_service_info.nPort});
183 nBestReachability = nReachability;
192 static std::vector<CAddress>
ConvertSeeds(
const std::vector<uint8_t> &vSeedsIn)
198 const auto one_week{7 * 24h};
199 std::vector<CAddress> vSeedsOut;
209 vSeedsOut.push_back(addr);
226 const auto it = mapLocalHost.find(addr);
227 return (it != mapLocalHost.end()) ? it->second.nScore : 0;
252 if (
node.IsInboundConn()) {
261 addrLocal.SetIP(
node.GetAddrLocal());
278 if (!addr.IsRoutable())
287 LogPrintf(
"AddLocal(%s,%i)\n", addr.ToStringAddrPort(), nScore);
291 const auto [it, is_newly_added] = mapLocalHost.emplace(addr,
LocalServiceInfo());
293 if (is_newly_added || nScore >= info.
nScore) {
294 info.
nScore = nScore + (is_newly_added ? 0 : 1);
295 info.
nPort = addr.GetPort();
311 mapLocalHost.erase(addr);
318 const auto it = mapLocalHost.find(addr);
319 if (it == mapLocalHost.end())
return false;
329 return mapLocalHost.count(addr) > 0;
335 for (
CNode* pnode : m_nodes) {
336 if (static_cast<CNetAddr>(pnode->addr) ==
ip) {
346 for (
CNode* pnode : m_nodes) {
347 if (pnode->m_addr_name == addrName) {
357 for (
CNode* pnode : m_nodes) {
358 if (static_cast<CService>(pnode->addr) == addr) {
373 for (
const CNode* pnode : m_nodes) {
374 if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() ==
nonce)
384 struct sockaddr_storage sockaddr_bind;
385 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
386 if (!sock.
GetSockName((
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
387 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
399 if (pszDest ==
nullptr) {
407 LogPrintf(
"Failed to open new connection, already connected\n");
415 Ticks<HoursDouble>(pszDest ? 0h : Now<NodeSeconds>() - addrConnect.
nTime));
418 const uint16_t default_port{pszDest !=
nullptr ?
GetDefaultPort(pszDest) :
422 if (!resolved.empty()) {
426 for (
const auto& r : resolved) {
445 bool connected =
false;
446 std::unique_ptr<Sock> sock;
450 std::unique_ptr<i2p::sam::Session> i2p_transient_session;
454 bool proxyConnectionFailed =
false;
456 if (addrConnect.
IsI2P() && use_proxy) {
460 connected =
m_i2p_sam_session->Connect(addrConnect, conn, proxyConnectionFailed);
464 if (m_unused_i2p_sessions.empty()) {
465 i2p_transient_session =
468 i2p_transient_session.swap(m_unused_i2p_sessions.front());
469 m_unused_i2p_sessions.pop();
472 connected = i2p_transient_session->Connect(addrConnect, conn, proxyConnectionFailed);
476 m_unused_i2p_sessions.emplace(i2p_transient_session.release());
482 sock = std::move(conn.
sock);
485 }
else if (use_proxy) {
501 if (!proxyConnectionFailed) {
512 uint16_t port{default_port};
514 bool proxyConnectionFailed;
516 proxyConnectionFailed);
534 pszDest ? pszDest :
"",
558 m_i2p_sam_session.reset();
577 if (addrLocal.IsValid()) {
578 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToStringAddrPort(), addrLocalIn.
ToStringAddrPort());
580 addrLocal = addrLocalIn;
595 #define X(name) stats.name = name 619 X(mapSendBytesPerMsgType);
624 X(mapRecvBytesPerMsgType);
646 const auto time = GetTime<std::chrono::microseconds>();
648 m_last_recv = std::chrono::duration_cast<std::chrono::seconds>(time);
649 nRecvBytes += msg_bytes.
size();
650 while (msg_bytes.
size() > 0) {
659 bool reject_message{
false};
661 if (reject_message) {
670 auto i = mapRecvBytesPerMsgType.find(
msg.m_type);
671 if (i == mapRecvBytesPerMsgType.end()) {
674 assert(i != mapRecvBytesPerMsgType.end());
675 i->second +=
msg.m_raw_message_size;
704 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
706 memcpy(&hdrbuf[nHdrPos], msg_bytes.
data(), nCopy);
717 catch (
const std::exception&) {
743 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
744 unsigned int nCopy = std::min<unsigned int>(nRemaining, msg_bytes.
size());
746 if (vRecv.size() < nDataPos + nCopy) {
748 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
751 hasher.Write(msg_bytes.
first(nCopy));
752 memcpy(&vRecv[nDataPos], msg_bytes.
data(), nCopy);
762 if (data_hash.IsNull())
763 hasher.Finalize(data_hash);
771 reject_message =
false;
777 msg.m_type = hdr.GetCommand();
779 msg.m_message_size = hdr.nMessageSize;
789 LogPrint(
BCLog::NET,
"Header error: Wrong checksum (%s, %u bytes), expected %s was %s, peer=%d\n",
794 reject_message =
true;
795 }
else if (!hdr.IsCommandValid()) {
798 reject_message =
true;
811 if (m_sending_header || m_bytes_sent < m_message_to_send.data.size())
return false;
821 m_header_to_send.clear();
825 m_message_to_send = std::move(
msg);
826 m_sending_header =
true;
835 if (m_sending_header) {
836 return {
Span{m_header_to_send}.
subspan(m_bytes_sent),
839 have_next_message || !m_message_to_send.data.empty(),
840 m_message_to_send.m_type
843 return {
Span{m_message_to_send.
data}.subspan(m_bytes_sent),
847 m_message_to_send.m_type
856 m_bytes_sent += bytes_sent;
857 if (m_sending_header && m_bytes_sent == m_header_to_send.size()) {
859 m_sending_header =
false;
861 }
else if (!m_sending_header && m_bytes_sent == m_message_to_send.data.size()) {
873 return m_message_to_send.GetMemoryUsage();
883 const std::array<std::string, 33> V2_MESSAGE_IDS = {
922 std::unordered_map<std::string, uint8_t> m_map;
925 V2MessageMap() noexcept
927 for (
size_t i = 1; i < std::size(V2_MESSAGE_IDS); ++i) {
928 m_map.emplace(V2_MESSAGE_IDS[i], i);
932 std::optional<uint8_t> operator()(
const std::string& message_name)
const noexcept
934 auto it = m_map.find(message_name);
935 if (it == m_map.end())
return std::nullopt;
940 const V2MessageMap V2_MESSAGE_MAP;
942 std::vector<uint8_t> GenerateRandomGarbage() noexcept
944 std::vector<uint8_t>
ret;
957 Assume(m_send_buffer.empty());
961 std::copy(m_send_garbage.begin(), m_send_garbage.end(), m_send_buffer.begin() +
EllSwiftPubKey::size());
966 : m_cipher{key, ent32}, m_initiating{initiating}, m_nodeid{nodeid},
967 m_v1_fallback{nodeid},
968 m_recv_state{initiating ?
RecvState::KEY : RecvState::KEY_MAYBE_V1},
969 m_send_garbage{std::move(garbage)},
970 m_send_state{initiating ? SendState::AWAITING_KEY : SendState::MAYBE_V1}
972 Assume(m_send_garbage.size() <= MAX_GARBAGE_LEN);
976 StartSendingHandshake();
988 switch (m_recv_state) {
989 case RecvState::KEY_MAYBE_V1:
993 Assume(recv_state == RecvState::GARB_GARBTERM);
995 case RecvState::GARB_GARBTERM:
999 Assume(recv_state == RecvState::APP);
1001 case RecvState::APP:
1002 Assume(recv_state == RecvState::APP_READY);
1004 case RecvState::APP_READY:
1005 Assume(recv_state == RecvState::APP);
1012 m_recv_state = recv_state;
1019 switch (m_send_state) {
1020 case SendState::MAYBE_V1:
1021 Assume(send_state == SendState::V1 || send_state == SendState::AWAITING_KEY);
1023 case SendState::AWAITING_KEY:
1024 Assume(send_state == SendState::READY);
1026 case SendState::READY:
1032 m_send_state = send_state;
1053 std::array<uint8_t, V1_PREFIX_LEN> v1_prefix = {0, 0, 0, 0,
'v',
'e',
'r',
's',
'i',
'o',
'n', 0, 0, 0, 0, 0};
1054 std::copy(std::begin(
Params().MessageStart()), std::end(
Params().MessageStart()), v1_prefix.begin());
1055 Assume(m_recv_buffer.size() <= v1_prefix.size());
1056 if (!std::equal(m_recv_buffer.begin(), m_recv_buffer.end(), v1_prefix.begin())) {
1063 }
else if (m_recv_buffer.size() == v1_prefix.size()) {
1070 Assume(feedback.empty());
1095 static constexpr std::array<uint8_t, 12> MATCH = {
'v',
'e',
'r',
's',
'i',
'o',
'n', 0, 0, 0, 0, 0};
1096 static constexpr
size_t OFFSET = std::tuple_size_v<MessageStartChars>;
1097 if (!
m_initiating && m_recv_buffer.size() >= OFFSET + MATCH.size()) {
1098 if (std::equal(MATCH.begin(), MATCH.end(), m_recv_buffer.begin() + OFFSET)) {
1116 m_recv_buffer.clear();
1150 m_recv_aad = std::move(m_recv_buffer);
1152 m_recv_buffer.clear();
1178 static constexpr
size_t MAX_CONTENTS_LEN =
1185 if (m_recv_len > MAX_CONTENTS_LEN) {
1193 m_recv_decode_buffer.resize(m_recv_len);
1212 switch (m_recv_state) {
1241 switch (m_recv_state) {
1291 static constexpr
size_t MAX_RESERVE_AHEAD = 256 * 1024;
1294 if (m_recv_state == RecvState::V1)
return m_v1_fallback.ReceivedBytes(msg_bytes);
1300 while (!msg_bytes.empty()) {
1302 size_t max_read = GetMaxBytesToProcess();
1305 if (m_recv_buffer.size() + std::min(msg_bytes.size(), max_read) > m_recv_buffer.capacity()) {
1306 switch (m_recv_state) {
1307 case RecvState::KEY_MAYBE_V1:
1309 case RecvState::GARB_GARBTERM:
1315 case RecvState::APP: {
1321 size_t alloc_add = std::min(max_read, msg_bytes.size() + MAX_RESERVE_AHEAD);
1322 m_recv_buffer.reserve(m_recv_buffer.size() + alloc_add);
1325 case RecvState::APP_READY:
1327 Assume(m_recv_buffer.empty());
1337 max_read = std::min(msg_bytes.size(), max_read);
1339 m_recv_buffer.insert(m_recv_buffer.end(),
UCharCast(msg_bytes.data()),
UCharCast(msg_bytes.data() + max_read));
1340 msg_bytes = msg_bytes.subspan(max_read);
1343 switch (m_recv_state) {
1344 case RecvState::KEY_MAYBE_V1:
1345 ProcessReceivedMaybeV1Bytes();
1346 if (m_recv_state == RecvState::V1)
return true;
1350 if (!ProcessReceivedKeyBytes())
return false;
1353 case RecvState::GARB_GARBTERM:
1354 if (!ProcessReceivedGarbageBytes())
return false;
1358 case RecvState::APP:
1359 if (!ProcessReceivedPacketBytes())
return false;
1362 case RecvState::APP_READY:
1379 if (contents.size() == 0)
return std::nullopt;
1380 uint8_t first_byte = contents[0];
1381 contents = contents.subspan(1);
1383 if (first_byte != 0) {
1385 if (first_byte < std::size(V2_MESSAGE_IDS)) {
1387 return V2_MESSAGE_IDS[first_byte];
1390 return std::nullopt;
1395 return std::nullopt;
1398 size_t msg_type_len{0};
1401 if (contents[msg_type_len] <
' ' || contents[msg_type_len] > 0x7F) {
1406 std::string
ret{
reinterpret_cast<const char*
>(contents.data()), msg_type_len};
1409 if (contents[msg_type_len] != 0)
return {};
1421 if (m_recv_state == RecvState::V1)
return m_v1_fallback.GetReceivedMessage(time, reject_message);
1423 Assume(m_recv_state == RecvState::APP_READY);
1425 auto msg_type = GetMessageType(contents);
1430 reject_message =
false;
1431 msg.m_type = std::move(*msg_type);
1433 msg.m_message_size = contents.size();
1434 msg.m_recv.resize(contents.size());
1435 std::copy(contents.begin(), contents.end(),
UCharCast(
msg.m_recv.data()));
1437 LogPrint(
BCLog::NET,
"V2 transport error: invalid message type (%u bytes contents), peer=%d\n", m_recv_decode_buffer.size(), m_nodeid);
1438 reject_message =
true;
1441 SetReceiveState(RecvState::APP);
1450 if (m_send_state == SendState::V1)
return m_v1_fallback.SetMessageToSend(
msg);
1454 if (!(m_send_state == SendState::READY && m_send_buffer.empty()))
return false;
1456 std::vector<uint8_t> contents;
1457 auto short_message_id = V2_MESSAGE_MAP(
msg.m_type);
1458 if (short_message_id) {
1459 contents.resize(1 +
msg.data.size());
1460 contents[0] = *short_message_id;
1461 std::copy(
msg.data.begin(),
msg.data.end(), contents.begin() + 1);
1466 std::copy(
msg.m_type.begin(),
msg.m_type.end(), contents.data() + 1);
1472 m_send_type =
msg.m_type;
1482 if (m_send_state == SendState::V1)
return m_v1_fallback.GetBytesToSend(have_next_message);
1484 if (m_send_state == SendState::MAYBE_V1)
Assume(m_send_buffer.empty());
1485 Assume(m_send_pos <= m_send_buffer.size());
1490 have_next_message && m_send_state == SendState::READY,
1499 if (m_send_state == SendState::V1)
return m_v1_fallback.MarkBytesSent(bytes_sent);
1501 if (m_send_state == SendState::AWAITING_KEY && m_send_pos == 0 && bytes_sent > 0) {
1505 m_send_pos += bytes_sent;
1506 Assume(m_send_pos <= m_send_buffer.size());
1508 m_sent_v1_header_worth =
true;
1511 if (m_send_pos == m_send_buffer.size()) {
1528 if (!m_recv_buffer.empty())
return false;
1531 return m_sent_v1_header_worth;
1566 auto it =
node.vSendMsg.begin();
1567 size_t nSentSize = 0;
1568 bool data_left{
false};
1569 std::optional<bool> expected_more;
1572 if (it !=
node.vSendMsg.end()) {
1576 size_t memusage = it->GetMemoryUsage();
1577 if (
node.m_transport->SetMessageToSend(*it)) {
1583 const auto& [data, more, msg_type] =
node.m_transport->GetBytesToSend(it !=
node.vSendMsg.end());
1587 if (expected_more.has_value())
Assume(!data.empty() == *expected_more);
1588 expected_more = more;
1589 data_left = !data.empty();
1591 if (!data.empty()) {
1605 nBytes =
node.m_sock->Send(reinterpret_cast<const char*>(data.data()), data.size(),
flags);
1608 node.m_last_send = GetTime<std::chrono::seconds>();
1609 node.nSendBytes += nBytes;
1611 node.m_transport->MarkBytesSent(nBytes);
1613 if (!msg_type.empty()) {
1614 node.AccountForSentBytes(msg_type, nBytes);
1616 nSentSize += nBytes;
1617 if ((
size_t)nBytes != data.size()) {
1627 node.CloseSocketDisconnect();
1636 if (it ==
node.vSendMsg.end()) {
1639 node.vSendMsg.erase(
node.vSendMsg.begin(), it);
1640 return {nSentSize, data_left};
1653 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1658 if (
node->fDisconnect)
1662 .m_connected =
node->m_connected,
1663 .m_min_ping_time =
node->m_min_ping_time,
1664 .m_last_block_time =
node->m_last_block_time,
1665 .m_last_tx_time =
node->m_last_tx_time,
1666 .fRelevantServices =
node->m_has_all_wanted_services,
1667 .m_relay_txs =
node->m_relays_txs.load(),
1668 .fBloomFilter =
node->m_bloom_filter_loaded.load(),
1669 .nKeyedNetGroup =
node->nKeyedNetGroup,
1670 .prefer_evict =
node->m_prefer_evict,
1671 .m_is_local =
node->addr.IsLocal(),
1672 .m_network =
node->ConnectedThroughNetwork(),
1674 .m_conn_type =
node->m_conn_type,
1676 vEvictionCandidates.push_back(candidate);
1679 const std::optional<NodeId> node_id_to_evict =
SelectNodeToEvict(std::move(vEvictionCandidates));
1680 if (!node_id_to_evict) {
1684 for (
CNode* pnode : m_nodes) {
1685 if (pnode->GetId() == *node_id_to_evict) {
1686 LogPrint(
BCLog::NET,
"selected %s connection for eviction peer=%d; disconnecting\n", pnode->ConnectionTypeAsString(), pnode->GetId());
1687 pnode->fDisconnect =
true;
1695 struct sockaddr_storage sockaddr;
1696 socklen_t len =
sizeof(sockaddr);
1697 auto sock = hListenSocket.
sock->Accept((
struct sockaddr*)&sockaddr, &len);
1708 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1740 for (
const CNode* pnode : m_nodes) {
1741 if (pnode->IsInboundConn()) nInbound++;
1750 if (!sock->IsSelectable()) {
1758 if (sock->SetSockOpt(IPPROTO_TCP, TCP_NODELAY, &on,
sizeof(on)) ==
SOCKET_ERROR) {
1759 LogPrint(
BCLog::NET,
"connection from %s: unable to set TCP_NODELAY, continuing anyway\n",
1783 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1812 .prefer_evict = discouraged,
1817 m_msgproc->InitializeNode(*pnode, nodeServices);
1823 m_nodes.push_back(pnode);
1833 std::optional<int> max_connections;
1834 switch (conn_type) {
1854 return std::count_if(m_nodes.begin(), m_nodes.end(), [conn_type](
CNode*
node) {
return node->m_conn_type == conn_type; }););
1857 if (max_connections != std::nullopt && existing_connections >= max_connections)
return false;
1861 if (!grant)
return false;
1874 decltype(m_reconnections) reconnections_to_add;
1881 for (
CNode* pnode : m_nodes) {
1882 if (!pnode->fDisconnect) {
1884 pnode->fDisconnect =
true;
1890 std::vector<CNode*> nodes_copy = m_nodes;
1891 for (
CNode* pnode : nodes_copy)
1893 if (pnode->fDisconnect)
1896 m_nodes.erase(
remove(m_nodes.begin(), m_nodes.end(), pnode), m_nodes.end());
1901 if (pnode->m_transport->ShouldReconnectV1()) {
1902 reconnections_to_add.push_back({
1903 .addr_connect = pnode->addr,
1904 .grant = std::move(pnode->grantOutbound),
1905 .destination = pnode->m_dest,
1906 .conn_type = pnode->m_conn_type,
1907 .use_v2transport =
false});
1908 LogPrint(
BCLog::NET,
"retrying with v1 transport protocol for peer=%d\n", pnode->GetId());
1912 pnode->grantOutbound.Release();
1915 pnode->CloseSocketDisconnect();
1918 if (pnode->IsManualOrFullOutboundConn()) --m_network_conn_counts[pnode->addr.GetNetwork()];
1929 for (
CNode* pnode : nodes_disconnected_copy)
1932 if (pnode->GetRefCount() <= 0) {
1941 m_reconnections.splice(m_reconnections.end(), std::move(reconnections_to_add));
1950 nodes_size = m_nodes.size();
1969 const auto now{GetTime<std::chrono::seconds>()};
1970 const auto last_send{
node.m_last_send.load()};
1971 const auto last_recv{
node.m_last_recv.load()};
1975 if (last_recv.count() == 0 || last_send.count() == 0) {
1990 if (!
node.fSuccessfullyConnected) {
2003 events_per_sock.emplace(hListenSocket.sock,
Sock::Events{Sock::RECV});
2006 for (
CNode* pnode : nodes) {
2007 bool select_recv = !pnode->fPauseRecv;
2010 LOCK(pnode->cs_vSend);
2014 const auto& [to_send, more, _msg_type] = pnode->m_transport->GetBytesToSend(!pnode->vSendMsg.empty());
2015 select_send = !to_send.empty() || more;
2017 if (!select_recv && !select_send)
continue;
2019 LOCK(pnode->m_sock_mutex);
2020 if (pnode->m_sock) {
2022 events_per_sock.emplace(pnode->m_sock,
Sock::Events{event});
2026 return events_per_sock;
2045 if (events_per_sock.empty() || !events_per_sock.begin()->first->WaitMany(timeout, events_per_sock)) {
2062 for (
CNode* pnode : nodes) {
2069 bool recvSet =
false;
2070 bool sendSet =
false;
2071 bool errorSet =
false;
2073 LOCK(pnode->m_sock_mutex);
2074 if (!pnode->m_sock) {
2077 const auto it = events_per_sock.find(pnode->m_sock);
2078 if (it != events_per_sock.end()) {
2081 errorSet = it->second.occurred &
Sock::ERR;
2098 if (data_left) recvSet =
false;
2102 if (recvSet || errorSet)
2105 uint8_t pchBuf[0x10000];
2108 LOCK(pnode->m_sock_mutex);
2109 if (!pnode->m_sock) {
2112 nBytes = pnode->m_sock->Recv(pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
2116 bool notify =
false;
2117 if (!pnode->ReceiveMsgBytes({pchBuf, (size_t)nBytes}, notify)) {
2118 pnode->CloseSocketDisconnect();
2122 pnode->MarkReceivedMsgsForProcessing();
2126 else if (nBytes == 0)
2129 if (!pnode->fDisconnect) {
2132 pnode->CloseSocketDisconnect();
2134 else if (nBytes < 0)
2140 if (!pnode->fDisconnect) {
2143 pnode->CloseSocketDisconnect();
2158 const auto it = events_per_sock.find(listen_socket.sock);
2159 if (it != events_per_sock.end() && it->second.occurred &
Sock::RECV) {
2181 fMsgProcWake =
true;
2190 Shuffle(seeds.begin(), seeds.end(), rng);
2191 int seeds_right_now = 0;
2196 seeds_right_now = seeds.size();
2201 seeds_right_now = seeds.size();
2218 for (
const std::string& seed : seeds) {
2219 if (seeds_right_now == 0) {
2223 LogPrintf(
"Waiting %d seconds before querying DNS seeds.\n", seeds_wait_time.count());
2224 std::chrono::seconds to_wait = seeds_wait_time;
2225 while (to_wait.count() > 0) {
2236 for (
const CNode* pnode : m_nodes) {
2237 if (pnode->fSuccessfullyConnected && pnode->IsFullOutboundConn()) ++nRelevant;
2240 if (nRelevant >= 2) {
2242 LogPrintf(
"%d addresses found from DNS seeds\n", found);
2243 LogPrintf(
"P2P peers available. Finished DNS seeding.\n");
2245 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
2257 LogPrintf(
"Waiting for network to be reactivated before querying DNS seeds.\n");
2263 LogPrintf(
"Loading addresses from DNS seed %s\n", seed);
2269 std::vector<CAddress> vAdd;
2271 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
2276 unsigned int nMaxIPs = 256;
2277 const auto addresses{
LookupHost(host, nMaxIPs,
true)};
2278 if (!addresses.empty()) {
2282 vAdd.push_back(addr);
2295 LogPrintf(
"%d addresses found from DNS seeds\n", found);
2300 const auto start{SteadyClock::now()};
2305 addrman.
Size(), Ticks<std::chrono::milliseconds>(SteadyClock::now() - start));
2311 std::string strDest;
2314 if (m_addr_fetches.empty())
2316 strDest = m_addr_fetches.front();
2317 m_addr_fetches.pop_front();
2337 LogPrint(
BCLog::NET,
"setting try another outbound peer=%s\n", flag ?
"true" :
"false");
2354 int full_outbound_peers = 0;
2357 for (
const CNode* pnode : m_nodes) {
2358 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsFullOutboundConn()) {
2359 ++full_outbound_peers;
2368 int block_relay_peers = 0;
2371 for (
const CNode* pnode : m_nodes) {
2372 if (pnode->fSuccessfullyConnected && !pnode->fDisconnect && pnode->IsBlockOnlyConn()) {
2373 ++block_relay_peers;
2382 std::unordered_set<Network> networks{};
2383 for (
int n = 0; n <
NET_MAX; n++) {
2387 networks.insert(net);
2396 return m_network_conn_counts[net] > 1;
2405 for (
const auto net : nets) {
2421 if (!connect.empty())
2426 for (int64_t nLoop = 0;; nLoop++)
2428 for (
const std::string& strAddr : connect)
2432 for (
int i = 0; i < 10 && i < nLoop; i++)
2445 auto start = GetTime<std::chrono::microseconds>();
2455 if (!add_fixed_seeds) {
2456 LogPrintf(
"Fixed seeds are disabled\n");
2473 if (add_fixed_seeds && !fixed_seed_networks.empty()) {
2478 bool add_fixed_seeds_now =
false;
2480 if (GetTime<std::chrono::seconds>() > start + std::chrono::minutes{1}) {
2481 add_fixed_seeds_now =
true;
2482 LogPrintf(
"Adding fixed seeds as 60 seconds have passed and addrman is empty for at least one reachable network\n");
2486 else if (!dnsseed && !use_seednodes) {
2488 if (m_added_node_params.empty()) {
2489 add_fixed_seeds_now =
true;
2490 LogPrintf(
"Adding fixed seeds as -dnsseed=0 (or IPv4/IPv6 connections are disabled via -onlynet) and neither -addnode nor -seednode are provided\n");
2494 if (add_fixed_seeds_now) {
2502 seed_addrs.erase(std::remove_if(seed_addrs.begin(), seed_addrs.end(),
2503 [&fixed_seed_networks](
const CAddress& addr) {
return fixed_seed_networks.count(addr.GetNetwork()) == 0; }),
2508 add_fixed_seeds =
false;
2509 LogPrintf(
"Added %d fixed seeds from reachable networks.\n", seed_addrs.size());
2519 int nOutboundFullRelay = 0;
2520 int nOutboundBlockRelay = 0;
2521 int outbound_privacy_network_peers = 0;
2522 std::set<std::vector<unsigned char>> outbound_ipv46_peer_netgroups;
2526 for (
const CNode* pnode : m_nodes) {
2527 if (pnode->IsFullOutboundConn()) nOutboundFullRelay++;
2528 if (pnode->IsBlockOnlyConn()) nOutboundBlockRelay++;
2531 switch (pnode->m_conn_type) {
2544 const CAddress address{pnode->addr};
2545 if (address.IsTor() || address.IsI2P() || address.IsCJDNS()) {
2553 ++outbound_privacy_network_peers;
2562 auto now = GetTime<std::chrono::microseconds>();
2563 bool anchor =
false;
2564 bool fFeeler =
false;
2565 std::optional<Network> preferred_net;
2611 }
else if (now > next_feeler) {
2617 now > next_extra_network_peer &&
2682 std::tie(addr, addr_last_try) =
addrman.
Select(
false, preferred_net);
2700 if (current_time - addr_last_try < 10min && nTries < 30) {
2723 preferred_net.has_value() ?
"network-specific " :
"",
2748 const bool count_failures{((int)outbound_ipv46_peer_netgroups.size() + outbound_privacy_network_peers) >= std::min(
m_max_automatic_connections - 1, 2)};
2758 std::vector<CAddress>
ret;
2760 for (
const CNode* pnode : m_nodes) {
2761 if (pnode->IsBlockOnlyConn()) {
2762 ret.push_back(pnode->addr);
2771 std::vector<AddedNodeInfo>
ret;
2773 std::list<AddedNodeParams> lAddresses(0);
2776 ret.reserve(m_added_node_params.size());
2777 std::copy(m_added_node_params.cbegin(), m_added_node_params.cend(), std::back_inserter(lAddresses));
2782 std::map<CService, bool> mapConnected;
2783 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
2786 for (
const CNode* pnode : m_nodes) {
2787 if (pnode->addr.IsValid()) {
2788 mapConnected[pnode->addr] = pnode->IsInboundConn();
2790 std::string addrName{pnode->m_addr_name};
2791 if (!addrName.empty()) {
2792 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->IsInboundConn(),
static_cast<const CService&
>(pnode->addr));
2797 for (
const auto& addr : lAddresses) {
2800 if (service.IsValid()) {
2802 auto it = mapConnected.find(service);
2803 if (it != mapConnected.end()) {
2804 if (!include_connected) {
2807 addedNode.resolvedAddress = service;
2808 addedNode.fConnected =
true;
2809 addedNode.fInbound = it->second;
2813 auto it = mapConnectedByName.find(addr.m_added_node);
2814 if (it != mapConnectedByName.end()) {
2815 if (!include_connected) {
2818 addedNode.resolvedAddress = it->second.second;
2819 addedNode.fConnected =
true;
2820 addedNode.fInbound = it->second.first;
2823 ret.emplace_back(std::move(addedNode));
2874 bool banned_or_discouraged =
m_banman && (
m_banman->IsDiscouraged(addrConnect) ||
m_banman->IsBanned(addrConnect));
2878 }
else if (
FindNode(std::string(pszDest)))
2890 m_nodes.push_back(pnode);
2905 bool fMoreWork =
false;
2913 for (
CNode* pnode : snap.Nodes()) {
2914 if (pnode->fDisconnect)
2919 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2934 fMsgProcWake =
false;
2940 static constexpr
auto err_wait_begin = 1s;
2941 static constexpr
auto err_wait_cap = 5min;
2942 auto err_wait = err_wait_begin;
2944 bool advertising_listen_addr =
false;
2947 auto SleepOnFailure = [&]() {
2949 if (err_wait < err_wait_cap) {
2957 if (advertising_listen_addr && conn.
me.
IsValid()) {
2959 advertising_listen_addr =
false;
2965 if (!advertising_listen_addr) {
2967 advertising_listen_addr =
true;
2978 err_wait = err_wait_begin;
2987 struct sockaddr_storage sockaddr;
2988 socklen_t len =
sizeof(sockaddr);
2989 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2996 std::unique_ptr<Sock> sock =
CreateSock(addrBind);
3020 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
3021 if (sock->SetSockOpt(IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int)) ==
SOCKET_ERROR) {
3028 if (sock->Bind(reinterpret_cast<struct sockaddr*>(&sockaddr), len) ==
SOCKET_ERROR) {
3058 char pszHostName[256] =
"";
3059 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
3061 const std::vector<CNetAddr> addresses{
LookupHost(pszHostName, 0,
true)};
3062 for (
const CNetAddr& addr : addresses)
3065 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToStringAddr());
3068 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) 3070 struct ifaddrs* myaddrs;
3071 if (getifaddrs(&myaddrs) == 0)
3073 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
3075 if (ifa->ifa_addr ==
nullptr)
continue;
3076 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
3077 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
3078 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
3079 if (ifa->ifa_addr->sa_family == AF_INET)
3081 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
3086 else if (ifa->ifa_addr->sa_family == AF_INET6)
3088 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
3094 freeifaddrs(myaddrs);
3101 LogPrintf(
"%s: %s\n", __func__, active);
3116 : addrman(addrman_in)
3117 , m_netgroupman{netgroupman}
3122 SetTryNewOutboundPeer(
false);
3124 Options connOptions;
3126 SetNetworkActive(network_active);
3131 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
3166 bool fBound =
false;
3167 for (
const auto& addrBind : options.
vBinds) {
3170 for (
const auto& addrBind : options.
vWhiteBinds) {
3173 for (
const auto& addr_bind : options.
onion_binds) {
3177 struct in_addr inaddr_any;
3178 inaddr_any.s_addr = htonl(INADDR_ANY);
3179 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
3194 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
3206 for (
const auto& strDest : connOptions.
vSeedNodes) {
3216 LogPrintf(
"%i block-relay-only anchors will be tried for connections.\n",
m_anchors.size());
3243 fMsgProcWake =
false;
3260 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same time."),
3364 std::vector<CNode*> nodes;
3366 for (
CNode* pnode : nodes) {
3367 pnode->CloseSocketDisconnect();
3393 std::vector<CAddress>
CConnman::GetAddresses(
size_t max_addresses,
size_t max_pct, std::optional<Network> network,
const bool filtered)
const 3395 std::vector<CAddress> addresses =
addrman.
GetAddr(max_addresses, max_pct, network, filtered);
3397 addresses.erase(std::remove_if(addresses.begin(), addresses.end(),
3409 .Write(local_socket_bytes)
3414 const auto current_time = GetTime<std::chrono::microseconds>();
3451 const bool resolved_is_valid{resolved.
IsValid()};
3454 for (
const auto& it : m_added_node_params) {
3458 m_added_node_params.push_back(add);
3465 for (
auto it = m_added_node_params.begin(); it != m_added_node_params.end(); ++it) {
3466 if (strNode == it->m_added_node) {
3467 m_added_node_params.erase(it);
3480 return (m_added_node_params.size() < 24
3481 && std::any_of(m_added_node_params.cbegin(), m_added_node_params.cend(),
3482 [&](
const auto& p) {
return p.m_added_node == addr_str || p.m_added_node == addr_port_str; }));
3489 return m_nodes.size();
3492 for (
const auto& pnode : m_nodes) {
3510 vstats.reserve(m_nodes.size());
3511 for (
CNode* pnode : m_nodes) {
3512 vstats.emplace_back();
3513 pnode->CopyStats(vstats.back());
3514 vstats.back().m_mapped_as =
GetMappedAS(pnode->addr);
3523 pnode->fDisconnect =
true;
3531 bool disconnected =
false;
3533 for (
CNode* pnode : m_nodes) {
3534 if (subnet.
Match(pnode->addr)) {
3536 pnode->fDisconnect =
true;
3537 disconnected =
true;
3540 return disconnected;
3551 for(
CNode* pnode : m_nodes) {
3552 if (
id == pnode->GetId()) {
3554 pnode->fDisconnect =
true;
3571 nTotalBytesSent += bytes;
3573 const auto now = GetTime<std::chrono::seconds>();
3577 nMaxOutboundCycleStartTime = now;
3578 nMaxOutboundTotalBytesSentInCycle = 0;
3581 nMaxOutboundTotalBytesSentInCycle += bytes;
3610 if (nMaxOutboundCycleStartTime.count() == 0)
3614 const auto now = GetTime<std::chrono::seconds>();
3615 return (cycleEndTime < now) ? 0s : cycleEndTime - now;
3625 if (historicalBlockServingLimit)
3658 return nTotalBytesSent;
3668 if (use_v2transport) {
3669 return std::make_unique<V2Transport>(id, !inbound);
3671 return std::make_unique<V1Transport>(id);
3676 std::shared_ptr<Sock> sock,
3678 uint64_t nKeyedNetGroupIn,
3679 uint64_t nLocalHostNonceIn,
3681 const std::string& addrNameIn,
3686 m_permission_flags{node_opts.permission_flags},
3688 m_connected{GetTime<std::chrono::seconds>()},
3690 addrBind{addrBindIn},
3691 m_addr_name{addrNameIn.empty() ? addr.ToStringAddrPort() : addrNameIn},
3693 m_inbound_onion{inbound_onion},
3694 m_prefer_evict{node_opts.prefer_evict},
3695 nKeyedNetGroup{nKeyedNetGroupIn},
3696 m_conn_type{conn_type_in},
3698 nLocalHostNonce{nLocalHostNonceIn},
3699 m_recv_flood_size{node_opts.recv_flood_size},
3700 m_i2p_sam_session{std::move(node_opts.i2p_sam_session)}
3705 mapRecvBytesPerMsgType[
msg] = 0;
3719 size_t nSizeAdded = 0;
3723 nSizeAdded +=
msg.m_raw_message_size;
3727 m_msg_process_queue.splice(m_msg_process_queue.end(),
vRecvMsg);
3728 m_msg_process_queue_size += nSizeAdded;
3735 if (m_msg_process_queue.empty())
return std::nullopt;
3737 std::list<CNetMessage> msgs;
3739 msgs.splice(msgs.begin(), m_msg_process_queue, m_msg_process_queue.begin());
3740 m_msg_process_queue_size -= msgs.front().m_raw_message_size;
3743 return std::make_pair(std::move(msgs.front()), !m_msg_process_queue.empty());
3754 size_t nMessageSize =
msg.data.size();
3760 TRACE6(net, outbound_message,
3769 size_t nBytesSent = 0;
3774 const auto& [to_send, more, _msg_type] =
3776 const bool queue_was_empty{to_send.empty() && pnode->vSendMsg.empty()};
3779 pnode->m_send_memusage +=
msg.GetMemoryUsage();
3782 pnode->vSendMsg.push_back(std::move(
msg));
3791 if (queue_was_empty && more) {
3800 CNode* found =
nullptr;
3802 for (
auto&& pnode : m_nodes) {
3803 if(pnode->
GetId() == id) {
3829 decltype(m_reconnections) todo;
3832 if (m_reconnections.empty())
break;
3833 todo.splice(todo.end(), m_reconnections, m_reconnections.begin());
3836 auto& item = *todo.begin();
3843 std::move(item.grant),
3844 item.destination.empty() ? nullptr : item.destination.c_str(),
3846 item.use_v2transport);
3854 std::vector<CNetAddr> clearnet_addrs;
3855 clearnet_addrs.reserve(v4_addrs.size() + v6_addrs.size());
3856 std::transform(v4_addrs.begin(), v4_addrs.end(), std::back_inserter(clearnet_addrs),
3858 std::transform(v6_addrs.begin(), v6_addrs.end(), std::back_inserter(clearnet_addrs),
3865 const std::string& msg_type,
3873 auto now = GetTime<std::chrono::microseconds>();
3877 std::replace(clean_addr.begin(), clean_addr.end(),
':',
'_');
3882 fs::path path = base_path / (is_incoming ?
"msgs_recv.dat" :
"msgs_sent.dat");
3886 f <<
Span{msg_type};
3890 uint32_t size = data.
size();
3895 std::function<void(
const CAddress& addr,
3896 const std::string& msg_type,
const std::vector< std::string > & DNSSeeds() const
Return the list of hostnames to look up for DNS seeds.
const char * GETCFILTERS
getcfilters requests compact filters for a range of blocks.
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
Wrapper that overrides the GetParams() function of a stream (and hides GetVersion/GetType).
bool RemoveAddedNode(const std::string &node) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
std::vector< CService > vBinds
std::atomic< bool > flagInterruptMsgProc
std::vector< unsigned char > GetGroup(const CNetAddr &address) const
Get the canonical identifier of the network group for address.
Span< const std::byte > GetSendGarbageTerminator() const noexcept
Get the Garbage Terminator to send.
std::vector< CAddress > m_addrs_response_cache
static const int MAX_BLOCK_RELAY_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
const char * PING
The ping message is sent periodically to help confirm that the receiving peer is still connected...
CONSTEXPR_IF_NOT_DEBUG Span< C > first(std::size_t count) const noexcept
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
Mutex m_send_mutex
Lock for sending state.
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
size_t Size(std::optional< Network > net=std::nullopt, std::optional< bool > in_new=std::nullopt) const
Return size information about addrman.
static constexpr auto FEELER_SLEEP_WINDOW
const uint256 & GetMessageHash() const EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
void RandAddEvent(const uint32_t event_info) noexcept
Gathers entropy from the low bits of the time at which events occur.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
const char * FILTERLOAD
The filterload message tells the receiving peer to filter all relayed transactions and requested merk...
const char * MERKLEBLOCK
The merkleblock message is a reply to a getdata message which requested a block using the inventory t...
std::atomic_bool fPauseSend
AddrFetch connections are short lived connections used to solicit addresses from peers.
static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH
Maximum length of incoming protocol messages (no message over 4 MB is currently acceptable).
BIP324Cipher m_cipher
Cipher state.
bool m_i2p_accept_incoming
const char * BLOCKTXN
Contains a BlockTransactions.
void ThreadDNSAddressSeed() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
std::atomic< bool > fNetworkActive
bool ProcessReceivedKeyBytes() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex
Process bytes in m_recv_buffer, while in KEY state.
size_t GetSendMemoryUsage() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Return the memory usage of this transport attributable to buffered data to send.
static void AddFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ServiceFlags
nServices flags
std::optional< std::pair< CNetMessage, bool > > PollMessage() EXCLUSIVE_LOCKS_REQUIRED(!m_msg_process_queue_mutex)
Poll the next message from the processing queue of this connection.
bool AddedNodesContain(const CAddress &addr) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Info GetInfo() const noexcept override
Retrieve information about this transport.
#define LogPrint(category,...)
Inbound connections are those initiated by a peer.
FILE * fopen(const fs::path &p, const char *mode)
A set of addresses that represent the hash of a string or FQDN.
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 ...
Dummy value to indicate the number of NET_* constants.
constexpr C * end() const noexcept
void SocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Check connected and listening sockets for IO readiness and process them accordingly.
Unencrypted, plaintext protocol.
NetPermissionFlags permission_flags
bool Bind(const CService &addr, unsigned int flags, NetPermissionFlags permissions)
bool OutboundTargetReached(bool historicalBlockServingLimit) const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
check if the outbound target is reached if param historicalBlockServingLimit is set true...
Feeler connections are short-lived connections made to check that a node is alive.
Mutex m_total_bytes_sent_mutex
void ASMapHealthCheck(const std::vector< CNetAddr > &clearnet_addrs) const
Analyze and log current health of ASMap based buckets.
std::shared_ptr< Sock > sock
std::list< CNode * > m_nodes_disconnected
void ser_writedata64(Stream &s, uint64_t obj)
void MarkBytesSent(size_t bytes_sent) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Report how many bytes returned by the last GetBytesToSend() have been sent.
bool SplitHostPort(std::string_view in, uint16_t &portOut, std::string &hostOut)
Splits socket address string into host string and port value.
bool sleep_for(Clock::duration rel_time) EXCLUSIVE_LOCKS_REQUIRED(!mut)
static constexpr size_t MAX_UNUSED_I2P_SESSIONS_SIZE
Cap on the size of m_unused_i2p_sessions, to ensure it does not unexpectedly use too much memory...
void SetReceiveState(RecvState recv_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
Change the receive state.
CService GetLocalAddress(const CNode &peer)
const std::chrono::seconds m_connected
Unix epoch time at peer connection.
BytesToSend GetBytesToSend(bool have_next_message) const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Get bytes to send on the wire, if any, along with other information about it.
static size_t DynamicUsage(const int8_t &v)
Dynamic memory usage for built-in types is zero.
static void ClearFlag(NetPermissionFlags &flags, NetPermissionFlags f)
ClearFlag is only called with f == NetPermissionFlags::Implicit.
bool SetMessageToSend(CSerializedNetMsg &msg) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Set the next message to send.
const std::string NET_MESSAGE_TYPE_OTHER
std::vector< unsigned char > data
static constexpr size_t size()
uint256 GetRandHash() noexcept
Nothing (this transport is using v1 fallback).
const ConnectionType m_conn_type
const char * SENDCMPCT
Contains a 1-byte bool and 8-byte LE version number.
uint64_t GetTotalBytesRecv() const
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
std::unordered_set< Network > GetReachableEmptyNetworks() const
Return reachable networks for which we have no addresses in addrman and therefore may require loadin...
constexpr auto GetRandMillis
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
std::vector< CAddress > GetAddresses(size_t max_addresses, size_t max_pct, std::optional< Network > network, const bool filtered=true) const
Return all or many randomly selected addresses, optionally by network.
bool GetProxy(enum Network net, Proxy &proxyInfoOut)
bool ConnectThroughProxy(const Proxy &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...
std::vector< AddedNodeInfo > GetAddedNodeInfo(bool include_connected) const EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
std::vector< CAddress > GetAddr(size_t max_addresses, size_t max_pct, std::optional< Network > network, const bool filtered=true) const
Return all or many randomly selected addresses, optionally by network.
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 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
static constexpr SerParams V2_NETWORK
const char * CFHEADERS
cfheaders is a response to a getcfheaders request containing a filter header and a vector of filter h...
RAII-style semaphore lock.
void Interrupt() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
V1Transport(const NodeId node_id) noexcept
CService me
Our I2P address.
bool BindListenPort(const CService &bindAddr, bilingual_str &strError, NetPermissionFlags permissions)
static constexpr uint32_t MAX_GARBAGE_LEN
bool DumpPeerAddresses(const ArgsManager &args, const AddrMan &addr)
static const unsigned char VERSION[]
void Initialize(const EllSwiftPubKey &their_pubkey, bool initiator, bool self_decrypt=false) noexcept
Initialize when the other side's public key is received.
const NodeId m_nodeid
NodeId (for debug logging).
void Discover()
Look up IP addresses from all interfaces on the machine and add them to the list of local addresses t...
bool ProcessReceivedPacketBytes() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
Process bytes in m_recv_buffer, while in VERSION/APP state.
unsigned DecryptLength(Span< const std::byte > input) noexcept
Decrypt the length of a packet.
bool Contains(Network net) const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
bool IsConnectedThroughPrivacyNet() const
Whether this peer connected through a privacy network.
void DisconnectNodes() EXCLUSIVE_LOCKS_REQUIRED(!m_reconnections_mutex
std::chrono::seconds GetMaxOutboundTimeLeftInCycle_() const EXCLUSIVE_LOCKS_REQUIRED(m_total_bytes_sent_mutex)
returns the time left in the current max outbound cycle in case of no limit, it will always return 0 ...
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SetTryNewOutboundPeer(bool flag)
CService MaybeFlipIPv6toCJDNS(const CService &service)
If an IPv6 address belongs to the address range used by the CJDNS network and the CJDNS network is re...
size_t GetMemoryUsage() const noexcept
Compute total memory usage of this object (own memory + any dynamic memory).
bool SetSpecial(const std::string &addr)
Parse a Tor or I2P address and set this object to it.
void RecordBytesSent(uint64_t bytes) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
bool IsPrivacyNet() const
Whether this object is a privacy network.
static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE
bool SeenLocal(const CService &addr)
vote for a local address
An established connection with another peer.
Network GetNetClass() const
size_t GetMaxBytesToProcess() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
Determine how many received bytes can be processed in one go (not allowed in V1 state).
m_max_outbound_block_relay
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.
static std::optional< CService > GetLocal(const CNode &peer)
const char * CFILTER
cfilter is a response to a getcfilters request containing a single compact filter.
V1Transport m_v1_fallback
Encapsulate a V1Transport to fall back to.
static std::vector< CAddress > ConvertSeeds(const std::vector< uint8_t > &vSeedsIn)
Convert the serialized seeds into usable address objects.
These are the default connections that we use to connect with the network.
const char * PONG
The pong message replies to a ping message, proving to the pinging node that the ponging node is stil...
void GetNodeStats(std::vector< CNodeStats > &vstats) const
Non-refcounted RAII wrapper for FILE*.
bool MultipleManualOrFullOutboundConns(Network net) const EXCLUSIVE_LOCKS_REQUIRED(m_nodes_mutex)
#define WSAGetLastError()
static constexpr std::chrono::minutes TIMEOUT_INTERVAL
Time after which to disconnect, after waiting for a ping response (or inactivity).
std::list< CNetMessage > vRecvMsg
bool GetTryNewOutboundPeer() const
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
BytesToSend GetBytesToSend(bool have_next_message) const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Get bytes to send on the wire, if any, along with other information about it.
const char * HEADERS
The headers message sends one or more block headers to a node which previously requested certain head...
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
const char * GETCFCHECKPT
getcfcheckpt requests evenly spaced compact filter headers, enabling parallelized download and valida...
std::string ToStringAddrPort() const
SendState
State type that controls the sender side.
std::map< uint64_t, CachedAddrResponse > m_addr_response_caches
Addr responses stored in different caches per (network, local socket) prevent cross-network node iden...
void Init(const Options &connOptions) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
uint64_t GetMaxOutboundTarget() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
void ProcessAddrFetch() EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
static constexpr Event SEND
If passed to Wait(), then it will wait for readiness to send to the socket.
static bool HasFlag(NetPermissionFlags flags, NetPermissionFlags f)
const char * INV
The inv message (inventory message) transmits one or more inventories of objects known to the transmi...
Stochastic address manager.
void AddSocketPermissionFlags(NetPermissionFlags &flags) const
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
uint16_t GetDefaultPort() const
bool ReceivedMessageComplete() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Returns true if the current message is complete (so GetReceivedMessage can be called).
constexpr unsigned char * begin()
std::string ToStringAddr() const
bool ReceiveMsgBytes(Span< const uint8_t > msg_bytes, bool &complete) EXCLUSIVE_LOCKS_REQUIRED(!cs_vRecv)
Receive bytes from the buffer and deserialize them into messages.
Mutex m_unused_i2p_sessions_mutex
Mutex protecting m_i2p_sam_sessions.
bool DisconnectNode(const std::string &node)
static constexpr int DNSSEEDS_DELAY_PEER_THRESHOLD
std::function< void(const CAddress &addr, const std::string &msg_type, Span< const unsigned char > data, bool is_incoming)> CaptureMessage
Defaults to CaptureMessageToFile(), but can be overridden by unit tests.
CKey GenerateRandomKey(bool compressed) noexcept
int GetExtraBlockRelayCount() const
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
TransportProtocolType m_transport_type
Transport protocol type.
void RecordBytesRecv(uint64_t bytes)
std::string SanitizeString(std::string_view str, int rule)
Remove unsafe chars.
std::chrono::steady_clock Clock
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
static constexpr auto EXTRA_NETWORK_PEER_INTERVAL
Frequency to attempt extra connections to reachable networks we're not connected to yet...
std::thread threadI2PAcceptIncoming
std::tuple< Span< const uint8_t >, bool, const std::string &> BytesToSend
Return type for GetBytesToSend, consisting of:
bool CompleteInternal() const noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
bool IsBadPort(uint16_t port)
Determine if a port is "bad" from the perspective of attempting to connect to a node on that port...
void SetAddrLocal(const CService &addrLocalIn) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
May not be called more than once.
Span< const std::byte > GetSessionID() const noexcept
Get the Session ID.
const char * GETHEADERS
The getheaders message requests a headers message that provides block headers starting from a particu...
std::optional< CService > GetLocalAddrForPeer(CNode &node)
Returns a local address that we should advertise to this peer.
std::optional< uint256 > session_id
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
bool Add(const std::vector< CAddress > &vAddr, const CNetAddr &source, std::chrono::seconds time_penalty=0s)
Attempt to add one or more addresses to addrman's new table.
static constexpr uint16_t I2P_SAM31_PORT
SAM 3.1 and earlier do not support specifying ports and force the port to 0.
std::chrono::microseconds m_cache_entry_expiration
static bool NodeFullyConnected(const CNode *pnode)
unsigned int nPrevNodeCount
bool UsingASMap() const
Indicates whether ASMap is being used for clearnet bucketing.
static constexpr unsigned GARBAGE_TERMINATOR_LEN
static const uint64_t RANDOMIZER_ID_NETGROUP
bool InactivityCheck(const CNode &node) const
Return true if the peer is inactive and should be disconnected.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::condition_variable condMsgProc
std::atomic_bool m_start_extra_block_relay_peers
flag for initiating extra block-relay-only peer connections.
const std::unique_ptr< Transport > m_transport
Transport serializer/deserializer.
constexpr ServiceFlags SeedsServiceFlags()
State independent service flags.
bool ConnectSocketDirectly(const CService &addrConnect, const Sock &sock, int nTimeout, bool manual_connection)
Try to connect to the specified service on the specified socket.
bool IsManualOrFullOutboundConn() const
const EllSwiftPubKey & GetOurPubKey() const noexcept
Retrieve our public key.
Mutex m_added_nodes_mutex
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
Return a timestamp in the future sampled from an exponential distribution (https://en.wikipedia.org/wiki/Exponential_distribution).
bool ShouldReconnectV1() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex
Whether upon disconnections, a reconnect with V1 is warranted.
static std::unique_ptr< Transport > MakeTransport(NodeId id, bool use_v2transport, bool inbound) noexcept
std::vector< CNetAddr > LookupHost(const std::string &name, unsigned int nMaxSolutions, bool fAllowLookup, DNSLookupFn dns_lookup_function)
Resolve a host string to its corresponding network addresses.
std::thread threadOpenAddedConnections
std::string ConnectionTypeAsString(ConnectionType conn_type)
Convert ConnectionType enum to a string value.
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
Obtain the IPv4/6 socket address this represents.
void PerformReconnections() EXCLUSIVE_LOCKS_REQUIRED(!m_reconnections_mutex
Attempt reconnections, if m_reconnections non-empty.
std::vector< CAddress > ReadAnchors(const fs::path &anchors_db_path)
Read the anchor IP address database (anchors.dat)
void StartExtraBlockRelayPeers()
Double ended buffer combining vector and stream-like interfaces.
CNode * FindNode(const CNetAddr &ip)
const char * ADDRV2
The addrv2 message relays connection information for peers on the network just like the addr message...
ServiceFlags GetLocalServices() const
Used to convey which local services we are offering peers during node connection. ...
bilingual_str _(const char *psz)
Translation function.
bool AddLocal(const CService &addr_, int nScore)
void fillrand(Span< std::byte > output)
Fill a byte Span with random bytes.
void SocketHandlerListening(const Sock::EventsPerSock &events_per_sock)
Accept incoming connections, one from each read-ready listening socket.
TransportProtocolType transport_type
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.
Transport protocol agnostic message container.
std::vector< std::string > vSeedNodes
std::vector< std::string > m_specified_outgoing
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant &&grant_outbound, const char *strDest, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
void SetSendState(SendState send_state) noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex)
Change the send state.
const char * MEMPOOL
The mempool message requests the TXIDs of transactions that the receiving node has verified as valid ...
std::unique_ptr< CSemaphore > semOutbound
std::thread threadMessageHandler
void Attempt(const CService &addr, bool fCountFailure, NodeSeconds time=Now< NodeSeconds >())
Mark an entry as connection attempted to.
An ElligatorSwift-encoded public key.
int GetExtraFullOutboundCount() const
A CService with information about it as peer.
std::vector< CAddress > GetCurrentBlockRelayOnlyConns() const
Return vector of current BLOCK_RELAY peers.
static int GetnScore(const CService &addr)
const std::vector< std::string > & getAllNetMessageTypes()
static constexpr bool DEFAULT_FIXEDSEEDS
void ClearShrink(V &v) noexcept
Clear a vector (or std::deque) and release its allocated memory.
uint32_t GetMappedAS(const CNetAddr &address) const
Get the autonomous system on the BGP path to address.
static bool IsPeerAddrLocalGood(CNode *pnode)
#define LogPrintLevel(category, level,...)
static CService ip(uint32_t i)
Do not call AddLocal() for our special addresses, e.g., for incoming Tor connections, to prevent gossiping them over the network.
int readData(Span< const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
const char * ADDR
The addr (IP address) message relays connection information for peers on 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...
bool ReceivedBytes(Span< const uint8_t > &msg_bytes) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex
Feed wire bytes to the transport.
(Responder only) either v2 public key or v1 header.
bool InitBinds(const Options &options)
void SetNetworkActive(bool active)
#define WAIT_LOCK(cs, name)
CThreadInterrupt g_socks5_interrupt
Interrupt SOCKS5 reads or writes.
static constexpr bool DEFAULT_DNSSEED
const CChainParams & m_params
Mutex m_recv_mutex
Lock for receive state.
const bool m_initiating
Whether we are the initiator side.
static void CaptureMessageToFile(const CAddress &addr, const std::string &msg_type, Span< const unsigned char > data, bool is_incoming)
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
const char * FILTERCLEAR
The filterclear message tells the receiving peer to remove a previously-set bloom filter...
std::atomic< bool > m_bip152_highbandwidth_to
const NetPermissionFlags m_permission_flags
const char * NOTFOUND
The notfound message is a reply to a getdata message which requested an object the receiving node doe...
NodeSeconds nTime
Always included in serialization. The behavior is unspecified if the value is not representable as ui...
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
bool SetMessageToSend(CSerializedNetMsg &msg) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Set the next message to send.
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.
void ProcessReceivedMaybeV1Bytes() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex
Process bytes in m_recv_buffer, while in KEY_MAYBE_V1 state.
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
const char * BLOCK
The block message transmits a single serialized block.
std::atomic_bool fDisconnect
void CreateNodeFromAcceptedSocket(std::unique_ptr< Sock > &&sock, NetPermissionFlags permission_flags, 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 m_nodes membe...
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
void AddAddrFetch(const std::string &strDest) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex)
const char * FEEFILTER
The feefilter message tells the receiving peer not to inv us any txs which do not meet the specified ...
const char * GETCFHEADERS
getcfheaders requests a compact filter header and the filter hashes for a range of blocks...
std::atomic< std::chrono::seconds > m_last_tx_time
UNIX epoch time of the last transaction received from this peer that we had not yet seen (e...
NetPermissionFlags m_flags
const bool use_v2transport(GetLocalServices() &NODE_P2P_V2)
static constexpr size_t MAX_BLOCK_RELAY_ONLY_ANCHORS
Maximum number of block-relay-only anchor connections.
Waiting for the other side's public key.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define Assume(val)
Assume is the identity function.
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
RecursiveMutex m_nodes_mutex
const size_t m_recv_flood_size
static bool MayHaveUsefulAddressDB(ServiceFlags services)
Checks if a peer with the given service flags may be capable of having a robust address-storage DB...
bool Decrypt(Span< const std::byte > input, Span< const std::byte > aad, bool &ignore, Span< std::byte > contents) noexcept
Decrypt a packet.
static constexpr std::chrono::hours ASMAP_HEALTH_CHECK_INTERVAL
Interval for ASMap Health Check.
constexpr int64_t count_seconds(std::chrono::seconds t)
void DeleteNode(CNode *pnode)
static constexpr std::chrono::seconds DNSSEEDS_DELAY_FEW_PEERS
How long to delay before querying DNS seeds.
static constexpr Event ERR
Ignored if passed to Wait(), but could be set in the occurred events if an exceptional condition has ...
std::unique_ptr< i2p::sam::Session > m_i2p_sam_session
I2P SAM session.
bool CheckIncomingNonce(uint64_t nonce)
void CloseSocketDisconnect() EXCLUSIVE_LOCKS_REQUIRED(!m_sock_mutex)
void ThreadOpenConnections(std::vector< std::string > connect) EXCLUSIVE_LOCKS_REQUIRED(!m_addr_fetches_mutex
const char * GETBLOCKS
The getblocks message requests an inv message that provides block header hashes starting from a parti...
std::pair< CAddress, NodeSeconds > Select(bool new_only=false, std::optional< Network > network=std::nullopt) const
Choose an address to connect to.
void ThreadOpenAddedConnections() EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex
bool Match(const CNetAddr &addr) const
Info GetInfo() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Retrieve information about this transport.
Mutex m_addr_fetches_mutex
size_t GetSendMemoryUsage() const noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Return the memory usage of this transport attributable to buffered data to send.
void StartSendingHandshake() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_send_mutex)
Put our public key + garbage in the send buffer.
std::atomic< std::chrono::seconds > m_last_send
std::atomic< NodeId > nLastNodeId
constexpr C * begin() const noexcept
bool GetNameProxy(Proxy &nameProxyOut)
Garbage and garbage terminator.
std::chrono::seconds GetMaxOutboundTimeLeftInCycle() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
std::vector< CService > onion_binds
static time_point now() noexcept
Return current system time or mocked time, if set.
size_t GetNodeCount(ConnectionDirection) const
std::vector< CService > Lookup(const std::string &name, uint16_t portDefault, bool fAllowLookup, unsigned int nMaxSolutions, DNSLookupFn dns_lookup_function)
Resolve a service string to its corresponding service.
void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
std::pair< CAddress, NodeSeconds > SelectTriedCollision()
Randomly select an address in the tried table that another address is attempting to evict...
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(...)
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
static constexpr Event RECV
If passed to Wait(), then it will wait for readiness to read from the socket.
const char * CMPCTBLOCK
Contains a CBlockHeaderAndShortTxIDs object - providing a header and list of "short txids"...
std::string ToString() const
m_max_automatic_connections
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
static const uint64_t SELECT_TIMEOUT_MILLISECONDS
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
uint64_t GetTotalBytesSent() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
V2Transport(NodeId nodeid, bool initiating) noexcept
Construct a V2 transport with securely generated random keys.
uint32_t GetMappedAS(const CNetAddr &addr) const
static std::optional< std::string > GetMessageType(Span< const uint8_t > &contents) noexcept
Given a packet's contents, find the message type (if valid), and strip it from contents.
bool ProcessReceivedGarbageBytes() noexcept EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
Process bytes in m_recv_buffer, while in GARB_GARBTERM state.
constexpr C * data() const noexcept
bool error(const char *fmt, const Args &... args)
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
void SocketHandlerConnected(const std::vector< CNode *> &nodes, const Sock::EventsPerSock &events_per_sock) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Do the read/write for connected sockets that are ready for IO.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
GlobalMutex g_maplocalhost_mutex
const MessageStartChars & MessageStart() const
std::atomic< std::chrono::seconds > m_last_recv
bool fAddressesInitialized
static CAddress GetBindAddress(const Sock &sock)
Get the bind address for a socket as CAddress.
std::thread threadDNSAddressSeed
bool MaybePickPreferredNetwork(std::optional< Network > &network)
Search for a "preferred" network, a reachable network to which we currently don't have any OUTBOUND_F...
#define TRACE6(context, event, a, b, c, d, e, f)
bool Start(CScheduler &scheduler, const Options &options) EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex
Span< const std::byte > MakeByteSpan(V &&v) noexcept
std::vector< ListenSocket > vhListenSocket
std::chrono::seconds GetMaxOutboundTimeframe() const
static const uint64_t RANDOMIZER_ID_ADDRCACHE
bool ReceivedBytes(Span< const uint8_t > &msg_bytes) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Feed wire bytes to the transport.
CService GetAddrLocal() const EXCLUSIVE_LOCKS_REQUIRED(!m_addr_local_mutex)
static uint32_t ReadLE32(const unsigned char *ptr)
std::atomic< int64_t > nTimeOffset
CNetMessage GetReceivedMessage(std::chrono::microseconds time, bool &reject_message) override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Retrieve a completed message from transport.
const char * GETDATA
The getdata message requests one or more data objects from another node.
static constexpr bool DEFAULT_FORCEDNSSEED
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(Span
Like the Span constructor, but for (const) unsigned char member types only.
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...
#define AssertLockNotHeld(cs)
std::string m_session_id
BIP324 session id string in hex, if any.
static constexpr auto FEELER_INTERVAL
Run the feeler connection loop once every 2 minutes.
RecvState
State type that defines the current contents of the receive buffer and/or how the next received bytes...
void Encrypt(Span< const std::byte > contents, Span< const std::byte > aad, bool ignore, Span< std::byte > output) noexcept
Encrypt a packet.
std::atomic< int > nVersion
Sock::EventsPerSock GenerateWaitSockets(Span< CNode *const > nodes)
Generate a collection of sockets to check for IO readiness.
bool AddNode(const AddedNodeParams &add) EXCLUSIVE_LOCKS_REQUIRED(!m_added_nodes_mutex)
Nothing (an application packet is available for GetMessage()).
void MarkReceivedMsgsForProcessing() EXCLUSIVE_LOCKS_REQUIRED(!m_msg_process_queue_mutex)
Move all messages from the received queue to the processing queue.
static constexpr auto EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL
Run the extra block-relay-only connection loop once every 5 minutes.
std::string ConnectionTypeAsString() const
ConnectionType
Different types of connections to a peer.
bool ShouldRunInactivityChecks(const CNode &node, std::chrono::seconds now) const
Return true if we should disconnect the peer for failing an inactivity check.
const char * CFCHECKPT
cfcheckpt is a response to a getcfcheckpt request containing a vector of evenly spaced filter headers...
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, const NetGroupManager &netgroupman, const CChainParams ¶ms, bool network_active=true)
static constexpr std::chrono::minutes DUMP_PEERS_INTERVAL
unsigned char * UCharCast(char *c)
Mutex m_msg_process_queue_mutex
std::atomic< bool > m_bip152_highbandwidth_from
void ThreadI2PAcceptIncoming()
const std::vector< uint8_t > & FixedSeeds() const
RAII helper class that manages a socket and closes it automatically when it goes out of scope...
static const unsigned int MAX_BLOCK_SERIALIZED_SIZE
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
Tp rand_uniform_delay(const Tp &time, typename Tp::duration range)
Return the time point advanced by a uniform random duration.
CNode(NodeId id, std::shared_ptr< Sock > sock, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn, ConnectionType conn_type_in, bool inbound_onion, CNodeOptions &&node_opts={})
Mutex m_reconnections_mutex
Mutex protecting m_reconnections.
std::function< std::unique_ptr< Sock >const CService &)> CreateSock
Socket factory.
std::pair< size_t, bool > SocketSendData(CNode &node) const EXCLUSIVE_LOCKS_REQUIRED(node.cs_vSend)
(Try to) send data from node's vSendMsg.
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
CNetMessage GetReceivedMessage(std::chrono::microseconds time, bool &reject_message) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Retrieve a completed message from transport.
RAII helper to atomically create a copy of m_nodes and add a reference to each of the nodes...
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS
Maximum number of automatic outgoing nodes over which we'll relay everything (blocks, tx, addrs, etc)
BindFlags
Used to pass flags to the Bind() function.
void ThreadMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc)
An encapsulated private key.
void AcceptConnection(const ListenSocket &hListenSocket)
A Span is an object that can refer to a contiguous sequence of objects.
const char * TX
The tx message transmits a single transaction.
static bool TryParse(const std::string &str, NetWhitebindPermissions &output, bilingual_str &error)
Different type to mark Mutex at global scope.
std::string GetNetworkName(enum Network net)
uint256 Hash(const T &in1)
Compute the 256-bit hash of an object.
Information about a peer.
static CNetCleanup instance_of_cnetcleanup
Span< const std::byte > GetReceiveGarbageTerminator() const noexcept
Get the expected Garbage Terminator to receive.
std::atomic< std::chrono::seconds > m_last_block_time
UNIX epoch time of the last block received from this peer that we had not yet seen (e...
bool SetSockAddr(const struct sockaddr *paddr)
std::thread threadSocketHandler
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.
Simple class for background tasks that should be run periodically or once "after a while"...
std::atomic< std::chrono::microseconds > m_last_ping_time
Last measured round-trip time.
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
std::map< CNetAddr, LocalServiceInfo > mapLocalHost GUARDED_BY(g_maplocalhost_mutex)
Network ConnectedThroughNetwork() const
Get network the peer connected through.
bool Good(const CService &addr, NodeSeconds time=Now< NodeSeconds >())
Mark an address record as accessible and attempt to move it to addrman's tried table.
std::vector< CAddress > m_anchors
Addresses that were saved during the previous clean shutdown.
static path u8path(const std::string &utf8_str)
virtual int GetSockName(sockaddr *name, socklen_t *name_len) const
getsockname(2) wrapper.
static constexpr unsigned EXPANSION
std::atomic< std::chrono::microseconds > m_min_ping_time
Lowest measured round-trip time.
const NetGroupManager & m_netgroupman
std::atomic< uint64_t > nTotalBytesRecv
Auxiliary requested/occurred events to wait for in WaitMany().
const std::string m_addr_name
std::atomic_bool fPauseRecv
std::unique_ptr< CSemaphore > semAddnode
std::unique_ptr< Sock > sock
Connected socket.
Span(T *, EndOrSize) -> Span< T >
CONSTEXPR_IF_NOT_DEBUG Span< C > last(std::size_t count) const noexcept
const MessageStartChars m_magic_bytes
CThreadInterrupt interruptNet
This is signaled when network activity should cease.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
bool ReceivedMessageComplete() const override EXCLUSIVE_LOCKS_REQUIRED(!m_recv_mutex)
Returns true if the current message is complete (so GetReceivedMessage can be called).
static constexpr std::array< std::byte, 0 > VERSION_CONTENTS
Contents of the version packet to send.
bool IsInboundConn() const
bool m_use_addrman_outgoing
std::vector< NetWhitebindPermissions > vWhiteBinds
static constexpr unsigned LENGTH_LEN
uint16_t GetDefaultPort(Network net) const
void scheduleEvery(Function f, std::chrono::milliseconds delta) EXCLUSIVE_LOCKS_REQUIRED(!newTaskMutex)
Repeat f until the scheduler is stopped.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
int readHeader(Span< const uint8_t > msg_bytes) EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
std::unique_ptr< i2p::sam::Session > i2p_sam_session
bool bind_on_any
True if the user did not specify -bind= or -whitebind= and thus we should bind on 0...
Chrono::duration rand_uniform_duration(typename Chrono::duration range) noexcept
Generate a uniform random duration in the range from 0 (inclusive) to range (exclusive).
void MarkBytesSent(size_t bytes_sent) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Report how many bytes returned by the last GetBytesToSend() have been sent.
const char *const ANCHORS_DATABASE_FILENAME
Anchor IP address database file name.
uint64_t GetOutboundTargetBytesLeft() const EXCLUSIVE_LOCKS_REQUIRED(!m_total_bytes_sent_mutex)
response the bytes left in the current max outbound cycle in case of no limit, it will always respons...
m_max_outbound_full_relay
void Reset() EXCLUSIVE_LOCKS_REQUIRED(m_recv_mutex)
Cache responses to addr requests to minimize privacy leak.
const char * FILTERADD
The filteradd message tells the receiving peer to add a single element to a previously-set bloom filt...
std::vector< unsigned char > GetAddrBytes() const
void RemoveLocal(const CService &addr)
This transport is using v1 fallback.
We use block-relay-only connections to help prevent against partition attacks.
bool IsLocal(const CService &addr)
check whether a given address is potentially local
void CopyStats(CNodeStats &stats) EXCLUSIVE_LOCKS_REQUIRED(!m_subver_mutex
ReachableNets g_reachable_nets
const char * GETBLOCKTXN
Contains a BlockTransactionsRequest Peer should respond with "blocktxn" message.
bool AddConnection(const std::string &address, ConnectionType conn_type, bool use_v2transport) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
Attempts to open a connection.
static constexpr size_t V1_PREFIX_LEN
The length of the V1 prefix to match bytes initially received by responders with to determine if thei...
void TraceThread(std::string_view thread_name, std::function< void()> thread_func)
A wrapper for do-something-once thread functions.
Addresses from these networks are not publicly routable on the global Internet.