26 #include <miniupnpc/miniupnpc.h>
27 #include <miniupnpc/miniwget.h>
28 #include <miniupnpc/upnpcommands.h>
29 #include <miniupnpc/upnperrors.h>
32 #include <boost/filesystem.hpp>
35 #define DUMP_ADDRESSES_INTERVAL 900
37 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
38 #define MSG_NOSIGNAL 0
42 using namespace boost;
44 static const int MAX_OUTBOUND_CONNECTIONS = 24;
55 static bool vfReachable[
NET_MAX] = {};
56 static bool vfLimited[
NET_MAX] = {};
57 static CNode* pnodeLocalHost = NULL;
58 static CNode* pnodeSync = NULL;
60 static std::vector<SOCKET> vhListenSocket;
68 static std::vector<SOCKET> vhI2PListenSocket;
69 int nI2PNodeCount = 0;
81 static deque<string> vOneShots;
102 vOneShots.push_back(strDest);
107 return (
unsigned short)(
GetArg(
"-port",
Params().GetDefaultPort()));
117 int nBestReachability = -1;
119 LOCK(cs_mapLocalHost);
122 int nScore = (*it).second.nScore;
123 int nReachability = (*it).first.GetReachabilityFrom(paddrPeer);
124 if (nReachability > nBestReachability || (nReachability == nBestReachability && nScore > nBestScore))
126 addr =
CService((*it).first, (*it).second.nPort);
127 nBestReachability = nReachability;
132 return nBestScore >= 0;
155 int nBytes = recv(hSocket, &c, 1, 0);
163 if (strLine.size() >= 9000)
166 else if (nBytes <= 0)
168 boost::this_thread::interruption_point();
180 if (!strLine.empty())
185 LogPrint(
"net",
"socket closed\n");
201 void static AdvertizeLocal()
220 LOCK(cs_mapLocalHost);
221 vfReachable[net] = fFlag;
241 LOCK(cs_mapLocalHost);
244 if (!fAlready || nScore >= info.
nScore) {
245 info.
nScore = nScore + (fAlready ? 1 : 0);
266 LOCK(cs_mapLocalHost);
267 vfLimited[net] = fLimited;
272 LOCK(cs_mapLocalHost);
273 return vfLimited[net];
285 LOCK(cs_mapLocalHost);
299 LOCK(cs_mapLocalHost);
306 LOCK(cs_mapLocalHost);
307 return vfReachable[net] && !vfLimited[net];
321 return error(
"GetMyExternalIP() : connection to %s failed", addrConnect.
ToString());
337 if (pszKeyword == NULL)
339 if (strLine.find(pszKeyword) != string::npos)
341 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
346 if (strLine.find(
"<") != string::npos)
347 strLine = strLine.substr(0, strLine.find(
"<"));
348 strLine = strLine.substr(strspn(strLine.c_str(),
" \t\n\r"));
349 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
350 strLine.resize(strLine.size()-1);
360 return error(
"GetMyExternalIP() : connection closed");
367 const char* pszKeyword;
369 for (
int nLookup = 0; nLookup <= 1; nLookup++)
370 for (
int nHost = 1; nHost <= 1; nHost++)
378 addrConnect =
CService(
"91.198.22.70", 80);
382 CService addrIP(
"checkip.dyndns.org", 80,
true);
384 addrConnect = addrIP;
387 pszGet =
"GET / HTTP/1.1\r\n"
388 "Host: checkip.dyndns.org\r\n"
389 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
390 "Connection: close\r\n"
393 pszKeyword =
"Address:";
459 if (pszDest == NULL) {
474 LogPrint(
"net",
"trying connection %s lastseen=%.1fhrs\n",
475 pszDest ? pszDest : addrConnect.
ToString(),
484 LogPrint(
"net",
"connected %s\n", pszDest ? pszDest : addrConnect.
ToString());
489 if (ioctlsocket(hSocket, FIONBIO, &nOne) ==
SOCKET_ERROR)
492 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) ==
SOCKET_ERROR)
497 CNode* pnode =
new CNode(hSocket, addrConnect, pszDest ? pszDest :
"",
false);
504 if (addrConnect.IsNativeI2P()) ++nI2PNodeCount;
522 LogPrint(
"net",
"disconnecting node %s\n", addrName);
533 if (
this == pnodeSync)
544 int nBestHeight = g_signals.
GetHeight().get_value_or(0);
551 LogPrint(
"net",
"send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.
ToString(), addrYou.
ToString(), addr.ToString());
552 PushMessage(
"version", PROTOCOL_VERSION,
nLocalServices, nTime, addrYou, addrMe,
570 bool fResult =
false;
573 std::map<CNetAddr, int64_t>::iterator i = setBanned.find(ip);
574 if (i != setBanned.end())
576 int64_t t = (*i).second;
588 if (setBanned[addr] < banTime)
589 setBanned[addr] = banTime;
595 #define X(name) stats.name = name
598 stats.
nodeid = this->GetId();
618 int64_t nPingUsecWait = 0;
619 if ((0 != nPingNonceSent) && (0 != nPingUsecStart)) {
624 stats.
dPingTime = (((double)nPingUsecTime) / 1e6);
625 stats.
dPingWait = (((double)nPingUsecWait) / 1e6);
638 if (vRecvMsg.empty() ||
639 vRecvMsg.back().complete())
649 handled = msg.
readData(pch, nBytes);
664 unsigned int nRemaining = 24 - nHdrPos;
665 unsigned int nCopy = std::min(nRemaining, nBytes);
667 memcpy(&hdrbuf[nHdrPos], pch, nCopy);
678 catch (std::exception &e) {
683 if (hdr.nMessageSize > MAX_SIZE)
688 vRecv.resize(hdr.nMessageSize);
695 unsigned int nRemaining = hdr.nMessageSize - nDataPos;
696 unsigned int nCopy = std::min(nRemaining, nBytes);
698 memcpy(&vRecv[nDataPos], pch, nCopy);
715 std::deque<CSerializeData>::iterator it = pnode->
vSendMsg.begin();
717 while (it != pnode->
vSendMsg.end()) {
756 static list<CNode*> vNodesDisconnected;
762 static void AddIncomingI2pConnection(
SOCKET hSocket,
const CAddress& addr)
777 LogPrintf(
"socket error accept failed: %d\n", nErr);
779 else if (nInbound >=
GetArg(
"-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
782 LOCK(cs_setservAddNodeAddresses);
795 CNode* pnode =
new CNode(hSocket, addr,
"",
true);
804 #endif // ENABLE_I2PSAM
812 unsigned int nPrevNodeCount = 0;
814 int nPrevI2PNodeCount = 0;
825 vector<CNode*> vNodesCopy =
vNodes;
826 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
844 vNodesDisconnected.push_back(pnode);
846 if (pnode->
addr.IsNativeI2P()) --nI2PNodeCount;
854 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
855 BOOST_FOREACH(
CNode* pnode, vNodesDisconnectedCopy)
860 bool fDelete =
false;
876 vNodesDisconnected.remove(pnode);
888 if (nPrevI2PNodeCount != nI2PNodeCount)
890 nPrevI2PNodeCount = nI2PNodeCount;
891 uiInterface.NotifyNumI2PConnectionsChanged(nI2PNodeCount);
893 #endif // ENABLE_I2PSAM
895 if(
vNodes.size() != nPrevNodeCount) {
896 nPrevNodeCount =
vNodes.size();
903 struct timeval timeout;
905 timeout.tv_usec = 50000;
912 FD_ZERO(&fdsetError);
914 bool have_fds =
false;
917 BOOST_FOREACH(
SOCKET hI2PListenSocket, vhI2PListenSocket) {
918 if (hI2PListenSocket != INVALID_SOCKET) {
919 FD_SET(hI2PListenSocket, &fdsetRecv);
920 hSocketMax = max(hSocketMax, hI2PListenSocket);
924 #endif // ENABLE_I2PSAM
926 BOOST_FOREACH(
SOCKET hListenSocket, vhListenSocket) {
927 FD_SET(hListenSocket, &fdsetRecv);
928 hSocketMax = max(hSocketMax, hListenSocket);
935 if (pnode->
hSocket == INVALID_SOCKET)
937 FD_SET(pnode->
hSocket, &fdsetError);
938 hSocketMax = max(hSocketMax, pnode->
hSocket);
958 if (lockSend && !pnode->
vSendMsg.empty()) {
959 FD_SET(pnode->
hSocket, &fdsetSend);
968 FD_SET(pnode->
hSocket, &fdsetRecv);
973 int nSelect = select(have_fds ? hSocketMax + 1 : 0,
974 &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
975 boost::this_thread::interruption_point();
983 for (
unsigned int i = 0; i <= hSocketMax; i++)
984 FD_SET(i, &fdsetRecv);
987 FD_ZERO(&fdsetError);
998 #endif // Without I2P onlynet, execute the original code
999 BOOST_FOREACH(
SOCKET hListenSocket, vhListenSocket)
1000 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
1002 struct sockaddr_storage sockaddr;
1003 socklen_t len =
sizeof(sockaddr);
1004 SOCKET hSocket = accept(hListenSocket, (
struct sockaddr*)&sockaddr, &len);
1008 if (hSocket != INVALID_SOCKET)
1009 if (!addr.
SetSockAddr((
const struct sockaddr*)&sockaddr))
1010 LogPrintf(
"Warning: Unknown socket family\n");
1019 if (hSocket == INVALID_SOCKET)
1036 LogPrint(
"net",
"accepted connection %s\n", addr.
ToString());
1037 CNode* pnode =
new CNode(hSocket, addr,
"",
true);
1045 #ifdef ENABLE_I2PSAM
1051 bool haveInvalids =
false;
1052 for (std::vector<SOCKET>::iterator it = vhI2PListenSocket.begin(); it != vhI2PListenSocket.end(); ++it)
1054 SOCKET& hI2PListenSocket = *it;
1055 if (hI2PListenSocket == INVALID_SOCKET)
1058 it = vhI2PListenSocket.erase(it) - 1;
1060 BindListenNativeI2P(hI2PListenSocket);
1061 haveInvalids =
true;
1063 else if (FD_ISSET(hI2PListenSocket, &fdsetRecv))
1066 char pchBuf[bufSize];
1067 memset(pchBuf, 0, bufSize);
1068 int nBytes = recv(hI2PListenSocket, pchBuf,
sizeof(pchBuf), MSG_DONTWAIT);
1078 if (addr.
SetSpecial(incomingAddr) && addr.IsNativeI2P())
1080 AddIncomingI2pConnection(hI2PListenSocket, addr);
1084 LogPrintf(
"Invalid incoming destination hash received (%s)\n", incomingAddr.c_str());
1090 LogPrintf(
"Invalid incoming destination hash size received (%d)\n", nBytes);
1094 else if (nBytes == 0)
1097 LogPrintf(
"I2P listen socket closed\n");
1100 else if (nBytes < 0)
1107 LogPrintf(
"I2P listen socket recv error %d\n", nErr);
1111 BindListenNativeI2P(hI2PListenSocket);
1115 #endif // ENABLE_I2PSAM
1120 vector<CNode*> vNodesCopy;
1124 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1127 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1129 boost::this_thread::interruption_point();
1134 if (pnode->
hSocket == INVALID_SOCKET)
1136 if (FD_ISSET(pnode->
hSocket, &fdsetRecv) || FD_ISSET(pnode->
hSocket, &fdsetError))
1143 char pchBuf[0x10000];
1144 int nBytes = recv(pnode->
hSocket, pchBuf,
sizeof(pchBuf), MSG_DONTWAIT);
1153 else if (nBytes == 0)
1157 LogPrint(
"net",
"socket closed\n");
1160 else if (nBytes < 0)
1178 if (pnode->
hSocket == INVALID_SOCKET)
1180 if (FD_ISSET(pnode->
hSocket, &fdsetSend))
1195 LogPrint(
"net",
"socket no message in first 60 seconds, %d %d\n", pnode->
nLastRecv != 0, pnode->
nLastSend != 0);
1198 else if (nTime - pnode->
nLastSend > TIMEOUT_INTERVAL)
1203 else if (nTime - pnode->
nLastRecv > (pnode->
nVersion > BIP0031_VERSION ? TIMEOUT_INTERVAL : 90*60))
1217 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1225 void ThreadMapPort()
1228 const char * multicastif = 0;
1229 const char * minissdpdpath = 0;
1230 struct UPNPDev * devlist = 0;
1233 #ifndef UPNPDISCOVER_SUCCESS
1235 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1239 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
1242 struct UPNPUrls urls;
1243 struct IGDdatas data;
1246 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr,
sizeof(lanaddr));
1250 char externalIPAddress[40];
1251 r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);
1252 if(r != UPNPCOMMAND_SUCCESS)
1253 LogPrintf(
"UPnP: GetExternalIPAddress() returned %d\n", r);
1256 if(externalIPAddress[0])
1258 LogPrintf(
"UPnP: ExternalIPAddress = %s\n", externalIPAddress);
1262 LogPrintf(
"UPnP: GetExternalIPAddress failed.\n");
1270 #ifndef UPNPDISCOVER_SUCCESS
1272 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1273 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0);
1276 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1277 port.c_str(), port.c_str(), lanaddr, strDesc.c_str(),
"TCP", 0,
"0");
1280 if(r!=UPNPCOMMAND_SUCCESS)
1281 LogPrintf(
"AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1282 port, port, lanaddr, r, strupnperror(r));
1284 LogPrintf(
"UPnP Port Mapping successful.\n");;
1289 catch (boost::thread_interrupted)
1291 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(),
"TCP", 0);
1292 LogPrintf(
"UPNP_DeletePortMapping() returned : %d\n", r);
1293 freeUPNPDevlist(devlist); devlist = 0;
1294 FreeUPNPUrls(&urls);
1298 LogPrintf(
"No valid UPnP IGDs found\n");
1299 freeUPNPDevlist(devlist); devlist = 0;
1301 FreeUPNPUrls(&urls);
1307 static boost::thread* upnp_thread = NULL;
1312 upnp_thread->interrupt();
1313 upnp_thread->join();
1316 upnp_thread =
new boost::thread(boost::bind(&
TraceThread<
void (*)()>,
"upnp", &ThreadMapPort));
1318 else if (upnp_thread) {
1319 upnp_thread->interrupt();
1320 upnp_thread->join();
1340 if ((addrman.
size() > 0) &&
1345 if (
vNodes.size() >= 2) {
1346 LogPrintf(
"P2P peers available. Skipped DNS seeding.\n");
1352 LogPrintf(
"Loading addresses from DNS seeds (could take a while)\n");
1356 #ifdef ENABLE_I2PSAM
1358 if( IsI2PEnabled() ) {
1359 LogPrintf(
"I2P DNS seed addresses...preferred\n");
1360 const vector<CDNSSeedData> &i2pvSeeds =
Params().i2pDNSSeeds();
1365 vector<CNetAddr> vaddr;
1366 vector<CAddress> vAdd;
1368 assert( vaddr.size() == 1 );
1371 int nOneDay = 24*3600;
1374 vAdd.push_back(addr);
1389 LogPrintf(
"Skipping Clearnet DNS seeds, Running I2P net only.\n");
1394 LogPrintf(
"Loading clearnet DNS seed addresses...\n");
1399 vector<CNetAddr> vIPs;
1400 vector<CAddress> vAdd;
1405 int nOneDay = 24*3600;
1408 vAdd.push_back(addr);
1417 LogPrintf(
"%d addresses found from DNS seeds\n", found);
1428 LogPrint(
"net",
"Flushed %d addresses to peers.dat %dms\n",
1432 void static ProcessOneShot()
1437 if (vOneShots.empty())
1439 strDest = vOneShots.front();
1440 vOneShots.pop_front();
1455 for (int64_t nLoop = 0;; nLoop++)
1458 BOOST_FOREACH(
string strAddr,
mapMultiArgs[
"-connect"])
1462 for (
int i = 0; i < 10 && i < nLoop; i++)
1480 boost::this_thread::interruption_point();
1483 if (addrman.
size() == 0 && (
GetTime() - nStart > 60)) {
1484 static bool done =
false;
1486 LogPrintf(
"Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1502 set<vector<unsigned char> > setConnected;
1536 if (nANow - addr.
nLastTry < 600 && nTries < 30)
1541 !addr.IsNativeI2P() &&
1561 LOCK(cs_vAddedNodes);
1567 list<string> lAddresses(0);
1569 LOCK(cs_vAddedNodes);
1571 lAddresses.push_back(strAddNode);
1573 BOOST_FOREACH(
string& strAddNode, lAddresses) {
1583 for (
unsigned int i = 0;
true; i++)
1585 list<string> lAddresses(0);
1587 LOCK(cs_vAddedNodes);
1589 lAddresses.push_back(strAddNode);
1592 list<vector<CService> > lservAddressesToAdd(0);
1593 BOOST_FOREACH(
string& strAddNode, lAddresses)
1595 vector<CService> vservNode(0);
1598 lservAddressesToAdd.push_back(vservNode);
1600 LOCK(cs_setservAddNodeAddresses);
1601 BOOST_FOREACH(
CService& serv, vservNode)
1611 for (list<vector<CService> >::iterator it = lservAddressesToAdd.begin(); it != lservAddressesToAdd.end(); it++)
1612 BOOST_FOREACH(
CService& addrNode, *(it))
1613 if (pnode->
addr == addrNode)
1615 it = lservAddressesToAdd.erase(it);
1620 BOOST_FOREACH(vector<CService>& vserv, lservAddressesToAdd)
1636 boost::this_thread::interruption_point();
1640 FindNode(addrConnect.ToStringIPPort().c_str()))
1646 boost::this_thread::interruption_point();
1662 static int64_t NodeSyncScore(
const CNode *pnode) {
1666 void static StartSync(
const vector<CNode*> &
vNodes) {
1667 CNode *pnodeNewSync = NULL;
1668 int64_t nBestScore = 0;
1670 int nBestHeight = g_signals.
GetHeight().get_value_or(0);
1673 BOOST_FOREACH(
CNode* pnode, vNodes) {
1678 (pnode->
nVersion < NOBLKS_VERSION_START || pnode->
nVersion >= NOBLKS_VERSION_END)) {
1680 int64_t nScore = NodeSyncScore(pnode);
1681 if (pnodeNewSync == NULL || nScore > nBestScore) {
1682 pnodeNewSync = pnode;
1683 nBestScore = nScore;
1690 pnodeSync = pnodeNewSync;
1699 bool fHaveSyncNode =
false;
1701 vector<CNode*> vNodesCopy;
1705 BOOST_FOREACH(
CNode* pnode, vNodesCopy) {
1707 if (pnode == pnodeSync)
1708 fHaveSyncNode =
true;
1713 StartSync(vNodesCopy);
1716 CNode* pnodeTrickle = NULL;
1717 if (!vNodesCopy.empty())
1718 pnodeTrickle = vNodesCopy[
GetRand(vNodesCopy.size())];
1722 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1744 boost::this_thread::interruption_point();
1752 boost::this_thread::interruption_point();
1757 BOOST_FOREACH(
CNode* pnode, vNodesCopy)
1773 struct sockaddr_storage sockaddr;
1774 socklen_t len =
sizeof(sockaddr);
1775 if (!addrBind.
GetSockAddr((
struct sockaddr*)&sockaddr, &len))
1777 strError =
strprintf(
"Error: bind address family for %s not supported", addrBind.
ToString());
1782 SOCKET hListenSocket = socket(((
struct sockaddr*)&sockaddr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
1783 if (hListenSocket == INVALID_SOCKET)
1792 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (
void*)&nOne,
sizeof(
int));
1798 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (
void*)&nOne,
sizeof(
int));
1804 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) ==
SOCKET_ERROR)
1806 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) ==
SOCKET_ERROR)
1819 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
const char*)&nOne,
sizeof(
int));
1821 setsockopt(hListenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (
void*)&nOne,
sizeof(
int));
1825 int nProtLevel = 10 ;
1826 int nParameterId = 23 ;
1828 setsockopt(hListenSocket, IPPROTO_IPV6, nParameterId, (
const char*)&nProtLevel,
sizeof(
int));
1832 if (::bind(hListenSocket, (
struct sockaddr*)&sockaddr, len) ==
SOCKET_ERROR)
1836 strError =
strprintf(
_(
"Unable to bind to %s on this computer. Anoncoin Core is probably already running."), addrBind.
ToString());
1852 vhListenSocket.push_back(hListenSocket);
1861 #ifdef ENABLE_I2PSAM
1865 std::string FormatI2PNativeFullVersion() {
1874 bool i2pOnly =
false;
1875 const std::vector<std::string>& onlyNets =
mapMultiArgs[
"-onlynet"];
1876 i2pOnly = (onlyNets.size() == 1 && onlyNets[0] ==
"tor");
1882 bool i2pOnly =
false;
1883 if (
mapArgs.count(
"-onlynet")) {
1884 const std::vector<std::string>& onlyNets =
mapMultiArgs[
"-onlynet"];
1891 bool IsDarknetOnly() {
1892 return IsI2POnly() || IsTorOnly() ||
1894 (
mapArgs.count(
"-i2p.options.enabled") &&
mapArgs[
"-i2p.options.enabled"] !=
"0")
1899 bool IsI2PEnabled() {
1900 return GetBoolArg(
"-i2p.options.enabled",
false) || IsI2POnly();
1903 bool IsBehindDarknet() {
1904 return IsDarknetOnly() || (
mapArgs.count(
"-onion") &&
mapArgs[
"-onion"] !=
"0");
1910 bool BindListenNativeI2P()
1913 if (!BindListenNativeI2P(hNewI2PListenSocket))
1915 vhI2PListenSocket.push_back(hNewI2PListenSocket);
1919 bool BindListenNativeI2P(
SOCKET& hSocket)
1923 if ( hSocket == INVALID_SOCKET )
return false;
1931 #endif // ENABLE_I2PSAM
1933 void static Discover(boost::thread_group& threadGroup)
1940 char pszHostName[1000] =
"";
1941 if (gethostname(pszHostName,
sizeof(pszHostName)) !=
SOCKET_ERROR)
1943 vector<CNetAddr> vaddr;
1946 BOOST_FOREACH (
const CNetAddr &addr, vaddr)
1954 struct ifaddrs* myaddrs;
1955 if (getifaddrs(&myaddrs) == 0)
1957 for (
struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1959 if (ifa->ifa_addr == NULL)
continue;
1960 if ((ifa->ifa_flags & IFF_UP) == 0)
continue;
1961 if (strcmp(ifa->ifa_name,
"lo") == 0)
continue;
1962 if (strcmp(ifa->ifa_name,
"lo0") == 0)
continue;
1963 if (ifa->ifa_addr->sa_family == AF_INET)
1965 struct sockaddr_in* s4 = (
struct sockaddr_in*)(ifa->ifa_addr);
1970 else if (ifa->ifa_addr->sa_family == AF_INET6)
1972 struct sockaddr_in6* s6 = (
struct sockaddr_in6*)(ifa->ifa_addr);
1978 freeifaddrs(myaddrs);
1996 if (!adb.
Read(addrman))
1997 LogPrintf(
"Invalid or missing peers.dat; recreating\n");
1999 LogPrintf(
"Loaded %i addresses from peers.dat %dms\n",
2003 if (semOutbound == NULL) {
2009 if (pnodeLocalHost == NULL)
2012 Discover(threadGroup);
2049 for (
int i=0; i<MAX_OUTBOUND_CONNECTIONS; i++)
2050 semOutbound->
post();
2070 BOOST_FOREACH(
CNode* pnode, vNodes)
2071 if (pnode->
hSocket != INVALID_SOCKET)
2073 BOOST_FOREACH(
SOCKET hListenSocket, vhListenSocket)
2074 if (hListenSocket != INVALID_SOCKET)
2077 #ifdef ENABLE_I2PSAM
2078 BOOST_FOREACH(
SOCKET& hI2PListenSocket, vhI2PListenSocket)
2079 if (hI2PListenSocket != INVALID_SOCKET)
2082 #endif // ENABLE_I2PSAM
2085 BOOST_FOREACH(
CNode *pnode, vNodes)
2087 BOOST_FOREACH(
CNode *pnode, vNodesDisconnected)
2090 vNodesDisconnected.clear();
2093 delete pnodeLocalHost;
2094 pnodeLocalHost = NULL;
2127 mapRelay.insert(std::make_pair(inv, ss));
2131 BOOST_FOREACH(
CNode* pnode, vNodes)
2147 LOCK(cs_totalBytesRecv);
2148 nTotalBytesRecv += bytes;
2153 LOCK(cs_totalBytesSent);
2154 nTotalBytesSent += bytes;
2159 LOCK(cs_totalBytesRecv);
2160 return nTotalBytesRecv;
2165 LOCK(cs_totalBytesSent);
2166 return nTotalBytesSent;
2171 if (!fSuccessfullyConnected)
return;
2172 if (
GetRand(nChance) != 0)
return;
2178 if (!ssSend.empty()) {
2180 ssSend[pos] ^= (
unsigned char)(
GetRand(256));
2185 if (!ssSend.empty()) {
2187 ssSend.erase(ssSend.begin()+pos);
2195 ssSend.insert(ssSend.begin()+pos, ch);
2216 unsigned short randv = 0;
2217 RAND_bytes((
unsigned char *)&randv,
sizeof(randv));
2218 std::string tmpfn =
strprintf(
"peers.dat.%04x", randv);
2228 boost::filesystem::path pathTmp =
GetDataDir() / tmpfn;
2229 FILE *file = fopen(pathTmp.string().c_str(),
"wb");
2232 return error(
"%s : Failed to open file %s", __func__, pathTmp.string());
2238 catch (std::exception &e) {
2239 return error(
"%s : Serialize or I/O error - %s", __func__, e.what());
2246 return error(
"%s : Rename-into-place failed", __func__);
2254 FILE *file = fopen(pathAddr.string().c_str(),
"rb");
2257 return error(
"%s : Failed to open file %s", __func__, pathAddr.string());
2260 int fileSize = boost::filesystem::file_size(pathAddr);
2261 int dataSize = fileSize -
sizeof(
uint256);
2265 vector<unsigned char> vchData;
2266 vchData.resize(dataSize);
2271 filein.read((
char *)&vchData[0], dataSize);
2274 catch (std::exception &e) {
2275 return error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
2283 if (hashIn != hashTmp)
2284 return error(
"%s : Checksum mismatch, data corrupted", __func__);
2286 unsigned char pchMsgTmp[4];
2292 if (memcmp(pchMsgTmp,
Params().MessageStart(),
sizeof(pchMsgTmp)))
2293 return error(
"%s : Invalid network magic number", __func__);
2298 catch (std::exception &e) {
2299 return error(
"%s : Deserialize or I/O error - %s", __func__, e.what());
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
const vector< CDNSSeedData > & DNSSeeds() const
CClientUIInterface uiInterface
void SetReachable(enum Network net, bool fFlag)
uint64_t GetRand(uint64_t nMax)
void Attempt(const CService &addr, int64_t nTime=GetAdjustedTime())
CNodeSignals & GetNodeSignals()
static uint64_t GetTotalBytesRecv()
void MoveTo(CSemaphoreGrant &grant)
Access to the (IP) address database (peers.dat)
bool GetLocal(CService &addr, const CNetAddr *paddrPeer)
void AddOneShot(string strDest)
unsigned short GetPort() const
CCriticalSection cs_filter
#define NATIVE_I2P_NET_STRING
bool AddLocal(const CService &addr, int nScore)
const_iterator begin() const
CNode * FindNode(const CNetAddr &ip)
bool fAddressesInitialized
#define TRY_LOCK(cs, name)
STL-like map container that only keeps the N elements with the highest value.
void SetIP(const CNetAddr &ip)
void FileCommit(FILE *fileout)
void MilliSleep(int64_t n)
std::string ToStringIP() const
static void ClearBanned()
bool GetMyExternalIP(CNetAddr &ipRet)
vector_type::size_type size_type
static SAM::StreamSessionAdapter & Instance()
void ThreadOpenConnections()
void SetLimited(enum Network net, bool fLimited)
Make a particular network entirely off-limits (no automatic connects to it)
RAII-style semaphore lock.
bool fDiscover
Specific functions we need to implement I2P functionality.
limitedmap< CInv, int64_t > mapAlreadyAskedFor(MAX_INV_SZ)
bool ConnectSocketByName(CService &addr, SOCKET &hSocketRet, const char *pszDest, int portDefault, int nTimeout)
Double ended buffer combining vector and stream-like interfaces.
void ThreadDNSAddressSeed()
Process DNS seed data from chainparams.
unsigned short GetListenPort()
CCriticalSection cs_inventory
bool SeenLocal(const CService &addr)
vote for a local address
SAM::SOCKET accept(bool silent)
bool RenameOver(boost::filesystem::path src, boost::filesystem::path dest)
bool Add(const CAddress &addr, const CNetAddr &source, int64_t nTimePenalty=0)
vector< std::string > vAddedNodes
#define WSAGetLastError()
static void RecordBytesRecv(uint64_t bytes)
void PushInventory(const CInv &inv)
bool RecvLine(SOCKET hSocket, string &strLine)
std::deque< CInv > vRecvGetData
void ThreadSocketHandler()
Main Thread that handling socket's & their housekeeping...
Stochastical (IP) address manager.
CCriticalSection cs_nLastNodeId
const std::string & getSAMVersion() const
CCriticalSection cs_vOneShots
std::deque< CNetMessage > vRecvMsg
unsigned int GetTotalRecvSize()
void CloseSocketDisconnect()
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
int64_t GetAdjustedTime()
bool Write(const CAddrMan &addr)
int GetDefaultPort() const
static uint64_t nTotalBytesRecv
void AddressCurrentlyConnected(const CService &addr)
unsigned int ReceiveFloodSize()
void ThreadMessageHandler()
CCriticalSection cs_mapLocalHost
A combination of a network address (CNetAddr) and a (TCP) port.
std::vector< char, zero_after_free_allocator< char > > CSerializeData
void TraceThread(const char *name, Callable func)
bool IsProxy(const CNetAddr &addr)
#define THREAD_PRIORITY_BELOW_NORMAL
#define NATIVE_I2P_DESTINATION_SIZE
static CCriticalSection cs_totalBytesRecv
bool ReceiveMsgBytes(const char *pch, unsigned int nBytes)
CCriticalSection cs_setservAddNodeAddresses
A CService with information about it as peer.
unsigned int SendBufferSize()
bool ConnectSocket(const CService &addrDest, SOCKET &hSocketRet, int nTimeout)
void RelayTransaction(const CTransaction &tx, const uint256 &hash)
bool fSuccessfullyConnected
std::string ToString() const
bool OpenNetworkConnection(const CAddress &addrConnect, CSemaphoreGrant *grantOutbound=NULL, const char *strDest=NULL, bool fOneShot=false)
uint256 Hash(const T1 pbegin, const T1 pend)
const std::string CLIENT_NAME
static uint64_t GetTotalBytesSent()
boost::signals2::signal< bool(CNode *, bool)> SendMessages
static CCriticalSection cs_totalBytesSent
map< CNetAddr, LocalServiceInfo > mapLocalHost
CNode * ConnectNode(CAddress addrConnect, const char *pszDest)
#define DUMP_ADDRESSES_INTERVAL
std::string FormatFullVersion()
boost::signals2::signal< bool(CNode *)> ProcessMessages
int readData(const char *pch, unsigned int nBytes)
CCriticalSection cs_vAddedNodes
void ThreadGetMyExternalIP()
void SetThreadPriority(int nPriority)
boost::signals2::signal< void(int newNumConnections)> NotifyNumConnectionsChanged
Number of network connections changed.
std::vector< unsigned char > GetGroup() const
boost::signals2::signal< int()> GetHeight
void SocketSendData(CNode *pnode)
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
static void RecordBytesSent(uint64_t bytes)
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
bool BindListenPort(const CService &addrBind, string &strError)
CCriticalSection cs_mapRelay
bool IsRelevantAndUpdate(const CTransaction &tx, const uint256 &hash)
CCriticalSection cs_vRecvMsg
void reserve(size_type n)
const CChainParams & Params()
Return the currently selected parameters.
CSemaphoreGrant grantOutbound
void * memcpy(void *a, const void *b, size_t c)
static bool IsBanned(CNetAddr ip)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
static CCriticalSection cs_setBanned
CAddress Select(int nUnkBias=50)
CAddress GetLocalAddress(const CNetAddr *paddrPeer)
static bool Ban(const CNetAddr &ip)
bool SetSpecial(const std::string &strName)
Returns TRUE if the address name can be looked up and resolved.
class CNetCleanup instance_of_cnetcleanup
int readHeader(const char *pch, unsigned int nBytes)
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
bool GetMyExternalIP2(const CService &addrConnect, const char *pszGet, const char *pszKeyword, CNetAddr &ipRet)
std::string NetworkErrorString(int err)
Return readable error string for a network error code.
deque< pair< int64_t, CInv > > vRelayExpiration
The basic transaction that is broadcasted on the network and contained in blocks. ...
Information about a peer.
bool LookupHost(const char *pszName, std::vector< CNetAddr > &vIP, unsigned int nMaxSolutions, bool fAllowLookup)
set< CNetAddr > setservAddNodeAddresses
bool SetSockAddr(const struct sockaddr *paddr)
CCriticalSection cs_vSend
static uint64_t nTotalBytesSent
void Connected(const CService &addr, int64_t nTime=GetAdjustedTime())
void copyStats(CNodeStats &stats)
map< string, vector< string > > mapMultiArgs
void LoopForever(const char *name, Callable func, int64_t msecs)
void ThreadOpenAddedConnections()
CCriticalSection cs_vNodes
bool Read(CAddrMan &addr)
static std::map< CNetAddr, int64_t > setBanned
bool GetSockAddr(struct sockaddr *paddr, socklen_t *addrlen) const
bool IsLimited(enum Network net)
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
void StartNode(boost::thread_group &threadGroup)
map< string, string > mapArgs
map< CInv, CDataStream > mapRelay
bool IsLocal(const CService &addr)
check whether a given address is potentially local
std::deque< CSerializeData > vSendMsg
const_iterator end() const
void PushAddress(const CAddress &addr)
enum Network GetNetwork() const