7 #if defined(HAVE_CONFIG_H) 33 #include <miniupnpc/miniupnpc.h> 34 #include <miniupnpc/miniwget.h> 35 #include <miniupnpc/upnpcommands.h> 36 #include <miniupnpc/upnperrors.h> 47 #define DUMP_ADDRESSES_INTERVAL 900 50 #define FEELER_SLEEP_WINDOW 1 52 #if !defined(HAVE_MSG_NOSIGNAL) 53 #define MSG_NOSIGNAL 0 57 #if !defined(HAVE_MSG_DONTWAIT) 58 #define MSG_DONTWAIT 0 64 #ifndef PROTECTION_LEVEL_UNRESTRICTED 65 #define PROTECTION_LEVEL_UNRESTRICTED 10 67 #ifndef IPV6_PROTECTION_LEVEL 68 #define IPV6_PROTECTION_LEVEL 23 80 const static std::string NET_MESSAGE_COMMAND_OTHER =
"*other*";
82 static const uint64_t RANDOMIZER_ID_NETGROUP = 0x6c0edd8036ef4036ULL;
83 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
92 static bool vfLimited[
NET_MAX] = {};
115 int nBestReachability = -1;
117 LOCK(cs_mapLocalHost);
118 for (std::map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
120 int nScore = (*it).second.nScore;
121 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
122 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
124 addr =
CService((*it).first, (*it).second.nPort);
125 nBestReachability = nReachability;
130 return nBestScore >= 0;
134 static std::vector<CAddress> convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
140 const int64_t nOneWeek = 7*24*60*60;
141 std::vector<CAddress> vSeedsOut;
142 vSeedsOut.reserve(vSeedsIn.size());
143 for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
146 memcpy(&ip, i->addr,
sizeof(ip));
149 vSeedsOut.push_back(addr);
164 ret =
CAddress(addr, nLocalServices);
172 LOCK(cs_mapLocalHost);
175 return mapLocalHost[addr].nScore;
224 LOCK(cs_mapLocalHost);
225 bool fAlready = mapLocalHost.count(addr) > 0;
227 if (!fAlready || nScore >= info.
nScore) {
228 info.
nScore = nScore + (fAlready ? 1 : 0);
243 LOCK(cs_mapLocalHost);
245 mapLocalHost.erase(addr);
254 LOCK(cs_mapLocalHost);
255 vfLimited[net] = fLimited;
260 LOCK(cs_mapLocalHost);
261 return vfLimited[net];
273 LOCK(cs_mapLocalHost);
274 if (mapLocalHost.count(addr) == 0)
276 mapLocalHost[addr].nScore++;
285 LOCK(cs_mapLocalHost);
286 return mapLocalHost.count(addr) > 0;
292 LOCK(cs_mapLocalHost);
293 return !vfLimited[net];
330 if (pnode->GetAddrName() == addrName) {
341 if ((
CService)pnode->addr == addr) {
352 if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
362 struct sockaddr_storage sockaddr_bind;
363 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
365 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
366 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
376 if (pszDest ==
nullptr) {
384 LogPrintf(
"Failed to open new connection, already connected\n");
391 pszDest ? pszDest : addrConnect.
ToString(),
397 std::vector<CService> resolved;
413 LogPrintf(
"Failed to open new connection, already connected\n");
420 bool connected =
false;
424 bool proxyConnectionFailed =
false;
430 if (!proxyConnectionFailed) {
437 int port = default_port;
442 if (!IsSelectableSocket(hSocket)) {
443 LogPrintf(
"Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
451 CAddress addr_bind = GetBindAddress(hSocket);
473 if (bandb.
Write(banmap)) {
521 banmap_t::iterator i =
setBanned.find(subnet);
534 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
540 if (bantimeoffset <= 0)
542 bantimeoffset =
gArgs.
GetArg(
"-bantime", DEFAULT_MISBEHAVING_BANTIME);
543 sinceUnixEpoch =
false;
562 pnode->fDisconnect =
true;
571 return Unban(subNet);
607 banmap_t::iterator it =
setBanned.begin();
638 if (subnet.Match(addr))
651 if (addrName.empty()) {
652 addrName = addrNameIn;
663 if (addrLocal.IsValid()) {
664 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
666 addrLocal = addrLocalIn;
671 #define X(name) stats.name = name 674 stats.
nodeid = this->GetId();
693 X(m_manual_connection);
697 X(mapSendBytesPerMsgCmd);
702 X(mapRecvBytesPerMsgCmd);
713 int64_t nPingUsecWait = 0;
714 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
719 stats.
dPingTime = (((double)nPingUsecTime) / 1e6);
720 stats.
dMinPing = (((double)nMinPingUsecTime) / 1e6);
721 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
724 CService addrLocalUnlocked = GetAddrLocal();
734 nLastRecv = nTimeMicros / 1000000;
735 nRecvBytes += nBytes;
739 if (vRecvMsg.empty() ||
740 vRecvMsg.back().complete())
750 handled = msg.
readData(pch, nBytes);
767 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.
hdr.
pchCommand);
768 if (i == mapRecvBytesPerMsgCmd.end())
769 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
770 assert(i != mapRecvBytesPerMsgCmd.end());
773 msg.
nTime = nTimeMicros;
788 if (nSendVersion != 0) {
789 error(
"Send version already set for node: %i. Refusing to change from %i to %i",
id, nSendVersion, nVersionIn);
791 nSendVersion = nVersionIn;
800 if (nSendVersion == 0) {
801 error(
"Requesting unset send version for node: %i. Using %i",
id, INIT_PROTO_VERSION);
802 return INIT_PROTO_VERSION;
811 unsigned int nRemaining = 24 - nHdrPos;
812 unsigned int nCopy = std::min(nRemaining, nBytes);
814 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
825 catch (
const std::exception&) {
830 if (hdr.nMessageSize > MAX_SIZE)
841 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
842 unsigned int nCopy = std::min(nRemaining, nBytes);
844 if (vRecv.size() < nDataPos + nCopy) {
846 vRecv.resize(std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
849 hasher.Write((
const unsigned char*)pch, nCopy);
850 memcpy(&vRecv[nDataPos], pch, nCopy);
859 if (data_hash.IsNull())
860 hasher.Finalize(data_hash.begin());
876 size_t nSentSize = 0;
878 while (it != pnode->
vSendMsg.end()) {
879 const auto &data = *it;
980 std::vector<NodeEvictionCandidate> vEvictionCandidates;
985 if (node->fWhitelisted)
989 if (node->fDisconnect)
992 node->nLastBlockTime, node->nLastTXTime,
993 HasAllDesirableServiceFlags(node->nServices),
994 node->fRelayTxes, node->pfilter !=
nullptr, node->addr, node->nKeyedNetGroup};
995 vEvictionCandidates.push_back(candidate);
999 if (vEvictionCandidates.empty())
return false;
1005 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
1006 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1008 if (vEvictionCandidates.empty())
return false;
1012 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
1013 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1015 if (vEvictionCandidates.empty())
return false;
1019 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime);
1020 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1022 if (vEvictionCandidates.empty())
return false;
1026 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime);
1027 vEvictionCandidates.erase(vEvictionCandidates.end() - std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1029 if (vEvictionCandidates.empty())
return false;
1033 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
1034 vEvictionCandidates.erase(vEvictionCandidates.end() -
static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
1036 if (vEvictionCandidates.empty())
return false;
1040 uint64_t naMostConnections;
1041 unsigned int nMostConnections = 0;
1042 int64_t nMostConnectionsTime = 0;
1043 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1045 mapNetGroupNodes[node.nKeyedNetGroup].push_back(node);
1046 int64_t grouptime = mapNetGroupNodes[node.nKeyedNetGroup][0].nTimeConnected;
1047 size_t groupsize = mapNetGroupNodes[node.nKeyedNetGroup].size();
1049 if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
1050 nMostConnections = groupsize;
1051 nMostConnectionsTime = grouptime;
1052 naMostConnections = node.nKeyedNetGroup;
1057 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1060 NodeId evicted = vEvictionCandidates.front().id;
1063 if (pnode->GetId() == evicted) {
1064 pnode->fDisconnect =
true;
1072 struct sockaddr_storage sockaddr;
1073 socklen_t len =
sizeof(sockaddr);
1074 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1080 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1081 LogPrintf(
"Warning: Unknown socket family\n");
1089 if (pnode->fInbound) nInbound++;
1102 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1107 if (!IsSelectableSocket(hSocket))
1109 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1118 if (
IsBanned(addr) && !whitelisted)
1125 if (nInbound >= nMaxInbound)
1129 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1137 CAddress addr_bind = GetBindAddress(hSocket);
1154 unsigned int nPrevNodeCount = 0;
1163 std::vector<CNode*> vNodesCopy =
vNodes;
1164 for (
CNode* pnode : vNodesCopy)
1166 if (pnode->fDisconnect)
1172 pnode->grantOutbound.Release();
1175 pnode->CloseSocketDisconnect();
1186 for (
CNode* pnode : vNodesDisconnectedCopy)
1189 if (pnode->GetRefCount() <= 0) {
1190 bool fDelete =
false;
1192 TRY_LOCK(pnode->cs_inventory, lockInv);
1194 TRY_LOCK(pnode->cs_vSend, lockSend);
1210 vNodesSize =
vNodes.size();
1212 if(vNodesSize != nPrevNodeCount) {
1213 nPrevNodeCount = vNodesSize;
1221 struct timeval timeout;
1223 timeout.tv_usec = 50000;
1228 FD_ZERO(&fdsetRecv);
1229 FD_ZERO(&fdsetSend);
1230 FD_ZERO(&fdsetError);
1232 bool have_fds =
false;
1235 FD_SET(hListenSocket.socket, &fdsetRecv);
1236 hSocketMax = std::max(hSocketMax, hListenSocket.socket);
1255 bool select_recv = !pnode->fPauseRecv;
1258 LOCK(pnode->cs_vSend);
1259 select_send = !pnode->vSendMsg.empty();
1262 LOCK(pnode->cs_hSocket);
1266 FD_SET(pnode->hSocket, &fdsetError);
1267 hSocketMax = std::max(hSocketMax, pnode->hSocket);
1271 FD_SET(pnode->hSocket, &fdsetSend);
1275 FD_SET(pnode->hSocket, &fdsetRecv);
1280 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1281 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1291 for (
unsigned int i = 0; i <= hSocketMax; i++)
1292 FD_SET(i, &fdsetRecv);
1294 FD_ZERO(&fdsetSend);
1295 FD_ZERO(&fdsetError);
1303 for (
const ListenSocket& hListenSocket : vhListenSocket)
1305 if (hListenSocket.socket !=
INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
1314 std::vector<CNode*> vNodesCopy;
1318 for (
CNode* pnode : vNodesCopy)
1321 for (
CNode* pnode : vNodesCopy)
1329 bool recvSet =
false;
1330 bool sendSet =
false;
1331 bool errorSet =
false;
1333 LOCK(pnode->cs_hSocket);
1336 recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
1337 sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
1338 errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
1340 if (recvSet || errorSet)
1343 char pchBuf[0x10000];
1346 LOCK(pnode->cs_hSocket);
1349 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1353 bool notify =
false;
1354 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1355 pnode->CloseSocketDisconnect();
1358 size_t nSizeAdded = 0;
1359 auto it(pnode->vRecvMsg.begin());
1360 for (; it != pnode->vRecvMsg.end(); ++it) {
1361 if (!it->complete())
1366 LOCK(pnode->cs_vProcessMsg);
1367 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1368 pnode->nProcessQueueSize += nSizeAdded;
1374 else if (nBytes == 0)
1377 if (!pnode->fDisconnect) {
1380 pnode->CloseSocketDisconnect();
1382 else if (nBytes < 0)
1388 if (!pnode->fDisconnect)
1390 pnode->CloseSocketDisconnect();
1400 LOCK(pnode->cs_vSend);
1411 if (nTime - pnode->nTimeConnected > 60)
1413 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1415 LogPrint(
BCLog::NET,
"socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1416 pnode->fDisconnect =
true;
1418 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1420 LogPrintf(
"socket sending timeout: %is\n", nTime - pnode->nLastSend);
1421 pnode->fDisconnect =
true;
1423 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1425 LogPrintf(
"socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1426 pnode->fDisconnect =
true;
1428 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 <
GetTimeMicros())
1431 pnode->fDisconnect =
true;
1433 else if (!pnode->fSuccessfullyConnected)
1435 LogPrintf(
"version handshake timeout from %d\n", pnode->GetId());
1436 pnode->fDisconnect =
true;
1442 for (
CNode* pnode : vNodesCopy)
1463 void ThreadMapPort()
1466 const char * multicastif =
nullptr;
1467 const char * minissdpdpath =
nullptr;
1468 struct UPNPDev * devlist =
nullptr;
1471 #ifndef UPNPDISCOVER_SUCCESS 1473 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1474 #elif MINIUPNPC_API_VERSION < 14 1477 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1481 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1484 struct UPNPUrls urls;
1485 struct IGDdatas data;
1488 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1492 char externalIPAddress[40];
1493 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1494 if(r != UPNPCOMMAND_SUCCESS)
1495 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1498 if(externalIPAddress[0])
1501 if(
LookupHost(externalIPAddress, resolved,
false)) {
1507 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1515 #ifndef UPNPDISCOVER_SUCCESS 1517 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1518 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0);
1521 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1522 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1525 if(r!=UPNPCOMMAND_SUCCESS)
1526 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1527 port, port, lanaddr, r, strupnperror(r));
1529 LogPrintf(
"UPnP Port Mapping successful.\n");
1534 catch (
const boost::thread_interrupted&)
1536 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1537 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1538 freeUPNPDevlist(devlist); devlist =
nullptr;
1539 FreeUPNPUrls(&urls);
1543 LogPrintf(
"No valid UPnP IGDs found\n");
1544 freeUPNPDevlist(devlist); devlist =
nullptr;
1546 FreeUPNPUrls(&urls);
1552 static boost::thread* upnp_thread =
nullptr;
1557 upnp_thread->interrupt();
1558 upnp_thread->join();
1561 upnp_thread =
new boost::thread(boost::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort));
1563 else if (upnp_thread) {
1564 upnp_thread->interrupt();
1565 upnp_thread->join();
1567 upnp_thread =
nullptr;
1592 return strprintf(
"x%x.%s", *requiredServiceBits, data.
host);
1609 for (
auto pnode :
vNodes) {
1610 nRelevant += pnode->fSuccessfullyConnected && !pnode->fFeeler && !pnode->fOneShot && !pnode->m_manual_connection && !pnode->fInbound;
1612 if (nRelevant >= 2) {
1613 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1621 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1632 std::vector<CNetAddr> vIPs;
1633 std::vector<CAddress> vAdd;
1635 std::string host = GetDNSHost(seed, &requiredServiceBits);
1648 int nOneDay = 24*3600;
1653 vAdd.push_back(addr);
1661 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1694 std::string strDest;
1718 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1733 if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
1746 for (int64_t nLoop = 0;; nLoop++)
1749 for (
const std::string& strAddr :
gArgs.
GetArgs(
"-connect"))
1753 for (
int i = 0; i < 10 && i < nLoop; i++)
1768 int64_t nNextFeeler =
PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1783 static bool done =
false;
1786 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1802 std::set<std::vector<unsigned char> > setConnected;
1806 if (!pnode->fInbound && !pnode->m_manual_connection) {
1812 setConnected.insert(pnode->addr.GetGroup());
1830 bool fFeeler =
false;
1834 if (nTime > nNextFeeler) {
1865 if (nANow - addr.
nLastTry < 600 && nTries < 30) {
1872 if (!fFeeler && !HasAllDesirableServiceFlags(addr.
nServices)) {
1874 }
else if (fFeeler && !MayHaveUsefulAddressDB(addr.
nServices)) {
1905 std::vector<AddedNodeInfo> ret;
1907 std::list<std::string> lAddresses(0);
1916 std::map<CService, bool> mapConnected;
1917 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1921 if (pnode->addr.IsValid()) {
1922 mapConnected[pnode->addr] = pnode->fInbound;
1924 std::string addrName = pnode->GetAddrName();
1925 if (!addrName.empty()) {
1926 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1931 for (
const std::string& strAddNode : lAddresses) {
1935 auto it = mapConnected.find(service);
1936 if (it != mapConnected.end()) {
1937 ret.push_back(
AddedNodeInfo{strAddNode, service,
true, it->second});
1943 auto it = mapConnectedByName.find(strAddNode);
1944 if (it != mapConnectedByName.end()) {
1945 ret.push_back(
AddedNodeInfo{strAddNode, it->second.second,
true, it->second.first});
1963 if (!info.fConnected) {
1997 FindNode(addrConnect.ToStringIPPort()))
1999 }
else if (
FindNode(std::string(pszDest)))
2012 if (manual_connection)
2028 std::vector<CNode*> vNodesCopy;
2032 for (
CNode* pnode : vNodesCopy) {
2037 bool fMoreWork =
false;
2039 for (
CNode* pnode : vNodesCopy)
2041 if (pnode->fDisconnect)
2046 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2051 LOCK(pnode->cs_sendProcessing);
2061 for (
CNode* pnode : vNodesCopy)
2067 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this] {
return fMsgProcWake; });
2084 struct sockaddr_storage sockaddr;
2085 socklen_t len =
sizeof(sockaddr);
2086 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2088 strError =
strprintf(
"Error: Bind address family for %s not supported", addrBind.
ToString());
2093 SOCKET hListenSocket = socket(((
struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
2100 if (!IsSelectableSocket(hListenSocket))
2102 strError =
"Error: Couldn't create a listenable socket for incoming connections";
2111 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&nOne,
sizeof(
int));
2115 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
void*)&nOne,
sizeof(
int));
2117 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
void*)&nOne,
sizeof(
int));
2119 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
const char*)&nOne,
sizeof(
int));
2120 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
const char*)&nOne,
sizeof(
int));
2136 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
const char*)&nOne,
sizeof(
int));
2138 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
void*)&nOne,
sizeof(
int));
2142 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2143 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2147 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2171 if (addrBind.
IsRoutable() && fDiscover && !fWhitelisted)
2184 char pszHostName[256] =
"";
2185 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2187 std::vector<CNetAddr> vaddr;
2193 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2199 struct ifaddrs* myaddrs;
2200 if (getifaddrs(&myaddrs) == 0)
2202 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2204 if (ifa->ifa_addr ==
nullptr)
continue;
2205 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2206 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2207 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2208 if (ifa->ifa_addr->sa_family == AF_INET)
2210 struct sockaddr_in*
s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2215 else if (ifa->ifa_addr->sa_family == AF_INET6)
2217 struct sockaddr_in6*
s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2223 freeifaddrs(myaddrs);
2242 pnode->CloseSocketDisconnect();
2268 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2275 std::string strError;
2286 bool fBound =
false;
2287 for (
const auto& addrBind : binds) {
2290 for (
const auto& addrBind : whiteBinds) {
2293 if (binds.empty() && whiteBinds.empty()) {
2294 struct in_addr inaddr_any;
2295 inaddr_any.s_addr = INADDR_ANY;
2316 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2322 LogPrintf(
"Connection Manager: Adding Seed Nodes\n");
2324 for (
const auto& strDest : connOptions.
vSeedNodes) {
2325 LogPrintf(
"Connection Manager: Adding Seed Node: %s\n", strDest);
2341 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2351 if (bandb.
Read(banmap)) {
2359 LogPrintf(
"Invalid or missing banlist.dat; recreating\n");
2404 _(
"Cannot provide specific connections and have addrman find outgoing connections at the same."),
2489 pnode->CloseSocketDisconnect();
2496 for (
CNode *pnode : vNodes) {
2503 vNodesDisconnected.clear();
2504 vhListenSocket.clear();
2514 bool fUpdateConnectionTime =
false;
2516 if(fUpdateConnectionTime) {
2557 if (strNode == it)
return false;
2560 vAddedNodes.push_back(strNode);
2568 if (strNode == *it) {
2583 for (
const auto& pnode :
vNodes) {
2596 vstats.reserve(
vNodes.size());
2598 vstats.emplace_back();
2599 pnode->copyStats(vstats.back());
2607 pnode->fDisconnect =
true;
2616 if (
id == pnode->GetId()) {
2617 pnode->fDisconnect =
true;
2676 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2697 if (historicalBlockServingLimit)
2739 nBestHeight.store(height, std::memory_order_release);
2744 return nBestHeight.load(std::memory_order_acquire);
2752 addrBind(addrBindIn),
2753 fInbound(fInboundIn),
2754 nKeyedNetGroup(nKeyedNetGroupIn),
2755 addrKnown(5000, 0.001),
2756 filterInventoryKnown(50000, 0.000001),
2758 nLocalHostNonce(nLocalHostNonceIn),
2760 nMyStartingHeight(nMyStartingHeightIn),
2842 int64_t nRequestTime;
2845 nRequestTime = it->second;
2852 static int64_t nLastTime;
2854 nNow = std::max(nNow, nLastTime);
2858 nRequestTime = std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2863 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2873 size_t nMessageSize = msg.data.size();
2877 std::vector<unsigned char> serializedHeader;
2878 serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
2879 uint256 hash =
Hash(msg.data.data(), msg.data.data() + nMessageSize);
2885 size_t nBytesSent = 0;
2888 bool optimisticSend(pnode->
vSendMsg.empty());
2894 if (pnode->
nSendSize > nSendBufferMaxSize)
2897 pnode->
vSendMsg.push_back(std::move(serializedHeader));
2900 pnode->
vSendMsg.push_back(std::move(msg.data));
2904 if (optimisticSend ==
true)
2905 nBytesSent = SocketSendData(pnode);
2908 RecordBytesSent(nBytesSent);
2913 CNode* found =
nullptr;
2915 for (
auto&& pnode : vNodes) {
2921 return found !=
nullptr && NodeFullyConnected(found) && func(found);
2925 return nNow + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
2935 std::vector<unsigned char> vchNetGroup(ad.
GetGroup());
2937 return GetDeterministicRandomizer(RANDOMIZER_ID_NETGROUP).Write(vchNetGroup.data(), vchNetGroup.size()).Finalize();
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
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
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
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.
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)
uint64_t nMaxOutboundTimeframe
void MilliSleep(int64_t n)
CConnman(uint64_t seed0, uint64_t seed1)
bool ConnectSocketDirectly(const CService &addrConnect, SOCKET &hSocketRet, int nTimeout)
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)
std::string DateTimeStrFormat(const char *pszFormat, int64_t nTime)
bool GetNameProxy(proxyType &nameProxyOut)
boost::signals2::signal< void(bool networkActive)> NotifyNetworkActiveChanged
Network activity state changed.
CCriticalSection cs_hSocket
void AskFor(const CInv &inv)
BloomFilter is a probabilistic filter which SPV clients provide so that we can filter the transaction...
bool GetTryNewOutboundPeer()
#define FEELER_SLEEP_WINDOW
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
RAII-style semaphore lock.
bool Unban(const CNetAddr &ip)
uint64_t GetMaxOutboundTarget()
CNode * ConnectNode(CAddress addrConnect, const char *pszDest, bool fCountFailure)
void PushMessage(CNode *pnode, CSerializedNetMsg &&msg)
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
uint64_t nMaxOutboundLimit
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)
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
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()
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
boost::signals2::signal< void(void)> BannedListChanged
Banlist did change.
std::atomic< int64_t > nLastSend
void RecordBytesRecv(uint64_t bytes)
virtual bool SendMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Access to the banlist database (banlist.dat)
std::vector< CAddress > GetAddr()
Return a bunch of addresses, selected at random.
bool supportsServiceBitsFiltering
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
bool OpenNetworkConnection(const CAddress &addrConnect, bool fCountFailure, CSemaphoreGrant *grantOutbound=nullptr, const char *strDest=nullptr, bool fOneShot=false, bool fFeeler=false, bool manual_connection=false)
std::map< CSubNet, CBanEntry > banmap_t
void CloseSocketDisconnect()
uint64_t GetOutboundTargetBytesLeft()
response the bytes left in the current max outbound cycle
uint64_t nMaxOutboundCycleStartTime
bool Write(const CAddrMan &addr)
static bool NodeFullyConnected(const CNode *pnode)
int GetnScore(const CService &addr)
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
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
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::thread threadMessageHandler
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()
bool ConnectThroughProxy(const proxyType &proxy, const std::string &strDest, int port, SOCKET &hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
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
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
void SetNetworkActive(bool active)
void AddNewAddresses(const std::vector< CAddress > &vAddr, const CAddress &addrFrom, int64_t nTimePenalty=0)
int GetDefaultPort() const
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)
bool SetSocketNonBlocking(const SOCKET &hSocket, bool fNonBlocking)
Disable or enable blocking-mode for a socket.
std::atomic< int > nRefCount
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
bool Match(const CNetAddr &addr) const
void ThreadOpenConnections()
const std::vector< CDNSSeedData > & DNSSeeds() const
bool Read(banmap_t &banSet)
#define LogPrint(category,...)
std::atomic< NodeId > nLastNodeId
bool RemoveAddedNode(const std::string &node)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
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
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds)
Return a timestamp in the future (in microseconds) for exponentially distributed events.
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::vector< CSubNet > vWhitelistedRange
std::thread threadOpenConnections
bool AttemptToEvictConnection()
Try to find a connection to evict when the node is full.
bool RemoveLocal(const CService &addr)
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::vector< std::string > vAddedNodes
std::thread threadDNSAddressSeed
std::deque< std::vector< unsigned char > > vSendMsg
int64_t GetAdjustedTime()
std::string ToStringIPPort() const
size_t SocketSendData(CNode *pnode) const
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
void SetSendVersion(int nVersionIn)
mapMsgCmdSize mapRecvBytesPerMsgCmd
std::vector< ListenSocket > vhListenSocket
void SetBestHeight(int height)
CAmount lastSentFeeFilter
std::atomic< int64_t > nTimeOffset
CCriticalSection cs_totalBytesSent
std::atomic_bool fSuccessfullyConnected
void Discover(boost::thread_group &threadGroup)
void ThreadMessageHandler()
bool error(const char *fmt, const Args &... args)
std::atomic< int > nVersion
uint64_t nMaxOutboundTotalBytesSentInCycle
void InterruptSocks5(bool interrupt)
unsigned int nSendBufferMaxSize
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
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.
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
static void callCleanup()
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)
Transform an arbitrary string into a non-routable ipv6 address.
virtual void InitializeNode(CNode *pnode)=0
std::string GetAddrName() const
CCriticalSection cs_vSend
unsigned int GetMaxBlockSerializedSize()
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
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: Call Translate signal on UI interface, which returns a boost::optional result...
virtual bool ProcessMessages(CNode *pnode, std::atomic< bool > &interrupt)=0
Wrapped boost mutex: supports recursive locking, but no waiting TODO: We should move away from using ...
int64_t nLastTry
last try whatsoever by us (memory only)
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
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
void Good(const CService &addr, int64_t nTime=GetAdjustedTime())
Mark an entry as accessible.
bool BindListenPort(const CService &bindAddr, std::string &strError, bool fWhitelisted=false)
void ThreadDNSAddressSeed()