6 #if defined(HAVE_CONFIG_H) 32 #include <miniupnpc/miniupnpc.h> 33 #include <miniupnpc/miniwget.h> 34 #include <miniupnpc/upnpcommands.h> 35 #include <miniupnpc/upnperrors.h> 42 #define DUMP_ADDRESSES_INTERVAL 900 45 #define FEELER_SLEEP_WINDOW 1 47 #if !defined(HAVE_MSG_NOSIGNAL) 48 #define MSG_NOSIGNAL 0 52 #if !defined(HAVE_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 = 0x6c0edd8036ef4036ULL;
78 static const uint64_t RANDOMIZER_ID_LOCALHOSTNONCE = 0xd93e69e2bbfa5735ULL;
87 static bool vfLimited[
NET_MAX] = {};
110 int nBestReachability = -1;
112 LOCK(cs_mapLocalHost);
113 for (std::map<CNetAddr, LocalServiceInfo>::iterator it = mapLocalHost.begin(); it != mapLocalHost.end(); it++)
115 int nScore = (*it).second.nScore;
116 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
117 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
119 addr =
CService((*it).first, (*it).second.nPort);
120 nBestReachability = nReachability;
125 return nBestScore >= 0;
129 static std::vector<CAddress> convertSeed6(
const std::vector<SeedSpec6> &vSeedsIn)
135 const int64_t nOneWeek = 7*24*60*60;
136 std::vector<CAddress> vSeedsOut;
137 vSeedsOut.reserve(vSeedsIn.size());
138 for (std::vector<SeedSpec6>::const_iterator i(vSeedsIn.begin()); i != vSeedsIn.end(); ++i)
141 memcpy(&ip, i->addr,
sizeof(ip));
144 vSeedsOut.push_back(addr);
159 ret =
CAddress(addr, nLocalServices);
167 LOCK(cs_mapLocalHost);
170 return mapLocalHost[addr].nScore;
219 LOCK(cs_mapLocalHost);
220 bool fAlready = mapLocalHost.count(addr) > 0;
222 if (!fAlready || nScore >= info.
nScore) {
223 info.
nScore = nScore + (fAlready ? 1 : 0);
238 LOCK(cs_mapLocalHost);
240 mapLocalHost.erase(addr);
249 LOCK(cs_mapLocalHost);
250 vfLimited[net] = fLimited;
255 LOCK(cs_mapLocalHost);
256 return vfLimited[net];
268 LOCK(cs_mapLocalHost);
269 if (mapLocalHost.count(addr) == 0)
271 mapLocalHost[addr].nScore++;
280 LOCK(cs_mapLocalHost);
281 return mapLocalHost.count(addr) > 0;
287 LOCK(cs_mapLocalHost);
288 return !vfLimited[net];
321 if (pnode->GetAddrName() == addrName) {
341 if (!pnode->fSuccessfullyConnected && !pnode->fInbound && pnode->GetLocalNonce() == nonce)
351 struct sockaddr_storage sockaddr_bind;
352 socklen_t sockaddr_bind_len =
sizeof(sockaddr_bind);
354 if (!getsockname(sock, (
struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
355 addr_bind.
SetSockAddr((
const struct sockaddr*)&sockaddr_bind);
365 if (pszDest ==
nullptr) {
373 LogPrintf(
"Failed to open new connection, already connected\n");
380 pszDest ? pszDest : addrConnect.
ToString(),
385 bool proxyConnectionFailed =
false;
389 if (!IsSelectableSocket(hSocket)) {
390 LogPrintf(
"Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
395 if (pszDest && addrConnect.
IsValid()) {
406 LogPrintf(
"Failed to open new connection, already connected\n");
416 CAddress addr_bind = GetBindAddress(hSocket);
422 }
else if (!proxyConnectionFailed) {
443 if (bandb.
Write(banmap)) {
492 banmap_t::iterator i =
setBanned.find(subnet);
505 Ban(subNet, banReason, bantimeoffset, sinceUnixEpoch);
511 if (bantimeoffset <= 0)
513 bantimeoffset =
gArgs.
GetArg(
"-bantime", DEFAULT_MISBEHAVING_BANTIME);
514 sinceUnixEpoch =
false;
533 pnode->fDisconnect =
true;
542 return Unban(subNet);
578 banmap_t::iterator it =
setBanned.begin();
609 if (subnet.Match(addr))
622 if (addrName.empty()) {
623 addrName = addrNameIn;
634 if (addrLocal.IsValid()) {
635 error(
"Addr local already set for node: %i. Refusing to change from %s to %s",
id, addrLocal.ToString(), addrLocalIn.
ToString());
637 addrLocal = addrLocalIn;
642 #define X(name) stats.name = name 645 stats.
nodeid = this->GetId();
664 X(m_manual_connection);
668 X(mapSendBytesPerMsgCmd);
673 X(mapRecvBytesPerMsgCmd);
684 int64_t nPingUsecWait = 0;
685 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
690 stats.
dPingTime = (((double)nPingUsecTime) / 1e6);
691 stats.
dMinPing = (((double)nMinPingUsecTime) / 1e6);
692 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
695 CService addrLocalUnlocked = GetAddrLocal();
705 nLastRecv = nTimeMicros / 1000000;
706 nRecvBytes += nBytes;
710 if (vRecvMsg.empty() ||
711 vRecvMsg.back().complete())
721 handled = msg.
readData(pch, nBytes);
739 mapMsgCmdSize::iterator i = mapRecvBytesPerMsgCmd.find(msg.
hdr.
pchCommand);
740 if (i == mapRecvBytesPerMsgCmd.end())
741 i = mapRecvBytesPerMsgCmd.find(NET_MESSAGE_COMMAND_OTHER);
742 assert(i != mapRecvBytesPerMsgCmd.end());
745 msg.
nTime = nTimeMicros;
760 if (nSendVersion != 0) {
761 error(
"Send version already set for node: %i. Refusing to change from %i to %i",
id, nSendVersion, nVersionIn);
763 nSendVersion = nVersionIn;
772 if (nSendVersion == 0) {
773 error(
"Requesting unset send version for node: %i. Using %i",
id, INIT_PROTO_VERSION);
774 return INIT_PROTO_VERSION;
783 unsigned int nRemaining = 24 - nHdrPos;
784 unsigned int nCopy =
std::min(nRemaining, nBytes);
786 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
797 catch (
const std::exception&) {
802 if (hdr.nMessageSize > MAX_SIZE)
813 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
814 unsigned int nCopy =
std::min(nRemaining, nBytes);
816 if (vRecv.size() < nDataPos + nCopy) {
818 vRecv.resize(
std::min(hdr.nMessageSize, nDataPos + nCopy + 256 * 1024));
821 hasher.Write((
const unsigned char*)pch, nCopy);
822 memcpy(&vRecv[nDataPos], pch, nCopy);
831 if (data_hash.IsNull())
832 hasher.Finalize(data_hash.begin());
848 size_t nSentSize = 0;
850 while (it != pnode->
vSendMsg.end()) {
851 const auto &
data = *it;
952 std::vector<NodeEvictionCandidate> vEvictionCandidates;
957 if (
node->fWhitelisted)
961 if (
node->fDisconnect)
964 node->nLastBlockTime,
node->nLastTXTime,
966 node->fRelayTxes,
node->pfilter !=
nullptr,
node->addr,
node->nKeyedNetGroup};
967 vEvictionCandidates.push_back(candidate);
971 if (vEvictionCandidates.empty())
return false;
977 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNetGroupKeyed);
978 vEvictionCandidates.erase(vEvictionCandidates.end() -
std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
980 if (vEvictionCandidates.empty())
return false;
984 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeMinPingTime);
985 vEvictionCandidates.erase(vEvictionCandidates.end() -
std::min(8, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
987 if (vEvictionCandidates.empty())
return false;
991 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeTXTime);
992 vEvictionCandidates.erase(vEvictionCandidates.end() -
std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
994 if (vEvictionCandidates.empty())
return false;
998 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), CompareNodeBlockTime);
999 vEvictionCandidates.erase(vEvictionCandidates.end() -
std::min(4, static_cast<int>(vEvictionCandidates.size())), vEvictionCandidates.end());
1001 if (vEvictionCandidates.empty())
return false;
1005 std::sort(vEvictionCandidates.begin(), vEvictionCandidates.end(), ReverseCompareNodeTimeConnected);
1006 vEvictionCandidates.erase(vEvictionCandidates.end() -
static_cast<int>(vEvictionCandidates.size() / 2), vEvictionCandidates.end());
1008 if (vEvictionCandidates.empty())
return false;
1012 uint64_t naMostConnections;
1013 unsigned int nMostConnections = 0;
1014 int64_t nMostConnectionsTime = 0;
1015 std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
1017 mapNetGroupNodes[
node.nKeyedNetGroup].push_back(
node);
1018 int64_t grouptime = mapNetGroupNodes[
node.nKeyedNetGroup][0].nTimeConnected;
1019 size_t groupsize = mapNetGroupNodes[
node.nKeyedNetGroup].size();
1021 if (groupsize > nMostConnections || (groupsize == nMostConnections && grouptime > nMostConnectionsTime)) {
1022 nMostConnections = groupsize;
1023 nMostConnectionsTime = grouptime;
1024 naMostConnections =
node.nKeyedNetGroup;
1029 vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
1032 NodeId evicted = vEvictionCandidates.front().id;
1034 for(std::vector<CNode*>::const_iterator it(
vNodes.begin()); it !=
vNodes.end(); ++it) {
1035 if ((*it)->GetId() == evicted) {
1036 (*it)->fDisconnect =
true;
1044 struct sockaddr_storage sockaddr;
1045 socklen_t len =
sizeof(sockaddr);
1046 SOCKET hSocket = accept(hListenSocket.
socket, (
struct sockaddr*)&sockaddr, &len);
1052 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr)) {
1053 LogPrintf(
"Warning: Unknown socket family\n");
1061 if (pnode->fInbound)
1074 LogPrintf(
"connection from %s dropped: not accepting new connections\n", addr.
ToString());
1079 if (!IsSelectableSocket(hSocket))
1081 LogPrintf(
"connection from %s dropped: non-selectable socket\n", addr.
ToString());
1090 if (
IsBanned(addr) && !whitelisted)
1097 if (nInbound >= nMaxInbound)
1101 LogPrint(
BCLog::NET,
"failed to find an eviction candidate - connection dropped (full)\n");
1109 CAddress addr_bind = GetBindAddress(hSocket);
1126 unsigned int nPrevNodeCount = 0;
1135 std::vector<CNode*> vNodesCopy =
vNodes;
1136 for (
CNode* pnode : vNodesCopy)
1138 if (pnode->fDisconnect)
1144 pnode->grantOutbound.Release();
1147 pnode->CloseSocketDisconnect();
1158 for (
CNode* pnode : vNodesDisconnectedCopy)
1161 if (pnode->GetRefCount() <= 0) {
1162 bool fDelete =
false;
1164 TRY_LOCK(pnode->cs_inventory, lockInv);
1166 TRY_LOCK(pnode->cs_vSend, lockSend);
1182 vNodesSize =
vNodes.size();
1184 if(vNodesSize != nPrevNodeCount) {
1185 nPrevNodeCount = vNodesSize;
1193 struct timeval timeout;
1195 timeout.tv_usec = 50000;
1200 FD_ZERO(&fdsetRecv);
1201 FD_ZERO(&fdsetSend);
1202 FD_ZERO(&fdsetError);
1204 bool have_fds =
false;
1207 FD_SET(hListenSocket.socket, &fdsetRecv);
1208 hSocketMax =
std::max(hSocketMax, hListenSocket.socket);
1227 bool select_recv = !pnode->fPauseRecv;
1230 LOCK(pnode->cs_vSend);
1231 select_send = !pnode->vSendMsg.empty();
1234 LOCK(pnode->cs_hSocket);
1238 FD_SET(pnode->hSocket, &fdsetError);
1239 hSocketMax =
std::max(hSocketMax, pnode->hSocket);
1243 FD_SET(pnode->hSocket, &fdsetSend);
1247 FD_SET(pnode->hSocket, &fdsetRecv);
1252 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
1253 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
1263 for (
unsigned int i = 0; i <= hSocketMax; i++)
1264 FD_SET(i, &fdsetRecv);
1266 FD_ZERO(&fdsetSend);
1267 FD_ZERO(&fdsetError);
1275 for (
const ListenSocket& hListenSocket : vhListenSocket)
1277 if (hListenSocket.socket !=
INVALID_SOCKET && FD_ISSET(hListenSocket.socket, &fdsetRecv))
1286 std::vector<CNode*> vNodesCopy;
1290 for (
CNode* pnode : vNodesCopy)
1293 for (
CNode* pnode : vNodesCopy)
1301 bool recvSet =
false;
1302 bool sendSet =
false;
1303 bool errorSet =
false;
1305 LOCK(pnode->cs_hSocket);
1308 recvSet = FD_ISSET(pnode->hSocket, &fdsetRecv);
1309 sendSet = FD_ISSET(pnode->hSocket, &fdsetSend);
1310 errorSet = FD_ISSET(pnode->hSocket, &fdsetError);
1312 if (recvSet || errorSet)
1315 char pchBuf[0x10000];
1318 LOCK(pnode->cs_hSocket);
1321 nBytes = recv(pnode->hSocket, pchBuf,
sizeof(pchBuf),
MSG_DONTWAIT);
1325 bool notify =
false;
1326 if (!pnode->ReceiveMsgBytes(pchBuf, nBytes, notify))
1327 pnode->CloseSocketDisconnect();
1330 size_t nSizeAdded = 0;
1331 auto it(pnode->vRecvMsg.begin());
1332 for (; it != pnode->vRecvMsg.end(); ++it) {
1333 if (!it->complete())
1338 LOCK(pnode->cs_vProcessMsg);
1339 pnode->vProcessMsg.splice(pnode->vProcessMsg.end(), pnode->vRecvMsg, pnode->vRecvMsg.begin(), it);
1340 pnode->nProcessQueueSize += nSizeAdded;
1346 else if (nBytes == 0)
1349 if (!pnode->fDisconnect) {
1352 pnode->CloseSocketDisconnect();
1354 else if (nBytes < 0)
1360 if (!pnode->fDisconnect)
1362 pnode->CloseSocketDisconnect();
1372 LOCK(pnode->cs_vSend);
1383 if (nTime - pnode->nTimeConnected > 60)
1385 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1387 LogPrint(
BCLog::NET,
"socket no message in first 60 seconds, %d %d from %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0, pnode->GetId());
1388 pnode->fDisconnect =
true;
1390 else if (nTime - pnode->nLastSend > TIMEOUT_INTERVAL)
1392 LogPrintf(
"socket sending timeout: %is\n", nTime - pnode->nLastSend);
1393 pnode->fDisconnect =
true;
1395 else if (nTime - pnode->nLastRecv > (pnode->nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1397 LogPrintf(
"socket receive timeout: %is\n", nTime - pnode->nLastRecv);
1398 pnode->fDisconnect =
true;
1400 else if (pnode->nPingNonceSent && pnode->nPingUsecStart + TIMEOUT_INTERVAL * 1000000 <
GetTimeMicros())
1403 pnode->fDisconnect =
true;
1405 else if (!pnode->fSuccessfullyConnected)
1407 LogPrintf(
"version handshake timeout from %d\n", pnode->GetId());
1408 pnode->fDisconnect =
true;
1414 for (
CNode* pnode : vNodesCopy)
1435 void ThreadMapPort()
1438 const char * multicastif = 0;
1439 const char * minissdpdpath = 0;
1440 struct UPNPDev * devlist = 0;
1443 #ifndef UPNPDISCOVER_SUCCESS 1445 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1446 #elif MINIUPNPC_API_VERSION < 14 1449 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1453 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);
1456 struct UPNPUrls urls;
1457 struct IGDdatas data;
1460 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1464 char externalIPAddress[40];
1465 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1466 if(r != UPNPCOMMAND_SUCCESS)
1467 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1470 if(externalIPAddress[0])
1473 if(
LookupHost(externalIPAddress, resolved,
false)) {
1479 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1487 #ifndef UPNPDISCOVER_SUCCESS 1489 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1490 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0);
1493 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1494 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1497 if(r!=UPNPCOMMAND_SUCCESS)
1498 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1499 port, port, lanaddr, r, strupnperror(r));
1501 LogPrintf(
"UPnP Port Mapping successful.\n");
1506 catch (
const boost::thread_interrupted&)
1508 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1509 LogPrintf(
"UPNP_DeletePortMapping() returned: %d\n", r);
1510 freeUPNPDevlist(devlist); devlist = 0;
1511 FreeUPNPUrls(&urls);
1515 LogPrintf(
"No valid UPnP IGDs found\n");
1516 freeUPNPDevlist(devlist); devlist = 0;
1518 FreeUPNPUrls(&urls);
1524 static boost::thread* upnp_thread =
nullptr;
1529 upnp_thread->interrupt();
1530 upnp_thread->join();
1533 upnp_thread =
new boost::thread(boost::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort));
1535 else if (upnp_thread) {
1536 upnp_thread->interrupt();
1537 upnp_thread->join();
1539 upnp_thread =
nullptr;
1564 return strprintf(
"x%x.%s", *requiredServiceBits, data.
host);
1581 for (
auto pnode :
vNodes) {
1584 if (nRelevant >= 2) {
1585 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1593 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1602 std::vector<CNetAddr> vIPs;
1603 std::vector<CAddress> vAdd;
1605 std::string host = GetDNSHost(seed, &requiredServiceBits);
1614 int nOneDay = 24*3600;
1617 vAdd.push_back(addr);
1625 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1658 std::string strDest;
1682 LogPrint(
BCLog::NET,
"net: setting try another outbound peer=%s\n", flag ?
"true" :
"false");
1697 if (!pnode->fInbound && !pnode->m_manual_connection && !pnode->fFeeler && !pnode->fDisconnect && !pnode->fOneShot && pnode->fSuccessfullyConnected) {
1710 for (int64_t nLoop = 0;; nLoop++)
1713 for (
const std::string& strAddr :
gArgs.
GetArgs(
"-connect"))
1717 for (
int i = 0; i < 10 && i < nLoop; i++)
1732 int64_t nNextFeeler =
PoissonNextSend(nStart*1000*1000, FEELER_INTERVAL);
1746 static bool done =
false;
1748 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1764 int nOutboundRelevant = 0;
1765 std::set<std::vector<unsigned char> > setConnected;
1769 if (!pnode->fInbound && !pnode->m_manual_connection) {
1773 nOutboundRelevant++;
1780 setConnected.insert(pnode->addr.GetGroup());
1798 bool fFeeler =
false;
1802 if (nTime > nNextFeeler) {
1831 if ((addr.
nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1835 if (nANow - addr.
nLastTry < 600 && nTries < 30)
1841 nRequiredServices = REQUIRED_SERVICES;
1844 if ((addr.
nServices & nRequiredServices) != nRequiredServices) {
1856 addrConnect.
nServices = REQUIRED_SERVICES;
1858 addrConnect.
nServices = nRequiredServices;
1880 std::vector<AddedNodeInfo> ret;
1882 std::list<std::string> lAddresses(0);
1887 lAddresses.push_back(strAddNode);
1892 std::map<CService, bool> mapConnected;
1893 std::map<std::string, std::pair<bool, CService>> mapConnectedByName;
1897 if (pnode->addr.IsValid()) {
1898 mapConnected[pnode->addr] = pnode->fInbound;
1900 std::string addrName = pnode->GetAddrName();
1901 if (!addrName.empty()) {
1902 mapConnectedByName[std::move(addrName)] = std::make_pair(pnode->fInbound, static_cast<const CService&>(pnode->addr));
1907 for (
const std::string& strAddNode : lAddresses) {
1911 auto it = mapConnected.find(service);
1912 if (it != mapConnected.end()) {
1913 ret.push_back(
AddedNodeInfo{strAddNode, service,
true, it->second});
1919 auto it = mapConnectedByName.find(strAddNode);
1920 if (it != mapConnectedByName.end()) {
1921 ret.push_back(
AddedNodeInfo{strAddNode, it->second.second,
true, it->second.first});
1944 if (!info.fConnected) {
1980 FindNode(addrConnect.ToStringIPPort()))
1982 }
else if (
FindNode(std::string(pszDest)))
1995 if (manual_connection)
2011 std::vector<CNode*> vNodesCopy;
2015 for (
CNode* pnode : vNodesCopy) {
2020 bool fMoreWork =
false;
2022 for (
CNode* pnode : vNodesCopy)
2024 if (pnode->fDisconnect)
2029 fMoreWork |= (fMoreNodeWork && !pnode->fPauseSend);
2034 LOCK(pnode->cs_sendProcessing);
2044 for (
CNode* pnode : vNodesCopy)
2050 condMsgProc.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::milliseconds(100), [
this] {
return fMsgProcWake; });
2067 struct sockaddr_storage sockaddr;
2068 socklen_t len =
sizeof(sockaddr);
2069 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
2071 strError =
strprintf(
"Error: Bind address family for %s not supported", addrBind.
ToString());
2076 SOCKET hListenSocket = socket(((
struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
2083 if (!IsSelectableSocket(hListenSocket))
2085 strError =
"Error: Couldn't create a listenable socket for incoming connections";
2094 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&nOne,
sizeof(
int));
2098 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
void*)&nOne,
sizeof(
int));
2100 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
void*)&nOne,
sizeof(
int));
2102 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
const char*)&nOne,
sizeof(
int));
2103 setsockopt(hListenSocket, IPPROTO_TCP, TCP_NODELAY, (
const char*)&nOne,
sizeof(
int));
2119 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
const char*)&nOne,
sizeof(
int));
2121 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
void*)&nOne,
sizeof(
int));
2125 int nProtLevel = PROTECTION_LEVEL_UNRESTRICTED;
2126 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL, (
const char*)&nProtLevel,
sizeof(
int));
2130 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
2154 if (addrBind.
IsRoutable() && fDiscover && !fWhitelisted)
2167 char pszHostName[256] =
"";
2168 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
2170 std::vector<CNetAddr> vaddr;
2176 LogPrintf(
"%s: %s - %s\n", __func__, pszHostName, addr.ToString());
2182 struct ifaddrs* myaddrs;
2183 if (getifaddrs(&myaddrs) == 0)
2185 for (
struct ifaddrs* ifa = myaddrs; ifa !=
nullptr; ifa = ifa->ifa_next)
2187 if (ifa->ifa_addr ==
nullptr)
continue;
2188 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
2189 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
2190 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
2191 if (ifa->ifa_addr->sa_family == AF_INET)
2193 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
2198 else if (ifa->ifa_addr->sa_family == AF_INET6)
2200 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
2206 freeifaddrs(myaddrs);
2225 pnode->CloseSocketDisconnect();
2251 return nLastNodeId.fetch_add(1, std::memory_order_relaxed);
2258 std::string strError;
2269 bool fBound =
false;
2270 for (
const auto& addrBind : binds) {
2273 for (
const auto& addrBind : whiteBinds) {
2276 if (binds.empty() && whiteBinds.empty()) {
2277 struct in_addr inaddr_any;
2278 inaddr_any.s_addr = INADDR_ANY;
2297 _(
"Failed to listen on any port. Use -listen=0 if you want this."),
2303 for (
const auto& strDest : connOptions.
vSeedNodes) {
2318 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
2328 if (bandb.
Read(banmap)) {
2336 LogPrintf(
"Invalid or missing banlist.dat; recreating\n");
2451 pnode->CloseSocketDisconnect();
2458 for (
CNode *pnode : vNodes) {
2465 vNodesDisconnected.clear();
2466 vhListenSocket.clear();
2476 bool fUpdateConnectionTime =
false;
2478 if(fUpdateConnectionTime) {
2531 if (strNode == *it) {
2546 for(std::vector<CNode*>::const_iterator it =
vNodes.begin(); it !=
vNodes.end(); ++it)
2557 vstats.reserve(
vNodes.size());
2558 for(std::vector<CNode*>::iterator it =
vNodes.begin(); it !=
vNodes.end(); ++it) {
2560 vstats.emplace_back();
2569 pnode->fDisconnect =
true;
2578 if (
id == pnode->GetId()) {
2579 pnode->fDisconnect =
true;
2638 return (cycleEndTime < now) ? 0 : cycleEndTime -
GetTime();
2659 if (historicalBlockServingLimit)
2703 nBestHeight.store(height, std::memory_order_release);
2708 return nBestHeight.load(std::memory_order_acquire);
2716 addrBind(addrBindIn),
2717 fInbound(fInboundIn),
2718 nKeyedNetGroup(nKeyedNetGroupIn),
2719 addrKnown(5000, 0.001),
2720 filterInventoryKnown(50000, 0.000001),
2722 nLocalHostNonce(nLocalHostNonceIn),
2724 nMyStartingHeight(nMyStartingHeightIn),
2804 int64_t nRequestTime;
2807 nRequestTime = it->second;
2814 static int64_t nLastTime;
2820 nRequestTime =
std::max(nRequestTime + 2 * 60 * 1000000, nNow);
2825 mapAskFor.insert(std::make_pair(nRequestTime, inv));
2835 size_t nMessageSize = msg.data.size();
2839 std::vector<unsigned char> serializedHeader;
2840 serializedHeader.reserve(CMessageHeader::HEADER_SIZE);
2841 uint256 hash =
Hash(msg.data.data(), msg.data.data() + nMessageSize);
2847 size_t nBytesSent = 0;
2850 bool optimisticSend(pnode->
vSendMsg.empty());
2856 if (pnode->
nSendSize > nSendBufferMaxSize)
2858 pnode->
vSendMsg.push_back(std::move(serializedHeader));
2860 pnode->
vSendMsg.push_back(std::move(msg.data));
2863 if (optimisticSend ==
true)
2864 nBytesSent = SocketSendData(pnode);
2867 RecordBytesSent(nBytesSent);
2872 CNode* found =
nullptr;
2874 for (
auto&& pnode : vNodes) {
2880 return found !=
nullptr && NodeFullyConnected(found) && func(found);
2884 return nNow + (int64_t)(log1p(
GetRand(1ULL << 48) * -0.0000000000000035527136788 ) * average_interval_seconds * -1000000.0 + 0.5);
2894 std::vector<unsigned char> vchNetGroup(ad.
GetGroup());
2896 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
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)
bool error(const char *fmt, const Args &...args)
bool BannedSetIsDirty()
check is the banlist has unwritten changes
std::atomic< uint64_t > nPingNonceSent
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
#define function(a, b, c, d, k, s)
unsigned short GetPort() const
uint64_t CalculateKeyedNetGroup(const CAddress &ad) 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.
unsigned int GetReceiveFloodSize() const
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)
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.
bool IsArgSet(const std::string &strArg)
Return true if the given argument has been manually set.
std::atomic< int > nBestHeight
void SetIP(const CNetAddr &ip)
void WakeMessageHandler()
void SetServices(const CService &addr, ServiceFlags nServices)
unsigned int dgpMaxBlockSerSize
The maximum allowed size for a serialized block, in bytes (only for buffer size limits) ...
ServiceFlags GetLocalServices() 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)
std::string ToStringIPPort() const
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)
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
void SetMaxOutboundTimeframe(uint64_t timeframe)
set the timeframe for the max outbound target
uint64_t nMaxOutboundLimit
CService GetAddrLocal() const
void GetBanned(banmap_t &banmap)
NetEventsInterface * m_msgproc
std::atomic< int64_t > nPingUsecStart
CCriticalSection cs_vNodes
CAddress GetLocalAddress(const CNetAddr *paddrPeer, ServiceFlags nLocalServices)
std::vector< std::string > GetArgs(const std::string &strArg)
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
std::string ToString() const
assert(len-trim+(2 *lenIndices)<=WIDTH)
CCriticalSection cs_vAddedNodes
void SetTryNewOutboundPeer(bool flag)
unsigned short GetListenPort()
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.
bool Match(const CNetAddr &addr) const
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()
bool ConnectSocketByName(CService &addr, SOCKET &hSocketRet, const char *pszDest, int portDefault, int nTimeout, bool *outProxyConnectionFailed)
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.
ServiceFlags nServicesExpected
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)
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
size_t size() const
Return the number of (unique) addresses in all tables.
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.
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()
uint64_t GetMaxOutboundTimeLeftInCycle()
response the time in second left in the current max outbound cycle
std::atomic< int64_t > nLastRecv
int GetDefaultPort() const
const uint64_t nSeed0
SipHasher seeds for deterministic randomness.
bool InitBinds(const std::vector< CService > &binds, const std::vector< CService > &whiteBinds)
std::thread threadOpenAddedConnections
CNode * FindNode(const CNetAddr &ip)
size_t GetAddressCount() const
std::vector< CNode * > vNodes
std::deque< std::string > vOneShots
bool IsPeerAddrLocalGood(CNode *pnode)
bool ConnectSocket(const CService &addrDest, SOCKET &hSocketRet, int nTimeout, bool *outProxyConnectionFailed)
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< CAddress > GetAddresses()
CRollingBloomFilter filterInventoryKnown
ServiceFlags nRelevantServices
Services this instance cares about.
std::thread threadMessageHandler
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
std::vector< byte > bytes
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::string ToString() const
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)
CClientUIInterface * clientInterface
void GetNodeStats(std::vector< CNodeStats > &vstats)
int GetSendVersion() const
std::atomic_bool fDisconnect
std::string strSubVersion
Subversion as sent to the P2P network in version messages.
ServiceFlags GetLocalServices() const
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
int readData(const char *pch, unsigned int nBytes)
void DeleteNode(CNode *pnode)
const uint256 & GetMessageHash() const
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.
std::vector< unsigned char > GetGroup() const
void ThreadOpenConnections()
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
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 GetAddrName() const
std::atomic< int64_t > nLastTXTime
int GetBestHeight() const
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
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
bool SetSocketNoDelay(const SOCKET &hSocket)
Set the TCP_NODELAY flag on a socket.
void * memcpy(void *a, const void *b, size_t c)
bool fAddressesInitialized
std::vector< std::string > vAddedNodes
std::thread threadDNSAddressSeed
std::deque< std::vector< unsigned char > > vSendMsg
int64_t GetAdjustedTime()
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()
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.
unsigned int dgpMaxProtoMsgLength
class CNetCleanup instance_of_cnetcleanup
int readHeader(const char *pch, unsigned int nBytes)
int GetExtraOutboundCount()
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
CSipHasher GetDeterministicRandomizer(uint64_t id) const
Get a unique deterministic randomizer.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
std::string ToString() const
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 ToString() const
CCriticalSection cs_vSend
const std::vector< CDNSSeedData > & DNSSeeds() const
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)
std::atomic< int > nRecvVersion
std::atomic< int64_t > nLastBlockTime
size_t SocketSendData(CNode *pnode) const
std::multimap< int64_t, CInv > mapAskFor
bool Read(CAddrMan &addr)
void AdvertiseLocal(CNode *pnode)
std::vector< AddedNodeInfo > GetAddedNodeInfo()
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) 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()
enum Network GetNetwork() const