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 "crypto/common.h"
17 #include "primitives/transaction.h"
18 #include "scheduler.h"
19 #include "ui_interface.h"
20 #include "utilstrencodings.h"
29 #include <miniupnpc/miniupnpc.h>
30 #include <miniupnpc/miniwget.h>
31 #include <miniupnpc/upnpcommands.h>
32 #include <miniupnpc/upnperrors.h>
35 #include <boost/filesystem.hpp>
36 #include <boost/thread.hpp>
38 // Dump addresses to peers.dat every 15 minutes (900s)
39 #define DUMP_ADDRESSES_INTERVAL 900
41 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
42 #define MSG_NOSIGNAL 0
45 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
46 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
48 #ifndef PROTECTION_LEVEL_UNRESTRICTED
49 #define PROTECTION_LEVEL_UNRESTRICTED 10
51 #ifndef IPV6_PROTECTION_LEVEL
52 #define IPV6_PROTECTION_LEVEL 23
59 const int MAX_OUTBOUND_CONNECTIONS
= 8;
65 ListenSocket(SOCKET socket
, bool whitelisted
) : socket(socket
), whitelisted(whitelisted
) {}
70 // Global state variables
72 bool fDiscover
= true;
74 uint64_t nLocalServices
= NODE_NETWORK
;
75 CCriticalSection cs_mapLocalHost
;
76 map
<CNetAddr
, LocalServiceInfo
> mapLocalHost
;
77 static bool vfReachable
[NET_MAX
] = {};
78 static bool vfLimited
[NET_MAX
] = {};
79 static CNode
* pnodeLocalHost
= NULL
;
80 uint64_t nLocalHostNonce
= 0;
81 static std::vector
<ListenSocket
> vhListenSocket
;
83 int nMaxConnections
= DEFAULT_MAX_PEER_CONNECTIONS
;
84 bool fAddressesInitialized
= false;
85 std::string strSubVersion
;
87 vector
<CNode
*> vNodes
;
88 CCriticalSection cs_vNodes
;
89 map
<CInv
, CDataStream
> mapRelay
;
90 deque
<pair
<int64_t, CInv
> > vRelayExpiration
;
91 CCriticalSection cs_mapRelay
;
92 limitedmap
<CInv
, int64_t> mapAlreadyAskedFor(MAX_INV_SZ
);
94 static deque
<string
> vOneShots
;
95 CCriticalSection cs_vOneShots
;
97 set
<CNetAddr
> setservAddNodeAddresses
;
98 CCriticalSection cs_setservAddNodeAddresses
;
100 vector
<std::string
> vAddedNodes
;
101 CCriticalSection cs_vAddedNodes
;
103 NodeId nLastNodeId
= 0;
104 CCriticalSection cs_nLastNodeId
;
106 static CSemaphore
*semOutbound
= NULL
;
107 boost::condition_variable messageHandlerCondition
;
109 // Signals for message handling
110 static CNodeSignals g_signals
;
111 CNodeSignals
& GetNodeSignals() { return g_signals
; }
113 void AddOneShot(const std::string
& strDest
)
116 vOneShots
.push_back(strDest
);
119 unsigned short GetListenPort()
121 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
124 // find 'best' local address for a particular peer
125 bool GetLocal(CService
& addr
, const CNetAddr
*paddrPeer
)
131 int nBestReachability
= -1;
133 LOCK(cs_mapLocalHost
);
134 for (map
<CNetAddr
, LocalServiceInfo
>::iterator it
= mapLocalHost
.begin(); it
!= mapLocalHost
.end(); it
++)
136 int nScore
= (*it
).second
.nScore
;
137 int nReachability
= (*it
).first
.GetReachabilityFrom(paddrPeer
);
138 if (nReachability
> nBestReachability
|| (nReachability
== nBestReachability
&& nScore
> nBestScore
))
140 addr
= CService((*it
).first
, (*it
).second
.nPort
);
141 nBestReachability
= nReachability
;
146 return nBestScore
>= 0;
149 //! Convert the pnSeeds6 array into usable address objects.
150 static std::vector
<CAddress
> convertSeed6(const std::vector
<SeedSpec6
> &vSeedsIn
)
152 // It'll only connect to one or two seed nodes because once it connects,
153 // it'll get a pile of addresses with newer timestamps.
154 // Seed nodes are given a random 'last seen time' of between one and two
156 const int64_t nOneWeek
= 7*24*60*60;
157 std::vector
<CAddress
> vSeedsOut
;
158 vSeedsOut
.reserve(vSeedsIn
.size());
159 for (std::vector
<SeedSpec6
>::const_iterator
i(vSeedsIn
.begin()); i
!= vSeedsIn
.end(); ++i
)
162 memcpy(&ip
, i
->addr
, sizeof(ip
));
163 CAddress
addr(CService(ip
, i
->port
));
164 addr
.nTime
= GetTime() - GetRand(nOneWeek
) - nOneWeek
;
165 vSeedsOut
.push_back(addr
);
170 // get best local address for a particular peer as a CAddress
171 // Otherwise, return the unroutable 0.0.0.0 but filled in with
172 // the normal parameters, since the IP may be changed to a useful
174 CAddress
GetLocalAddress(const CNetAddr
*paddrPeer
)
176 CAddress
ret(CService("0.0.0.0",GetListenPort()),0);
178 if (GetLocal(addr
, paddrPeer
))
180 ret
= CAddress(addr
);
182 ret
.nServices
= nLocalServices
;
183 ret
.nTime
= GetAdjustedTime();
187 int GetnScore(const CService
& addr
)
189 LOCK(cs_mapLocalHost
);
190 if (mapLocalHost
.count(addr
) == LOCAL_NONE
)
192 return mapLocalHost
[addr
].nScore
;
195 // Is our peer's addrLocal potentially useful as an external IP source?
196 bool IsPeerAddrLocalGood(CNode
*pnode
)
198 return fDiscover
&& pnode
->addr
.IsRoutable() && pnode
->addrLocal
.IsRoutable() &&
199 !IsLimited(pnode
->addrLocal
.GetNetwork());
202 // pushes our own address to a peer
203 void AdvertizeLocal(CNode
*pnode
)
205 if (fListen
&& pnode
->fSuccessfullyConnected
)
207 CAddress addrLocal
= GetLocalAddress(&pnode
->addr
);
208 // If discovery is enabled, sometimes give our peer the address it
209 // tells us that it sees us as in case it has a better idea of our
210 // address than we do.
211 if (IsPeerAddrLocalGood(pnode
) && (!addrLocal
.IsRoutable() ||
212 GetRand((GetnScore(addrLocal
) > LOCAL_MANUAL
) ? 8:2) == 0))
214 addrLocal
.SetIP(pnode
->addrLocal
);
216 if (addrLocal
.IsRoutable())
218 pnode
->PushAddress(addrLocal
);
223 void SetReachable(enum Network net
, bool fFlag
)
225 LOCK(cs_mapLocalHost
);
226 vfReachable
[net
] = fFlag
;
227 if (net
== NET_IPV6
&& fFlag
)
228 vfReachable
[NET_IPV4
] = true;
231 // learn a new local address
232 bool AddLocal(const CService
& addr
, int nScore
)
234 if (!addr
.IsRoutable())
237 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
243 LogPrintf("AddLocal(%s,%i)\n", addr
.ToString(), nScore
);
246 LOCK(cs_mapLocalHost
);
247 bool fAlready
= mapLocalHost
.count(addr
) > 0;
248 LocalServiceInfo
&info
= mapLocalHost
[addr
];
249 if (!fAlready
|| nScore
>= info
.nScore
) {
250 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
251 info
.nPort
= addr
.GetPort();
253 SetReachable(addr
.GetNetwork());
259 bool AddLocal(const CNetAddr
&addr
, int nScore
)
261 return AddLocal(CService(addr
, GetListenPort()), nScore
);
264 /** Make a particular network entirely off-limits (no automatic connects to it) */
265 void SetLimited(enum Network net
, bool fLimited
)
267 if (net
== NET_UNROUTABLE
)
269 LOCK(cs_mapLocalHost
);
270 vfLimited
[net
] = fLimited
;
273 bool IsLimited(enum Network net
)
275 LOCK(cs_mapLocalHost
);
276 return vfLimited
[net
];
279 bool IsLimited(const CNetAddr
&addr
)
281 return IsLimited(addr
.GetNetwork());
284 /** vote for a local address */
285 bool SeenLocal(const CService
& addr
)
288 LOCK(cs_mapLocalHost
);
289 if (mapLocalHost
.count(addr
) == 0)
291 mapLocalHost
[addr
].nScore
++;
297 /** check whether a given address is potentially local */
298 bool IsLocal(const CService
& addr
)
300 LOCK(cs_mapLocalHost
);
301 return mapLocalHost
.count(addr
) > 0;
304 /** check whether a given network is one we can probably connect to */
305 bool IsReachable(enum Network net
)
307 LOCK(cs_mapLocalHost
);
308 return vfReachable
[net
] && !vfLimited
[net
];
311 /** check whether a given address is in a network we can probably connect to */
312 bool IsReachable(const CNetAddr
& addr
)
314 enum Network net
= addr
.GetNetwork();
315 return IsReachable(net
);
318 void AddressCurrentlyConnected(const CService
& addr
)
320 addrman
.Connected(addr
);
324 uint64_t CNode::nTotalBytesRecv
= 0;
325 uint64_t CNode::nTotalBytesSent
= 0;
326 CCriticalSection
CNode::cs_totalBytesRecv
;
327 CCriticalSection
CNode::cs_totalBytesSent
;
329 CNode
* FindNode(const CNetAddr
& ip
)
332 BOOST_FOREACH(CNode
* pnode
, vNodes
)
333 if ((CNetAddr
)pnode
->addr
== ip
)
338 CNode
* FindNode(const CSubNet
& subNet
)
341 BOOST_FOREACH(CNode
* pnode
, vNodes
)
342 if (subNet
.Match((CNetAddr
)pnode
->addr
))
347 CNode
* FindNode(const std::string
& addrName
)
350 BOOST_FOREACH(CNode
* pnode
, vNodes
)
351 if (pnode
->addrName
== addrName
)
356 CNode
* FindNode(const CService
& addr
)
359 BOOST_FOREACH(CNode
* pnode
, vNodes
)
360 if ((CService
)pnode
->addr
== addr
)
365 CNode
* ConnectNode(CAddress addrConnect
, const char *pszDest
)
367 if (pszDest
== NULL
) {
368 if (IsLocal(addrConnect
))
371 // Look for an existing connection
372 CNode
* pnode
= FindNode((CService
)addrConnect
);
381 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
382 pszDest
? pszDest
: addrConnect
.ToString(),
383 pszDest
? 0.0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
387 bool proxyConnectionFailed
= false;
388 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, Params().GetDefaultPort(), nConnectTimeout
, &proxyConnectionFailed
) :
389 ConnectSocket(addrConnect
, hSocket
, nConnectTimeout
, &proxyConnectionFailed
))
391 if (!IsSelectableSocket(hSocket
)) {
392 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
393 CloseSocket(hSocket
);
397 addrman
.Attempt(addrConnect
);
400 CNode
* pnode
= new CNode(hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
405 vNodes
.push_back(pnode
);
408 pnode
->nTimeConnected
= GetTime();
411 } else if (!proxyConnectionFailed
) {
412 // If connecting to the node failed, and failure is not caused by a problem connecting to
413 // the proxy, mark this as an attempt.
414 addrman
.Attempt(addrConnect
);
420 void CNode::CloseSocketDisconnect()
423 if (hSocket
!= INVALID_SOCKET
)
425 LogPrint("net", "disconnecting peer=%d\n", id
);
426 CloseSocket(hSocket
);
429 // in case this fails, we'll empty the recv buffer when the CNode is deleted
430 TRY_LOCK(cs_vRecvMsg
, lockRecv
);
435 void CNode::PushVersion()
437 int nBestHeight
= g_signals
.GetHeight().get_value_or(0);
439 int64_t nTime
= (fInbound
? GetAdjustedTime() : GetTime());
440 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService("0.0.0.0",0)));
441 CAddress addrMe
= GetLocalAddress(&addr
);
442 GetRandBytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
444 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), addrYou
.ToString(), id
);
446 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), id
);
447 PushMessage("version", PROTOCOL_VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
448 nLocalHostNonce
, strSubVersion
, nBestHeight
, true);
455 banmap_t
CNode::setBanned
;
456 CCriticalSection
CNode::cs_setBanned
;
457 bool CNode::setBannedIsDirty
;
459 void CNode::ClearBanned()
463 setBannedIsDirty
= true;
466 bool CNode::IsBanned(CNetAddr ip
)
468 bool fResult
= false;
471 for (banmap_t::iterator it
= setBanned
.begin(); it
!= setBanned
.end(); it
++)
473 CSubNet subNet
= (*it
).first
;
474 CBanEntry banEntry
= (*it
).second
;
476 if(subNet
.Match(ip
) && GetTime() < banEntry
.nBanUntil
)
483 bool CNode::IsBanned(CSubNet subnet
)
485 bool fResult
= false;
488 banmap_t::iterator i
= setBanned
.find(subnet
);
489 if (i
!= setBanned
.end())
491 CBanEntry banEntry
= (*i
).second
;
492 if (GetTime() < banEntry
.nBanUntil
)
499 void CNode::Ban(const CNetAddr
& addr
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
500 CSubNet
subNet(addr
);
501 Ban(subNet
, banReason
, bantimeoffset
, sinceUnixEpoch
);
504 void CNode::Ban(const CSubNet
& subNet
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
505 CBanEntry
banEntry(GetTime());
506 banEntry
.banReason
= banReason
;
507 if (bantimeoffset
<= 0)
509 bantimeoffset
= GetArg("-bantime", 60*60*24); // Default 24-hour ban
510 sinceUnixEpoch
= false;
512 banEntry
.nBanUntil
= (sinceUnixEpoch
? 0 : GetTime() )+bantimeoffset
;
516 if (setBanned
[subNet
].nBanUntil
< banEntry
.nBanUntil
)
517 setBanned
[subNet
] = banEntry
;
519 setBannedIsDirty
= true;
522 bool CNode::Unban(const CNetAddr
&addr
) {
523 CSubNet
subNet(addr
);
524 return Unban(subNet
);
527 bool CNode::Unban(const CSubNet
&subNet
) {
529 if (setBanned
.erase(subNet
))
531 setBannedIsDirty
= true;
537 void CNode::GetBanned(banmap_t
&banMap
)
540 banMap
= setBanned
; //create a thread safe copy
543 void CNode::SetBanned(const banmap_t
&banMap
)
547 setBannedIsDirty
= true;
550 void CNode::SweepBanned()
552 int64_t now
= GetTime();
555 banmap_t::iterator it
= setBanned
.begin();
556 while(it
!= setBanned
.end())
558 CBanEntry banEntry
= (*it
).second
;
559 if(now
> banEntry
.nBanUntil
)
561 setBanned
.erase(it
++);
562 setBannedIsDirty
= true;
569 bool CNode::BannedSetIsDirty()
572 return setBannedIsDirty
;
575 void CNode::SetBannedSetDirty(bool dirty
)
577 LOCK(cs_setBanned
); //reuse setBanned lock for the isDirty flag
578 setBannedIsDirty
= dirty
;
582 std::vector
<CSubNet
> CNode::vWhitelistedRange
;
583 CCriticalSection
CNode::cs_vWhitelistedRange
;
585 bool CNode::IsWhitelistedRange(const CNetAddr
&addr
) {
586 LOCK(cs_vWhitelistedRange
);
587 BOOST_FOREACH(const CSubNet
& subnet
, vWhitelistedRange
) {
588 if (subnet
.Match(addr
))
594 void CNode::AddWhitelistedRange(const CSubNet
&subnet
) {
595 LOCK(cs_vWhitelistedRange
);
596 vWhitelistedRange
.push_back(subnet
);
600 #define X(name) stats.name = name
601 void CNode::copyStats(CNodeStats
&stats
)
603 stats
.nodeid
= this->GetId();
618 // It is common for nodes with good ping times to suddenly become lagged,
619 // due to a new block arriving or other large transfer.
620 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
621 // since pingtime does not update until the ping is complete, which might take a while.
622 // So, if a ping is taking an unusually long time in flight,
623 // the caller can immediately detect that this is happening.
624 int64_t nPingUsecWait
= 0;
625 if ((0 != nPingNonceSent
) && (0 != nPingUsecStart
)) {
626 nPingUsecWait
= GetTimeMicros() - nPingUsecStart
;
629 // 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 :)
630 stats
.dPingTime
= (((double)nPingUsecTime
) / 1e6
);
631 stats
.dPingWait
= (((double)nPingUsecWait
) / 1e6
);
633 // Leave string empty if addrLocal invalid (not filled in yet)
634 stats
.addrLocal
= addrLocal
.IsValid() ? addrLocal
.ToString() : "";
638 // requires LOCK(cs_vRecvMsg)
639 bool CNode::ReceiveMsgBytes(const char *pch
, unsigned int nBytes
)
643 // get current incomplete message, or create a new one
644 if (vRecvMsg
.empty() ||
645 vRecvMsg
.back().complete())
646 vRecvMsg
.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK
, nRecvVersion
));
648 CNetMessage
& msg
= vRecvMsg
.back();
650 // absorb network data
653 handled
= msg
.readHeader(pch
, nBytes
);
655 handled
= msg
.readData(pch
, nBytes
);
660 if (msg
.in_data
&& msg
.hdr
.nMessageSize
> MAX_PROTOCOL_MESSAGE_LENGTH
) {
661 LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
668 if (msg
.complete()) {
669 msg
.nTime
= GetTimeMicros();
670 messageHandlerCondition
.notify_one();
677 int CNetMessage::readHeader(const char *pch
, unsigned int nBytes
)
679 // copy data to temporary parsing buffer
680 unsigned int nRemaining
= 24 - nHdrPos
;
681 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
683 memcpy(&hdrbuf
[nHdrPos
], pch
, nCopy
);
686 // if header incomplete, exit
690 // deserialize to CMessageHeader
694 catch (const std::exception
&) {
698 // reject messages larger than MAX_SIZE
699 if (hdr
.nMessageSize
> MAX_SIZE
)
702 // switch state to reading message data
708 int CNetMessage::readData(const char *pch
, unsigned int nBytes
)
710 unsigned int nRemaining
= hdr
.nMessageSize
- nDataPos
;
711 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
713 if (vRecv
.size() < nDataPos
+ nCopy
) {
714 // Allocate up to 256 KiB ahead, but never more than the total message size.
715 vRecv
.resize(std::min(hdr
.nMessageSize
, nDataPos
+ nCopy
+ 256 * 1024));
718 memcpy(&vRecv
[nDataPos
], pch
, nCopy
);
732 // requires LOCK(cs_vSend)
733 void SocketSendData(CNode
*pnode
)
735 std::deque
<CSerializeData
>::iterator it
= pnode
->vSendMsg
.begin();
737 while (it
!= pnode
->vSendMsg
.end()) {
738 const CSerializeData
&data
= *it
;
739 assert(data
.size() > pnode
->nSendOffset
);
740 int nBytes
= send(pnode
->hSocket
, &data
[pnode
->nSendOffset
], data
.size() - pnode
->nSendOffset
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
742 pnode
->nLastSend
= GetTime();
743 pnode
->nSendBytes
+= nBytes
;
744 pnode
->nSendOffset
+= nBytes
;
745 pnode
->RecordBytesSent(nBytes
);
746 if (pnode
->nSendOffset
== data
.size()) {
747 pnode
->nSendOffset
= 0;
748 pnode
->nSendSize
-= data
.size();
751 // could not send full message; stop sending more
757 int nErr
= WSAGetLastError();
758 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
760 LogPrintf("socket send error %s\n", NetworkErrorString(nErr
));
761 pnode
->CloseSocketDisconnect();
764 // couldn't send anything at all
769 if (it
== pnode
->vSendMsg
.end()) {
770 assert(pnode
->nSendOffset
== 0);
771 assert(pnode
->nSendSize
== 0);
773 pnode
->vSendMsg
.erase(pnode
->vSendMsg
.begin(), it
);
776 static list
<CNode
*> vNodesDisconnected
;
778 static bool ReverseCompareNodeMinPingTime(CNode
*a
, CNode
*b
)
780 return a
->nMinPingUsecTime
> b
->nMinPingUsecTime
;
783 static bool ReverseCompareNodeTimeConnected(CNode
*a
, CNode
*b
)
785 return a
->nTimeConnected
> b
->nTimeConnected
;
788 class CompareNetGroupKeyed
790 std::vector
<unsigned char> vchSecretKey
;
792 CompareNetGroupKeyed()
794 vchSecretKey
.resize(32, 0);
795 GetRandBytes(vchSecretKey
.data(), vchSecretKey
.size());
798 bool operator()(CNode
*a
, CNode
*b
)
800 std::vector
<unsigned char> vchGroupA
, vchGroupB
;
801 CSHA256 hashA
, hashB
;
802 std::vector
<unsigned char> vchA(32), vchB(32);
804 vchGroupA
= a
->addr
.GetGroup();
805 vchGroupB
= b
->addr
.GetGroup();
807 hashA
.Write(begin_ptr(vchGroupA
), vchGroupA
.size());
808 hashB
.Write(begin_ptr(vchGroupB
), vchGroupB
.size());
810 hashA
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
811 hashB
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
813 hashA
.Finalize(begin_ptr(vchA
));
814 hashB
.Finalize(begin_ptr(vchB
));
820 static bool AttemptToEvictConnection(bool fPreferNewConnection
) {
821 std::vector
<CNode
*> vEvictionCandidates
;
825 BOOST_FOREACH(CNode
*node
, vNodes
) {
826 if (node
->fWhitelisted
)
830 if (node
->fDisconnect
)
832 if (node
->addr
.IsLocal())
834 vEvictionCandidates
.push_back(node
);
838 // Protect connections with certain characteristics
840 // Deterministically select 4 peers to protect by netgroup.
841 // An attacker cannot predict which netgroups will be protected.
842 static CompareNetGroupKeyed comparerNetGroupKeyed
;
843 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), comparerNetGroupKeyed
);
844 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
846 // Protect the 8 nodes with the best ping times.
847 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
848 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeMinPingTime
);
849 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(8, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
851 // Protect the 64 nodes which have been connected the longest.
852 // This replicates the existing implicit behavior.
853 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
854 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(64, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
856 if (vEvictionCandidates
.empty())
859 // Identify CNetAddr with the most connections
860 CNetAddr naMostConnections
;
861 unsigned int nMostConnections
= 0;
862 std::map
<CNetAddr
, std::vector
<CNode
*> > mapAddrCounts
;
863 BOOST_FOREACH(CNode
*node
, vEvictionCandidates
) {
864 mapAddrCounts
[node
->addr
].push_back(node
);
866 if (mapAddrCounts
[node
->addr
].size() > nMostConnections
) {
867 nMostConnections
= mapAddrCounts
[node
->addr
].size();
868 naMostConnections
= node
->addr
;
872 // Reduce to the CNetAddr with the most connections
873 vEvictionCandidates
= mapAddrCounts
[naMostConnections
];
875 // Do not disconnect peers who have only 1 evictable connection
876 if (vEvictionCandidates
.size() <= 1)
877 // unless we prefer the new connection (for whitelisted peers)
878 if (!fPreferNewConnection
)
881 // Disconnect the most recent connection from the CNetAddr with the most connections
882 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
883 vEvictionCandidates
[0]->fDisconnect
= true;
888 static void AcceptConnection(const ListenSocket
& hListenSocket
) {
889 struct sockaddr_storage sockaddr
;
890 socklen_t len
= sizeof(sockaddr
);
891 SOCKET hSocket
= accept(hListenSocket
.socket
, (struct sockaddr
*)&sockaddr
, &len
);
894 int nMaxInbound
= nMaxConnections
- MAX_OUTBOUND_CONNECTIONS
;
896 if (hSocket
!= INVALID_SOCKET
)
897 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
898 LogPrintf("Warning: Unknown socket family\n");
900 bool whitelisted
= hListenSocket
.whitelisted
|| CNode::IsWhitelistedRange(addr
);
903 BOOST_FOREACH(CNode
* pnode
, vNodes
)
908 if (hSocket
== INVALID_SOCKET
)
910 int nErr
= WSAGetLastError();
911 if (nErr
!= WSAEWOULDBLOCK
)
912 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr
));
916 if (!IsSelectableSocket(hSocket
))
918 LogPrintf("connection from %s dropped: non-selectable socket\n", addr
.ToString());
919 CloseSocket(hSocket
);
923 if (CNode::IsBanned(addr
) && !whitelisted
)
925 LogPrintf("connection from %s dropped (banned)\n", addr
.ToString());
926 CloseSocket(hSocket
);
930 if (nInbound
>= nMaxInbound
)
932 if (!AttemptToEvictConnection(whitelisted
)) {
933 // No connection to evict, disconnect the new connection
934 LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
935 CloseSocket(hSocket
);
940 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
942 pnode
->fWhitelisted
= whitelisted
;
944 LogPrint("net", "connection from %s accepted\n", addr
.ToString());
948 vNodes
.push_back(pnode
);
952 void ThreadSocketHandler()
954 unsigned int nPrevNodeCount
= 0;
962 // Disconnect unused nodes
963 vector
<CNode
*> vNodesCopy
= vNodes
;
964 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
966 if (pnode
->fDisconnect
||
967 (pnode
->GetRefCount() <= 0 && pnode
->vRecvMsg
.empty() && pnode
->nSendSize
== 0 && pnode
->ssSend
.empty()))
969 // remove from vNodes
970 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
972 // release outbound grant (if any)
973 pnode
->grantOutbound
.Release();
975 // close socket and cleanup
976 pnode
->CloseSocketDisconnect();
978 // hold in disconnected pool until all refs are released
979 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
981 vNodesDisconnected
.push_back(pnode
);
986 // Delete disconnected nodes
987 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
988 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
990 // wait until threads are done using it
991 if (pnode
->GetRefCount() <= 0)
993 bool fDelete
= false;
995 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
998 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1001 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
1009 vNodesDisconnected
.remove(pnode
);
1015 if(vNodes
.size() != nPrevNodeCount
) {
1016 nPrevNodeCount
= vNodes
.size();
1017 uiInterface
.NotifyNumConnectionsChanged(nPrevNodeCount
);
1021 // Find which sockets have data to receive
1023 struct timeval timeout
;
1025 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
1030 FD_ZERO(&fdsetRecv
);
1031 FD_ZERO(&fdsetSend
);
1032 FD_ZERO(&fdsetError
);
1033 SOCKET hSocketMax
= 0;
1034 bool have_fds
= false;
1036 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
) {
1037 FD_SET(hListenSocket
.socket
, &fdsetRecv
);
1038 hSocketMax
= max(hSocketMax
, hListenSocket
.socket
);
1044 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1046 if (pnode
->hSocket
== INVALID_SOCKET
)
1048 FD_SET(pnode
->hSocket
, &fdsetError
);
1049 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
1052 // Implement the following logic:
1053 // * If there is data to send, select() for sending data. As this only
1054 // happens when optimistic write failed, we choose to first drain the
1055 // write buffer in this case before receiving more. This avoids
1056 // needlessly queueing received data, if the remote peer is not themselves
1057 // receiving data. This means properly utilizing TCP flow control signalling.
1058 // * Otherwise, if there is no (complete) message in the receive buffer,
1059 // or there is space left in the buffer, select() for receiving data.
1060 // * (if neither of the above applies, there is certainly one message
1061 // in the receiver buffer ready to be processed).
1062 // Together, that means that at least one of the following is always possible,
1063 // so we don't deadlock:
1064 // * We send some data.
1065 // * We wait for data to be received (and disconnect after timeout).
1066 // * We process a message in the buffer (message handler thread).
1068 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1069 if (lockSend
&& !pnode
->vSendMsg
.empty()) {
1070 FD_SET(pnode
->hSocket
, &fdsetSend
);
1075 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1077 pnode
->vRecvMsg
.empty() || !pnode
->vRecvMsg
.front().complete() ||
1078 pnode
->GetTotalRecvSize() <= ReceiveFloodSize()))
1079 FD_SET(pnode
->hSocket
, &fdsetRecv
);
1084 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
1085 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
1086 boost::this_thread::interruption_point();
1088 if (nSelect
== SOCKET_ERROR
)
1092 int nErr
= WSAGetLastError();
1093 LogPrintf("socket select error %s\n", NetworkErrorString(nErr
));
1094 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
1095 FD_SET(i
, &fdsetRecv
);
1097 FD_ZERO(&fdsetSend
);
1098 FD_ZERO(&fdsetError
);
1099 MilliSleep(timeout
.tv_usec
/1000);
1103 // Accept new connections
1105 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
)
1107 if (hListenSocket
.socket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
.socket
, &fdsetRecv
))
1109 AcceptConnection(hListenSocket
);
1114 // Service each socket
1116 vector
<CNode
*> vNodesCopy
;
1119 vNodesCopy
= vNodes
;
1120 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1123 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1125 boost::this_thread::interruption_point();
1130 if (pnode
->hSocket
== INVALID_SOCKET
)
1132 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
1134 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1138 // typical socket buffer is 8K-64K
1139 char pchBuf
[0x10000];
1140 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
1143 if (!pnode
->ReceiveMsgBytes(pchBuf
, nBytes
))
1144 pnode
->CloseSocketDisconnect();
1145 pnode
->nLastRecv
= GetTime();
1146 pnode
->nRecvBytes
+= nBytes
;
1147 pnode
->RecordBytesRecv(nBytes
);
1149 else if (nBytes
== 0)
1151 // socket closed gracefully
1152 if (!pnode
->fDisconnect
)
1153 LogPrint("net", "socket closed\n");
1154 pnode
->CloseSocketDisconnect();
1156 else if (nBytes
< 0)
1159 int nErr
= WSAGetLastError();
1160 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
1162 if (!pnode
->fDisconnect
)
1163 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr
));
1164 pnode
->CloseSocketDisconnect();
1174 if (pnode
->hSocket
== INVALID_SOCKET
)
1176 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
1178 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1180 SocketSendData(pnode
);
1184 // Inactivity checking
1186 int64_t nTime
= GetTime();
1187 if (nTime
- pnode
->nTimeConnected
> 60)
1189 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
1191 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0, pnode
->id
);
1192 pnode
->fDisconnect
= true;
1194 else if (nTime
- pnode
->nLastSend
> TIMEOUT_INTERVAL
)
1196 LogPrintf("socket sending timeout: %is\n", nTime
- pnode
->nLastSend
);
1197 pnode
->fDisconnect
= true;
1199 else if (nTime
- pnode
->nLastRecv
> (pnode
->nVersion
> BIP0031_VERSION
? TIMEOUT_INTERVAL
: 90*60))
1201 LogPrintf("socket receive timeout: %is\n", nTime
- pnode
->nLastRecv
);
1202 pnode
->fDisconnect
= true;
1204 else if (pnode
->nPingNonceSent
&& pnode
->nPingUsecStart
+ TIMEOUT_INTERVAL
* 1000000 < GetTimeMicros())
1206 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode
->nPingUsecStart
));
1207 pnode
->fDisconnect
= true;
1213 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1228 void ThreadMapPort()
1230 std::string port
= strprintf("%u", GetListenPort());
1231 const char * multicastif
= 0;
1232 const char * minissdpdpath
= 0;
1233 struct UPNPDev
* devlist
= 0;
1236 #ifndef UPNPDISCOVER_SUCCESS
1238 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1242 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1245 struct UPNPUrls urls
;
1246 struct IGDdatas data
;
1249 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1253 char externalIPAddress
[40];
1254 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1255 if(r
!= UPNPCOMMAND_SUCCESS
)
1256 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1259 if(externalIPAddress
[0])
1261 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1262 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1265 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1269 string strDesc
= "Bitcoin " + FormatFullVersion();
1273 #ifndef UPNPDISCOVER_SUCCESS
1275 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1276 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1279 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1280 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1283 if(r
!=UPNPCOMMAND_SUCCESS
)
1284 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1285 port
, port
, lanaddr
, r
, strupnperror(r
));
1287 LogPrintf("UPnP Port Mapping successful.\n");;
1289 MilliSleep(20*60*1000); // Refresh every 20 minutes
1292 catch (const boost::thread_interrupted
&)
1294 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1295 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r
);
1296 freeUPNPDevlist(devlist
); devlist
= 0;
1297 FreeUPNPUrls(&urls
);
1301 LogPrintf("No valid UPnP IGDs found\n");
1302 freeUPNPDevlist(devlist
); devlist
= 0;
1304 FreeUPNPUrls(&urls
);
1308 void MapPort(bool fUseUPnP
)
1310 static boost::thread
* upnp_thread
= NULL
;
1315 upnp_thread
->interrupt();
1316 upnp_thread
->join();
1319 upnp_thread
= new boost::thread(boost::bind(&TraceThread
<void (*)()>, "upnp", &ThreadMapPort
));
1321 else if (upnp_thread
) {
1322 upnp_thread
->interrupt();
1323 upnp_thread
->join();
1332 // Intentionally left blank.
1341 void ThreadDNSAddressSeed()
1343 // goal: only query DNS seeds if address need is acute
1344 if ((addrman
.size() > 0) &&
1345 (!GetBoolArg("-forcednsseed", false))) {
1346 MilliSleep(11 * 1000);
1349 if (vNodes
.size() >= 2) {
1350 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1355 const vector
<CDNSSeedData
> &vSeeds
= Params().DNSSeeds();
1358 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1360 BOOST_FOREACH(const CDNSSeedData
&seed
, vSeeds
) {
1361 if (HaveNameProxy()) {
1362 AddOneShot(seed
.host
);
1364 vector
<CNetAddr
> vIPs
;
1365 vector
<CAddress
> vAdd
;
1366 if (LookupHost(seed
.host
.c_str(), vIPs
))
1368 BOOST_FOREACH(const CNetAddr
& ip
, vIPs
)
1370 int nOneDay
= 24*3600;
1371 CAddress addr
= CAddress(CService(ip
, Params().GetDefaultPort()));
1372 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1373 vAdd
.push_back(addr
);
1377 addrman
.Add(vAdd
, CNetAddr(seed
.name
, true));
1381 LogPrintf("%d addresses found from DNS seeds\n", found
);
1395 void DumpAddresses()
1397 int64_t nStart
= GetTimeMillis();
1402 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1403 addrman
.size(), GetTimeMillis() - nStart
);
1410 if (CNode::BannedSetIsDirty())
1413 CNode::SetBannedSetDirty(false);
1417 void static ProcessOneShot()
1422 if (vOneShots
.empty())
1424 strDest
= vOneShots
.front();
1425 vOneShots
.pop_front();
1428 CSemaphoreGrant
grant(*semOutbound
, true);
1430 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1431 AddOneShot(strDest
);
1435 void ThreadOpenConnections()
1437 // Connect to specific addresses
1438 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1440 for (int64_t nLoop
= 0;; nLoop
++)
1443 BOOST_FOREACH(const std::string
& strAddr
, mapMultiArgs
["-connect"])
1446 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1447 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1456 // Initiate network connections
1457 int64_t nStart
= GetTime();
1464 CSemaphoreGrant
grant(*semOutbound
);
1465 boost::this_thread::interruption_point();
1467 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1468 if (addrman
.size() == 0 && (GetTime() - nStart
> 60)) {
1469 static bool done
= false;
1471 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1472 addrman
.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1478 // Choose an address to connect to based on most recently seen
1480 CAddress addrConnect
;
1482 // Only connect out to one peer per network group (/16 for IPv4).
1483 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1485 set
<vector
<unsigned char> > setConnected
;
1488 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1489 if (!pnode
->fInbound
) {
1490 setConnected
.insert(pnode
->addr
.GetGroup());
1496 int64_t nANow
= GetAdjustedTime();
1501 CAddrInfo addr
= addrman
.Select();
1503 // if we selected an invalid address, restart
1504 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1507 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1508 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1509 // already-connected network ranges, ...) before trying new addrman addresses.
1514 if (IsLimited(addr
))
1517 // only consider very recently tried nodes after 30 failed attempts
1518 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1521 // do not allow non-default ports, unless after 50 invalid addresses selected already
1522 if (addr
.GetPort() != Params().GetDefaultPort() && nTries
< 50)
1529 if (addrConnect
.IsValid())
1530 OpenNetworkConnection(addrConnect
, &grant
);
1534 void ThreadOpenAddedConnections()
1537 LOCK(cs_vAddedNodes
);
1538 vAddedNodes
= mapMultiArgs
["-addnode"];
1541 if (HaveNameProxy()) {
1543 list
<string
> lAddresses(0);
1545 LOCK(cs_vAddedNodes
);
1546 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1547 lAddresses
.push_back(strAddNode
);
1549 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1551 CSemaphoreGrant
grant(*semOutbound
);
1552 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1555 MilliSleep(120000); // Retry every 2 minutes
1559 for (unsigned int i
= 0; true; i
++)
1561 list
<string
> lAddresses(0);
1563 LOCK(cs_vAddedNodes
);
1564 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1565 lAddresses
.push_back(strAddNode
);
1568 list
<vector
<CService
> > lservAddressesToAdd(0);
1569 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1570 vector
<CService
> vservNode(0);
1571 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
1573 lservAddressesToAdd
.push_back(vservNode
);
1575 LOCK(cs_setservAddNodeAddresses
);
1576 BOOST_FOREACH(const CService
& serv
, vservNode
)
1577 setservAddNodeAddresses
.insert(serv
);
1581 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1582 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1585 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1586 for (list
<vector
<CService
> >::iterator it
= lservAddressesToAdd
.begin(); it
!= lservAddressesToAdd
.end(); it
++)
1587 BOOST_FOREACH(const CService
& addrNode
, *(it
))
1588 if (pnode
->addr
== addrNode
)
1590 it
= lservAddressesToAdd
.erase(it
);
1595 BOOST_FOREACH(vector
<CService
>& vserv
, lservAddressesToAdd
)
1597 CSemaphoreGrant
grant(*semOutbound
);
1598 OpenNetworkConnection(CAddress(vserv
[i
% vserv
.size()]), &grant
);
1601 MilliSleep(120000); // Retry every 2 minutes
1605 // if successful, this moves the passed grant to the constructed node
1606 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *pszDest
, bool fOneShot
)
1609 // Initiate outbound network connection
1611 boost::this_thread::interruption_point();
1613 if (IsLocal(addrConnect
) ||
1614 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1615 FindNode(addrConnect
.ToStringIPPort()))
1617 } else if (FindNode(std::string(pszDest
)))
1620 CNode
* pnode
= ConnectNode(addrConnect
, pszDest
);
1621 boost::this_thread::interruption_point();
1626 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1627 pnode
->fNetworkNode
= true;
1629 pnode
->fOneShot
= true;
1635 void ThreadMessageHandler()
1637 boost::mutex condition_mutex
;
1638 boost::unique_lock
<boost::mutex
> lock(condition_mutex
);
1640 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1643 vector
<CNode
*> vNodesCopy
;
1646 vNodesCopy
= vNodes
;
1647 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
) {
1652 // Poll the connected nodes for messages
1653 CNode
* pnodeTrickle
= NULL
;
1654 if (!vNodesCopy
.empty())
1655 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1659 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1661 if (pnode
->fDisconnect
)
1666 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1669 if (!g_signals
.ProcessMessages(pnode
))
1670 pnode
->CloseSocketDisconnect();
1672 if (pnode
->nSendSize
< SendBufferSize())
1674 if (!pnode
->vRecvGetData
.empty() || (!pnode
->vRecvMsg
.empty() && pnode
->vRecvMsg
[0].complete()))
1681 boost::this_thread::interruption_point();
1685 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1687 g_signals
.SendMessages(pnode
, pnode
== pnodeTrickle
|| pnode
->fWhitelisted
);
1689 boost::this_thread::interruption_point();
1694 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1699 messageHandlerCondition
.timed_wait(lock
, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1708 bool BindListenPort(const CService
&addrBind
, string
& strError
, bool fWhitelisted
)
1713 // Create socket for listening for incoming connections
1714 struct sockaddr_storage sockaddr
;
1715 socklen_t len
= sizeof(sockaddr
);
1716 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1718 strError
= strprintf("Error: Bind address family for %s not supported", addrBind
.ToString());
1719 LogPrintf("%s\n", strError
);
1723 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1724 if (hListenSocket
== INVALID_SOCKET
)
1726 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1727 LogPrintf("%s\n", strError
);
1730 if (!IsSelectableSocket(hListenSocket
))
1732 strError
= "Error: Couldn't create a listenable socket for incoming connections";
1733 LogPrintf("%s\n", strError
);
1740 // Different way of disabling SIGPIPE on BSD
1741 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1743 // Allow binding if the port is still in TIME_WAIT state after
1744 // the program was closed and restarted. Not an issue on windows!
1745 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1748 // Set to non-blocking, incoming connections will also inherit this
1749 if (!SetSocketNonBlocking(hListenSocket
, true)) {
1750 strError
= strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1751 LogPrintf("%s\n", strError
);
1755 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1756 // and enable it by default or not. Try to enable it, if possible.
1757 if (addrBind
.IsIPv6()) {
1760 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (const char*)&nOne
, sizeof(int));
1762 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1766 int nProtLevel
= PROTECTION_LEVEL_UNRESTRICTED
;
1767 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_PROTECTION_LEVEL
, (const char*)&nProtLevel
, sizeof(int));
1771 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1773 int nErr
= WSAGetLastError();
1774 if (nErr
== WSAEADDRINUSE
)
1775 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind
.ToString());
1777 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind
.ToString(), NetworkErrorString(nErr
));
1778 LogPrintf("%s\n", strError
);
1779 CloseSocket(hListenSocket
);
1782 LogPrintf("Bound to %s\n", addrBind
.ToString());
1784 // Listen for incoming connections
1785 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1787 strError
= strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1788 LogPrintf("%s\n", strError
);
1789 CloseSocket(hListenSocket
);
1793 vhListenSocket
.push_back(ListenSocket(hListenSocket
, fWhitelisted
));
1795 if (addrBind
.IsRoutable() && fDiscover
&& !fWhitelisted
)
1796 AddLocal(addrBind
, LOCAL_BIND
);
1801 void static Discover(boost::thread_group
& threadGroup
)
1807 // Get local host IP
1808 char pszHostName
[256] = "";
1809 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1811 vector
<CNetAddr
> vaddr
;
1812 if (LookupHost(pszHostName
, vaddr
))
1814 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1816 if (AddLocal(addr
, LOCAL_IF
))
1817 LogPrintf("%s: %s - %s\n", __func__
, pszHostName
, addr
.ToString());
1822 // Get local host ip
1823 struct ifaddrs
* myaddrs
;
1824 if (getifaddrs(&myaddrs
) == 0)
1826 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1828 if (ifa
->ifa_addr
== NULL
) continue;
1829 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1830 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1831 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1832 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1834 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1835 CNetAddr
addr(s4
->sin_addr
);
1836 if (AddLocal(addr
, LOCAL_IF
))
1837 LogPrintf("%s: IPv4 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1839 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1841 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1842 CNetAddr
addr(s6
->sin6_addr
);
1843 if (AddLocal(addr
, LOCAL_IF
))
1844 LogPrintf("%s: IPv6 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1847 freeifaddrs(myaddrs
);
1852 void StartNode(boost::thread_group
& threadGroup
, CScheduler
& scheduler
)
1854 uiInterface
.InitMessage(_("Loading addresses..."));
1855 // Load addresses for peers.dat
1856 int64_t nStart
= GetTimeMillis();
1859 if (!adb
.Read(addrman
))
1860 LogPrintf("Invalid or missing peers.dat; recreating\n");
1863 //try to read stored banlist
1866 if (!bandb
.Read(banmap
))
1867 LogPrintf("Invalid or missing banlist.dat; recreating\n");
1869 CNode::SetBanned(banmap
); //thread save setter
1870 CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
1871 CNode::SweepBanned(); //sweap out unused entries
1873 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1874 addrman
.size(), GetTimeMillis() - nStart
);
1875 fAddressesInitialized
= true;
1877 if (semOutbound
== NULL
) {
1878 // initialize semaphore
1879 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, nMaxConnections
);
1880 semOutbound
= new CSemaphore(nMaxOutbound
);
1883 if (pnodeLocalHost
== NULL
)
1884 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1886 Discover(threadGroup
);
1892 if (!GetBoolArg("-dnsseed", true))
1893 LogPrintf("DNS seeding disabled\n");
1895 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "dnsseed", &ThreadDNSAddressSeed
));
1897 // Map ports with UPnP
1898 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP
));
1900 // Send and receive from sockets, accept connections
1901 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "net", &ThreadSocketHandler
));
1903 // Initiate outbound connections from -addnode
1904 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "addcon", &ThreadOpenAddedConnections
));
1906 // Initiate outbound connections
1907 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "opencon", &ThreadOpenConnections
));
1910 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "msghand", &ThreadMessageHandler
));
1912 // Dump network addresses
1913 scheduler
.scheduleEvery(&DumpData
, DUMP_ADDRESSES_INTERVAL
);
1918 LogPrintf("StopNode()\n");
1921 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1922 semOutbound
->post();
1924 if (fAddressesInitialized
)
1927 fAddressesInitialized
= false;
1941 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1942 if (pnode
->hSocket
!= INVALID_SOCKET
)
1943 CloseSocket(pnode
->hSocket
);
1944 BOOST_FOREACH(ListenSocket
& hListenSocket
, vhListenSocket
)
1945 if (hListenSocket
.socket
!= INVALID_SOCKET
)
1946 if (!CloseSocket(hListenSocket
.socket
))
1947 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1949 // clean up some globals (to help leak detection)
1950 BOOST_FOREACH(CNode
*pnode
, vNodes
)
1952 BOOST_FOREACH(CNode
*pnode
, vNodesDisconnected
)
1955 vNodesDisconnected
.clear();
1956 vhListenSocket
.clear();
1959 delete pnodeLocalHost
;
1960 pnodeLocalHost
= NULL
;
1963 // Shutdown Windows Sockets
1968 instance_of_cnetcleanup
;
1976 void RelayTransaction(const CTransaction
& tx
)
1978 CDataStream
ss(SER_NETWORK
, PROTOCOL_VERSION
);
1981 RelayTransaction(tx
, ss
);
1984 void RelayTransaction(const CTransaction
& tx
, const CDataStream
& ss
)
1986 CInv
inv(MSG_TX
, tx
.GetHash());
1989 // Expire old relay messages
1990 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
1992 mapRelay
.erase(vRelayExpiration
.front().second
);
1993 vRelayExpiration
.pop_front();
1996 // Save original serialized message so newer versions are preserved
1997 mapRelay
.insert(std::make_pair(inv
, ss
));
1998 vRelayExpiration
.push_back(std::make_pair(GetTime() + 15 * 60, inv
));
2001 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2003 if(!pnode
->fRelayTxes
)
2005 LOCK(pnode
->cs_filter
);
2008 if (pnode
->pfilter
->IsRelevantAndUpdate(tx
))
2009 pnode
->PushInventory(inv
);
2011 pnode
->PushInventory(inv
);
2015 void CNode::RecordBytesRecv(uint64_t bytes
)
2017 LOCK(cs_totalBytesRecv
);
2018 nTotalBytesRecv
+= bytes
;
2021 void CNode::RecordBytesSent(uint64_t bytes
)
2023 LOCK(cs_totalBytesSent
);
2024 nTotalBytesSent
+= bytes
;
2027 uint64_t CNode::GetTotalBytesRecv()
2029 LOCK(cs_totalBytesRecv
);
2030 return nTotalBytesRecv
;
2033 uint64_t CNode::GetTotalBytesSent()
2035 LOCK(cs_totalBytesSent
);
2036 return nTotalBytesSent
;
2039 void CNode::Fuzz(int nChance
)
2041 if (!fSuccessfullyConnected
) return; // Don't fuzz initial handshake
2042 if (GetRand(nChance
) != 0) return; // Fuzz 1 of every nChance messages
2047 // xor a random byte with a random value:
2048 if (!ssSend
.empty()) {
2049 CDataStream::size_type pos
= GetRand(ssSend
.size());
2050 ssSend
[pos
] ^= (unsigned char)(GetRand(256));
2054 // delete a random byte:
2055 if (!ssSend
.empty()) {
2056 CDataStream::size_type pos
= GetRand(ssSend
.size());
2057 ssSend
.erase(ssSend
.begin()+pos
);
2061 // insert a random byte at a random position
2063 CDataStream::size_type pos
= GetRand(ssSend
.size());
2064 char ch
= (char)GetRand(256);
2065 ssSend
.insert(ssSend
.begin()+pos
, ch
);
2069 // Chance of more than one change half the time:
2070 // (more changes exponentially less likely):
2080 pathAddr
= GetDataDir() / "peers.dat";
2083 bool CAddrDB::Write(const CAddrMan
& addr
)
2085 // Generate random temporary filename
2086 unsigned short randv
= 0;
2087 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2088 std::string tmpfn
= strprintf("peers.dat.%04x", randv
);
2090 // serialize addresses, checksum data up to that point, then append csum
2091 CDataStream
ssPeers(SER_DISK
, CLIENT_VERSION
);
2092 ssPeers
<< FLATDATA(Params().MessageStart());
2094 uint256 hash
= Hash(ssPeers
.begin(), ssPeers
.end());
2097 // open temp output file, and associate with CAutoFile
2098 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2099 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2100 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2101 if (fileout
.IsNull())
2102 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2104 // Write and commit header, data
2108 catch (const std::exception
& e
) {
2109 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2111 FileCommit(fileout
.Get());
2114 // replace existing peers.dat, if any, with new peers.dat.XXXX
2115 if (!RenameOver(pathTmp
, pathAddr
))
2116 return error("%s: Rename-into-place failed", __func__
);
2121 bool CAddrDB::Read(CAddrMan
& addr
)
2123 // open input file, and associate with CAutoFile
2124 FILE *file
= fopen(pathAddr
.string().c_str(), "rb");
2125 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2126 if (filein
.IsNull())
2127 return error("%s: Failed to open file %s", __func__
, pathAddr
.string());
2129 // use file size to size memory buffer
2130 uint64_t fileSize
= boost::filesystem::file_size(pathAddr
);
2131 uint64_t dataSize
= 0;
2132 // Don't try to resize to a negative number if file is small
2133 if (fileSize
>= sizeof(uint256
))
2134 dataSize
= fileSize
- sizeof(uint256
);
2135 vector
<unsigned char> vchData
;
2136 vchData
.resize(dataSize
);
2139 // read data and checksum from file
2141 filein
.read((char *)&vchData
[0], dataSize
);
2144 catch (const std::exception
& e
) {
2145 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2149 CDataStream
ssPeers(vchData
, SER_DISK
, CLIENT_VERSION
);
2151 // verify stored checksum matches input data
2152 uint256 hashTmp
= Hash(ssPeers
.begin(), ssPeers
.end());
2153 if (hashIn
!= hashTmp
)
2154 return error("%s: Checksum mismatch, data corrupted", __func__
);
2156 unsigned char pchMsgTmp
[4];
2158 // de-serialize file header (network specific magic number) and ..
2159 ssPeers
>> FLATDATA(pchMsgTmp
);
2161 // ... verify the network matches ours
2162 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2163 return error("%s: Invalid network magic number", __func__
);
2165 // de-serialize address data into one CAddrMan object
2168 catch (const std::exception
& e
) {
2169 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2175 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2176 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2178 CNode::CNode(SOCKET hSocketIn
, const CAddress
& addrIn
, const std::string
& addrNameIn
, bool fInboundIn
) :
2179 ssSend(SER_NETWORK
, INIT_PROTO_VERSION
),
2180 addrKnown(5000, 0.001),
2181 setInventoryKnown(SendBufferSize() / 1000)
2184 hSocket
= hSocketIn
;
2185 nRecvVersion
= INIT_PROTO_VERSION
;
2190 nTimeConnected
= GetTime();
2193 addrName
= addrNameIn
== "" ? addr
.ToStringIPPort() : addrNameIn
;
2196 fWhitelisted
= false;
2198 fClient
= false; // set by version message
2199 fInbound
= fInboundIn
;
2200 fNetworkNode
= false;
2201 fSuccessfullyConnected
= false;
2202 fDisconnect
= false;
2206 hashContinue
= uint256();
2207 nStartingHeight
= -1;
2210 pfilter
= new CBloomFilter();
2214 fPingQueued
= false;
2217 LOCK(cs_nLastNodeId
);
2222 LogPrint("net", "Added connection to %s peer=%d\n", addrName
, id
);
2224 LogPrint("net", "Added connection peer=%d\n", id
);
2226 // Be shy and don't send version until we hear
2227 if (hSocket
!= INVALID_SOCKET
&& !fInbound
)
2230 GetNodeSignals().InitializeNode(GetId(), this);
2235 CloseSocket(hSocket
);
2240 GetNodeSignals().FinalizeNode(GetId());
2243 void CNode::AskFor(const CInv
& inv
)
2245 if (mapAskFor
.size() > MAPASKFOR_MAX_SZ
)
2247 // We're using mapAskFor as a priority queue,
2248 // the key is the earliest time the request can be sent
2249 int64_t nRequestTime
;
2250 limitedmap
<CInv
, int64_t>::const_iterator it
= mapAlreadyAskedFor
.find(inv
);
2251 if (it
!= mapAlreadyAskedFor
.end())
2252 nRequestTime
= it
->second
;
2255 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv
.ToString(), nRequestTime
, DateTimeStrFormat("%H:%M:%S", nRequestTime
/1000000), id
);
2257 // Make sure not to reuse time indexes to keep things in the same order
2258 int64_t nNow
= GetTimeMicros() - 1000000;
2259 static int64_t nLastTime
;
2261 nNow
= std::max(nNow
, nLastTime
);
2264 // Each retry is 2 minutes after the last
2265 nRequestTime
= std::max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
2266 if (it
!= mapAlreadyAskedFor
.end())
2267 mapAlreadyAskedFor
.update(it
, nRequestTime
);
2269 mapAlreadyAskedFor
.insert(std::make_pair(inv
, nRequestTime
));
2270 mapAskFor
.insert(std::make_pair(nRequestTime
, inv
));
2273 void CNode::BeginMessage(const char* pszCommand
) EXCLUSIVE_LOCK_FUNCTION(cs_vSend
)
2275 ENTER_CRITICAL_SECTION(cs_vSend
);
2276 assert(ssSend
.size() == 0);
2277 ssSend
<< CMessageHeader(Params().MessageStart(), pszCommand
, 0);
2278 LogPrint("net", "sending: %s ", SanitizeString(pszCommand
));
2281 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend
)
2285 LEAVE_CRITICAL_SECTION(cs_vSend
);
2287 LogPrint("net", "(aborted)\n");
2290 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend
)
2292 // The -*messagestest options are intentionally not documented in the help message,
2293 // since they are only used during development to debug the networking code and are
2294 // not intended for end-users.
2295 if (mapArgs
.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2297 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2301 if (mapArgs
.count("-fuzzmessagestest"))
2302 Fuzz(GetArg("-fuzzmessagestest", 10));
2304 if (ssSend
.size() == 0)
2306 LEAVE_CRITICAL_SECTION(cs_vSend
);
2310 unsigned int nSize
= ssSend
.size() - CMessageHeader::HEADER_SIZE
;
2311 WriteLE32((uint8_t*)&ssSend
[CMessageHeader::MESSAGE_SIZE_OFFSET
], nSize
);
2314 uint256 hash
= Hash(ssSend
.begin() + CMessageHeader::HEADER_SIZE
, ssSend
.end());
2315 unsigned int nChecksum
= 0;
2316 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
2317 assert(ssSend
.size () >= CMessageHeader::CHECKSUM_OFFSET
+ sizeof(nChecksum
));
2318 memcpy((char*)&ssSend
[CMessageHeader::CHECKSUM_OFFSET
], &nChecksum
, sizeof(nChecksum
));
2320 LogPrint("net", "(%d bytes) peer=%d\n", nSize
, id
);
2322 std::deque
<CSerializeData
>::iterator it
= vSendMsg
.insert(vSendMsg
.end(), CSerializeData());
2323 ssSend
.GetAndClear(*it
);
2324 nSendSize
+= (*it
).size();
2326 // If write queue empty, attempt "optimistic write"
2327 if (it
== vSendMsg
.begin())
2328 SocketSendData(this);
2330 LEAVE_CRITICAL_SECTION(cs_vSend
);
2339 pathBanlist
= GetDataDir() / "banlist.dat";
2342 bool CBanDB::Write(const banmap_t
& banSet
)
2344 // Generate random temporary filename
2345 unsigned short randv
= 0;
2346 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2347 std::string tmpfn
= strprintf("banlist.dat.%04x", randv
);
2349 // serialize banlist, checksum data up to that point, then append csum
2350 CDataStream
ssBanlist(SER_DISK
, CLIENT_VERSION
);
2351 ssBanlist
<< FLATDATA(Params().MessageStart());
2352 ssBanlist
<< banSet
;
2353 uint256 hash
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2356 // open temp output file, and associate with CAutoFile
2357 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2358 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2359 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2360 if (fileout
.IsNull())
2361 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2363 // Write and commit header, data
2365 fileout
<< ssBanlist
;
2367 catch (const std::exception
& e
) {
2368 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2370 FileCommit(fileout
.Get());
2373 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2374 if (!RenameOver(pathTmp
, pathBanlist
))
2375 return error("%s: Rename-into-place failed", __func__
);
2380 bool CBanDB::Read(banmap_t
& banSet
)
2382 // open input file, and associate with CAutoFile
2383 FILE *file
= fopen(pathBanlist
.string().c_str(), "rb");
2384 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2385 if (filein
.IsNull())
2386 return error("%s: Failed to open file %s", __func__
, pathBanlist
.string());
2388 // use file size to size memory buffer
2389 uint64_t fileSize
= boost::filesystem::file_size(pathBanlist
);
2390 uint64_t dataSize
= 0;
2391 // Don't try to resize to a negative number if file is small
2392 if (fileSize
>= sizeof(uint256
))
2393 dataSize
= fileSize
- sizeof(uint256
);
2394 vector
<unsigned char> vchData
;
2395 vchData
.resize(dataSize
);
2398 // read data and checksum from file
2400 filein
.read((char *)&vchData
[0], dataSize
);
2403 catch (const std::exception
& e
) {
2404 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2408 CDataStream
ssBanlist(vchData
, SER_DISK
, CLIENT_VERSION
);
2410 // verify stored checksum matches input data
2411 uint256 hashTmp
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2412 if (hashIn
!= hashTmp
)
2413 return error("%s: Checksum mismatch, data corrupted", __func__
);
2415 unsigned char pchMsgTmp
[4];
2417 // de-serialize file header (network specific magic number) and ..
2418 ssBanlist
>> FLATDATA(pchMsgTmp
);
2420 // ... verify the network matches ours
2421 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2422 return error("%s: Invalid network magic number", __func__
);
2424 // de-serialize address data into one CAddrMan object
2425 ssBanlist
>> banSet
;
2427 catch (const std::exception
& e
) {
2428 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2436 int64_t nStart
= GetTimeMillis();
2438 CNode::SweepBanned(); //clean unused entries (if bantime has expired)
2442 CNode::GetBanned(banmap
);
2443 bandb
.Write(banmap
);
2445 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
2446 banmap
.size(), GetTimeMillis() - nStart
);