1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #if defined(HAVE_CONFIG_H)
7 #include "config/bitcoin-config.h"
13 #include "chainparams.h"
14 #include "clientversion.h"
15 #include "consensus/consensus.h"
16 #include "crypto/common.h"
17 #include "crypto/sha256.h"
19 #include "primitives/transaction.h"
21 #include "scheduler.h"
22 #include "ui_interface.h"
23 #include "utilstrencodings.h"
32 #include <miniupnpc/miniupnpc.h>
33 #include <miniupnpc/miniwget.h>
34 #include <miniupnpc/upnpcommands.h>
35 #include <miniupnpc/upnperrors.h>
38 #include <boost/filesystem.hpp>
39 #include <boost/thread.hpp>
43 // Dump addresses to peers.dat and banlist.dat every 15 minutes (900s)
44 #define DUMP_ADDRESSES_INTERVAL 900
46 // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization.
47 #define FEELER_SLEEP_WINDOW 1
49 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
50 #define MSG_NOSIGNAL 0
53 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
54 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
56 #ifndef PROTECTION_LEVEL_UNRESTRICTED
57 #define PROTECTION_LEVEL_UNRESTRICTED 10
59 #ifndef IPV6_PROTECTION_LEVEL
60 #define IPV6_PROTECTION_LEVEL 23
66 const int MAX_FEELER_CONNECTIONS
= 1;
69 const static std::string NET_MESSAGE_COMMAND_OTHER
= "*other*";
72 // Global state variables
74 bool fDiscover
= true;
76 bool fRelayTxes
= true;
77 CCriticalSection cs_mapLocalHost
;
78 std::map
<CNetAddr
, LocalServiceInfo
> mapLocalHost
;
79 static bool vfLimited
[NET_MAX
] = {};
80 static CNode
* pnodeLocalHost
= NULL
;
81 std::string strSubVersion
;
83 limitedmap
<uint256
, int64_t> mapAlreadyAskedFor(MAX_INV_SZ
);
85 // Signals for message handling
86 static CNodeSignals g_signals
;
87 CNodeSignals
& GetNodeSignals() { return g_signals
; }
89 void CConnman::AddOneShot(const std::string
& strDest
)
92 vOneShots
.push_back(strDest
);
95 unsigned short GetListenPort()
97 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
100 // find 'best' local address for a particular peer
101 bool GetLocal(CService
& addr
, const CNetAddr
*paddrPeer
)
107 int nBestReachability
= -1;
109 LOCK(cs_mapLocalHost
);
110 for (std::map
<CNetAddr
, LocalServiceInfo
>::iterator it
= mapLocalHost
.begin(); it
!= mapLocalHost
.end(); it
++)
112 int nScore
= (*it
).second
.nScore
;
113 int nReachability
= (*it
).first
.GetReachabilityFrom(paddrPeer
);
114 if (nReachability
> nBestReachability
|| (nReachability
== nBestReachability
&& nScore
> nBestScore
))
116 addr
= CService((*it
).first
, (*it
).second
.nPort
);
117 nBestReachability
= nReachability
;
122 return nBestScore
>= 0;
125 //! Convert the pnSeeds6 array into usable address objects.
126 static std::vector
<CAddress
> convertSeed6(const std::vector
<SeedSpec6
> &vSeedsIn
)
128 // It'll only connect to one or two seed nodes because once it connects,
129 // it'll get a pile of addresses with newer timestamps.
130 // Seed nodes are given a random 'last seen time' of between one and two
132 const int64_t nOneWeek
= 7*24*60*60;
133 std::vector
<CAddress
> vSeedsOut
;
134 vSeedsOut
.reserve(vSeedsIn
.size());
135 for (std::vector
<SeedSpec6
>::const_iterator
i(vSeedsIn
.begin()); i
!= vSeedsIn
.end(); ++i
)
138 memcpy(&ip
, i
->addr
, sizeof(ip
));
139 CAddress
addr(CService(ip
, i
->port
), NODE_NETWORK
);
140 addr
.nTime
= GetTime() - GetRand(nOneWeek
) - nOneWeek
;
141 vSeedsOut
.push_back(addr
);
146 // get best local address for a particular peer as a CAddress
147 // Otherwise, return the unroutable 0.0.0.0 but filled in with
148 // the normal parameters, since the IP may be changed to a useful
150 CAddress
GetLocalAddress(const CNetAddr
*paddrPeer
, ServiceFlags nLocalServices
)
152 CAddress
ret(CService(CNetAddr(),GetListenPort()), NODE_NONE
);
154 if (GetLocal(addr
, paddrPeer
))
156 ret
= CAddress(addr
, nLocalServices
);
158 ret
.nTime
= GetAdjustedTime();
162 int GetnScore(const CService
& addr
)
164 LOCK(cs_mapLocalHost
);
165 if (mapLocalHost
.count(addr
) == LOCAL_NONE
)
167 return mapLocalHost
[addr
].nScore
;
170 // Is our peer's addrLocal potentially useful as an external IP source?
171 bool IsPeerAddrLocalGood(CNode
*pnode
)
173 return fDiscover
&& pnode
->addr
.IsRoutable() && pnode
->addrLocal
.IsRoutable() &&
174 !IsLimited(pnode
->addrLocal
.GetNetwork());
177 // pushes our own address to a peer
178 void AdvertiseLocal(CNode
*pnode
)
180 if (fListen
&& pnode
->fSuccessfullyConnected
)
182 CAddress addrLocal
= GetLocalAddress(&pnode
->addr
, pnode
->GetLocalServices());
183 // If discovery is enabled, sometimes give our peer the address it
184 // tells us that it sees us as in case it has a better idea of our
185 // address than we do.
186 if (IsPeerAddrLocalGood(pnode
) && (!addrLocal
.IsRoutable() ||
187 GetRand((GetnScore(addrLocal
) > LOCAL_MANUAL
) ? 8:2) == 0))
189 addrLocal
.SetIP(pnode
->addrLocal
);
191 if (addrLocal
.IsRoutable())
193 LogPrint("net", "AdvertiseLocal: advertising address %s\n", addrLocal
.ToString());
194 pnode
->PushAddress(addrLocal
);
199 // learn a new local address
200 bool AddLocal(const CService
& addr
, int nScore
)
202 if (!addr
.IsRoutable())
205 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
211 LogPrintf("AddLocal(%s,%i)\n", addr
.ToString(), nScore
);
214 LOCK(cs_mapLocalHost
);
215 bool fAlready
= mapLocalHost
.count(addr
) > 0;
216 LocalServiceInfo
&info
= mapLocalHost
[addr
];
217 if (!fAlready
|| nScore
>= info
.nScore
) {
218 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
219 info
.nPort
= addr
.GetPort();
226 bool AddLocal(const CNetAddr
&addr
, int nScore
)
228 return AddLocal(CService(addr
, GetListenPort()), nScore
);
231 bool RemoveLocal(const CService
& addr
)
233 LOCK(cs_mapLocalHost
);
234 LogPrintf("RemoveLocal(%s)\n", addr
.ToString());
235 mapLocalHost
.erase(addr
);
239 /** Make a particular network entirely off-limits (no automatic connects to it) */
240 void SetLimited(enum Network net
, bool fLimited
)
242 if (net
== NET_UNROUTABLE
)
244 LOCK(cs_mapLocalHost
);
245 vfLimited
[net
] = fLimited
;
248 bool IsLimited(enum Network net
)
250 LOCK(cs_mapLocalHost
);
251 return vfLimited
[net
];
254 bool IsLimited(const CNetAddr
&addr
)
256 return IsLimited(addr
.GetNetwork());
259 /** vote for a local address */
260 bool SeenLocal(const CService
& addr
)
263 LOCK(cs_mapLocalHost
);
264 if (mapLocalHost
.count(addr
) == 0)
266 mapLocalHost
[addr
].nScore
++;
272 /** check whether a given address is potentially local */
273 bool IsLocal(const CService
& addr
)
275 LOCK(cs_mapLocalHost
);
276 return mapLocalHost
.count(addr
) > 0;
279 /** check whether a given network is one we can probably connect to */
280 bool IsReachable(enum Network net
)
282 LOCK(cs_mapLocalHost
);
283 return !vfLimited
[net
];
286 /** check whether a given address is in a network we can probably connect to */
287 bool IsReachable(const CNetAddr
& addr
)
289 enum Network net
= addr
.GetNetwork();
290 return IsReachable(net
);
294 CNode
* CConnman::FindNode(const CNetAddr
& ip
)
297 BOOST_FOREACH(CNode
* pnode
, vNodes
)
298 if ((CNetAddr
)pnode
->addr
== ip
)
303 CNode
* CConnman::FindNode(const CSubNet
& subNet
)
306 BOOST_FOREACH(CNode
* pnode
, vNodes
)
307 if (subNet
.Match((CNetAddr
)pnode
->addr
))
312 CNode
* CConnman::FindNode(const std::string
& addrName
)
315 BOOST_FOREACH(CNode
* pnode
, vNodes
)
316 if (pnode
->addrName
== addrName
)
321 CNode
* CConnman::FindNode(const CService
& addr
)
324 BOOST_FOREACH(CNode
* pnode
, vNodes
)
325 if ((CService
)pnode
->addr
== addr
)
330 bool CConnman::CheckIncomingNonce(uint64_t nonce
)
333 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
334 if (!pnode
->fSuccessfullyConnected
&& !pnode
->fInbound
&& pnode
->GetLocalNonce() == nonce
)
340 CNode
* CConnman::ConnectNode(CAddress addrConnect
, const char *pszDest
, bool fCountFailure
)
342 if (pszDest
== NULL
) {
343 if (IsLocal(addrConnect
))
346 // Look for an existing connection
347 CNode
* pnode
= FindNode((CService
)addrConnect
);
356 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
357 pszDest
? pszDest
: addrConnect
.ToString(),
358 pszDest
? 0.0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
362 bool proxyConnectionFailed
= false;
363 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, Params().GetDefaultPort(), nConnectTimeout
, &proxyConnectionFailed
) :
364 ConnectSocket(addrConnect
, hSocket
, nConnectTimeout
, &proxyConnectionFailed
))
366 if (!IsSelectableSocket(hSocket
)) {
367 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
368 CloseSocket(hSocket
);
372 if (pszDest
&& addrConnect
.IsValid()) {
373 // It is possible that we already have a connection to the IP/port pszDest resolved to.
374 // In that case, drop the connection that was just created, and return the existing CNode instead.
375 // Also store the name we used to connect in that CNode, so that future FindNode() calls to that
376 // name catch this early.
377 CNode
* pnode
= FindNode((CService
)addrConnect
);
383 if (pnode
->addrName
.empty()) {
384 pnode
->addrName
= std::string(pszDest
);
387 CloseSocket(hSocket
);
392 addrman
.Attempt(addrConnect
, fCountFailure
);
395 CNode
* pnode
= new CNode(GetNewNodeId(), nLocalServices
, GetBestHeight(), hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
396 GetNodeSignals().InitializeNode(pnode
->GetId(), pnode
);
401 vNodes
.push_back(pnode
);
404 pnode
->nServicesExpected
= ServiceFlags(addrConnect
.nServices
& nRelevantServices
);
405 pnode
->nTimeConnected
= GetTime();
408 } else if (!proxyConnectionFailed
) {
409 // If connecting to the node failed, and failure is not caused by a problem connecting to
410 // the proxy, mark this as an attempt.
411 addrman
.Attempt(addrConnect
, fCountFailure
);
417 void CConnman::DumpBanlist()
419 SweepBanned(); // clean unused entries (if bantime has expired)
421 if (!BannedSetIsDirty())
424 int64_t nStart
= GetTimeMillis();
428 SetBannedSetDirty(false);
430 if (!bandb
.Write(banmap
))
431 SetBannedSetDirty(true);
433 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
434 banmap
.size(), GetTimeMillis() - nStart
);
437 void CNode::CloseSocketDisconnect()
440 if (hSocket
!= INVALID_SOCKET
)
442 LogPrint("net", "disconnecting peer=%d\n", id
);
443 CloseSocket(hSocket
);
446 // in case this fails, we'll empty the recv buffer when the CNode is deleted
447 TRY_LOCK(cs_vRecvMsg
, lockRecv
);
452 void CNode::PushVersion()
454 int64_t nTime
= (fInbound
? GetAdjustedTime() : GetTime());
455 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService(), addr
.nServices
));
456 CAddress addrMe
= GetLocalAddress(&addr
, nLocalServices
);
458 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION
, nMyStartingHeight
, addrMe
.ToString(), addrYou
.ToString(), id
);
460 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION
, nMyStartingHeight
, addrMe
.ToString(), id
);
461 PushMessage(NetMsgType::VERSION
, PROTOCOL_VERSION
, (uint64_t)nLocalServices
, nTime
, addrYou
, addrMe
,
462 nLocalHostNonce
, strSubVersion
, nMyStartingHeight
, ::fRelayTxes
);
469 void CConnman::ClearBanned()
474 setBannedIsDirty
= true;
476 DumpBanlist(); //store banlist to disk
478 clientInterface
->BannedListChanged();
481 bool CConnman::IsBanned(CNetAddr ip
)
483 bool fResult
= false;
486 for (banmap_t::iterator it
= setBanned
.begin(); it
!= setBanned
.end(); it
++)
488 CSubNet subNet
= (*it
).first
;
489 CBanEntry banEntry
= (*it
).second
;
491 if(subNet
.Match(ip
) && GetTime() < banEntry
.nBanUntil
)
498 bool CConnman::IsBanned(CSubNet subnet
)
500 bool fResult
= false;
503 banmap_t::iterator i
= setBanned
.find(subnet
);
504 if (i
!= setBanned
.end())
506 CBanEntry banEntry
= (*i
).second
;
507 if (GetTime() < banEntry
.nBanUntil
)
514 void CConnman::Ban(const CNetAddr
& addr
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
515 CSubNet
subNet(addr
);
516 Ban(subNet
, banReason
, bantimeoffset
, sinceUnixEpoch
);
519 void CConnman::Ban(const CSubNet
& subNet
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
520 CBanEntry
banEntry(GetTime());
521 banEntry
.banReason
= banReason
;
522 if (bantimeoffset
<= 0)
524 bantimeoffset
= GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME
);
525 sinceUnixEpoch
= false;
527 banEntry
.nBanUntil
= (sinceUnixEpoch
? 0 : GetTime() )+bantimeoffset
;
531 if (setBanned
[subNet
].nBanUntil
< banEntry
.nBanUntil
) {
532 setBanned
[subNet
] = banEntry
;
533 setBannedIsDirty
= true;
539 clientInterface
->BannedListChanged();
542 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
543 if (subNet
.Match((CNetAddr
)pnode
->addr
))
544 pnode
->fDisconnect
= true;
547 if(banReason
== BanReasonManuallyAdded
)
548 DumpBanlist(); //store banlist to disk immediately if user requested ban
551 bool CConnman::Unban(const CNetAddr
&addr
) {
552 CSubNet
subNet(addr
);
553 return Unban(subNet
);
556 bool CConnman::Unban(const CSubNet
&subNet
) {
559 if (!setBanned
.erase(subNet
))
561 setBannedIsDirty
= true;
564 clientInterface
->BannedListChanged();
565 DumpBanlist(); //store banlist to disk immediately
569 void CConnman::GetBanned(banmap_t
&banMap
)
572 banMap
= setBanned
; //create a thread safe copy
575 void CConnman::SetBanned(const banmap_t
&banMap
)
579 setBannedIsDirty
= true;
582 void CConnman::SweepBanned()
584 int64_t now
= GetTime();
587 banmap_t::iterator it
= setBanned
.begin();
588 while(it
!= setBanned
.end())
590 CSubNet subNet
= (*it
).first
;
591 CBanEntry banEntry
= (*it
).second
;
592 if(now
> banEntry
.nBanUntil
)
594 setBanned
.erase(it
++);
595 setBannedIsDirty
= true;
596 LogPrint("net", "%s: Removed banned node ip/subnet from banlist.dat: %s\n", __func__
, subNet
.ToString());
603 bool CConnman::BannedSetIsDirty()
606 return setBannedIsDirty
;
609 void CConnman::SetBannedSetDirty(bool dirty
)
611 LOCK(cs_setBanned
); //reuse setBanned lock for the isDirty flag
612 setBannedIsDirty
= dirty
;
616 bool CConnman::IsWhitelistedRange(const CNetAddr
&addr
) {
617 LOCK(cs_vWhitelistedRange
);
618 BOOST_FOREACH(const CSubNet
& subnet
, vWhitelistedRange
) {
619 if (subnet
.Match(addr
))
625 void CConnman::AddWhitelistedRange(const CSubNet
&subnet
) {
626 LOCK(cs_vWhitelistedRange
);
627 vWhitelistedRange
.push_back(subnet
);
631 #define X(name) stats.name = name
632 void CNode::copyStats(CNodeStats
&stats
)
634 stats
.nodeid
= this->GetId();
647 X(mapSendBytesPerMsgCmd
);
649 X(mapRecvBytesPerMsgCmd
);
652 // It is common for nodes with good ping times to suddenly become lagged,
653 // due to a new block arriving or other large transfer.
654 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
655 // since pingtime does not update until the ping is complete, which might take a while.
656 // So, if a ping is taking an unusually long time in flight,
657 // the caller can immediately detect that this is happening.
658 int64_t nPingUsecWait
= 0;
659 if ((0 != nPingNonceSent
) && (0 != nPingUsecStart
)) {
660 nPingUsecWait
= GetTimeMicros() - nPingUsecStart
;
663 // Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
664 stats
.dPingTime
= (((double)nPingUsecTime
) / 1e6
);
665 stats
.dPingMin
= (((double)nMinPingUsecTime
) / 1e6
);
666 stats
.dPingWait
= (((double)nPingUsecWait
) / 1e6
);
668 // Leave string empty if addrLocal invalid (not filled in yet)
669 stats
.addrLocal
= addrLocal
.IsValid() ? addrLocal
.ToString() : "";
673 // requires LOCK(cs_vRecvMsg)
674 bool CNode::ReceiveMsgBytes(const char *pch
, unsigned int nBytes
, bool& complete
)
679 // get current incomplete message, or create a new one
680 if (vRecvMsg
.empty() ||
681 vRecvMsg
.back().complete())
682 vRecvMsg
.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK
, nRecvVersion
));
684 CNetMessage
& msg
= vRecvMsg
.back();
686 // absorb network data
689 handled
= msg
.readHeader(pch
, nBytes
);
691 handled
= msg
.readData(pch
, nBytes
);
696 if (msg
.in_data
&& msg
.hdr
.nMessageSize
> MAX_PROTOCOL_MESSAGE_LENGTH
) {
697 LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
704 if (msg
.complete()) {
706 //store received bytes per message command
707 //to prevent a memory DOS, only allow valid commands
708 mapMsgCmdSize::iterator i
= mapRecvBytesPerMsgCmd
.find(msg
.hdr
.pchCommand
);
709 if (i
== mapRecvBytesPerMsgCmd
.end())
710 i
= mapRecvBytesPerMsgCmd
.find(NET_MESSAGE_COMMAND_OTHER
);
711 assert(i
!= mapRecvBytesPerMsgCmd
.end());
712 i
->second
+= msg
.hdr
.nMessageSize
+ CMessageHeader::HEADER_SIZE
;
714 msg
.nTime
= GetTimeMicros();
722 int CNetMessage::readHeader(const char *pch
, unsigned int nBytes
)
724 // copy data to temporary parsing buffer
725 unsigned int nRemaining
= 24 - nHdrPos
;
726 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
728 memcpy(&hdrbuf
[nHdrPos
], pch
, nCopy
);
731 // if header incomplete, exit
735 // deserialize to CMessageHeader
739 catch (const std::exception
&) {
743 // reject messages larger than MAX_SIZE
744 if (hdr
.nMessageSize
> MAX_SIZE
)
747 // switch state to reading message data
753 int CNetMessage::readData(const char *pch
, unsigned int nBytes
)
755 unsigned int nRemaining
= hdr
.nMessageSize
- nDataPos
;
756 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
758 if (vRecv
.size() < nDataPos
+ nCopy
) {
759 // Allocate up to 256 KiB ahead, but never more than the total message size.
760 vRecv
.resize(std::min(hdr
.nMessageSize
, nDataPos
+ nCopy
+ 256 * 1024));
763 memcpy(&vRecv
[nDataPos
], pch
, nCopy
);
777 // requires LOCK(cs_vSend)
778 size_t SocketSendData(CNode
*pnode
)
780 std::deque
<CSerializeData
>::iterator it
= pnode
->vSendMsg
.begin();
781 size_t nSentSize
= 0;
783 while (it
!= pnode
->vSendMsg
.end()) {
784 const CSerializeData
&data
= *it
;
785 assert(data
.size() > pnode
->nSendOffset
);
786 int nBytes
= send(pnode
->hSocket
, &data
[pnode
->nSendOffset
], data
.size() - pnode
->nSendOffset
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
788 pnode
->nLastSend
= GetTime();
789 pnode
->nSendBytes
+= nBytes
;
790 pnode
->nSendOffset
+= nBytes
;
792 if (pnode
->nSendOffset
== data
.size()) {
793 pnode
->nSendOffset
= 0;
794 pnode
->nSendSize
-= data
.size();
797 // could not send full message; stop sending more
803 int nErr
= WSAGetLastError();
804 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
806 LogPrintf("socket send error %s\n", NetworkErrorString(nErr
));
807 pnode
->CloseSocketDisconnect();
810 // couldn't send anything at all
815 if (it
== pnode
->vSendMsg
.end()) {
816 assert(pnode
->nSendOffset
== 0);
817 assert(pnode
->nSendSize
== 0);
819 pnode
->vSendMsg
.erase(pnode
->vSendMsg
.begin(), it
);
823 static std::list
<CNode
*> vNodesDisconnected
;
825 struct NodeEvictionCandidate
828 int64_t nTimeConnected
;
829 int64_t nMinPingUsecTime
;
830 int64_t nLastBlockTime
;
836 uint64_t nKeyedNetGroup
;
839 static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate
&a
, const NodeEvictionCandidate
&b
)
841 return a
.nMinPingUsecTime
> b
.nMinPingUsecTime
;
844 static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate
&a
, const NodeEvictionCandidate
&b
)
846 return a
.nTimeConnected
> b
.nTimeConnected
;
849 static bool CompareNetGroupKeyed(const NodeEvictionCandidate
&a
, const NodeEvictionCandidate
&b
) {
850 return a
.nKeyedNetGroup
< b
.nKeyedNetGroup
;
853 static bool CompareNodeBlockTime(const NodeEvictionCandidate
&a
, const NodeEvictionCandidate
&b
)
855 // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
856 if (a
.nLastBlockTime
!= b
.nLastBlockTime
) return a
.nLastBlockTime
< b
.nLastBlockTime
;
857 if (a
.fNetworkNode
!= b
.fNetworkNode
) return b
.fNetworkNode
;
858 return a
.nTimeConnected
> b
.nTimeConnected
;
861 static bool CompareNodeTXTime(const NodeEvictionCandidate
&a
, const NodeEvictionCandidate
&b
)
863 // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
864 if (a
.nLastTXTime
!= b
.nLastTXTime
) return a
.nLastTXTime
< b
.nLastTXTime
;
865 if (a
.fRelayTxes
!= b
.fRelayTxes
) return b
.fRelayTxes
;
866 if (a
.fBloomFilter
!= b
.fBloomFilter
) return a
.fBloomFilter
;
867 return a
.nTimeConnected
> b
.nTimeConnected
;
870 /** Try to find a connection to evict when the node is full.
871 * Extreme care must be taken to avoid opening the node to attacker
872 * triggered network partitioning.
873 * The strategy used here is to protect a small number of peers
874 * for each of several distinct characteristics which are difficult
875 * to forge. In order to partition a node the attacker must be
876 * simultaneously better at all of them than honest peers.
878 bool CConnman::AttemptToEvictConnection()
880 std::vector
<NodeEvictionCandidate
> vEvictionCandidates
;
884 BOOST_FOREACH(CNode
*node
, vNodes
) {
885 if (node
->fWhitelisted
)
889 if (node
->fDisconnect
)
891 NodeEvictionCandidate candidate
= {node
->id
, node
->nTimeConnected
, node
->nMinPingUsecTime
,
892 node
->nLastBlockTime
, node
->nLastTXTime
, node
->fNetworkNode
,
893 node
->fRelayTxes
, node
->pfilter
!= NULL
, node
->addr
, node
->nKeyedNetGroup
};
894 vEvictionCandidates
.push_back(candidate
);
898 if (vEvictionCandidates
.empty()) return false;
900 // Protect connections with certain characteristics
902 // Deterministically select 4 peers to protect by netgroup.
903 // An attacker cannot predict which netgroups will be protected
904 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), CompareNetGroupKeyed
);
905 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
907 if (vEvictionCandidates
.empty()) return false;
909 // Protect the 8 nodes with the lowest minimum ping time.
910 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
911 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeMinPingTime
);
912 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(8, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
914 if (vEvictionCandidates
.empty()) return false;
916 // Protect 4 nodes that most recently sent us transactions.
917 // An attacker cannot manipulate this metric without performing useful work.
918 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), CompareNodeTXTime
);
919 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
921 if (vEvictionCandidates
.empty()) return false;
923 // Protect 4 nodes that most recently sent us blocks.
924 // An attacker cannot manipulate this metric without performing useful work.
925 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), CompareNodeBlockTime
);
926 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
928 if (vEvictionCandidates
.empty()) return false;
930 // Protect the half of the remaining nodes which have been connected the longest.
931 // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
932 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
933 vEvictionCandidates
.erase(vEvictionCandidates
.end() - static_cast<int>(vEvictionCandidates
.size() / 2), vEvictionCandidates
.end());
935 if (vEvictionCandidates
.empty()) return false;
937 // Identify the network group with the most connections and youngest member.
938 // (vEvictionCandidates is already sorted by reverse connect time)
939 uint64_t naMostConnections
;
940 unsigned int nMostConnections
= 0;
941 int64_t nMostConnectionsTime
= 0;
942 std::map
<uint64_t, std::vector
<NodeEvictionCandidate
> > mapNetGroupNodes
;
943 BOOST_FOREACH(const NodeEvictionCandidate
&node
, vEvictionCandidates
) {
944 mapNetGroupNodes
[node
.nKeyedNetGroup
].push_back(node
);
945 int64_t grouptime
= mapNetGroupNodes
[node
.nKeyedNetGroup
][0].nTimeConnected
;
946 size_t groupsize
= mapNetGroupNodes
[node
.nKeyedNetGroup
].size();
948 if (groupsize
> nMostConnections
|| (groupsize
== nMostConnections
&& grouptime
> nMostConnectionsTime
)) {
949 nMostConnections
= groupsize
;
950 nMostConnectionsTime
= grouptime
;
951 naMostConnections
= node
.nKeyedNetGroup
;
955 // Reduce to the network group with the most connections
956 vEvictionCandidates
= std::move(mapNetGroupNodes
[naMostConnections
]);
958 // Disconnect from the network group with the most connections
959 NodeId evicted
= vEvictionCandidates
.front().id
;
961 for(std::vector
<CNode
*>::const_iterator
it(vNodes
.begin()); it
!= vNodes
.end(); ++it
) {
962 if ((*it
)->GetId() == evicted
) {
963 (*it
)->fDisconnect
= true;
970 void CConnman::AcceptConnection(const ListenSocket
& hListenSocket
) {
971 struct sockaddr_storage sockaddr
;
972 socklen_t len
= sizeof(sockaddr
);
973 SOCKET hSocket
= accept(hListenSocket
.socket
, (struct sockaddr
*)&sockaddr
, &len
);
976 int nMaxInbound
= nMaxConnections
- (nMaxOutbound
+ MAX_FEELER_CONNECTIONS
);
977 assert(nMaxInbound
> 0);
979 if (hSocket
!= INVALID_SOCKET
)
980 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
981 LogPrintf("Warning: Unknown socket family\n");
983 bool whitelisted
= hListenSocket
.whitelisted
|| IsWhitelistedRange(addr
);
986 BOOST_FOREACH(CNode
* pnode
, vNodes
)
991 if (hSocket
== INVALID_SOCKET
)
993 int nErr
= WSAGetLastError();
994 if (nErr
!= WSAEWOULDBLOCK
)
995 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr
));
999 if (!IsSelectableSocket(hSocket
))
1001 LogPrintf("connection from %s dropped: non-selectable socket\n", addr
.ToString());
1002 CloseSocket(hSocket
);
1006 // According to the internet TCP_NODELAY is not carried into accepted sockets
1007 // on all platforms. Set it again here just to be sure.
1010 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&set
, sizeof(int));
1012 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&set
, sizeof(int));
1015 if (IsBanned(addr
) && !whitelisted
)
1017 LogPrintf("connection from %s dropped (banned)\n", addr
.ToString());
1018 CloseSocket(hSocket
);
1022 if (nInbound
>= nMaxInbound
)
1024 if (!AttemptToEvictConnection()) {
1025 // No connection to evict, disconnect the new connection
1026 LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
1027 CloseSocket(hSocket
);
1032 CNode
* pnode
= new CNode(GetNewNodeId(), nLocalServices
, GetBestHeight(), hSocket
, addr
, "", true);
1033 GetNodeSignals().InitializeNode(pnode
->GetId(), pnode
);
1035 pnode
->fWhitelisted
= whitelisted
;
1037 LogPrint("net", "connection from %s accepted\n", addr
.ToString());
1041 vNodes
.push_back(pnode
);
1045 void CConnman::ThreadSocketHandler()
1047 unsigned int nPrevNodeCount
= 0;
1055 // Disconnect unused nodes
1056 std::vector
<CNode
*> vNodesCopy
= vNodes
;
1057 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1059 if (pnode
->fDisconnect
||
1060 (pnode
->GetRefCount() <= 0 && pnode
->vRecvMsg
.empty() && pnode
->nSendSize
== 0 && pnode
->ssSend
.empty()))
1062 // remove from vNodes
1063 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
1065 // release outbound grant (if any)
1066 pnode
->grantOutbound
.Release();
1068 // close socket and cleanup
1069 pnode
->CloseSocketDisconnect();
1071 // hold in disconnected pool until all refs are released
1072 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
1074 vNodesDisconnected
.push_back(pnode
);
1079 // Delete disconnected nodes
1080 std::list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
1081 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
1083 // wait until threads are done using it
1084 if (pnode
->GetRefCount() <= 0)
1086 bool fDelete
= false;
1088 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1091 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1094 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
1102 vNodesDisconnected
.remove(pnode
);
1108 if(vNodes
.size() != nPrevNodeCount
) {
1109 nPrevNodeCount
= vNodes
.size();
1111 clientInterface
->NotifyNumConnectionsChanged(nPrevNodeCount
);
1115 // Find which sockets have data to receive
1117 struct timeval timeout
;
1119 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
1124 FD_ZERO(&fdsetRecv
);
1125 FD_ZERO(&fdsetSend
);
1126 FD_ZERO(&fdsetError
);
1127 SOCKET hSocketMax
= 0;
1128 bool have_fds
= false;
1130 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
) {
1131 FD_SET(hListenSocket
.socket
, &fdsetRecv
);
1132 hSocketMax
= std::max(hSocketMax
, hListenSocket
.socket
);
1138 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1140 if (pnode
->hSocket
== INVALID_SOCKET
)
1142 FD_SET(pnode
->hSocket
, &fdsetError
);
1143 hSocketMax
= std::max(hSocketMax
, pnode
->hSocket
);
1146 // Implement the following logic:
1147 // * If there is data to send, select() for sending data. As this only
1148 // happens when optimistic write failed, we choose to first drain the
1149 // write buffer in this case before receiving more. This avoids
1150 // needlessly queueing received data, if the remote peer is not themselves
1151 // receiving data. This means properly utilizing TCP flow control signalling.
1152 // * Otherwise, if there is no (complete) message in the receive buffer,
1153 // or there is space left in the buffer, select() for receiving data.
1154 // * (if neither of the above applies, there is certainly one message
1155 // in the receiver buffer ready to be processed).
1156 // Together, that means that at least one of the following is always possible,
1157 // so we don't deadlock:
1158 // * We send some data.
1159 // * We wait for data to be received (and disconnect after timeout).
1160 // * We process a message in the buffer (message handler thread).
1162 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1164 if (pnode
->nOptimisticBytesWritten
) {
1165 RecordBytesSent(pnode
->nOptimisticBytesWritten
);
1166 pnode
->nOptimisticBytesWritten
= 0;
1168 if (!pnode
->vSendMsg
.empty()) {
1169 FD_SET(pnode
->hSocket
, &fdsetSend
);
1175 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1177 pnode
->vRecvMsg
.empty() || !pnode
->vRecvMsg
.front().complete() ||
1178 pnode
->GetTotalRecvSize() <= GetReceiveFloodSize()))
1179 FD_SET(pnode
->hSocket
, &fdsetRecv
);
1184 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
1185 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
1186 boost::this_thread::interruption_point();
1188 if (nSelect
== SOCKET_ERROR
)
1192 int nErr
= WSAGetLastError();
1193 LogPrintf("socket select error %s\n", NetworkErrorString(nErr
));
1194 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
1195 FD_SET(i
, &fdsetRecv
);
1197 FD_ZERO(&fdsetSend
);
1198 FD_ZERO(&fdsetError
);
1199 MilliSleep(timeout
.tv_usec
/1000);
1203 // Accept new connections
1205 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
)
1207 if (hListenSocket
.socket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
.socket
, &fdsetRecv
))
1209 AcceptConnection(hListenSocket
);
1214 // Service each socket
1216 std::vector
<CNode
*> vNodesCopy
;
1219 vNodesCopy
= vNodes
;
1220 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1223 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1225 boost::this_thread::interruption_point();
1230 if (pnode
->hSocket
== INVALID_SOCKET
)
1232 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
1234 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1238 // typical socket buffer is 8K-64K
1239 char pchBuf
[0x10000];
1240 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
1243 bool notify
= false;
1244 if (!pnode
->ReceiveMsgBytes(pchBuf
, nBytes
, notify
))
1245 pnode
->CloseSocketDisconnect();
1247 messageHandlerCondition
.notify_one();
1248 pnode
->nLastRecv
= GetTime();
1249 pnode
->nRecvBytes
+= nBytes
;
1250 RecordBytesRecv(nBytes
);
1252 else if (nBytes
== 0)
1254 // socket closed gracefully
1255 if (!pnode
->fDisconnect
)
1256 LogPrint("net", "socket closed\n");
1257 pnode
->CloseSocketDisconnect();
1259 else if (nBytes
< 0)
1262 int nErr
= WSAGetLastError();
1263 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
1265 if (!pnode
->fDisconnect
)
1266 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr
));
1267 pnode
->CloseSocketDisconnect();
1277 if (pnode
->hSocket
== INVALID_SOCKET
)
1279 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
1281 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1283 size_t nBytes
= SocketSendData(pnode
);
1285 RecordBytesSent(nBytes
);
1290 // Inactivity checking
1292 int64_t nTime
= GetTime();
1293 if (nTime
- pnode
->nTimeConnected
> 60)
1295 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
1297 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0, pnode
->id
);
1298 pnode
->fDisconnect
= true;
1300 else if (nTime
- pnode
->nLastSend
> TIMEOUT_INTERVAL
)
1302 LogPrintf("socket sending timeout: %is\n", nTime
- pnode
->nLastSend
);
1303 pnode
->fDisconnect
= true;
1305 else if (nTime
- pnode
->nLastRecv
> (pnode
->nVersion
> BIP0031_VERSION
? TIMEOUT_INTERVAL
: 90*60))
1307 LogPrintf("socket receive timeout: %is\n", nTime
- pnode
->nLastRecv
);
1308 pnode
->fDisconnect
= true;
1310 else if (pnode
->nPingNonceSent
&& pnode
->nPingUsecStart
+ TIMEOUT_INTERVAL
* 1000000 < GetTimeMicros())
1312 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode
->nPingUsecStart
));
1313 pnode
->fDisconnect
= true;
1319 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1334 void ThreadMapPort()
1336 std::string port
= strprintf("%u", GetListenPort());
1337 const char * multicastif
= 0;
1338 const char * minissdpdpath
= 0;
1339 struct UPNPDev
* devlist
= 0;
1342 #ifndef UPNPDISCOVER_SUCCESS
1344 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1345 #elif MINIUPNPC_API_VERSION < 14
1348 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1350 /* miniupnpc 1.9.20150730 */
1352 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, 2, &error
);
1355 struct UPNPUrls urls
;
1356 struct IGDdatas data
;
1359 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1363 char externalIPAddress
[40];
1364 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1365 if(r
!= UPNPCOMMAND_SUCCESS
)
1366 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1369 if(externalIPAddress
[0])
1372 if(LookupHost(externalIPAddress
, resolved
, false)) {
1373 LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved
.ToString().c_str());
1374 AddLocal(resolved
, LOCAL_UPNP
);
1378 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1382 std::string strDesc
= "Bitcoin " + FormatFullVersion();
1386 #ifndef UPNPDISCOVER_SUCCESS
1388 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1389 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1392 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1393 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1396 if(r
!=UPNPCOMMAND_SUCCESS
)
1397 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1398 port
, port
, lanaddr
, r
, strupnperror(r
));
1400 LogPrintf("UPnP Port Mapping successful.\n");
1402 MilliSleep(20*60*1000); // Refresh every 20 minutes
1405 catch (const boost::thread_interrupted
&)
1407 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1408 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r
);
1409 freeUPNPDevlist(devlist
); devlist
= 0;
1410 FreeUPNPUrls(&urls
);
1414 LogPrintf("No valid UPnP IGDs found\n");
1415 freeUPNPDevlist(devlist
); devlist
= 0;
1417 FreeUPNPUrls(&urls
);
1421 void MapPort(bool fUseUPnP
)
1423 static boost::thread
* upnp_thread
= NULL
;
1428 upnp_thread
->interrupt();
1429 upnp_thread
->join();
1432 upnp_thread
= new boost::thread(boost::bind(&TraceThread
<void (*)()>, "upnp", &ThreadMapPort
));
1434 else if (upnp_thread
) {
1435 upnp_thread
->interrupt();
1436 upnp_thread
->join();
1445 // Intentionally left blank.
1454 static std::string
GetDNSHost(const CDNSSeedData
& data
, ServiceFlags
* requiredServiceBits
)
1456 //use default host for non-filter-capable seeds or if we use the default service bits (NODE_NETWORK)
1457 if (!data
.supportsServiceBitsFiltering
|| *requiredServiceBits
== NODE_NETWORK
) {
1458 *requiredServiceBits
= NODE_NETWORK
;
1462 return strprintf("x%x.%s", *requiredServiceBits
, data
.host
);
1466 void CConnman::ThreadDNSAddressSeed()
1468 // goal: only query DNS seeds if address need is acute
1469 if ((addrman
.size() > 0) &&
1470 (!GetBoolArg("-forcednsseed", DEFAULT_FORCEDNSSEED
))) {
1471 MilliSleep(11 * 1000);
1474 if (vNodes
.size() >= 2) {
1475 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1480 const std::vector
<CDNSSeedData
> &vSeeds
= Params().DNSSeeds();
1483 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1485 BOOST_FOREACH(const CDNSSeedData
&seed
, vSeeds
) {
1486 if (HaveNameProxy()) {
1487 AddOneShot(seed
.host
);
1489 std::vector
<CNetAddr
> vIPs
;
1490 std::vector
<CAddress
> vAdd
;
1491 ServiceFlags requiredServiceBits
= nRelevantServices
;
1492 if (LookupHost(GetDNSHost(seed
, &requiredServiceBits
).c_str(), vIPs
, 0, true))
1494 BOOST_FOREACH(const CNetAddr
& ip
, vIPs
)
1496 int nOneDay
= 24*3600;
1497 CAddress addr
= CAddress(CService(ip
, Params().GetDefaultPort()), requiredServiceBits
);
1498 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1499 vAdd
.push_back(addr
);
1503 // TODO: The seed name resolve may fail, yielding an IP of [::], which results in
1504 // addrman assigning the same source to results from different seeds.
1505 // This should switch to a hard-coded stable dummy IP for each seed name, so that the
1506 // resolve is not required at all.
1507 if (!vIPs
.empty()) {
1508 CService seedSource
;
1509 Lookup(seed
.name
.c_str(), seedSource
, 0, true);
1510 addrman
.Add(vAdd
, seedSource
);
1515 LogPrintf("%d addresses found from DNS seeds\n", found
);
1529 void CConnman::DumpAddresses()
1531 int64_t nStart
= GetTimeMillis();
1536 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1537 addrman
.size(), GetTimeMillis() - nStart
);
1540 void CConnman::DumpData()
1546 void CConnman::ProcessOneShot()
1548 std::string strDest
;
1551 if (vOneShots
.empty())
1553 strDest
= vOneShots
.front();
1554 vOneShots
.pop_front();
1557 CSemaphoreGrant
grant(*semOutbound
, true);
1559 if (!OpenNetworkConnection(addr
, false, &grant
, strDest
.c_str(), true))
1560 AddOneShot(strDest
);
1564 void CConnman::ThreadOpenConnections()
1566 // Connect to specific addresses
1567 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1569 for (int64_t nLoop
= 0;; nLoop
++)
1572 BOOST_FOREACH(const std::string
& strAddr
, mapMultiArgs
["-connect"])
1574 CAddress
addr(CService(), NODE_NONE
);
1575 OpenNetworkConnection(addr
, false, NULL
, strAddr
.c_str());
1576 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1585 // Initiate network connections
1586 int64_t nStart
= GetTime();
1588 // Minimum time before next feeler connection (in microseconds).
1589 int64_t nNextFeeler
= PoissonNextSend(nStart
*1000*1000, FEELER_INTERVAL
);
1596 CSemaphoreGrant
grant(*semOutbound
);
1597 boost::this_thread::interruption_point();
1599 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1600 if (addrman
.size() == 0 && (GetTime() - nStart
> 60)) {
1601 static bool done
= false;
1603 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1605 LookupHost("127.0.0.1", local
, false);
1606 addrman
.Add(convertSeed6(Params().FixedSeeds()), local
);
1612 // Choose an address to connect to based on most recently seen
1614 CAddress addrConnect
;
1616 // Only connect out to one peer per network group (/16 for IPv4).
1617 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1619 std::set
<std::vector
<unsigned char> > setConnected
;
1622 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1623 if (!pnode
->fInbound
) {
1624 setConnected
.insert(pnode
->addr
.GetGroup());
1629 assert(nOutbound
<= (nMaxOutbound
+ MAX_FEELER_CONNECTIONS
));
1631 // Feeler Connections
1634 // * Increase the number of connectable addresses in the tried table.
1637 // * Choose a random address from new and attempt to connect to it if we can connect
1638 // successfully it is added to tried.
1639 // * Start attempting feeler connections only after node finishes making outbound
1641 // * Only make a feeler connection once every few minutes.
1643 bool fFeeler
= false;
1644 if (nOutbound
>= nMaxOutbound
) {
1645 int64_t nTime
= GetTimeMicros(); // The current time right now (in microseconds).
1646 if (nTime
> nNextFeeler
) {
1647 nNextFeeler
= PoissonNextSend(nTime
, FEELER_INTERVAL
);
1654 int64_t nANow
= GetAdjustedTime();
1658 CAddrInfo addr
= addrman
.Select(fFeeler
);
1660 // if we selected an invalid address, restart
1661 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1664 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1665 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1666 // already-connected network ranges, ...) before trying new addrman addresses.
1671 if (IsLimited(addr
))
1674 // only connect to full nodes
1675 if ((addr
.nServices
& REQUIRED_SERVICES
) != REQUIRED_SERVICES
)
1678 // only consider very recently tried nodes after 30 failed attempts
1679 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1682 // only consider nodes missing relevant services after 40 failed attempts
1683 if ((addr
.nServices
& nRelevantServices
) != nRelevantServices
&& nTries
< 40)
1686 // do not allow non-default ports, unless after 50 invalid addresses selected already
1687 if (addr
.GetPort() != Params().GetDefaultPort() && nTries
< 50)
1694 if (addrConnect
.IsValid()) {
1697 // Add small amount of random noise before connection to avoid synchronization.
1698 int randsleep
= GetRandInt(FEELER_SLEEP_WINDOW
* 1000);
1699 MilliSleep(randsleep
);
1700 LogPrint("net", "Making feeler connection to %s\n", addrConnect
.ToString());
1703 OpenNetworkConnection(addrConnect
, (int)setConnected
.size() >= std::min(nMaxConnections
- 1, 2), &grant
, NULL
, false, fFeeler
);
1708 std::vector
<AddedNodeInfo
> CConnman::GetAddedNodeInfo()
1710 std::vector
<AddedNodeInfo
> ret
;
1712 std::list
<std::string
> lAddresses(0);
1714 LOCK(cs_vAddedNodes
);
1715 ret
.reserve(vAddedNodes
.size());
1716 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1717 lAddresses
.push_back(strAddNode
);
1721 // Build a map of all already connected addresses (by IP:port and by name) to inbound/outbound and resolved CService
1722 std::map
<CService
, bool> mapConnected
;
1723 std::map
<std::string
, std::pair
<bool, CService
>> mapConnectedByName
;
1726 for (const CNode
* pnode
: vNodes
) {
1727 if (pnode
->addr
.IsValid()) {
1728 mapConnected
[pnode
->addr
] = pnode
->fInbound
;
1730 if (!pnode
->addrName
.empty()) {
1731 mapConnectedByName
[pnode
->addrName
] = std::make_pair(pnode
->fInbound
, static_cast<const CService
&>(pnode
->addr
));
1736 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1737 CService
service(LookupNumeric(strAddNode
.c_str(), Params().GetDefaultPort()));
1738 if (service
.IsValid()) {
1739 // strAddNode is an IP:port
1740 auto it
= mapConnected
.find(service
);
1741 if (it
!= mapConnected
.end()) {
1742 ret
.push_back(AddedNodeInfo
{strAddNode
, service
, true, it
->second
});
1744 ret
.push_back(AddedNodeInfo
{strAddNode
, CService(), false, false});
1747 // strAddNode is a name
1748 auto it
= mapConnectedByName
.find(strAddNode
);
1749 if (it
!= mapConnectedByName
.end()) {
1750 ret
.push_back(AddedNodeInfo
{strAddNode
, it
->second
.second
, true, it
->second
.first
});
1752 ret
.push_back(AddedNodeInfo
{strAddNode
, CService(), false, false});
1760 void CConnman::ThreadOpenAddedConnections()
1763 LOCK(cs_vAddedNodes
);
1764 vAddedNodes
= mapMultiArgs
["-addnode"];
1767 for (unsigned int i
= 0; true; i
++)
1769 std::vector
<AddedNodeInfo
> vInfo
= GetAddedNodeInfo();
1770 for (const AddedNodeInfo
& info
: vInfo
) {
1771 if (!info
.fConnected
) {
1772 CSemaphoreGrant
grant(*semOutbound
);
1773 // If strAddedNode is an IP/port, decode it immediately, so
1774 // OpenNetworkConnection can detect existing connections to that IP/port.
1775 CService
service(LookupNumeric(info
.strAddedNode
.c_str(), Params().GetDefaultPort()));
1776 OpenNetworkConnection(CAddress(service
, NODE_NONE
), false, &grant
, info
.strAddedNode
.c_str(), false);
1781 MilliSleep(120000); // Retry every 2 minutes
1785 // if successful, this moves the passed grant to the constructed node
1786 bool CConnman::OpenNetworkConnection(const CAddress
& addrConnect
, bool fCountFailure
, CSemaphoreGrant
*grantOutbound
, const char *pszDest
, bool fOneShot
, bool fFeeler
)
1789 // Initiate outbound network connection
1791 boost::this_thread::interruption_point();
1793 if (IsLocal(addrConnect
) ||
1794 FindNode((CNetAddr
)addrConnect
) || IsBanned(addrConnect
) ||
1795 FindNode(addrConnect
.ToStringIPPort()))
1797 } else if (FindNode(std::string(pszDest
)))
1800 CNode
* pnode
= ConnectNode(addrConnect
, pszDest
, fCountFailure
);
1801 boost::this_thread::interruption_point();
1806 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1807 pnode
->fNetworkNode
= true;
1809 pnode
->fOneShot
= true;
1811 pnode
->fFeeler
= true;
1817 void CConnman::ThreadMessageHandler()
1819 boost::mutex condition_mutex
;
1820 boost::unique_lock
<boost::mutex
> lock(condition_mutex
);
1824 std::vector
<CNode
*> vNodesCopy
;
1827 vNodesCopy
= vNodes
;
1828 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
) {
1835 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1837 if (pnode
->fDisconnect
)
1842 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1845 if (!GetNodeSignals().ProcessMessages(pnode
, *this))
1846 pnode
->CloseSocketDisconnect();
1848 if (pnode
->nSendSize
< GetSendBufferSize())
1850 if (!pnode
->vRecvGetData
.empty() || (!pnode
->vRecvMsg
.empty() && pnode
->vRecvMsg
[0].complete()))
1857 boost::this_thread::interruption_point();
1861 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1863 GetNodeSignals().SendMessages(pnode
, *this);
1865 boost::this_thread::interruption_point();
1870 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1875 messageHandlerCondition
.timed_wait(lock
, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1884 bool CConnman::BindListenPort(const CService
&addrBind
, std::string
& strError
, bool fWhitelisted
)
1889 // Create socket for listening for incoming connections
1890 struct sockaddr_storage sockaddr
;
1891 socklen_t len
= sizeof(sockaddr
);
1892 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1894 strError
= strprintf("Error: Bind address family for %s not supported", addrBind
.ToString());
1895 LogPrintf("%s\n", strError
);
1899 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1900 if (hListenSocket
== INVALID_SOCKET
)
1902 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1903 LogPrintf("%s\n", strError
);
1906 if (!IsSelectableSocket(hListenSocket
))
1908 strError
= "Error: Couldn't create a listenable socket for incoming connections";
1909 LogPrintf("%s\n", strError
);
1916 // Different way of disabling SIGPIPE on BSD
1917 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1919 // Allow binding if the port is still in TIME_WAIT state after
1920 // the program was closed and restarted.
1921 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1922 // Disable Nagle's algorithm
1923 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&nOne
, sizeof(int));
1925 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&nOne
, sizeof(int));
1926 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&nOne
, sizeof(int));
1929 // Set to non-blocking, incoming connections will also inherit this
1930 if (!SetSocketNonBlocking(hListenSocket
, true)) {
1931 strError
= strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1932 LogPrintf("%s\n", strError
);
1936 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1937 // and enable it by default or not. Try to enable it, if possible.
1938 if (addrBind
.IsIPv6()) {
1941 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (const char*)&nOne
, sizeof(int));
1943 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1947 int nProtLevel
= PROTECTION_LEVEL_UNRESTRICTED
;
1948 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_PROTECTION_LEVEL
, (const char*)&nProtLevel
, sizeof(int));
1952 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1954 int nErr
= WSAGetLastError();
1955 if (nErr
== WSAEADDRINUSE
)
1956 strError
= strprintf(_("Unable to bind to %s on this computer. %s is probably already running."), addrBind
.ToString(), _(PACKAGE_NAME
));
1958 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind
.ToString(), NetworkErrorString(nErr
));
1959 LogPrintf("%s\n", strError
);
1960 CloseSocket(hListenSocket
);
1963 LogPrintf("Bound to %s\n", addrBind
.ToString());
1965 // Listen for incoming connections
1966 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1968 strError
= strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1969 LogPrintf("%s\n", strError
);
1970 CloseSocket(hListenSocket
);
1974 vhListenSocket
.push_back(ListenSocket(hListenSocket
, fWhitelisted
));
1976 if (addrBind
.IsRoutable() && fDiscover
&& !fWhitelisted
)
1977 AddLocal(addrBind
, LOCAL_BIND
);
1982 void Discover(boost::thread_group
& threadGroup
)
1988 // Get local host IP
1989 char pszHostName
[256] = "";
1990 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1992 std::vector
<CNetAddr
> vaddr
;
1993 if (LookupHost(pszHostName
, vaddr
, 0, true))
1995 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1997 if (AddLocal(addr
, LOCAL_IF
))
1998 LogPrintf("%s: %s - %s\n", __func__
, pszHostName
, addr
.ToString());
2003 // Get local host ip
2004 struct ifaddrs
* myaddrs
;
2005 if (getifaddrs(&myaddrs
) == 0)
2007 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
2009 if (ifa
->ifa_addr
== NULL
) continue;
2010 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
2011 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
2012 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
2013 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
2015 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
2016 CNetAddr
addr(s4
->sin_addr
);
2017 if (AddLocal(addr
, LOCAL_IF
))
2018 LogPrintf("%s: IPv4 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
2020 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
2022 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
2023 CNetAddr
addr(s6
->sin6_addr
);
2024 if (AddLocal(addr
, LOCAL_IF
))
2025 LogPrintf("%s: IPv6 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
2028 freeifaddrs(myaddrs
);
2033 CConnman::CConnman()
2035 setBannedIsDirty
= false;
2036 fAddressesInitialized
= false;
2038 nSendBufferMaxSize
= 0;
2039 nReceiveFloodSize
= 0;
2041 nMaxConnections
= 0;
2044 clientInterface
= NULL
;
2047 NodeId
CConnman::GetNewNodeId()
2049 return nLastNodeId
.fetch_add(1, std::memory_order_relaxed
);
2052 bool CConnman::Start(boost::thread_group
& threadGroup
, CScheduler
& scheduler
, std::string
& strNodeError
, Options connOptions
)
2054 nTotalBytesRecv
= 0;
2055 nTotalBytesSent
= 0;
2056 nMaxOutboundLimit
= 0;
2057 nMaxOutboundTotalBytesSentInCycle
= 0;
2058 nMaxOutboundTimeframe
= 60*60*24; //1 day
2059 nMaxOutboundCycleStartTime
= 0;
2061 nRelevantServices
= connOptions
.nRelevantServices
;
2062 nLocalServices
= connOptions
.nLocalServices
;
2063 nMaxConnections
= connOptions
.nMaxConnections
;
2064 nMaxOutbound
= std::min((connOptions
.nMaxOutbound
), nMaxConnections
);
2066 nSendBufferMaxSize
= 1000*GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER
);
2067 nReceiveFloodSize
= 1000*GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER
);
2069 SetBestHeight(connOptions
.nBestHeight
);
2071 clientInterface
= connOptions
.uiInterface
;
2072 if (clientInterface
)
2073 clientInterface
->InitMessage(_("Loading addresses..."));
2074 // Load addresses from peers.dat
2075 int64_t nStart
= GetTimeMillis();
2078 if (adb
.Read(addrman
))
2079 LogPrintf("Loaded %i addresses from peers.dat %dms\n", addrman
.size(), GetTimeMillis() - nStart
);
2081 addrman
.Clear(); // Addrman can be in an inconsistent state after failure, reset it
2082 LogPrintf("Invalid or missing peers.dat; recreating\n");
2086 if (clientInterface
)
2087 clientInterface
->InitMessage(_("Loading banlist..."));
2088 // Load addresses from banlist.dat
2089 nStart
= GetTimeMillis();
2092 if (bandb
.Read(banmap
)) {
2093 SetBanned(banmap
); // thread save setter
2094 SetBannedSetDirty(false); // no need to write down, just read data
2095 SweepBanned(); // sweep out unused entries
2097 LogPrint("net", "Loaded %d banned node ips/subnets from banlist.dat %dms\n",
2098 banmap
.size(), GetTimeMillis() - nStart
);
2100 LogPrintf("Invalid or missing banlist.dat; recreating\n");
2101 SetBannedSetDirty(true); // force write
2105 uiInterface
.InitMessage(_("Starting network threads..."));
2107 fAddressesInitialized
= true;
2109 if (semOutbound
== NULL
) {
2110 // initialize semaphore
2111 semOutbound
= new CSemaphore(std::min((nMaxOutbound
+ MAX_FEELER_CONNECTIONS
), nMaxConnections
));
2114 if (pnodeLocalHost
== NULL
) {
2116 LookupHost("127.0.0.1", local
, false);
2117 pnodeLocalHost
= new CNode(GetNewNodeId(), nLocalServices
, GetBestHeight(), INVALID_SOCKET
, CAddress(CService(local
, 0), nLocalServices
));
2118 GetNodeSignals().InitializeNode(pnodeLocalHost
->GetId(), pnodeLocalHost
);
2125 if (!GetBoolArg("-dnsseed", true))
2126 LogPrintf("DNS seeding disabled\n");
2128 threadGroup
.create_thread(boost::bind(&TraceThread
<boost::function
<void()> >, "dnsseed", boost::function
<void()>(boost::bind(&CConnman::ThreadDNSAddressSeed
, this))));
2130 // Send and receive from sockets, accept connections
2131 threadGroup
.create_thread(boost::bind(&TraceThread
<boost::function
<void()> >, "net", boost::function
<void()>(boost::bind(&CConnman::ThreadSocketHandler
, this))));
2133 // Initiate outbound connections from -addnode
2134 threadGroup
.create_thread(boost::bind(&TraceThread
<boost::function
<void()> >, "addcon", boost::function
<void()>(boost::bind(&CConnman::ThreadOpenAddedConnections
, this))));
2136 // Initiate outbound connections
2137 threadGroup
.create_thread(boost::bind(&TraceThread
<boost::function
<void()> >, "opencon", boost::function
<void()>(boost::bind(&CConnman::ThreadOpenConnections
, this))));
2140 threadGroup
.create_thread(boost::bind(&TraceThread
<boost::function
<void()> >, "msghand", boost::function
<void()>(boost::bind(&CConnman::ThreadMessageHandler
, this))));
2142 // Dump network addresses
2143 scheduler
.scheduleEvery(boost::bind(&CConnman::DumpData
, this), DUMP_ADDRESSES_INTERVAL
);
2156 // Shutdown Windows Sockets
2161 instance_of_cnetcleanup
;
2163 void CConnman::Stop()
2165 LogPrintf("%s\n",__func__
);
2167 for (int i
=0; i
<(nMaxOutbound
+ MAX_FEELER_CONNECTIONS
); i
++)
2168 semOutbound
->post();
2170 if (fAddressesInitialized
)
2173 fAddressesInitialized
= false;
2177 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2178 if (pnode
->hSocket
!= INVALID_SOCKET
)
2179 CloseSocket(pnode
->hSocket
);
2180 BOOST_FOREACH(ListenSocket
& hListenSocket
, vhListenSocket
)
2181 if (hListenSocket
.socket
!= INVALID_SOCKET
)
2182 if (!CloseSocket(hListenSocket
.socket
))
2183 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2185 // clean up some globals (to help leak detection)
2186 BOOST_FOREACH(CNode
*pnode
, vNodes
) {
2189 BOOST_FOREACH(CNode
*pnode
, vNodesDisconnected
) {
2193 vNodesDisconnected
.clear();
2194 vhListenSocket
.clear();
2198 DeleteNode(pnodeLocalHost
);
2199 pnodeLocalHost
= NULL
;
2202 void CConnman::DeleteNode(CNode
* pnode
)
2205 bool fUpdateConnectionTime
= false;
2206 GetNodeSignals().FinalizeNode(pnode
->GetId(), fUpdateConnectionTime
);
2207 if(fUpdateConnectionTime
)
2208 addrman
.Connected(pnode
->addr
);
2212 CConnman::~CConnman()
2216 size_t CConnman::GetAddressCount() const
2218 return addrman
.size();
2221 void CConnman::SetServices(const CService
&addr
, ServiceFlags nServices
)
2223 addrman
.SetServices(addr
, nServices
);
2226 void CConnman::MarkAddressGood(const CAddress
& addr
)
2231 void CConnman::AddNewAddress(const CAddress
& addr
, const CAddress
& addrFrom
, int64_t nTimePenalty
)
2233 addrman
.Add(addr
, addrFrom
, nTimePenalty
);
2236 void CConnman::AddNewAddresses(const std::vector
<CAddress
>& vAddr
, const CAddress
& addrFrom
, int64_t nTimePenalty
)
2238 addrman
.Add(vAddr
, addrFrom
, nTimePenalty
);
2241 std::vector
<CAddress
> CConnman::GetAddresses()
2243 return addrman
.GetAddr();
2246 bool CConnman::AddNode(const std::string
& strNode
)
2248 LOCK(cs_vAddedNodes
);
2249 for(std::vector
<std::string
>::const_iterator it
= vAddedNodes
.begin(); it
!= vAddedNodes
.end(); ++it
) {
2254 vAddedNodes
.push_back(strNode
);
2258 bool CConnman::RemoveAddedNode(const std::string
& strNode
)
2260 LOCK(cs_vAddedNodes
);
2261 for(std::vector
<std::string
>::iterator it
= vAddedNodes
.begin(); it
!= vAddedNodes
.end(); ++it
) {
2262 if (strNode
== *it
) {
2263 vAddedNodes
.erase(it
);
2270 size_t CConnman::GetNodeCount(NumConnections flags
)
2273 if (flags
== CConnman::CONNECTIONS_ALL
) // Shortcut if we want total
2274 return vNodes
.size();
2277 for(std::vector
<CNode
*>::const_iterator it
= vNodes
.begin(); it
!= vNodes
.end(); ++it
)
2278 if (flags
& ((*it
)->fInbound
? CONNECTIONS_IN
: CONNECTIONS_OUT
))
2284 void CConnman::GetNodeStats(std::vector
<CNodeStats
>& vstats
)
2288 vstats
.reserve(vNodes
.size());
2289 for(std::vector
<CNode
*>::iterator it
= vNodes
.begin(); it
!= vNodes
.end(); ++it
) {
2292 pnode
->copyStats(stats
);
2293 vstats
.push_back(stats
);
2297 bool CConnman::DisconnectAddress(const CNetAddr
& netAddr
)
2299 if (CNode
* pnode
= FindNode(netAddr
)) {
2300 pnode
->fDisconnect
= true;
2306 bool CConnman::DisconnectSubnet(const CSubNet
& subNet
)
2308 if (CNode
* pnode
= FindNode(subNet
)) {
2309 pnode
->fDisconnect
= true;
2315 bool CConnman::DisconnectNode(const std::string
& strNode
)
2317 if (CNode
* pnode
= FindNode(strNode
)) {
2318 pnode
->fDisconnect
= true;
2323 bool CConnman::DisconnectNode(NodeId id
)
2326 for(CNode
* pnode
: vNodes
) {
2327 if (id
== pnode
->id
) {
2328 pnode
->fDisconnect
= true;
2335 void CConnman::RelayTransaction(const CTransaction
& tx
)
2337 CInv
inv(MSG_TX
, tx
.GetHash());
2339 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2341 pnode
->PushInventory(inv
);
2345 void CConnman::RecordBytesRecv(uint64_t bytes
)
2347 LOCK(cs_totalBytesRecv
);
2348 nTotalBytesRecv
+= bytes
;
2351 void CConnman::RecordBytesSent(uint64_t bytes
)
2353 LOCK(cs_totalBytesSent
);
2354 nTotalBytesSent
+= bytes
;
2356 uint64_t now
= GetTime();
2357 if (nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
< now
)
2359 // timeframe expired, reset cycle
2360 nMaxOutboundCycleStartTime
= now
;
2361 nMaxOutboundTotalBytesSentInCycle
= 0;
2364 // TODO, exclude whitebind peers
2365 nMaxOutboundTotalBytesSentInCycle
+= bytes
;
2368 void CConnman::SetMaxOutboundTarget(uint64_t limit
)
2370 LOCK(cs_totalBytesSent
);
2371 uint64_t recommendedMinimum
= (nMaxOutboundTimeframe
/ 600) * MAX_BLOCK_SERIALIZED_SIZE
;
2372 nMaxOutboundLimit
= limit
;
2374 if (limit
> 0 && limit
< recommendedMinimum
)
2375 LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit
, recommendedMinimum
);
2378 uint64_t CConnman::GetMaxOutboundTarget()
2380 LOCK(cs_totalBytesSent
);
2381 return nMaxOutboundLimit
;
2384 uint64_t CConnman::GetMaxOutboundTimeframe()
2386 LOCK(cs_totalBytesSent
);
2387 return nMaxOutboundTimeframe
;
2390 uint64_t CConnman::GetMaxOutboundTimeLeftInCycle()
2392 LOCK(cs_totalBytesSent
);
2393 if (nMaxOutboundLimit
== 0)
2396 if (nMaxOutboundCycleStartTime
== 0)
2397 return nMaxOutboundTimeframe
;
2399 uint64_t cycleEndTime
= nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
;
2400 uint64_t now
= GetTime();
2401 return (cycleEndTime
< now
) ? 0 : cycleEndTime
- GetTime();
2404 void CConnman::SetMaxOutboundTimeframe(uint64_t timeframe
)
2406 LOCK(cs_totalBytesSent
);
2407 if (nMaxOutboundTimeframe
!= timeframe
)
2409 // reset measure-cycle in case of changing
2411 nMaxOutboundCycleStartTime
= GetTime();
2413 nMaxOutboundTimeframe
= timeframe
;
2416 bool CConnman::OutboundTargetReached(bool historicalBlockServingLimit
)
2418 LOCK(cs_totalBytesSent
);
2419 if (nMaxOutboundLimit
== 0)
2422 if (historicalBlockServingLimit
)
2424 // keep a large enough buffer to at least relay each block once
2425 uint64_t timeLeftInCycle
= GetMaxOutboundTimeLeftInCycle();
2426 uint64_t buffer
= timeLeftInCycle
/ 600 * MAX_BLOCK_SERIALIZED_SIZE
;
2427 if (buffer
>= nMaxOutboundLimit
|| nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
- buffer
)
2430 else if (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
)
2436 uint64_t CConnman::GetOutboundTargetBytesLeft()
2438 LOCK(cs_totalBytesSent
);
2439 if (nMaxOutboundLimit
== 0)
2442 return (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
) ? 0 : nMaxOutboundLimit
- nMaxOutboundTotalBytesSentInCycle
;
2445 uint64_t CConnman::GetTotalBytesRecv()
2447 LOCK(cs_totalBytesRecv
);
2448 return nTotalBytesRecv
;
2451 uint64_t CConnman::GetTotalBytesSent()
2453 LOCK(cs_totalBytesSent
);
2454 return nTotalBytesSent
;
2457 ServiceFlags
CConnman::GetLocalServices() const
2459 return nLocalServices
;
2462 void CConnman::SetBestHeight(int height
)
2464 nBestHeight
.store(height
, std::memory_order_release
);
2467 int CConnman::GetBestHeight() const
2469 return nBestHeight
.load(std::memory_order_acquire
);
2472 void CNode::Fuzz(int nChance
)
2474 if (!fSuccessfullyConnected
) return; // Don't fuzz initial handshake
2475 if (GetRand(nChance
) != 0) return; // Fuzz 1 of every nChance messages
2480 // xor a random byte with a random value:
2481 if (!ssSend
.empty()) {
2482 CDataStream::size_type pos
= GetRand(ssSend
.size());
2483 ssSend
[pos
] ^= (unsigned char)(GetRand(256));
2487 // delete a random byte:
2488 if (!ssSend
.empty()) {
2489 CDataStream::size_type pos
= GetRand(ssSend
.size());
2490 ssSend
.erase(ssSend
.begin()+pos
);
2494 // insert a random byte at a random position
2496 CDataStream::size_type pos
= GetRand(ssSend
.size());
2497 char ch
= (char)GetRand(256);
2498 ssSend
.insert(ssSend
.begin()+pos
, ch
);
2502 // Chance of more than one change half the time:
2503 // (more changes exponentially less likely):
2507 unsigned int CConnman::GetReceiveFloodSize() const { return nReceiveFloodSize
; }
2508 unsigned int CConnman::GetSendBufferSize() const{ return nSendBufferMaxSize
; }
2510 CNode::CNode(NodeId idIn
, ServiceFlags nLocalServicesIn
, int nMyStartingHeightIn
, SOCKET hSocketIn
, const CAddress
& addrIn
, const std::string
& addrNameIn
, bool fInboundIn
) :
2511 ssSend(SER_NETWORK
, INIT_PROTO_VERSION
),
2513 nKeyedNetGroup(CalculateKeyedNetGroup(addrIn
)),
2514 addrKnown(5000, 0.001),
2515 filterInventoryKnown(50000, 0.000001)
2517 nServices
= NODE_NONE
;
2518 nServicesExpected
= NODE_NONE
;
2519 hSocket
= hSocketIn
;
2520 nRecvVersion
= INIT_PROTO_VERSION
;
2525 nTimeConnected
= GetTime();
2527 addrName
= addrNameIn
== "" ? addr
.ToStringIPPort() : addrNameIn
;
2530 fWhitelisted
= false;
2532 fClient
= false; // set by version message
2534 fInbound
= fInboundIn
;
2535 fNetworkNode
= false;
2536 fSuccessfullyConnected
= false;
2537 fDisconnect
= false;
2541 hashContinue
= uint256();
2542 nStartingHeight
= -1;
2543 filterInventoryKnown
.reset();
2544 fSendMempool
= false;
2546 nNextLocalAddrSend
= 0;
2551 pfilter
= new CBloomFilter();
2552 timeLastMempoolReq
= 0;
2558 fPingQueued
= false;
2559 nMinPingUsecTime
= std::numeric_limits
<int64_t>::max();
2561 lastSentFeeFilter
= 0;
2562 nextSendTimeFeeFilter
= 0;
2564 nOptimisticBytesWritten
= 0;
2565 nLocalServices
= nLocalServicesIn
;
2567 GetRandBytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
2568 nMyStartingHeight
= nMyStartingHeightIn
;
2570 BOOST_FOREACH(const std::string
&msg
, getAllNetMessageTypes())
2571 mapRecvBytesPerMsgCmd
[msg
] = 0;
2572 mapRecvBytesPerMsgCmd
[NET_MESSAGE_COMMAND_OTHER
] = 0;
2575 LogPrint("net", "Added connection to %s peer=%d\n", addrName
, id
);
2577 LogPrint("net", "Added connection peer=%d\n", id
);
2579 // Be shy and don't send version until we hear
2580 if (hSocket
!= INVALID_SOCKET
&& !fInbound
)
2586 CloseSocket(hSocket
);
2592 void CNode::AskFor(const CInv
& inv
)
2594 if (mapAskFor
.size() > MAPASKFOR_MAX_SZ
|| setAskFor
.size() > SETASKFOR_MAX_SZ
)
2596 // a peer may not have multiple non-responded queue positions for a single inv item
2597 if (!setAskFor
.insert(inv
.hash
).second
)
2600 // We're using mapAskFor as a priority queue,
2601 // the key is the earliest time the request can be sent
2602 int64_t nRequestTime
;
2603 limitedmap
<uint256
, int64_t>::const_iterator it
= mapAlreadyAskedFor
.find(inv
.hash
);
2604 if (it
!= mapAlreadyAskedFor
.end())
2605 nRequestTime
= it
->second
;
2608 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv
.ToString(), nRequestTime
, DateTimeStrFormat("%H:%M:%S", nRequestTime
/1000000), id
);
2610 // Make sure not to reuse time indexes to keep things in the same order
2611 int64_t nNow
= GetTimeMicros() - 1000000;
2612 static int64_t nLastTime
;
2614 nNow
= std::max(nNow
, nLastTime
);
2617 // Each retry is 2 minutes after the last
2618 nRequestTime
= std::max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
2619 if (it
!= mapAlreadyAskedFor
.end())
2620 mapAlreadyAskedFor
.update(it
, nRequestTime
);
2622 mapAlreadyAskedFor
.insert(std::make_pair(inv
.hash
, nRequestTime
));
2623 mapAskFor
.insert(std::make_pair(nRequestTime
, inv
));
2626 void CNode::BeginMessage(const char* pszCommand
) EXCLUSIVE_LOCK_FUNCTION(cs_vSend
)
2628 ENTER_CRITICAL_SECTION(cs_vSend
);
2629 assert(ssSend
.size() == 0);
2630 ssSend
<< CMessageHeader(Params().MessageStart(), pszCommand
, 0);
2631 LogPrint("net", "sending: %s ", SanitizeString(pszCommand
));
2634 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend
)
2638 LEAVE_CRITICAL_SECTION(cs_vSend
);
2640 LogPrint("net", "(aborted)\n");
2643 void CNode::EndMessage(const char* pszCommand
) UNLOCK_FUNCTION(cs_vSend
)
2645 // The -*messagestest options are intentionally not documented in the help message,
2646 // since they are only used during development to debug the networking code and are
2647 // not intended for end-users.
2648 if (mapArgs
.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2650 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2654 if (mapArgs
.count("-fuzzmessagestest"))
2655 Fuzz(GetArg("-fuzzmessagestest", 10));
2657 if (ssSend
.size() == 0)
2659 LEAVE_CRITICAL_SECTION(cs_vSend
);
2663 unsigned int nSize
= ssSend
.size() - CMessageHeader::HEADER_SIZE
;
2664 WriteLE32((uint8_t*)&ssSend
[CMessageHeader::MESSAGE_SIZE_OFFSET
], nSize
);
2666 //log total amount of bytes per command
2667 mapSendBytesPerMsgCmd
[std::string(pszCommand
)] += nSize
+ CMessageHeader::HEADER_SIZE
;
2670 uint256 hash
= Hash(ssSend
.begin() + CMessageHeader::HEADER_SIZE
, ssSend
.end());
2671 unsigned int nChecksum
= 0;
2672 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
2673 assert(ssSend
.size () >= CMessageHeader::CHECKSUM_OFFSET
+ sizeof(nChecksum
));
2674 memcpy((char*)&ssSend
[CMessageHeader::CHECKSUM_OFFSET
], &nChecksum
, sizeof(nChecksum
));
2676 LogPrint("net", "(%d bytes) peer=%d\n", nSize
, id
);
2678 std::deque
<CSerializeData
>::iterator it
= vSendMsg
.insert(vSendMsg
.end(), CSerializeData());
2679 ssSend
.GetAndClear(*it
);
2680 nSendSize
+= (*it
).size();
2682 // If write queue empty, attempt "optimistic write"
2683 if (it
== vSendMsg
.begin())
2684 nOptimisticBytesWritten
+= SocketSendData(this);
2686 LEAVE_CRITICAL_SECTION(cs_vSend
);
2689 bool CConnman::ForNode(NodeId id
, std::function
<bool(CNode
* pnode
)> func
)
2691 CNode
* found
= nullptr;
2693 for (auto&& pnode
: vNodes
) {
2694 if(pnode
->id
== id
) {
2699 return found
!= nullptr && func(found
);
2702 bool CConnman::ForEachNode(std::function
<bool(CNode
* pnode
)> func
)
2705 for (auto&& node
: vNodes
)
2711 bool CConnman::ForEachNode(std::function
<bool(const CNode
* pnode
)> func
) const
2714 for (const auto& node
: vNodes
)
2720 bool CConnman::ForEachNodeThen(std::function
<bool(CNode
* pnode
)> pre
, std::function
<void()> post
)
2724 for (auto&& node
: vNodes
)
2733 bool CConnman::ForEachNodeThen(std::function
<bool(const CNode
* pnode
)> pre
, std::function
<void()> post
) const
2737 for (const auto& node
: vNodes
)
2746 int64_t PoissonNextSend(int64_t nNow
, int average_interval_seconds
) {
2747 return nNow
+ (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds
* -1000000.0 + 0.5);
2750 /* static */ uint64_t CNode::CalculateKeyedNetGroup(const CAddress
& ad
)
2752 static const uint64_t k0
= GetRand(std::numeric_limits
<uint64_t>::max());
2753 static const uint64_t k1
= GetRand(std::numeric_limits
<uint64_t>::max());
2755 std::vector
<unsigned char> vchNetGroup(ad
.GetGroup());
2757 return CSipHasher(k0
, k1
).Write(&vchNetGroup
[0], vchNetGroup
.size()).Finalize();