7 #if defined(HAVE_CONFIG_H) 31 #include <miniupnpc/miniupnpc.h> 32 #include <miniupnpc/miniwget.h> 33 #include <miniupnpc/upnpcommands.h> 34 #include <miniupnpc/upnperrors.h> 41 #define DUMP_ADDRESSES_INTERVAL 900 44 #define FEELER_SLEEP_WINDOW 1 47 #if !defined(MSG_NOSIGNAL) 48 #define MSG_NOSIGNAL 0 52 #if !defined(MSG_DONTWAIT) 53 #define MSG_DONTWAIT 0 59 #ifndef PROTECTION_LEVEL_UNRESTRICTED 60 #define PROTECTION_LEVEL_UNRESTRICTED 10 62 #ifndef IPV6_PROTECTION_LEVEL 63 #define IPV6_PROTECTION_LEVEL 23 75 const static std::string NET_MESSAGE_COMMAND_OTHER =
"*other*";
77 static const uint64_t RANDOMIZER_ID_NETGROUP = 0xabb2b5f9a692e3aaULL;
78 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xe42e8de9f9a5d4d6ULL;
88 static bool vfLimited[
NET_MAX] = {};
111 int nBestReachability = -1;
116 int nScore = entry.second.nScore;
117 int nReachability = entry.first.GetReachabilityFrom(paddrPeer);
118 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
120 addr =
CService(entry.first, entry.second.nPort);
121 nBestReachability = nReachability;
126 return nBestScore >= 0;
130 static std::vector<CAddress> convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
136 const int64_t nOneWeek = 7*24*60*60;
137 std::vector<CAddress> vSeedsOut;
138 vSeedsOut.reserve(vSeedsIn.size());
139 for (
const auto& seed_in : vSeedsIn) {
141 memcpy(&ip, seed_in.addr,
sizeof(ip));
144 vSeedsOut.push_back(addr);
165 static int GetnScore(
const CService& addr)
201 LogPrint(
BCLog::NET,
"AdvertiseLocal: advertising address %s\n", addrLocal.
ToString());
220 LogPrintf(
"AddLocal(%s,%i)\n", addr.
ToString(), nScore);
226 if (!fAlready || nScore >= info.
nScore) {
227 info.
nScore = nScore + (fAlready ? 1 : 0);
243 LogPrintf(
"RemoveLocal(%s)\n", addr.
ToString());
253 vfLimited[net] = fLimited;
259 return vfLimited[net];
291 return !vfLimited[net];
306 if (static_cast<CNetAddr>(pnode->addr) == ip) {
317 if (subNet.
Match(static_cast<CNetAddr>(pnode->addr))) {
328 if (pnode->GetAddrName() == addrName) {
339 if (static_cast<CService>(pnode->addr) == addr) {
350 if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
360 struct sockaddr_storage sockaddr_bind;
361 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
363 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
364 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
366 LogPrint(
BCLog::NET,
"Warning: getsockname failed\n");
374 if (pszDest ==
nullptr) {
382 LogPrintf(
"Failed to open new connection, already connected\n");
388 LogPrint(
BCLog::NET,
"trying connection %s lastseen=%.1fhrs\n",
389 pszDest ? pszDest : addrConnect.
ToString(),
395 std::vector<CService> resolved;
399 LogPrint(
BCLog::NET,
"Resolver returned invalid address %s for %s\n", addrConnect.
ToString(), pszDest);
411 LogPrintf(
"Failed to open new connection, already connected\n");
418 bool connected =
false;
422 bool proxyConnectionFailed =
false;
438 if (!proxyConnectionFailed) {
449 int port = default_port;
461 CAddress addr_bind = GetBindAddress(hSocket);
480 if (bandb.
Write(banmap)) {
484 LogPrint(
BCLog::NET,
"Flushed %d banned node ips/subnets to banlist.dat %dms\n",
494 LogPrint(
BCLog::NET,
"disconnecting peer=%d\n",
id);
528 banmap_t::iterator i =
setBanned.find(subnet);
541 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
547 if (bantimeoffset <= 0)
549 bantimeoffset =
gArgs.
GetArg(
"-bantime", DEFAULT_MISBEHAVING_BANTIME);
550 sinceUnixEpoch =
false;
568 if (subNet.
Match(static_cast<CNetAddr>(pnode->addr)))
569 pnode->fDisconnect =
true;
578 return Unban(subNet);
612 bool notifyUI =
false;
615 banmap_t::iterator it =
setBanned.begin();
625 LogPrint(
BCLog::NET,
"%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__, subNet.
ToString());
652 if (subnet.Match(addr))
685 #define X(name) stats.name = name 728 int64_t nPingUsecWait = 0;
736 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
765 handled = msg.
readData(pch, nBytes);
771 LogPrint(
BCLog::NET,
"Oversized message from peer=%i, disconnecting\n",
GetId());
788 msg.
nTime = nTimeMicros;
804 error(
"Send version already set for node: %i. Refusing to change from %i to %i",
id,
nSendVersion, nVersionIn);
816 error(
"Requesting unset send version for node: %i. Using %i",
id, INIT_PROTO_VERSION);
817 return INIT_PROTO_VERSION;
826 unsigned int nRemaining = 24 -
nHdrPos;
827 unsigned int nCopy = std::min(nRemaining, nBytes);
840 catch (
const std::exception&) {
857 unsigned int nCopy = std::min(nRemaining, nBytes);
891 size_t nSentSize = 0;
893 while (it != pnode->
vSendMsg.end()) {
894 const auto &data = *it;
987 template<
typename T,
typename Comparator>
988 static void EraseLastKElements(std::vector<T> &elements, Comparator comparator,
size_t k)
990 std::sort(elements.begin(), elements.end(), comparator);
991 size_t eraseSize = std::min(k, elements.size());
992 elements.erase(elements.end() - eraseSize, elements.end());
1005 std::vector<NodeEvictionCandidate> vEvictionCandidates;
1010 if (node->fWhitelisted)
1012 if (!node->fInbound)
1014 if (node->fDisconnect)
1017 node->nLastBlockTime, node->nLastTXTime,
1018 HasAllDesirableServiceFlags(node->nServices),
1019 node->fRelayTxes, node->pfilter !=
nullptr, node->addr, node->nKeyedNetGroup};
1020 vEvictionCandidates.push_back(candidate);
1028 EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
1031 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
1034 EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
1037 EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
1040 EraseLastKElements(vEvictionCandidates, ReverseCompareNodeTimeConnected, vEvictionCandidates.size() / 2);
1042 if (vEvictionCandidates.empty())
return false;
1046 uint64_t naMostConnections;
1047 unsigned int nMostConnections = 0;
1048 int64_t nMostConnectionsTime = 0;
1049 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1051 std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
1052 group.push_back(node);
1053 int64_t grouptime = group[0].nTimeConnected;
1055 if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
1056 nMostConnections = group.size();
1057 nMostConnectionsTime = grouptime;
1058 naMostConnections = node.nKeyedNetGroup;
1063 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1066 NodeId evicted = vEvictionCandidates.front().id;
1069 if (pnode->GetId() == evicted) {
1070 pnode->fDisconnect =
true;
1078 struct sockaddr_storage sockaddr;
1079 socklen_t len =
sizeof(sockaddr);
1080 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1086 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1087 LogPrintf(
"Warning: Unknown socket family\n");
1095 if (pnode->fInbound) nInbound++;
1108 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1113 if (!IsSelectableSocket(hSocket))
1115 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1124 if (
IsBanned(addr) && !whitelisted)
1131 if (nInbound >= nMaxInbound)
1135 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1143 CAddress addr_bind = GetBindAddress(hSocket);
1166 if (!pnode->fDisconnect) {
1167 LogPrint(
BCLog::NET,
"Network not active, dropping peer=%d\n", pnode->GetId());
1168 pnode->fDisconnect =
true;
1174 std::vector<CNode*> vNodesCopy =
vNodes;
1175 for (
CNode* pnode : vNodesCopy)
1177 if (pnode->fDisconnect)
1183 pnode->grantOutbound.Release();
1186 pnode->CloseSocketDisconnect();
1197 for (
CNode* pnode : vNodesDisconnectedCopy)
1200 if (pnode->GetRefCount() <= 0) {
1201 bool fDelete =
false;
1203 TRY_LOCK(pnode->cs_inventory, lockInv);
1205 TRY_LOCK(pnode->cs_vSend, lockSend);
1225 vNodesSize =
vNodes.size();
1244 else if (nTime - pnode->
nLastSend > TIMEOUT_INTERVAL)
1246 LogPrintf(
"socket sending timeout: %is\n", nTime - pnode->
nLastSend);
1249 else if (nTime - pnode->
nLastRecv > (pnode->
nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1251 LogPrintf(
"socket receive timeout: %is\n", nTime - pnode->
nLastRecv);
1261 LogPrint(
BCLog::NET,
"version handshake timeout from %d\n", pnode->
GetId());
1272 struct timeval timeout;
1274 timeout.tv_usec = 50000;
1279 FD_ZERO(&fdsetRecv);
1280 FD_ZERO(&fdsetSend);
1281 FD_ZERO(&fdsetError);
1283 bool have_fds =
false;
1286 FD_SET(hListenSocket.socket, &fdsetRecv);
1287 hSocketMax = std::max(hSocketMax, hListenSocket.socket);
1306 bool select_recv = !pnode->fPauseRecv;
1309 LOCK(pnode->cs_vSend);
1310 select_send = !pnode->vSendMsg.empty();
1313 LOCK(pnode->cs_hSocket);
1317 FD_SET(pnode->hSocket, &fdsetError);
1318 hSocketMax = std::max(hSocketMax, pnode->hSocket);
1322 FD_SET(pnode->hSocket, &fdsetSend);
1326 FD_SET(pnode->hSocket, &fdsetRecv);
1331 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1332 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1342 for (
unsigned int i = 0; i <= hSocketMax; i++)
1343 FD_SET(i, &fdsetRecv);
1345 FD_ZERO(&fdsetSend);
1346 FD_ZERO(&fdsetError);
1356 if (hListenSocket.socket !=
INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
1365 std::vector<CNode*> vNodesCopy;
1369 for (
CNode* pnode : vNodesCopy)
1372 for (
CNode* pnode : vNodesCopy)
1380 bool recvSet =
false;
1381 bool sendSet =
false;
1382 bool errorSet =
false;
1384 LOCK(pnode->cs_hSocket);
1387 recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
1388 sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
1389 errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
1391 if (recvSet || errorSet)
1394 char pchBuf[0x10000];
1397 LOCK(pnode->cs_hSocket);
1400 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1404 bool notify =
false;
1405 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1406 pnode->CloseSocketDisconnect();
1409 size_t nSizeAdded = 0;
1410 auto it(pnode->vRecvMsg.begin());
1411 for (; it != pnode->vRecvMsg.end(); ++it) {
1412 if (!it->complete())
1417 LOCK(pnode->cs_vProcessMsg);
1418 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1419 pnode->nProcessQueueSize += nSizeAdded;
1425 else if (nBytes == 0)
1428 if (!pnode->fDisconnect) {
1431 pnode->CloseSocketDisconnect();
1433 else if (nBytes < 0)
1439 if (!pnode->fDisconnect)
1441 pnode->CloseSocketDisconnect();
1451 LOCK(pnode->cs_vSend);
1462 for (
CNode* pnode : vNodesCopy)
1493 static std::thread g_upnp_thread;
1494 static void ThreadMapPort()
1497 const char * multicastif =
nullptr;
1498 const char * minissdpdpath =
nullptr;
1499 struct UPNPDev * devlist =
nullptr;
1502 #ifndef UPNPDISCOVER_SUCCESS 1504 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1505 #elif MINIUPNPC_API_VERSION < 14 1508 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &
error);
1512 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &
error);
1515 struct UPNPUrls urls;
1516 struct IGDdatas data;
1519 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1523 char externalIPAddress[40];
1524 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1525 if(r != UPNPCOMMAND_SUCCESS)
1526 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1529 if(externalIPAddress[0])
1532 if(
LookupHost(externalIPAddress, resolved,
false)) {
1533 LogPrintf(
"UPnP: ExternalIPAddress = %s\n", resolved.
ToString().c_str());
1538 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1545 #ifndef UPNPDISCOVER_SUCCESS 1547 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1548 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0);
1551 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1552 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1555 if(r!=UPNPCOMMAND_SUCCESS)
1556 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1557 port, port, lanaddr, r, strupnperror(r));
1559 LogPrintf(
"UPnP Port Mapping successful.\n");
1561 while(g_upnp_interrupt.
sleep_for(std::chrono::minutes(20)));
1563 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1564 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1565 freeUPNPDevlist(devlist); devlist =
nullptr;
1566 FreeUPNPUrls(&urls);
1568 LogPrintf(
"No valid UPnP IGDs found\n");
1569 freeUPNPDevlist(devlist); devlist =
nullptr;
1571 FreeUPNPUrls(&urls);
1577 if (!g_upnp_thread.joinable()) {
1578 assert(!g_upnp_interrupt);
1579 g_upnp_thread = std::thread((std::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort)));
1585 if(g_upnp_thread.joinable()) {
1592 if(g_upnp_thread.joinable()) {
1593 g_upnp_thread.join();
1594 g_upnp_interrupt.
reset();
1632 nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
1634 if (nRelevant >= 2) {
1635 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1643 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1645 for (
const std::string &seed : vSeeds) {
1652 std::vector<CNetAddr> vIPs;
1653 std::vector<CAddress> vAdd;
1655 std::string host =
strprintf(
"x%x.%s", requiredServiceBits, seed);
1660 unsigned int nMaxIPs = 256;
1661 if (
LookupHost(host.c_str(), vIPs, nMaxIPs,
true))
1665 int nOneDay = 24*3600;
1668 vAdd.push_back(addr);
1680 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1701 LogPrint(
BCLog::NET,
"Flushed %d addresses to peers.dat %dms\n",
1713 std::string strDest;
1736 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1751 if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
1762 if (!connect.empty())
1764 for (int64_t nLoop = 0;; nLoop++)
1767 for (
const std::string& strAddr : connect)
1771 for (
int i = 0; i < 10 && i < nLoop; i++)
1786 int64_t nNextFeeler =
PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1800 static bool done =
false;
1802 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1817 std::set<std::vector<unsigned char> > setConnected;
1821 if (!pnode->fInbound && !pnode->m_manual_connection) {
1827 setConnected.insert(pnode->addr.GetGroup());
1845 bool fFeeler =
false;
1849 if (nTime > nNextFeeler) {
1866 if (!fFeeler || !addr.
IsValid()) {
1885 if (nANow - addr.
nLastTry < 600 && nTries < 30)
1891 if (!fFeeler && !HasAllDesirableServiceFlags(addr.
nServices)) {
1893 }
else if (fFeeler && !MayHaveUsefulAddressDB(addr.
nServices)) {
1922 std::vector<AddedNodeInfo>
ret;
1924 std::list<std::string> lAddresses(0);
1927 ret.reserve(vAddedNodes.size());
1928 std::copy(vAddedNodes.cbegin(), vAddedNodes.cend(), std::back_inserter(lAddresses));
1933 std::map<CService, bool> mapConnected;
1934 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1938 if (pnode->addr.IsValid()) {
1939 mapConnected[pnode->addr] = pnode->fInbound;
1941 std::string addrName = pnode->GetAddrName();
1942 if (!addrName.empty()) {
1943 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1948 for (
const std::string& strAddNode : lAddresses) {
1953 auto it = mapConnected.find(service);
1954 if (it != mapConnected.end()) {
1955 addedNode.resolvedAddress = service;
1956 addedNode.fConnected =
true;
1957 addedNode.fInbound = it->second;
1961 auto it = mapConnectedByName.find(strAddNode);
1962 if (it != mapConnectedByName.end()) {
1963 addedNode.resolvedAddress = it->second.second;
1964 addedNode.fConnected =
true;
1965 addedNode.fInbound = it->second.first;
1968 ret.emplace_back(std::move(addedNode));
1982 if (!info.fConnected) {
2018 }
else if (
FindNode(std::string(pszDest)))
2021 CNode* pnode =
ConnectNode(addrConnect, pszDest, fCountFailure, manual_connection);
2031 if (manual_connection)
2045 std::vector<CNode*> vNodesCopy;
2049 for (
CNode* pnode : vNodesCopy) {
2054 bool fMoreWork =
false;
2056 for (
CNode* pnode : vNodesCopy)
2058 if (pnode->fDisconnect)
2063 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2068 LOCK(pnode->cs_sendProcessing);
2078 for (
CNode* pnode : vNodesCopy)
2084 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this] {
return fMsgProcWake; });
2101 struct sockaddr_storage sockaddr;
2102 socklen_t len =
sizeof(sockaddr);
2103 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2105 strError =
strprintf(
"Error: Bind address family for %s not supported", addrBind.
ToString());
2106 LogPrintf(
"%s\n", strError);
2114 LogPrintf(
"%s\n", strError);
2120 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
sockopt_arg_type)&nOne,
sizeof(
int));
2126 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
sockopt_arg_type)&nOne,
sizeof(
int));
2129 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2130 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2134 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2141 LogPrintf(
"%s\n", strError);
2145 LogPrintf(
"Bound to %s\n", addrBind.
ToString());
2151 LogPrintf(
"%s\n", strError);
2171 char pszHostName[256] =
"";
2172 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2174 std::vector<CNetAddr> vaddr;
2180 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.
ToString());
2184 #elif (HAVE_DECL_GETIFADDRS && HAVE_DECL_FREEIFADDRS) 2186 struct ifaddrs* myaddrs;
2187 if (getifaddrs(&myaddrs) == 0)
2189 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2191 if (ifa->ifa_addr ==
nullptr)
continue;
2192 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2193 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2194 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2195 if (ifa->ifa_addr->sa_family == AF_INET)
2197 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2200 LogPrintf(
"%s: IPv4 %s: %s\n", __func__, ifa->ifa_name, addr.
ToString());
2202 else if (ifa->ifa_addr->sa_family == AF_INET6)
2204 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2207 LogPrintf(
"%s: IPv6 %s: %s\n", __func__, ifa->ifa_name, addr.
ToString());
2210 freeifaddrs(myaddrs);
2217 LogPrint(
BCLog::NET,
"SetNetworkActive: %s\n", active);
2246 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2253 std::string strError;
2264 bool fBound =
false;
2265 for (
const auto& addrBind : binds) {
2268 for (
const auto& addrBind : whiteBinds) {
2271 if (binds.empty() && whiteBinds.empty()) {
2272 struct in_addr inaddr_any;
2273 inaddr_any.s_addr = INADDR_ANY;
2274 struct in6_addr inaddr6_any = IN6ADDR_ANY_INIT;
2287 nTotalBytesRecv = 0;
2291 nTotalBytesSent = 0;
2292 nMaxOutboundTotalBytesSentInCycle = 0;
2293 nMaxOutboundCycleStartTime = 0;
2299 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2305 LogPrintf(
"Connection Manager: Adding Seed Nodes\n");
2307 for (
const auto& strDest : connOptions.
vSeedNodes) {
2308 LogPrintf(
"Connection Manager: Adding Seed Node: %s\n", strDest);
2324 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2334 if (bandb.
Read(banmap)) {
2339 LogPrint(
BCLog::NET,
"Loaded %d banned node ips/subnets from banlist.dat %dms\n",
2342 LogPrintf(
"Invalid or missing banlist.dat; recreating\n");
2347 uiInterface.InitMessage(
_(
"Starting network threads..."));
2377 LogPrintf(
"DNS seeding disabled\n");
2387 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2464 pnode->CloseSocketDisconnect();
2487 bool fUpdateConnectionTime =
false;
2489 if(fUpdateConnectionTime) {
2529 for (
const std::string& it : vAddedNodes) {
2530 if (strNode == it)
return false;
2533 vAddedNodes.push_back(strNode);
2540 for(std::vector<std::string>::iterator it = vAddedNodes.begin(); it != vAddedNodes.end(); ++it) {
2541 if (strNode == *it) {
2542 vAddedNodes.erase(it);
2556 for (
const auto& pnode :
vNodes) {
2569 vstats.reserve(
vNodes.size());
2571 vstats.emplace_back();
2572 pnode->copyStats(vstats.back());
2580 pnode->fDisconnect =
true;
2589 if (
id == pnode->GetId()) {
2590 pnode->fDisconnect =
true;
2600 nTotalBytesRecv += bytes;
2606 nTotalBytesSent += bytes;
2609 if (nMaxOutboundCycleStartTime + nMaxOutboundTimeframe < now)
2612 nMaxOutboundCycleStartTime = now;
2613 nMaxOutboundTotalBytesSentInCycle = 0;
2617 nMaxOutboundTotalBytesSentInCycle += bytes;
2623 nMaxOutboundLimit = limit;
2629 return nMaxOutboundLimit;
2635 return nMaxOutboundTimeframe;
2641 if (nMaxOutboundLimit == 0)
2644 if (nMaxOutboundCycleStartTime == 0)
2645 return nMaxOutboundTimeframe;
2647 uint64_t cycleEndTime = nMaxOutboundCycleStartTime + nMaxOutboundTimeframe;
2649 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2655 if (nMaxOutboundTimeframe != timeframe)
2659 nMaxOutboundCycleStartTime =
GetTime();
2661 nMaxOutboundTimeframe = timeframe;
2667 if (nMaxOutboundLimit == 0)
2670 if (historicalBlockServingLimit)
2674 uint64_t buffer = timeLeftInCycle / 600 * MAX_BLOCK_SERIALIZED_SIZE;
2675 if (buffer >= nMaxOutboundLimit || nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit - buffer)
2678 else if (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit)
2687 if (nMaxOutboundLimit == 0)
2690 return (nMaxOutboundTotalBytesSentInCycle >= nMaxOutboundLimit) ? 0 : nMaxOutboundLimit - nMaxOutboundTotalBytesSentInCycle;
2696 return nTotalBytesRecv;
2702 return nTotalBytesSent;
2712 nBestHeight.store(height, std::memory_order_release);
2717 return nBestHeight.load(std::memory_order_acquire);
2725 addrBind(addrBindIn),
2726 fInbound(fInboundIn),
2727 nKeyedNetGroup(nKeyedNetGroupIn),
2728 addrKnown(5000, 0.001),
2729 filterInventoryKnown(50000, 0.000001),
2731 nLocalHostNonce(nLocalHostNonceIn),
2732 nLocalServices(nLocalServicesIn),
2733 nMyStartingHeight(nMyStartingHeightIn),
2768 pfilter = MakeUnique<CBloomFilter>();
2791 LogPrint(
BCLog::NET,
"Added connection peer=%d\n",
id);
2810 int64_t nRequestTime;
2813 nRequestTime = it->second;
2820 static int64_t nLastTime;
2822 nNow = std::max(nNow, nLastTime);
2826 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2831 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2841 size_t nMessageSize = msg.data.size();
2845 std::vector<unsigned char> serializedHeader;
2847 uint256 hash =
Hash(msg.data.data(), msg.data.data() + nMessageSize);
2853 size_t nBytesSent = 0;
2856 bool optimisticSend(pnode->
vSendMsg.empty());
2864 pnode->
vSendMsg.push_back(std::move(serializedHeader));
2866 pnode->
vSendMsg.push_back(std::move(msg.data));
2869 if (optimisticSend ==
true)
2878 CNode* found =
nullptr;
2880 for (
auto&& pnode :
vNodes) {
2881 if(pnode->
GetId() == id) {
2902 return now + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
2912 std::vector<unsigned char> vchNetGroup(ad.
GetGroup());
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
std::map< K, V >::const_iterator const_iterator
uint64_t CalculateKeyedNetGroup(const CAddress &ad) const
CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, const std::string &addrNameIn="", bool fInboundIn=false)
unsigned short GetPort() const
bool BannedSetIsDirty()
check is the banlist has unwritten changes
std::atomic< uint64_t > nPingNonceSent
CCriticalSection cs_addrName
void MoveTo(CSemaphoreGrant &grant)
std::atomic_bool fPauseSend
Access to the (IP) address database (peers.dat)
void ThreadOpenAddedConnections()
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
bool sleep_for(std::chrono::milliseconds rel_time)
void SetBannedSetDirty(bool dirty=true)
set the "dirty" flag for the banlist
int64_t nextSendTimeFeeFilter
int GetSendVersion() const
bool ConnectSocketDirectly(const CService &addrConnect, const SOCKET &hSocket, int nTimeout, bool manual_connection)
void SetBanned(const banmap_t &banmap)
std::atomic< bool > fNetworkActive
bool fMsgProcWake
flag for waking the message processor.
ServiceFlags
nServices flags
CAddrInfo Select(bool newOnly=false)
Choose an address to connect to.
CCriticalSection cs_filter
void Attempt(const CService &addr, bool fCountFailure, int64_t nTime=GetAdjustedTime())
Mark an entry as connection attempted to.
bool AddLocal(const CService &addr, int nScore)
CConnman(uint64_t seed0, uint64_t seed1)
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 ...
#define TRY_LOCK(cs, name)
STL-like map container that only keeps the N elements with the highest value.
std::atomic< int > nBestHeight
size_t GetAddressCount() const
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
void SetServices(const CService &addr, ServiceFlags nServices)
std::string ToString() const
void SweepBanned()
clean unused entries (if bantime has expired)
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes, bool &complete)
mapMsgCmdSize mapSendBytesPerMsgCmd
CService LookupNumeric(const char *pszName, int portDefault)
UniValue ret(UniValue::VARR)
void resize(size_type n, value_type c=0)
bool GetNameProxy(proxyType &nameProxyOut)
CCriticalSection cs_hSocket
void AskFor(const CInv &inv)
CCriticalSection cs_SubVer
bool GetTryNewOutboundPeer()
#define FEELER_SLEEP_WINDOW
std::atomic< int64_t > m_next_send_inv_to_incoming
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
CCriticalSection cs_addrLocal
RAII-style semaphore lock.
bool Unban(const CNetAddr &ip)
uint64_t GetMaxOutboundTarget()
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
std::unique_ptr< CBloomFilter > pfilter
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
void GetBanned(banmap_t &banmap)
NetEventsInterface * m_msgproc
std::atomic< int64_t > nPingUsecStart
CCriticalSection cs_vNodes
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
void OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=nullptr, const char *strDest=nullptr, bool fOneShot=false, bool fFeeler=false, bool manual_connection=false)
CCriticalSection cs_vAddedNodes
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
void SetTryNewOutboundPeer(bool flag)
unsigned short GetListenPort()
std::string ToString() const
bool SeenLocal(const CService &addr)
vote for a local address
void ThreadSocketHandler()
std::vector< CService > vWhiteBinds
virtual bool SendMessages(CNode *pnode)=0
size_t GetNodeCount(NumConnections num)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
Add a single address.
std::atomic< int > nStartingHeight
void PushAddress(const CAddress &_addr, FastRandomContext &insecure_rand)
std::atomic< int64_t > timeLastMempoolReq
void AddOneShot(const std::string &strDest)
#define WSAGetLastError()
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
std::list< CNetMessage > vRecvMsg
void NotifyNumConnectionsChanged()
enum Network GetNetwork() const
void SetMaxOutboundTarget(uint64_t limit)
set the max outbound target in bytes
void RecordBytesSent(uint64_t bytes)
std::atomic< ServiceFlags > nServices
void SetAddrLocal(const CService &addrLocalIn)
May not be called more than once.
int64_t nNextLocalAddrSend
uint64_t GetMaxOutboundTimeframe()
bool ForNode(NodeId id, std::function< bool(CNode *pnode)> func)
ServiceFlags nLocalServices
Services this instance offers.
bool IsWhitelistedRange(const CNetAddr &addr)
bool DisconnectNode(const std::string &node)
std::vector< unsigned char > GetGroup() const
std::atomic< int64_t > nLastSend
void RecordBytesRecv(uint64_t bytes)
Access to the banlist database (banlist.dat)
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
std::atomic< int64_t > nPingUsecTime
std::atomic< int64_t > nMinPingUsecTime
void Ban(const CNetAddr &netAddr, const BanReason &reason, int64_t bantimeoffset=0, bool sinceUnixEpoch=false)
Extended statistics about a CAddress.
ServiceFlags GetLocalServices() const
std::map< CSubNet, CBanEntry > banmap_t
void CloseSocketDisconnect()
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle
bool Write(const CAddrMan &addr)
static bool NodeFullyConnected(const CNode *pnode)
unsigned int nPrevNodeCount
bool AddNode(const std::string &node)
std::condition_variable condMsgProc
int64_t GetSystemTimeInSeconds()
CService GetAddrLocal() const
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle
void InactivityCheck(CNode *pnode)
std::atomic< int64_t > nLastRecv
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
bool InitBinds(const std::vector< CService > &binds, const std::vector< CService > &whiteBinds)
std::thread threadOpenAddedConnections
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
std::string ToStringIP() const
CNode * FindNode(const CNetAddr &ip)
std::vector< CNode * > vNodes
ServiceFlags GetLocalServices() const
std::deque< std::string > vOneShots
bool IsPeerAddrLocalGood(CNode *pnode)
CCriticalSection cs_mapLocalHost
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< std::string > vSeedNodes
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds)
Attempts to obfuscate tx time through exponentially distributed emitting.
bool OutboundTargetReached(bool historicalBlockServingLimit)
check if the outbound target is reached
void TraceThread(const char *name, Callable func)
std::vector< std::string > m_specified_outgoing
std::vector< CAddress > GetAddresses()
CRollingBloomFilter filterInventoryKnown
std::unique_ptr< CSemaphore > semOutbound
void ThreadOpenConnections(std::vector< std::string > connect)
std::thread threadMessageHandler
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, int port, const SOCKET &hSocket, int nTimeout, bool *outProxyConnectionFailed)
std::map< CNetAddr, LocalServiceInfo > mapLocalHost
A CService with information about it as peer.
bool Start(CScheduler &scheduler, const Options &options)
void MaybeSetAddrName(const std::string &addrNameIn)
Sets the addrName only if it was not previously set.
const std::vector< std::string > & getAllNetMessageTypes()
uint64_t GetTotalBytesRecv()
std::atomic_bool m_try_another_outbound_peer
flag for deciding to connect to an extra outbound peer, in excess of nMaxOutbound This takes the plac...
virtual void FinalizeNode(NodeId id, bool &update_connection_time)=0
void SetNetworkActive(bool active)
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
int GetDefaultPort() const
#define WAIT_LOCK(cs, name)
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
CClientUIInterface * clientInterface
void GetNodeStats(std::vector< CNodeStats > &vstats)
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
std::atomic_bool fDisconnect
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
bool CloseSocket(SOCKET &hSocket)
Close socket and set hSocket to INVALID_SOCKET.
#define DUMP_ADDRESSES_INTERVAL
CCriticalSection cs_vOneShots
bool Write(const banmap_t &banSet)
std::string FormatFullVersion()
bool IsBanned(CNetAddr ip)
CCriticalSection cs_setBanned
unsigned int GetReceiveFloodSize() const
int readData(const char *pch, unsigned int nBytes)
void DeleteNode(CNode *pnode)
bool CheckIncomingNonce(uint64_t nonce)
std::atomic< int > nRefCount
bool Match(const CNetAddr &addr) const
const int64_t nTimeConnected
bool Read(banmap_t &banSet)
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
CCriticalSection cs_vRecv
std::list< CNode * > vNodesDisconnected
std::atomic< bool > fPingQueued
size_t size() const
Return the number of (unique) addresses in all tables.
int GetBestHeight() const
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
void Finalize(unsigned char hash[OUTPUT_SIZE])
bool Bind(const CService &addr, unsigned int flags)
std::string ToString() const
void SplitHostPort(std::string in, int &portOut, std::string &hostOut)
std::atomic< int64_t > nLastTXTime
std::string FormatISO8601Time(int64_t nTime)
std::vector< CSubNet > vWhitelistedRange
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
void * memcpy(void *a, const void *b, size_t c)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool fAddressesInitialized
std::thread threadDNSAddressSeed
std::deque< std::vector< unsigned char > > vSendMsg
int64_t GetAdjustedTime()
CAddrInfo SelectTriedCollision()
Randomly select an address in tried that another address is attempting to evict.
std::string ToStringIPPort() const
size_t SocketSendData(CNode *pnode) const
ServiceFlags GetDesirableServiceFlags(ServiceFlags services)
Gets the set of service flags which are "desirable" for a given peer.
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
CHash3 & Write(const unsigned char *data, size_t len)
void SetSendVersion(int nVersionIn)
mapMsgCmdSize mapRecvBytesPerMsgCmd
std::vector< ListenSocket > vhListenSocket
void SetBestHeight(int height)
SOCKET CreateSocket(const CService &addrConnect)
CAmount lastSentFeeFilter
std::atomic< int64_t > nTimeOffset
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
CCriticalSection cs_totalBytesSent
std::atomic_bool fSuccessfullyConnected
void ThreadMessageHandler()
void ResolveCollisions()
See if any to-be-evicted tried table entries have been tested and if so resolve the collisions...
bool error(const char *fmt, const Args &... args)
std::atomic< int > nVersion
void InterruptSocks5(bool interrupt)
unsigned int nSendBufferMaxSize
class CNetCleanup instance_of_cnetcleanup
int readHeader(const char *pch, unsigned int nBytes)
std::string ToString() const
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
int GetExtraOutboundCount()
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
void Good(const CService &addr, bool test_before_evict=true, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
BindFlags
Used to pass flags to the Bind() function.
void SetServices(const CService &addr, ServiceFlags nServices)
uint64_t GetTotalBytesSent()
void AcceptConnection(const ListenSocket &hListenSocket)
CClientUIInterface uiInterface
void MarkAddressGood(const CAddress &addr)
Information about a peer.
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
bool SetSockAddr(const struct sockaddr *paddr)
std::thread threadSocketHandler
bool SetInternal(const std::string &name)
Transform an arbitrary string into a non-routable ipv6 address.
virtual void InitializeNode(CNode *pnode)=0
std::string GetAddrName() const
CCriticalSection cs_vSend
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure, bool manual_connection)
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as currently-connected-to.
void copyStats(CNodeStats &stats)
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
std::atomic_bool fPauseRecv
std::unique_ptr< CSemaphore > semAddnode
void Init(const Options &connOptions)
CThreadInterrupt interruptNet
CCriticalSection cs_totalBytesRecv
limitedmap< uint256, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool m_use_addrman_outgoing
std::atomic< int > nRecvVersion
std::atomic< int64_t > nLastBlockTime
std::multimap< int64_t, CInv > mapAskFor
bool Read(CAddrMan &addr)
void AdvertiseLocal(CNode *pnode)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
const uint256 & GetMessageHash() const
bool IsLimited(enum Network net)
std::string _(const char *psz)
Translation function.
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
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
uint64_t GetRand(uint64_t nMax)
std::set< uint256 > setAskFor
unsigned int nReceiveFloodSize
bool BindListenPort(const CService &bindAddr, std::string &strError, bool fWhitelisted=false)
void ThreadDNSAddressSeed()