1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 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"
18 #include "primitives/transaction.h"
19 #include "scheduler.h"
20 #include "ui_interface.h"
21 #include "utilstrencodings.h"
30 #include <miniupnpc/miniupnpc.h>
31 #include <miniupnpc/miniwget.h>
32 #include <miniupnpc/upnpcommands.h>
33 #include <miniupnpc/upnperrors.h>
36 #include <boost/filesystem.hpp>
37 #include <boost/thread.hpp>
39 // Dump addresses to peers.dat every 15 minutes (900s)
40 #define DUMP_ADDRESSES_INTERVAL 900
42 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
43 #define MSG_NOSIGNAL 0
46 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
47 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
49 #ifndef PROTECTION_LEVEL_UNRESTRICTED
50 #define PROTECTION_LEVEL_UNRESTRICTED 10
52 #ifndef IPV6_PROTECTION_LEVEL
53 #define IPV6_PROTECTION_LEVEL 23
60 const int MAX_OUTBOUND_CONNECTIONS
= 8;
66 ListenSocket(SOCKET socket
, bool whitelisted
) : socket(socket
), whitelisted(whitelisted
) {}
71 // Global state variables
73 bool fDiscover
= true;
75 uint64_t nLocalServices
= NODE_NETWORK
;
76 CCriticalSection cs_mapLocalHost
;
77 map
<CNetAddr
, LocalServiceInfo
> mapLocalHost
;
78 static bool vfReachable
[NET_MAX
] = {};
79 static bool vfLimited
[NET_MAX
] = {};
80 static CNode
* pnodeLocalHost
= NULL
;
81 uint64_t nLocalHostNonce
= 0;
82 static std::vector
<ListenSocket
> vhListenSocket
;
84 int nMaxConnections
= DEFAULT_MAX_PEER_CONNECTIONS
;
85 bool fAddressesInitialized
= false;
86 std::string strSubVersion
;
88 vector
<CNode
*> vNodes
;
89 CCriticalSection cs_vNodes
;
90 map
<CInv
, CDataStream
> mapRelay
;
91 deque
<pair
<int64_t, CInv
> > vRelayExpiration
;
92 CCriticalSection cs_mapRelay
;
93 limitedmap
<CInv
, int64_t> mapAlreadyAskedFor(MAX_INV_SZ
);
95 static deque
<string
> vOneShots
;
96 CCriticalSection cs_vOneShots
;
98 set
<CNetAddr
> setservAddNodeAddresses
;
99 CCriticalSection cs_setservAddNodeAddresses
;
101 vector
<std::string
> vAddedNodes
;
102 CCriticalSection cs_vAddedNodes
;
104 NodeId nLastNodeId
= 0;
105 CCriticalSection cs_nLastNodeId
;
107 static CSemaphore
*semOutbound
= NULL
;
108 boost::condition_variable messageHandlerCondition
;
110 // Signals for message handling
111 static CNodeSignals g_signals
;
112 CNodeSignals
& GetNodeSignals() { return g_signals
; }
114 void AddOneShot(const std::string
& strDest
)
117 vOneShots
.push_back(strDest
);
120 unsigned short GetListenPort()
122 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
125 // find 'best' local address for a particular peer
126 bool GetLocal(CService
& addr
, const CNetAddr
*paddrPeer
)
132 int nBestReachability
= -1;
134 LOCK(cs_mapLocalHost
);
135 for (map
<CNetAddr
, LocalServiceInfo
>::iterator it
= mapLocalHost
.begin(); it
!= mapLocalHost
.end(); it
++)
137 int nScore
= (*it
).second
.nScore
;
138 int nReachability
= (*it
).first
.GetReachabilityFrom(paddrPeer
);
139 if (nReachability
> nBestReachability
|| (nReachability
== nBestReachability
&& nScore
> nBestScore
))
141 addr
= CService((*it
).first
, (*it
).second
.nPort
);
142 nBestReachability
= nReachability
;
147 return nBestScore
>= 0;
150 //! Convert the pnSeeds6 array into usable address objects.
151 static std::vector
<CAddress
> convertSeed6(const std::vector
<SeedSpec6
> &vSeedsIn
)
153 // It'll only connect to one or two seed nodes because once it connects,
154 // it'll get a pile of addresses with newer timestamps.
155 // Seed nodes are given a random 'last seen time' of between one and two
157 const int64_t nOneWeek
= 7*24*60*60;
158 std::vector
<CAddress
> vSeedsOut
;
159 vSeedsOut
.reserve(vSeedsIn
.size());
160 for (std::vector
<SeedSpec6
>::const_iterator
i(vSeedsIn
.begin()); i
!= vSeedsIn
.end(); ++i
)
163 memcpy(&ip
, i
->addr
, sizeof(ip
));
164 CAddress
addr(CService(ip
, i
->port
));
165 addr
.nTime
= GetTime() - GetRand(nOneWeek
) - nOneWeek
;
166 vSeedsOut
.push_back(addr
);
171 // get best local address for a particular peer as a CAddress
172 // Otherwise, return the unroutable 0.0.0.0 but filled in with
173 // the normal parameters, since the IP may be changed to a useful
175 CAddress
GetLocalAddress(const CNetAddr
*paddrPeer
)
177 CAddress
ret(CService("0.0.0.0",GetListenPort()),0);
179 if (GetLocal(addr
, paddrPeer
))
181 ret
= CAddress(addr
);
183 ret
.nServices
= nLocalServices
;
184 ret
.nTime
= GetAdjustedTime();
188 int GetnScore(const CService
& addr
)
190 LOCK(cs_mapLocalHost
);
191 if (mapLocalHost
.count(addr
) == LOCAL_NONE
)
193 return mapLocalHost
[addr
].nScore
;
196 // Is our peer's addrLocal potentially useful as an external IP source?
197 bool IsPeerAddrLocalGood(CNode
*pnode
)
199 return fDiscover
&& pnode
->addr
.IsRoutable() && pnode
->addrLocal
.IsRoutable() &&
200 !IsLimited(pnode
->addrLocal
.GetNetwork());
203 // pushes our own address to a peer
204 void AdvertizeLocal(CNode
*pnode
)
206 if (fListen
&& pnode
->fSuccessfullyConnected
)
208 CAddress addrLocal
= GetLocalAddress(&pnode
->addr
);
209 // If discovery is enabled, sometimes give our peer the address it
210 // tells us that it sees us as in case it has a better idea of our
211 // address than we do.
212 if (IsPeerAddrLocalGood(pnode
) && (!addrLocal
.IsRoutable() ||
213 GetRand((GetnScore(addrLocal
) > LOCAL_MANUAL
) ? 8:2) == 0))
215 addrLocal
.SetIP(pnode
->addrLocal
);
217 if (addrLocal
.IsRoutable())
219 LogPrintf("AdvertizeLocal: advertizing address %s\n", addrLocal
.ToString());
220 pnode
->PushAddress(addrLocal
);
225 void SetReachable(enum Network net
, bool fFlag
)
227 LOCK(cs_mapLocalHost
);
228 vfReachable
[net
] = fFlag
;
229 if (net
== NET_IPV6
&& fFlag
)
230 vfReachable
[NET_IPV4
] = true;
233 // learn a new local address
234 bool AddLocal(const CService
& addr
, int nScore
)
236 if (!addr
.IsRoutable())
239 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
245 LogPrintf("AddLocal(%s,%i)\n", addr
.ToString(), nScore
);
248 LOCK(cs_mapLocalHost
);
249 bool fAlready
= mapLocalHost
.count(addr
) > 0;
250 LocalServiceInfo
&info
= mapLocalHost
[addr
];
251 if (!fAlready
|| nScore
>= info
.nScore
) {
252 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
253 info
.nPort
= addr
.GetPort();
255 SetReachable(addr
.GetNetwork());
261 bool AddLocal(const CNetAddr
&addr
, int nScore
)
263 return AddLocal(CService(addr
, GetListenPort()), nScore
);
266 bool RemoveLocal(const CService
& addr
)
268 LOCK(cs_mapLocalHost
);
269 LogPrintf("RemoveLocal(%s)\n", addr
.ToString());
270 mapLocalHost
.erase(addr
);
274 /** Make a particular network entirely off-limits (no automatic connects to it) */
275 void SetLimited(enum Network net
, bool fLimited
)
277 if (net
== NET_UNROUTABLE
)
279 LOCK(cs_mapLocalHost
);
280 vfLimited
[net
] = fLimited
;
283 bool IsLimited(enum Network net
)
285 LOCK(cs_mapLocalHost
);
286 return vfLimited
[net
];
289 bool IsLimited(const CNetAddr
&addr
)
291 return IsLimited(addr
.GetNetwork());
294 /** vote for a local address */
295 bool SeenLocal(const CService
& addr
)
298 LOCK(cs_mapLocalHost
);
299 if (mapLocalHost
.count(addr
) == 0)
301 mapLocalHost
[addr
].nScore
++;
307 /** check whether a given address is potentially local */
308 bool IsLocal(const CService
& addr
)
310 LOCK(cs_mapLocalHost
);
311 return mapLocalHost
.count(addr
) > 0;
314 /** check whether a given network is one we can probably connect to */
315 bool IsReachable(enum Network net
)
317 LOCK(cs_mapLocalHost
);
318 return vfReachable
[net
] && !vfLimited
[net
];
321 /** check whether a given address is in a network we can probably connect to */
322 bool IsReachable(const CNetAddr
& addr
)
324 enum Network net
= addr
.GetNetwork();
325 return IsReachable(net
);
328 void AddressCurrentlyConnected(const CService
& addr
)
330 addrman
.Connected(addr
);
334 uint64_t CNode::nTotalBytesRecv
= 0;
335 uint64_t CNode::nTotalBytesSent
= 0;
336 CCriticalSection
CNode::cs_totalBytesRecv
;
337 CCriticalSection
CNode::cs_totalBytesSent
;
339 uint64_t CNode::nMaxOutboundLimit
= 0;
340 uint64_t CNode::nMaxOutboundTotalBytesSentInCycle
= 0;
341 uint64_t CNode::nMaxOutboundTimeframe
= 60*60*24; //1 day
342 uint64_t CNode::nMaxOutboundCycleStartTime
= 0;
344 CNode
* FindNode(const CNetAddr
& ip
)
347 BOOST_FOREACH(CNode
* pnode
, vNodes
)
348 if ((CNetAddr
)pnode
->addr
== ip
)
353 CNode
* FindNode(const CSubNet
& subNet
)
356 BOOST_FOREACH(CNode
* pnode
, vNodes
)
357 if (subNet
.Match((CNetAddr
)pnode
->addr
))
362 CNode
* FindNode(const std::string
& addrName
)
365 BOOST_FOREACH(CNode
* pnode
, vNodes
)
366 if (pnode
->addrName
== addrName
)
371 CNode
* FindNode(const CService
& addr
)
374 BOOST_FOREACH(CNode
* pnode
, vNodes
)
375 if ((CService
)pnode
->addr
== addr
)
380 CNode
* ConnectNode(CAddress addrConnect
, const char *pszDest
)
382 if (pszDest
== NULL
) {
383 if (IsLocal(addrConnect
))
386 // Look for an existing connection
387 CNode
* pnode
= FindNode((CService
)addrConnect
);
396 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
397 pszDest
? pszDest
: addrConnect
.ToString(),
398 pszDest
? 0.0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
402 bool proxyConnectionFailed
= false;
403 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, Params().GetDefaultPort(), nConnectTimeout
, &proxyConnectionFailed
) :
404 ConnectSocket(addrConnect
, hSocket
, nConnectTimeout
, &proxyConnectionFailed
))
406 if (!IsSelectableSocket(hSocket
)) {
407 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
408 CloseSocket(hSocket
);
412 addrman
.Attempt(addrConnect
);
415 CNode
* pnode
= new CNode(hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
420 vNodes
.push_back(pnode
);
423 pnode
->nTimeConnected
= GetTime();
426 } else if (!proxyConnectionFailed
) {
427 // If connecting to the node failed, and failure is not caused by a problem connecting to
428 // the proxy, mark this as an attempt.
429 addrman
.Attempt(addrConnect
);
435 void CNode::CloseSocketDisconnect()
438 if (hSocket
!= INVALID_SOCKET
)
440 LogPrint("net", "disconnecting peer=%d\n", id
);
441 CloseSocket(hSocket
);
444 // in case this fails, we'll empty the recv buffer when the CNode is deleted
445 TRY_LOCK(cs_vRecvMsg
, lockRecv
);
450 void CNode::PushVersion()
452 int nBestHeight
= g_signals
.GetHeight().get_value_or(0);
454 int64_t nTime
= (fInbound
? GetAdjustedTime() : GetTime());
455 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService("0.0.0.0",0)));
456 CAddress addrMe
= GetLocalAddress(&addr
);
457 GetRandBytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
459 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), addrYou
.ToString(), id
);
461 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), id
);
462 PushMessage("version", PROTOCOL_VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
463 nLocalHostNonce
, strSubVersion
, nBestHeight
, !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY
));
470 banmap_t
CNode::setBanned
;
471 CCriticalSection
CNode::cs_setBanned
;
472 bool CNode::setBannedIsDirty
;
474 void CNode::ClearBanned()
478 setBannedIsDirty
= true;
481 bool CNode::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 CNode::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 CNode::Ban(const CNetAddr
& addr
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
515 CSubNet
subNet(addr
);
516 Ban(subNet
, banReason
, bantimeoffset
, sinceUnixEpoch
);
519 void CNode::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", 60*60*24); // Default 24-hour ban
525 sinceUnixEpoch
= false;
527 banEntry
.nBanUntil
= (sinceUnixEpoch
? 0 : GetTime() )+bantimeoffset
;
531 if (setBanned
[subNet
].nBanUntil
< banEntry
.nBanUntil
)
532 setBanned
[subNet
] = banEntry
;
534 setBannedIsDirty
= true;
537 bool CNode::Unban(const CNetAddr
&addr
) {
538 CSubNet
subNet(addr
);
539 return Unban(subNet
);
542 bool CNode::Unban(const CSubNet
&subNet
) {
544 if (setBanned
.erase(subNet
))
546 setBannedIsDirty
= true;
552 void CNode::GetBanned(banmap_t
&banMap
)
555 banMap
= setBanned
; //create a thread safe copy
558 void CNode::SetBanned(const banmap_t
&banMap
)
562 setBannedIsDirty
= true;
565 void CNode::SweepBanned()
567 int64_t now
= GetTime();
570 banmap_t::iterator it
= setBanned
.begin();
571 while(it
!= setBanned
.end())
573 CBanEntry banEntry
= (*it
).second
;
574 if(now
> banEntry
.nBanUntil
)
576 setBanned
.erase(it
++);
577 setBannedIsDirty
= true;
584 bool CNode::BannedSetIsDirty()
587 return setBannedIsDirty
;
590 void CNode::SetBannedSetDirty(bool dirty
)
592 LOCK(cs_setBanned
); //reuse setBanned lock for the isDirty flag
593 setBannedIsDirty
= dirty
;
597 std::vector
<CSubNet
> CNode::vWhitelistedRange
;
598 CCriticalSection
CNode::cs_vWhitelistedRange
;
600 bool CNode::IsWhitelistedRange(const CNetAddr
&addr
) {
601 LOCK(cs_vWhitelistedRange
);
602 BOOST_FOREACH(const CSubNet
& subnet
, vWhitelistedRange
) {
603 if (subnet
.Match(addr
))
609 void CNode::AddWhitelistedRange(const CSubNet
&subnet
) {
610 LOCK(cs_vWhitelistedRange
);
611 vWhitelistedRange
.push_back(subnet
);
615 #define X(name) stats.name = name
616 void CNode::copyStats(CNodeStats
&stats
)
618 stats
.nodeid
= this->GetId();
633 // It is common for nodes with good ping times to suddenly become lagged,
634 // due to a new block arriving or other large transfer.
635 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
636 // since pingtime does not update until the ping is complete, which might take a while.
637 // So, if a ping is taking an unusually long time in flight,
638 // the caller can immediately detect that this is happening.
639 int64_t nPingUsecWait
= 0;
640 if ((0 != nPingNonceSent
) && (0 != nPingUsecStart
)) {
641 nPingUsecWait
= GetTimeMicros() - nPingUsecStart
;
644 // 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 :)
645 stats
.dPingTime
= (((double)nPingUsecTime
) / 1e6
);
646 stats
.dPingMin
= (((double)nMinPingUsecTime
) / 1e6
);
647 stats
.dPingWait
= (((double)nPingUsecWait
) / 1e6
);
649 // Leave string empty if addrLocal invalid (not filled in yet)
650 stats
.addrLocal
= addrLocal
.IsValid() ? addrLocal
.ToString() : "";
654 // requires LOCK(cs_vRecvMsg)
655 bool CNode::ReceiveMsgBytes(const char *pch
, unsigned int nBytes
)
659 // get current incomplete message, or create a new one
660 if (vRecvMsg
.empty() ||
661 vRecvMsg
.back().complete())
662 vRecvMsg
.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK
, nRecvVersion
));
664 CNetMessage
& msg
= vRecvMsg
.back();
666 // absorb network data
669 handled
= msg
.readHeader(pch
, nBytes
);
671 handled
= msg
.readData(pch
, nBytes
);
676 if (msg
.in_data
&& msg
.hdr
.nMessageSize
> MAX_PROTOCOL_MESSAGE_LENGTH
) {
677 LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
684 if (msg
.complete()) {
685 msg
.nTime
= GetTimeMicros();
686 messageHandlerCondition
.notify_one();
693 int CNetMessage::readHeader(const char *pch
, unsigned int nBytes
)
695 // copy data to temporary parsing buffer
696 unsigned int nRemaining
= 24 - nHdrPos
;
697 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
699 memcpy(&hdrbuf
[nHdrPos
], pch
, nCopy
);
702 // if header incomplete, exit
706 // deserialize to CMessageHeader
710 catch (const std::exception
&) {
714 // reject messages larger than MAX_SIZE
715 if (hdr
.nMessageSize
> MAX_SIZE
)
718 // switch state to reading message data
724 int CNetMessage::readData(const char *pch
, unsigned int nBytes
)
726 unsigned int nRemaining
= hdr
.nMessageSize
- nDataPos
;
727 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
729 if (vRecv
.size() < nDataPos
+ nCopy
) {
730 // Allocate up to 256 KiB ahead, but never more than the total message size.
731 vRecv
.resize(std::min(hdr
.nMessageSize
, nDataPos
+ nCopy
+ 256 * 1024));
734 memcpy(&vRecv
[nDataPos
], pch
, nCopy
);
748 // requires LOCK(cs_vSend)
749 void SocketSendData(CNode
*pnode
)
751 std::deque
<CSerializeData
>::iterator it
= pnode
->vSendMsg
.begin();
753 while (it
!= pnode
->vSendMsg
.end()) {
754 const CSerializeData
&data
= *it
;
755 assert(data
.size() > pnode
->nSendOffset
);
756 int nBytes
= send(pnode
->hSocket
, &data
[pnode
->nSendOffset
], data
.size() - pnode
->nSendOffset
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
758 pnode
->nLastSend
= GetTime();
759 pnode
->nSendBytes
+= nBytes
;
760 pnode
->nSendOffset
+= nBytes
;
761 pnode
->RecordBytesSent(nBytes
);
762 if (pnode
->nSendOffset
== data
.size()) {
763 pnode
->nSendOffset
= 0;
764 pnode
->nSendSize
-= data
.size();
767 // could not send full message; stop sending more
773 int nErr
= WSAGetLastError();
774 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
776 LogPrintf("socket send error %s\n", NetworkErrorString(nErr
));
777 pnode
->CloseSocketDisconnect();
780 // couldn't send anything at all
785 if (it
== pnode
->vSendMsg
.end()) {
786 assert(pnode
->nSendOffset
== 0);
787 assert(pnode
->nSendSize
== 0);
789 pnode
->vSendMsg
.erase(pnode
->vSendMsg
.begin(), it
);
792 static list
<CNode
*> vNodesDisconnected
;
796 CNodeRef(CNode
*pnode
) : _pnode(pnode
) {
806 CNode
& operator *() const {return *_pnode
;};
807 CNode
* operator ->() const {return _pnode
;};
809 CNodeRef
& operator =(const CNodeRef
& other
)
811 if (this != &other
) {
815 _pnode
= other
._pnode
;
821 CNodeRef(const CNodeRef
& other
):
831 static bool ReverseCompareNodeMinPingTime(const CNodeRef
&a
, const CNodeRef
&b
)
833 return a
->nMinPingUsecTime
> b
->nMinPingUsecTime
;
836 static bool ReverseCompareNodeTimeConnected(const CNodeRef
&a
, const CNodeRef
&b
)
838 return a
->nTimeConnected
> b
->nTimeConnected
;
841 class CompareNetGroupKeyed
843 std::vector
<unsigned char> vchSecretKey
;
845 CompareNetGroupKeyed()
847 vchSecretKey
.resize(32, 0);
848 GetRandBytes(vchSecretKey
.data(), vchSecretKey
.size());
851 bool operator()(const CNodeRef
&a
, const CNodeRef
&b
)
853 std::vector
<unsigned char> vchGroupA
, vchGroupB
;
854 CSHA256 hashA
, hashB
;
855 std::vector
<unsigned char> vchA(32), vchB(32);
857 vchGroupA
= a
->addr
.GetGroup();
858 vchGroupB
= b
->addr
.GetGroup();
860 hashA
.Write(begin_ptr(vchGroupA
), vchGroupA
.size());
861 hashB
.Write(begin_ptr(vchGroupB
), vchGroupB
.size());
863 hashA
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
864 hashB
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
866 hashA
.Finalize(begin_ptr(vchA
));
867 hashB
.Finalize(begin_ptr(vchB
));
873 static bool AttemptToEvictConnection(bool fPreferNewConnection
) {
874 std::vector
<CNodeRef
> vEvictionCandidates
;
878 BOOST_FOREACH(CNode
*node
, vNodes
) {
879 if (node
->fWhitelisted
)
883 if (node
->fDisconnect
)
885 if (node
->addr
.IsLocal())
887 vEvictionCandidates
.push_back(CNodeRef(node
));
891 if (vEvictionCandidates
.empty()) return false;
893 // Protect connections with certain characteristics
895 // Deterministically select 4 peers to protect by netgroup.
896 // An attacker cannot predict which netgroups will be protected.
897 static CompareNetGroupKeyed comparerNetGroupKeyed
;
898 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), comparerNetGroupKeyed
);
899 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
901 if (vEvictionCandidates
.empty()) return false;
903 // Protect the 8 nodes with the best ping times.
904 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
905 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeMinPingTime
);
906 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(8, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
908 if (vEvictionCandidates
.empty()) return false;
910 // Protect the half of the remaining nodes which have been connected the longest.
911 // This replicates the existing implicit behavior.
912 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
913 vEvictionCandidates
.erase(vEvictionCandidates
.end() - static_cast<int>(vEvictionCandidates
.size() / 2), vEvictionCandidates
.end());
915 if (vEvictionCandidates
.empty()) return false;
917 // Identify the network group with the most connections
918 std::vector
<unsigned char> naMostConnections
;
919 unsigned int nMostConnections
= 0;
920 std::map
<std::vector
<unsigned char>, std::vector
<CNodeRef
> > mapAddrCounts
;
921 BOOST_FOREACH(const CNodeRef
&node
, vEvictionCandidates
) {
922 mapAddrCounts
[node
->addr
.GetGroup()].push_back(node
);
924 if (mapAddrCounts
[node
->addr
.GetGroup()].size() > nMostConnections
) {
925 nMostConnections
= mapAddrCounts
[node
->addr
.GetGroup()].size();
926 naMostConnections
= node
->addr
.GetGroup();
930 // Reduce to the network group with the most connections
931 vEvictionCandidates
= mapAddrCounts
[naMostConnections
];
933 // Do not disconnect peers if there is only 1 connection from their network group
934 if (vEvictionCandidates
.size() <= 1)
935 // unless we prefer the new connection (for whitelisted peers)
936 if (!fPreferNewConnection
)
939 // Disconnect the most recent connection from the network group with the most connections
940 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
941 vEvictionCandidates
[0]->fDisconnect
= true;
946 static void AcceptConnection(const ListenSocket
& hListenSocket
) {
947 struct sockaddr_storage sockaddr
;
948 socklen_t len
= sizeof(sockaddr
);
949 SOCKET hSocket
= accept(hListenSocket
.socket
, (struct sockaddr
*)&sockaddr
, &len
);
952 int nMaxInbound
= nMaxConnections
- MAX_OUTBOUND_CONNECTIONS
;
954 if (hSocket
!= INVALID_SOCKET
)
955 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
956 LogPrintf("Warning: Unknown socket family\n");
958 bool whitelisted
= hListenSocket
.whitelisted
|| CNode::IsWhitelistedRange(addr
);
961 BOOST_FOREACH(CNode
* pnode
, vNodes
)
966 if (hSocket
== INVALID_SOCKET
)
968 int nErr
= WSAGetLastError();
969 if (nErr
!= WSAEWOULDBLOCK
)
970 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr
));
974 if (!IsSelectableSocket(hSocket
))
976 LogPrintf("connection from %s dropped: non-selectable socket\n", addr
.ToString());
977 CloseSocket(hSocket
);
981 // According to the internet TCP_NODELAY is not carried into accepted sockets
982 // on all platforms. Set it again here just to be sure.
985 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&set
, sizeof(int));
987 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&set
, sizeof(int));
990 if (CNode::IsBanned(addr
) && !whitelisted
)
992 LogPrintf("connection from %s dropped (banned)\n", addr
.ToString());
993 CloseSocket(hSocket
);
997 if (nInbound
>= nMaxInbound
)
999 if (!AttemptToEvictConnection(whitelisted
)) {
1000 // No connection to evict, disconnect the new connection
1001 LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
1002 CloseSocket(hSocket
);
1007 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
1009 pnode
->fWhitelisted
= whitelisted
;
1011 LogPrint("net", "connection from %s accepted\n", addr
.ToString());
1015 vNodes
.push_back(pnode
);
1019 void ThreadSocketHandler()
1021 unsigned int nPrevNodeCount
= 0;
1029 // Disconnect unused nodes
1030 vector
<CNode
*> vNodesCopy
= vNodes
;
1031 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1033 if (pnode
->fDisconnect
||
1034 (pnode
->GetRefCount() <= 0 && pnode
->vRecvMsg
.empty() && pnode
->nSendSize
== 0 && pnode
->ssSend
.empty()))
1036 // remove from vNodes
1037 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
1039 // release outbound grant (if any)
1040 pnode
->grantOutbound
.Release();
1042 // close socket and cleanup
1043 pnode
->CloseSocketDisconnect();
1045 // hold in disconnected pool until all refs are released
1046 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
1048 vNodesDisconnected
.push_back(pnode
);
1053 // Delete disconnected nodes
1054 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
1055 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
1057 // wait until threads are done using it
1058 if (pnode
->GetRefCount() <= 0)
1060 bool fDelete
= false;
1062 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1065 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1068 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
1076 vNodesDisconnected
.remove(pnode
);
1082 if(vNodes
.size() != nPrevNodeCount
) {
1083 nPrevNodeCount
= vNodes
.size();
1084 uiInterface
.NotifyNumConnectionsChanged(nPrevNodeCount
);
1088 // Find which sockets have data to receive
1090 struct timeval timeout
;
1092 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
1097 FD_ZERO(&fdsetRecv
);
1098 FD_ZERO(&fdsetSend
);
1099 FD_ZERO(&fdsetError
);
1100 SOCKET hSocketMax
= 0;
1101 bool have_fds
= false;
1103 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
) {
1104 FD_SET(hListenSocket
.socket
, &fdsetRecv
);
1105 hSocketMax
= max(hSocketMax
, hListenSocket
.socket
);
1111 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1113 if (pnode
->hSocket
== INVALID_SOCKET
)
1115 FD_SET(pnode
->hSocket
, &fdsetError
);
1116 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
1119 // Implement the following logic:
1120 // * If there is data to send, select() for sending data. As this only
1121 // happens when optimistic write failed, we choose to first drain the
1122 // write buffer in this case before receiving more. This avoids
1123 // needlessly queueing received data, if the remote peer is not themselves
1124 // receiving data. This means properly utilizing TCP flow control signalling.
1125 // * Otherwise, if there is no (complete) message in the receive buffer,
1126 // or there is space left in the buffer, select() for receiving data.
1127 // * (if neither of the above applies, there is certainly one message
1128 // in the receiver buffer ready to be processed).
1129 // Together, that means that at least one of the following is always possible,
1130 // so we don't deadlock:
1131 // * We send some data.
1132 // * We wait for data to be received (and disconnect after timeout).
1133 // * We process a message in the buffer (message handler thread).
1135 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1136 if (lockSend
&& !pnode
->vSendMsg
.empty()) {
1137 FD_SET(pnode
->hSocket
, &fdsetSend
);
1142 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1144 pnode
->vRecvMsg
.empty() || !pnode
->vRecvMsg
.front().complete() ||
1145 pnode
->GetTotalRecvSize() <= ReceiveFloodSize()))
1146 FD_SET(pnode
->hSocket
, &fdsetRecv
);
1151 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
1152 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
1153 boost::this_thread::interruption_point();
1155 if (nSelect
== SOCKET_ERROR
)
1159 int nErr
= WSAGetLastError();
1160 LogPrintf("socket select error %s\n", NetworkErrorString(nErr
));
1161 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
1162 FD_SET(i
, &fdsetRecv
);
1164 FD_ZERO(&fdsetSend
);
1165 FD_ZERO(&fdsetError
);
1166 MilliSleep(timeout
.tv_usec
/1000);
1170 // Accept new connections
1172 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
)
1174 if (hListenSocket
.socket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
.socket
, &fdsetRecv
))
1176 AcceptConnection(hListenSocket
);
1181 // Service each socket
1183 vector
<CNode
*> vNodesCopy
;
1186 vNodesCopy
= vNodes
;
1187 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1190 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1192 boost::this_thread::interruption_point();
1197 if (pnode
->hSocket
== INVALID_SOCKET
)
1199 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
1201 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1205 // typical socket buffer is 8K-64K
1206 char pchBuf
[0x10000];
1207 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
1210 if (!pnode
->ReceiveMsgBytes(pchBuf
, nBytes
))
1211 pnode
->CloseSocketDisconnect();
1212 pnode
->nLastRecv
= GetTime();
1213 pnode
->nRecvBytes
+= nBytes
;
1214 pnode
->RecordBytesRecv(nBytes
);
1216 else if (nBytes
== 0)
1218 // socket closed gracefully
1219 if (!pnode
->fDisconnect
)
1220 LogPrint("net", "socket closed\n");
1221 pnode
->CloseSocketDisconnect();
1223 else if (nBytes
< 0)
1226 int nErr
= WSAGetLastError();
1227 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
1229 if (!pnode
->fDisconnect
)
1230 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr
));
1231 pnode
->CloseSocketDisconnect();
1241 if (pnode
->hSocket
== INVALID_SOCKET
)
1243 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
1245 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1247 SocketSendData(pnode
);
1251 // Inactivity checking
1253 int64_t nTime
= GetTime();
1254 if (nTime
- pnode
->nTimeConnected
> 60)
1256 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
1258 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0, pnode
->id
);
1259 pnode
->fDisconnect
= true;
1261 else if (nTime
- pnode
->nLastSend
> TIMEOUT_INTERVAL
)
1263 LogPrintf("socket sending timeout: %is\n", nTime
- pnode
->nLastSend
);
1264 pnode
->fDisconnect
= true;
1266 else if (nTime
- pnode
->nLastRecv
> (pnode
->nVersion
> BIP0031_VERSION
? TIMEOUT_INTERVAL
: 90*60))
1268 LogPrintf("socket receive timeout: %is\n", nTime
- pnode
->nLastRecv
);
1269 pnode
->fDisconnect
= true;
1271 else if (pnode
->nPingNonceSent
&& pnode
->nPingUsecStart
+ TIMEOUT_INTERVAL
* 1000000 < GetTimeMicros())
1273 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode
->nPingUsecStart
));
1274 pnode
->fDisconnect
= true;
1280 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1295 void ThreadMapPort()
1297 std::string port
= strprintf("%u", GetListenPort());
1298 const char * multicastif
= 0;
1299 const char * minissdpdpath
= 0;
1300 struct UPNPDev
* devlist
= 0;
1303 #ifndef UPNPDISCOVER_SUCCESS
1305 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1306 #elif MINIUPNPC_API_VERSION < 14
1309 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1311 /* miniupnpc 1.9.20150730 */
1313 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, 2, &error
);
1316 struct UPNPUrls urls
;
1317 struct IGDdatas data
;
1320 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1324 char externalIPAddress
[40];
1325 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1326 if(r
!= UPNPCOMMAND_SUCCESS
)
1327 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1330 if(externalIPAddress
[0])
1332 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1333 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1336 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1340 string strDesc
= "Bitcoin " + FormatFullVersion();
1344 #ifndef UPNPDISCOVER_SUCCESS
1346 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1347 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1350 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1351 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1354 if(r
!=UPNPCOMMAND_SUCCESS
)
1355 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1356 port
, port
, lanaddr
, r
, strupnperror(r
));
1358 LogPrintf("UPnP Port Mapping successful.\n");;
1360 MilliSleep(20*60*1000); // Refresh every 20 minutes
1363 catch (const boost::thread_interrupted
&)
1365 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1366 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r
);
1367 freeUPNPDevlist(devlist
); devlist
= 0;
1368 FreeUPNPUrls(&urls
);
1372 LogPrintf("No valid UPnP IGDs found\n");
1373 freeUPNPDevlist(devlist
); devlist
= 0;
1375 FreeUPNPUrls(&urls
);
1379 void MapPort(bool fUseUPnP
)
1381 static boost::thread
* upnp_thread
= NULL
;
1386 upnp_thread
->interrupt();
1387 upnp_thread
->join();
1390 upnp_thread
= new boost::thread(boost::bind(&TraceThread
<void (*)()>, "upnp", &ThreadMapPort
));
1392 else if (upnp_thread
) {
1393 upnp_thread
->interrupt();
1394 upnp_thread
->join();
1403 // Intentionally left blank.
1412 void ThreadDNSAddressSeed()
1414 // goal: only query DNS seeds if address need is acute
1415 if ((addrman
.size() > 0) &&
1416 (!GetBoolArg("-forcednsseed", false))) {
1417 MilliSleep(11 * 1000);
1420 if (vNodes
.size() >= 2) {
1421 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1426 const vector
<CDNSSeedData
> &vSeeds
= Params().DNSSeeds();
1429 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1431 BOOST_FOREACH(const CDNSSeedData
&seed
, vSeeds
) {
1432 if (HaveNameProxy()) {
1433 AddOneShot(seed
.host
);
1435 vector
<CNetAddr
> vIPs
;
1436 vector
<CAddress
> vAdd
;
1437 if (LookupHost(seed
.host
.c_str(), vIPs
))
1439 BOOST_FOREACH(const CNetAddr
& ip
, vIPs
)
1441 int nOneDay
= 24*3600;
1442 CAddress addr
= CAddress(CService(ip
, Params().GetDefaultPort()));
1443 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1444 vAdd
.push_back(addr
);
1448 addrman
.Add(vAdd
, CNetAddr(seed
.name
, true));
1452 LogPrintf("%d addresses found from DNS seeds\n", found
);
1466 void DumpAddresses()
1468 int64_t nStart
= GetTimeMillis();
1473 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1474 addrman
.size(), GetTimeMillis() - nStart
);
1481 if (CNode::BannedSetIsDirty())
1484 CNode::SetBannedSetDirty(false);
1488 void static ProcessOneShot()
1493 if (vOneShots
.empty())
1495 strDest
= vOneShots
.front();
1496 vOneShots
.pop_front();
1499 CSemaphoreGrant
grant(*semOutbound
, true);
1501 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1502 AddOneShot(strDest
);
1506 void ThreadOpenConnections()
1508 // Connect to specific addresses
1509 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1511 for (int64_t nLoop
= 0;; nLoop
++)
1514 BOOST_FOREACH(const std::string
& strAddr
, mapMultiArgs
["-connect"])
1517 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1518 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1527 // Initiate network connections
1528 int64_t nStart
= GetTime();
1535 CSemaphoreGrant
grant(*semOutbound
);
1536 boost::this_thread::interruption_point();
1538 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1539 if (addrman
.size() == 0 && (GetTime() - nStart
> 60)) {
1540 static bool done
= false;
1542 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1543 addrman
.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1549 // Choose an address to connect to based on most recently seen
1551 CAddress addrConnect
;
1553 // Only connect out to one peer per network group (/16 for IPv4).
1554 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1556 set
<vector
<unsigned char> > setConnected
;
1559 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1560 if (!pnode
->fInbound
) {
1561 setConnected
.insert(pnode
->addr
.GetGroup());
1567 int64_t nANow
= GetAdjustedTime();
1572 CAddrInfo addr
= addrman
.Select();
1574 // if we selected an invalid address, restart
1575 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1578 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1579 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1580 // already-connected network ranges, ...) before trying new addrman addresses.
1585 if (IsLimited(addr
))
1588 // only consider very recently tried nodes after 30 failed attempts
1589 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1592 // do not allow non-default ports, unless after 50 invalid addresses selected already
1593 if (addr
.GetPort() != Params().GetDefaultPort() && nTries
< 50)
1600 if (addrConnect
.IsValid())
1601 OpenNetworkConnection(addrConnect
, &grant
);
1605 void ThreadOpenAddedConnections()
1608 LOCK(cs_vAddedNodes
);
1609 vAddedNodes
= mapMultiArgs
["-addnode"];
1612 if (HaveNameProxy()) {
1614 list
<string
> lAddresses(0);
1616 LOCK(cs_vAddedNodes
);
1617 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1618 lAddresses
.push_back(strAddNode
);
1620 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1622 CSemaphoreGrant
grant(*semOutbound
);
1623 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1626 MilliSleep(120000); // Retry every 2 minutes
1630 for (unsigned int i
= 0; true; i
++)
1632 list
<string
> lAddresses(0);
1634 LOCK(cs_vAddedNodes
);
1635 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1636 lAddresses
.push_back(strAddNode
);
1639 list
<vector
<CService
> > lservAddressesToAdd(0);
1640 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1641 vector
<CService
> vservNode(0);
1642 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
1644 lservAddressesToAdd
.push_back(vservNode
);
1646 LOCK(cs_setservAddNodeAddresses
);
1647 BOOST_FOREACH(const CService
& serv
, vservNode
)
1648 setservAddNodeAddresses
.insert(serv
);
1652 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1653 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1656 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1657 for (list
<vector
<CService
> >::iterator it
= lservAddressesToAdd
.begin(); it
!= lservAddressesToAdd
.end(); it
++)
1658 BOOST_FOREACH(const CService
& addrNode
, *(it
))
1659 if (pnode
->addr
== addrNode
)
1661 it
= lservAddressesToAdd
.erase(it
);
1666 BOOST_FOREACH(vector
<CService
>& vserv
, lservAddressesToAdd
)
1668 CSemaphoreGrant
grant(*semOutbound
);
1669 OpenNetworkConnection(CAddress(vserv
[i
% vserv
.size()]), &grant
);
1672 MilliSleep(120000); // Retry every 2 minutes
1676 // if successful, this moves the passed grant to the constructed node
1677 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *pszDest
, bool fOneShot
)
1680 // Initiate outbound network connection
1682 boost::this_thread::interruption_point();
1684 if (IsLocal(addrConnect
) ||
1685 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1686 FindNode(addrConnect
.ToStringIPPort()))
1688 } else if (FindNode(std::string(pszDest
)))
1691 CNode
* pnode
= ConnectNode(addrConnect
, pszDest
);
1692 boost::this_thread::interruption_point();
1697 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1698 pnode
->fNetworkNode
= true;
1700 pnode
->fOneShot
= true;
1706 void ThreadMessageHandler()
1708 boost::mutex condition_mutex
;
1709 boost::unique_lock
<boost::mutex
> lock(condition_mutex
);
1711 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1714 vector
<CNode
*> vNodesCopy
;
1717 vNodesCopy
= vNodes
;
1718 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
) {
1723 // Poll the connected nodes for messages
1724 CNode
* pnodeTrickle
= NULL
;
1725 if (!vNodesCopy
.empty())
1726 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1730 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1732 if (pnode
->fDisconnect
)
1737 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1740 if (!g_signals
.ProcessMessages(pnode
))
1741 pnode
->CloseSocketDisconnect();
1743 if (pnode
->nSendSize
< SendBufferSize())
1745 if (!pnode
->vRecvGetData
.empty() || (!pnode
->vRecvMsg
.empty() && pnode
->vRecvMsg
[0].complete()))
1752 boost::this_thread::interruption_point();
1756 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1758 g_signals
.SendMessages(pnode
, pnode
== pnodeTrickle
|| pnode
->fWhitelisted
);
1760 boost::this_thread::interruption_point();
1765 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1770 messageHandlerCondition
.timed_wait(lock
, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1779 bool BindListenPort(const CService
&addrBind
, string
& strError
, bool fWhitelisted
)
1784 // Create socket for listening for incoming connections
1785 struct sockaddr_storage sockaddr
;
1786 socklen_t len
= sizeof(sockaddr
);
1787 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1789 strError
= strprintf("Error: Bind address family for %s not supported", addrBind
.ToString());
1790 LogPrintf("%s\n", strError
);
1794 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1795 if (hListenSocket
== INVALID_SOCKET
)
1797 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1798 LogPrintf("%s\n", strError
);
1801 if (!IsSelectableSocket(hListenSocket
))
1803 strError
= "Error: Couldn't create a listenable socket for incoming connections";
1804 LogPrintf("%s\n", strError
);
1811 // Different way of disabling SIGPIPE on BSD
1812 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1814 // Allow binding if the port is still in TIME_WAIT state after
1815 // the program was closed and restarted.
1816 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1817 // Disable Nagle's algorithm
1818 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&nOne
, sizeof(int));
1820 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&nOne
, sizeof(int));
1821 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&nOne
, sizeof(int));
1824 // Set to non-blocking, incoming connections will also inherit this
1825 if (!SetSocketNonBlocking(hListenSocket
, true)) {
1826 strError
= strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1827 LogPrintf("%s\n", strError
);
1831 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1832 // and enable it by default or not. Try to enable it, if possible.
1833 if (addrBind
.IsIPv6()) {
1836 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (const char*)&nOne
, sizeof(int));
1838 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1842 int nProtLevel
= PROTECTION_LEVEL_UNRESTRICTED
;
1843 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_PROTECTION_LEVEL
, (const char*)&nProtLevel
, sizeof(int));
1847 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1849 int nErr
= WSAGetLastError();
1850 if (nErr
== WSAEADDRINUSE
)
1851 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind
.ToString());
1853 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind
.ToString(), NetworkErrorString(nErr
));
1854 LogPrintf("%s\n", strError
);
1855 CloseSocket(hListenSocket
);
1858 LogPrintf("Bound to %s\n", addrBind
.ToString());
1860 // Listen for incoming connections
1861 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1863 strError
= strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1864 LogPrintf("%s\n", strError
);
1865 CloseSocket(hListenSocket
);
1869 vhListenSocket
.push_back(ListenSocket(hListenSocket
, fWhitelisted
));
1871 if (addrBind
.IsRoutable() && fDiscover
&& !fWhitelisted
)
1872 AddLocal(addrBind
, LOCAL_BIND
);
1877 void static Discover(boost::thread_group
& threadGroup
)
1883 // Get local host IP
1884 char pszHostName
[256] = "";
1885 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1887 vector
<CNetAddr
> vaddr
;
1888 if (LookupHost(pszHostName
, vaddr
))
1890 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1892 if (AddLocal(addr
, LOCAL_IF
))
1893 LogPrintf("%s: %s - %s\n", __func__
, pszHostName
, addr
.ToString());
1898 // Get local host ip
1899 struct ifaddrs
* myaddrs
;
1900 if (getifaddrs(&myaddrs
) == 0)
1902 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1904 if (ifa
->ifa_addr
== NULL
) continue;
1905 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1906 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1907 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1908 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1910 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1911 CNetAddr
addr(s4
->sin_addr
);
1912 if (AddLocal(addr
, LOCAL_IF
))
1913 LogPrintf("%s: IPv4 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1915 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1917 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1918 CNetAddr
addr(s6
->sin6_addr
);
1919 if (AddLocal(addr
, LOCAL_IF
))
1920 LogPrintf("%s: IPv6 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1923 freeifaddrs(myaddrs
);
1928 void StartNode(boost::thread_group
& threadGroup
, CScheduler
& scheduler
)
1930 uiInterface
.InitMessage(_("Loading addresses..."));
1931 // Load addresses for peers.dat
1932 int64_t nStart
= GetTimeMillis();
1935 if (!adb
.Read(addrman
))
1936 LogPrintf("Invalid or missing peers.dat; recreating\n");
1939 //try to read stored banlist
1942 if (!bandb
.Read(banmap
))
1943 LogPrintf("Invalid or missing banlist.dat; recreating\n");
1945 CNode::SetBanned(banmap
); //thread save setter
1946 CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
1947 CNode::SweepBanned(); //sweap out unused entries
1949 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1950 addrman
.size(), GetTimeMillis() - nStart
);
1951 fAddressesInitialized
= true;
1953 if (semOutbound
== NULL
) {
1954 // initialize semaphore
1955 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, nMaxConnections
);
1956 semOutbound
= new CSemaphore(nMaxOutbound
);
1959 if (pnodeLocalHost
== NULL
)
1960 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1962 Discover(threadGroup
);
1968 if (!GetBoolArg("-dnsseed", true))
1969 LogPrintf("DNS seeding disabled\n");
1971 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "dnsseed", &ThreadDNSAddressSeed
));
1973 // Map ports with UPnP
1974 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP
));
1976 // Send and receive from sockets, accept connections
1977 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "net", &ThreadSocketHandler
));
1979 // Initiate outbound connections from -addnode
1980 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "addcon", &ThreadOpenAddedConnections
));
1982 // Initiate outbound connections
1983 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "opencon", &ThreadOpenConnections
));
1986 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "msghand", &ThreadMessageHandler
));
1988 // Dump network addresses
1989 scheduler
.scheduleEvery(&DumpData
, DUMP_ADDRESSES_INTERVAL
);
1994 LogPrintf("StopNode()\n");
1997 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1998 semOutbound
->post();
2000 if (fAddressesInitialized
)
2003 fAddressesInitialized
= false;
2017 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2018 if (pnode
->hSocket
!= INVALID_SOCKET
)
2019 CloseSocket(pnode
->hSocket
);
2020 BOOST_FOREACH(ListenSocket
& hListenSocket
, vhListenSocket
)
2021 if (hListenSocket
.socket
!= INVALID_SOCKET
)
2022 if (!CloseSocket(hListenSocket
.socket
))
2023 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2025 // clean up some globals (to help leak detection)
2026 BOOST_FOREACH(CNode
*pnode
, vNodes
)
2028 BOOST_FOREACH(CNode
*pnode
, vNodesDisconnected
)
2031 vNodesDisconnected
.clear();
2032 vhListenSocket
.clear();
2035 delete pnodeLocalHost
;
2036 pnodeLocalHost
= NULL
;
2039 // Shutdown Windows Sockets
2044 instance_of_cnetcleanup
;
2052 void RelayTransaction(const CTransaction
& tx
)
2054 CDataStream
ss(SER_NETWORK
, PROTOCOL_VERSION
);
2057 RelayTransaction(tx
, ss
);
2060 void RelayTransaction(const CTransaction
& tx
, const CDataStream
& ss
)
2062 CInv
inv(MSG_TX
, tx
.GetHash());
2065 // Expire old relay messages
2066 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
2068 mapRelay
.erase(vRelayExpiration
.front().second
);
2069 vRelayExpiration
.pop_front();
2072 // Save original serialized message so newer versions are preserved
2073 mapRelay
.insert(std::make_pair(inv
, ss
));
2074 vRelayExpiration
.push_back(std::make_pair(GetTime() + 15 * 60, inv
));
2077 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2079 if(!pnode
->fRelayTxes
)
2081 LOCK(pnode
->cs_filter
);
2084 if (pnode
->pfilter
->IsRelevantAndUpdate(tx
))
2085 pnode
->PushInventory(inv
);
2087 pnode
->PushInventory(inv
);
2091 void CNode::RecordBytesRecv(uint64_t bytes
)
2093 LOCK(cs_totalBytesRecv
);
2094 nTotalBytesRecv
+= bytes
;
2097 void CNode::RecordBytesSent(uint64_t bytes
)
2099 LOCK(cs_totalBytesSent
);
2100 nTotalBytesSent
+= bytes
;
2102 uint64_t now
= GetTime();
2103 if (nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
< now
)
2105 // timeframe expired, reset cycle
2106 nMaxOutboundCycleStartTime
= now
;
2107 nMaxOutboundTotalBytesSentInCycle
= 0;
2110 // TODO, exclude whitebind peers
2111 nMaxOutboundTotalBytesSentInCycle
+= bytes
;
2114 void CNode::SetMaxOutboundTarget(uint64_t limit
)
2116 LOCK(cs_totalBytesSent
);
2117 uint64_t recommendedMinimum
= (nMaxOutboundTimeframe
/ 600) * MAX_BLOCK_SIZE
;
2118 nMaxOutboundLimit
= limit
;
2120 if (limit
> 0 && limit
< recommendedMinimum
)
2121 LogPrintf("Max outbound target is very small (%s bytes) and will be overshot. Recommended minimum is %s bytes.\n", nMaxOutboundLimit
, recommendedMinimum
);
2124 uint64_t CNode::GetMaxOutboundTarget()
2126 LOCK(cs_totalBytesSent
);
2127 return nMaxOutboundLimit
;
2130 uint64_t CNode::GetMaxOutboundTimeframe()
2132 LOCK(cs_totalBytesSent
);
2133 return nMaxOutboundTimeframe
;
2136 uint64_t CNode::GetMaxOutboundTimeLeftInCycle()
2138 LOCK(cs_totalBytesSent
);
2139 if (nMaxOutboundLimit
== 0)
2142 if (nMaxOutboundCycleStartTime
== 0)
2143 return nMaxOutboundTimeframe
;
2145 uint64_t cycleEndTime
= nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
;
2146 uint64_t now
= GetTime();
2147 return (cycleEndTime
< now
) ? 0 : cycleEndTime
- GetTime();
2150 void CNode::SetMaxOutboundTimeframe(uint64_t timeframe
)
2152 LOCK(cs_totalBytesSent
);
2153 if (nMaxOutboundTimeframe
!= timeframe
)
2155 // reset measure-cycle in case of changing
2157 nMaxOutboundCycleStartTime
= GetTime();
2159 nMaxOutboundTimeframe
= timeframe
;
2162 bool CNode::OutboundTargetReached(bool historicalBlockServingLimit
)
2164 LOCK(cs_totalBytesSent
);
2165 if (nMaxOutboundLimit
== 0)
2168 if (historicalBlockServingLimit
)
2170 // keep a large enought buffer to at least relay each block once
2171 uint64_t timeLeftInCycle
= GetMaxOutboundTimeLeftInCycle();
2172 uint64_t buffer
= timeLeftInCycle
/ 600 * MAX_BLOCK_SIZE
;
2173 if (buffer
>= nMaxOutboundLimit
|| nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
- buffer
)
2176 else if (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
)
2182 uint64_t CNode::GetOutboundTargetBytesLeft()
2184 LOCK(cs_totalBytesSent
);
2185 if (nMaxOutboundLimit
== 0)
2188 return (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
) ? 0 : nMaxOutboundLimit
- nMaxOutboundTotalBytesSentInCycle
;
2191 uint64_t CNode::GetTotalBytesRecv()
2193 LOCK(cs_totalBytesRecv
);
2194 return nTotalBytesRecv
;
2197 uint64_t CNode::GetTotalBytesSent()
2199 LOCK(cs_totalBytesSent
);
2200 return nTotalBytesSent
;
2203 void CNode::Fuzz(int nChance
)
2205 if (!fSuccessfullyConnected
) return; // Don't fuzz initial handshake
2206 if (GetRand(nChance
) != 0) return; // Fuzz 1 of every nChance messages
2211 // xor a random byte with a random value:
2212 if (!ssSend
.empty()) {
2213 CDataStream::size_type pos
= GetRand(ssSend
.size());
2214 ssSend
[pos
] ^= (unsigned char)(GetRand(256));
2218 // delete a random byte:
2219 if (!ssSend
.empty()) {
2220 CDataStream::size_type pos
= GetRand(ssSend
.size());
2221 ssSend
.erase(ssSend
.begin()+pos
);
2225 // insert a random byte at a random position
2227 CDataStream::size_type pos
= GetRand(ssSend
.size());
2228 char ch
= (char)GetRand(256);
2229 ssSend
.insert(ssSend
.begin()+pos
, ch
);
2233 // Chance of more than one change half the time:
2234 // (more changes exponentially less likely):
2244 pathAddr
= GetDataDir() / "peers.dat";
2247 bool CAddrDB::Write(const CAddrMan
& addr
)
2249 // Generate random temporary filename
2250 unsigned short randv
= 0;
2251 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2252 std::string tmpfn
= strprintf("peers.dat.%04x", randv
);
2254 // serialize addresses, checksum data up to that point, then append csum
2255 CDataStream
ssPeers(SER_DISK
, CLIENT_VERSION
);
2256 ssPeers
<< FLATDATA(Params().MessageStart());
2258 uint256 hash
= Hash(ssPeers
.begin(), ssPeers
.end());
2261 // open temp output file, and associate with CAutoFile
2262 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2263 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2264 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2265 if (fileout
.IsNull())
2266 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2268 // Write and commit header, data
2272 catch (const std::exception
& e
) {
2273 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2275 FileCommit(fileout
.Get());
2278 // replace existing peers.dat, if any, with new peers.dat.XXXX
2279 if (!RenameOver(pathTmp
, pathAddr
))
2280 return error("%s: Rename-into-place failed", __func__
);
2285 bool CAddrDB::Read(CAddrMan
& addr
)
2287 // open input file, and associate with CAutoFile
2288 FILE *file
= fopen(pathAddr
.string().c_str(), "rb");
2289 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2290 if (filein
.IsNull())
2291 return error("%s: Failed to open file %s", __func__
, pathAddr
.string());
2293 // use file size to size memory buffer
2294 uint64_t fileSize
= boost::filesystem::file_size(pathAddr
);
2295 uint64_t dataSize
= 0;
2296 // Don't try to resize to a negative number if file is small
2297 if (fileSize
>= sizeof(uint256
))
2298 dataSize
= fileSize
- sizeof(uint256
);
2299 vector
<unsigned char> vchData
;
2300 vchData
.resize(dataSize
);
2303 // read data and checksum from file
2305 filein
.read((char *)&vchData
[0], dataSize
);
2308 catch (const std::exception
& e
) {
2309 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2313 CDataStream
ssPeers(vchData
, SER_DISK
, CLIENT_VERSION
);
2315 // verify stored checksum matches input data
2316 uint256 hashTmp
= Hash(ssPeers
.begin(), ssPeers
.end());
2317 if (hashIn
!= hashTmp
)
2318 return error("%s: Checksum mismatch, data corrupted", __func__
);
2320 unsigned char pchMsgTmp
[4];
2322 // de-serialize file header (network specific magic number) and ..
2323 ssPeers
>> FLATDATA(pchMsgTmp
);
2325 // ... verify the network matches ours
2326 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2327 return error("%s: Invalid network magic number", __func__
);
2329 // de-serialize address data into one CAddrMan object
2332 catch (const std::exception
& e
) {
2333 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2339 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2340 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2342 CNode::CNode(SOCKET hSocketIn
, const CAddress
& addrIn
, const std::string
& addrNameIn
, bool fInboundIn
) :
2343 ssSend(SER_NETWORK
, INIT_PROTO_VERSION
),
2344 addrKnown(5000, 0.001),
2345 setInventoryKnown(SendBufferSize() / 1000)
2348 hSocket
= hSocketIn
;
2349 nRecvVersion
= INIT_PROTO_VERSION
;
2354 nTimeConnected
= GetTime();
2357 addrName
= addrNameIn
== "" ? addr
.ToStringIPPort() : addrNameIn
;
2360 fWhitelisted
= false;
2362 fClient
= false; // set by version message
2363 fInbound
= fInboundIn
;
2364 fNetworkNode
= false;
2365 fSuccessfullyConnected
= false;
2366 fDisconnect
= false;
2370 hashContinue
= uint256();
2371 nStartingHeight
= -1;
2374 pfilter
= new CBloomFilter();
2378 fPingQueued
= false;
2379 nMinPingUsecTime
= std::numeric_limits
<int64_t>::max();
2382 LOCK(cs_nLastNodeId
);
2387 LogPrint("net", "Added connection to %s peer=%d\n", addrName
, id
);
2389 LogPrint("net", "Added connection peer=%d\n", id
);
2391 // Be shy and don't send version until we hear
2392 if (hSocket
!= INVALID_SOCKET
&& !fInbound
)
2395 GetNodeSignals().InitializeNode(GetId(), this);
2400 CloseSocket(hSocket
);
2405 GetNodeSignals().FinalizeNode(GetId());
2408 void CNode::AskFor(const CInv
& inv
)
2410 if (mapAskFor
.size() > MAPASKFOR_MAX_SZ
)
2412 // We're using mapAskFor as a priority queue,
2413 // the key is the earliest time the request can be sent
2414 int64_t nRequestTime
;
2415 limitedmap
<CInv
, int64_t>::const_iterator it
= mapAlreadyAskedFor
.find(inv
);
2416 if (it
!= mapAlreadyAskedFor
.end())
2417 nRequestTime
= it
->second
;
2420 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv
.ToString(), nRequestTime
, DateTimeStrFormat("%H:%M:%S", nRequestTime
/1000000), id
);
2422 // Make sure not to reuse time indexes to keep things in the same order
2423 int64_t nNow
= GetTimeMicros() - 1000000;
2424 static int64_t nLastTime
;
2426 nNow
= std::max(nNow
, nLastTime
);
2429 // Each retry is 2 minutes after the last
2430 nRequestTime
= std::max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
2431 if (it
!= mapAlreadyAskedFor
.end())
2432 mapAlreadyAskedFor
.update(it
, nRequestTime
);
2434 mapAlreadyAskedFor
.insert(std::make_pair(inv
, nRequestTime
));
2435 mapAskFor
.insert(std::make_pair(nRequestTime
, inv
));
2438 void CNode::BeginMessage(const char* pszCommand
) EXCLUSIVE_LOCK_FUNCTION(cs_vSend
)
2440 ENTER_CRITICAL_SECTION(cs_vSend
);
2441 assert(ssSend
.size() == 0);
2442 ssSend
<< CMessageHeader(Params().MessageStart(), pszCommand
, 0);
2443 LogPrint("net", "sending: %s ", SanitizeString(pszCommand
));
2446 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend
)
2450 LEAVE_CRITICAL_SECTION(cs_vSend
);
2452 LogPrint("net", "(aborted)\n");
2455 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend
)
2457 // The -*messagestest options are intentionally not documented in the help message,
2458 // since they are only used during development to debug the networking code and are
2459 // not intended for end-users.
2460 if (mapArgs
.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2462 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2466 if (mapArgs
.count("-fuzzmessagestest"))
2467 Fuzz(GetArg("-fuzzmessagestest", 10));
2469 if (ssSend
.size() == 0)
2471 LEAVE_CRITICAL_SECTION(cs_vSend
);
2475 unsigned int nSize
= ssSend
.size() - CMessageHeader::HEADER_SIZE
;
2476 WriteLE32((uint8_t*)&ssSend
[CMessageHeader::MESSAGE_SIZE_OFFSET
], nSize
);
2479 uint256 hash
= Hash(ssSend
.begin() + CMessageHeader::HEADER_SIZE
, ssSend
.end());
2480 unsigned int nChecksum
= 0;
2481 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
2482 assert(ssSend
.size () >= CMessageHeader::CHECKSUM_OFFSET
+ sizeof(nChecksum
));
2483 memcpy((char*)&ssSend
[CMessageHeader::CHECKSUM_OFFSET
], &nChecksum
, sizeof(nChecksum
));
2485 LogPrint("net", "(%d bytes) peer=%d\n", nSize
, id
);
2487 std::deque
<CSerializeData
>::iterator it
= vSendMsg
.insert(vSendMsg
.end(), CSerializeData());
2488 ssSend
.GetAndClear(*it
);
2489 nSendSize
+= (*it
).size();
2491 // If write queue empty, attempt "optimistic write"
2492 if (it
== vSendMsg
.begin())
2493 SocketSendData(this);
2495 LEAVE_CRITICAL_SECTION(cs_vSend
);
2504 pathBanlist
= GetDataDir() / "banlist.dat";
2507 bool CBanDB::Write(const banmap_t
& banSet
)
2509 // Generate random temporary filename
2510 unsigned short randv
= 0;
2511 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2512 std::string tmpfn
= strprintf("banlist.dat.%04x", randv
);
2514 // serialize banlist, checksum data up to that point, then append csum
2515 CDataStream
ssBanlist(SER_DISK
, CLIENT_VERSION
);
2516 ssBanlist
<< FLATDATA(Params().MessageStart());
2517 ssBanlist
<< banSet
;
2518 uint256 hash
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2521 // open temp output file, and associate with CAutoFile
2522 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2523 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2524 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2525 if (fileout
.IsNull())
2526 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2528 // Write and commit header, data
2530 fileout
<< ssBanlist
;
2532 catch (const std::exception
& e
) {
2533 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2535 FileCommit(fileout
.Get());
2538 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2539 if (!RenameOver(pathTmp
, pathBanlist
))
2540 return error("%s: Rename-into-place failed", __func__
);
2545 bool CBanDB::Read(banmap_t
& banSet
)
2547 // open input file, and associate with CAutoFile
2548 FILE *file
= fopen(pathBanlist
.string().c_str(), "rb");
2549 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2550 if (filein
.IsNull())
2551 return error("%s: Failed to open file %s", __func__
, pathBanlist
.string());
2553 // use file size to size memory buffer
2554 uint64_t fileSize
= boost::filesystem::file_size(pathBanlist
);
2555 uint64_t dataSize
= 0;
2556 // Don't try to resize to a negative number if file is small
2557 if (fileSize
>= sizeof(uint256
))
2558 dataSize
= fileSize
- sizeof(uint256
);
2559 vector
<unsigned char> vchData
;
2560 vchData
.resize(dataSize
);
2563 // read data and checksum from file
2565 filein
.read((char *)&vchData
[0], dataSize
);
2568 catch (const std::exception
& e
) {
2569 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2573 CDataStream
ssBanlist(vchData
, SER_DISK
, CLIENT_VERSION
);
2575 // verify stored checksum matches input data
2576 uint256 hashTmp
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2577 if (hashIn
!= hashTmp
)
2578 return error("%s: Checksum mismatch, data corrupted", __func__
);
2580 unsigned char pchMsgTmp
[4];
2582 // de-serialize file header (network specific magic number) and ..
2583 ssBanlist
>> FLATDATA(pchMsgTmp
);
2585 // ... verify the network matches ours
2586 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2587 return error("%s: Invalid network magic number", __func__
);
2589 // de-serialize address data into one CAddrMan object
2590 ssBanlist
>> banSet
;
2592 catch (const std::exception
& e
) {
2593 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2601 int64_t nStart
= GetTimeMillis();
2603 CNode::SweepBanned(); //clean unused entries (if bantime has expired)
2607 CNode::GetBanned(banmap
);
2608 bandb
.Write(banmap
);
2610 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
2611 banmap
.size(), GetTimeMillis() - nStart
);