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 pnode
->PushAddress(addrLocal
);
224 void SetReachable(enum Network net
, bool fFlag
)
226 LOCK(cs_mapLocalHost
);
227 vfReachable
[net
] = fFlag
;
228 if (net
== NET_IPV6
&& fFlag
)
229 vfReachable
[NET_IPV4
] = true;
232 // learn a new local address
233 bool AddLocal(const CService
& addr
, int nScore
)
235 if (!addr
.IsRoutable())
238 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
244 LogPrintf("AddLocal(%s,%i)\n", addr
.ToString(), nScore
);
247 LOCK(cs_mapLocalHost
);
248 bool fAlready
= mapLocalHost
.count(addr
) > 0;
249 LocalServiceInfo
&info
= mapLocalHost
[addr
];
250 if (!fAlready
|| nScore
>= info
.nScore
) {
251 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
252 info
.nPort
= addr
.GetPort();
254 SetReachable(addr
.GetNetwork());
260 bool AddLocal(const CNetAddr
&addr
, int nScore
)
262 return AddLocal(CService(addr
, GetListenPort()), nScore
);
265 /** Make a particular network entirely off-limits (no automatic connects to it) */
266 void SetLimited(enum Network net
, bool fLimited
)
268 if (net
== NET_UNROUTABLE
)
270 LOCK(cs_mapLocalHost
);
271 vfLimited
[net
] = fLimited
;
274 bool IsLimited(enum Network net
)
276 LOCK(cs_mapLocalHost
);
277 return vfLimited
[net
];
280 bool IsLimited(const CNetAddr
&addr
)
282 return IsLimited(addr
.GetNetwork());
285 /** vote for a local address */
286 bool SeenLocal(const CService
& addr
)
289 LOCK(cs_mapLocalHost
);
290 if (mapLocalHost
.count(addr
) == 0)
292 mapLocalHost
[addr
].nScore
++;
298 /** check whether a given address is potentially local */
299 bool IsLocal(const CService
& addr
)
301 LOCK(cs_mapLocalHost
);
302 return mapLocalHost
.count(addr
) > 0;
305 /** check whether a given network is one we can probably connect to */
306 bool IsReachable(enum Network net
)
308 LOCK(cs_mapLocalHost
);
309 return vfReachable
[net
] && !vfLimited
[net
];
312 /** check whether a given address is in a network we can probably connect to */
313 bool IsReachable(const CNetAddr
& addr
)
315 enum Network net
= addr
.GetNetwork();
316 return IsReachable(net
);
319 void AddressCurrentlyConnected(const CService
& addr
)
321 addrman
.Connected(addr
);
325 uint64_t CNode::nTotalBytesRecv
= 0;
326 uint64_t CNode::nTotalBytesSent
= 0;
327 CCriticalSection
CNode::cs_totalBytesRecv
;
328 CCriticalSection
CNode::cs_totalBytesSent
;
330 uint64_t CNode::nMaxOutboundLimit
= 0;
331 uint64_t CNode::nMaxOutboundTotalBytesSentInCycle
= 0;
332 uint64_t CNode::nMaxOutboundTimeframe
= 60*60*24; //1 day
333 uint64_t CNode::nMaxOutboundCycleStartTime
= 0;
335 CNode
* FindNode(const CNetAddr
& ip
)
338 BOOST_FOREACH(CNode
* pnode
, vNodes
)
339 if ((CNetAddr
)pnode
->addr
== ip
)
344 CNode
* FindNode(const CSubNet
& subNet
)
347 BOOST_FOREACH(CNode
* pnode
, vNodes
)
348 if (subNet
.Match((CNetAddr
)pnode
->addr
))
353 CNode
* FindNode(const std::string
& addrName
)
356 BOOST_FOREACH(CNode
* pnode
, vNodes
)
357 if (pnode
->addrName
== addrName
)
362 CNode
* FindNode(const CService
& addr
)
365 BOOST_FOREACH(CNode
* pnode
, vNodes
)
366 if ((CService
)pnode
->addr
== addr
)
371 CNode
* ConnectNode(CAddress addrConnect
, const char *pszDest
)
373 if (pszDest
== NULL
) {
374 if (IsLocal(addrConnect
))
377 // Look for an existing connection
378 CNode
* pnode
= FindNode((CService
)addrConnect
);
387 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
388 pszDest
? pszDest
: addrConnect
.ToString(),
389 pszDest
? 0.0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
393 bool proxyConnectionFailed
= false;
394 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, Params().GetDefaultPort(), nConnectTimeout
, &proxyConnectionFailed
) :
395 ConnectSocket(addrConnect
, hSocket
, nConnectTimeout
, &proxyConnectionFailed
))
397 if (!IsSelectableSocket(hSocket
)) {
398 LogPrintf("Cannot create connection: non-selectable socket created (fd >= FD_SETSIZE ?)\n");
399 CloseSocket(hSocket
);
403 addrman
.Attempt(addrConnect
);
406 CNode
* pnode
= new CNode(hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
411 vNodes
.push_back(pnode
);
414 pnode
->nTimeConnected
= GetTime();
417 } else if (!proxyConnectionFailed
) {
418 // If connecting to the node failed, and failure is not caused by a problem connecting to
419 // the proxy, mark this as an attempt.
420 addrman
.Attempt(addrConnect
);
426 void CNode::CloseSocketDisconnect()
429 if (hSocket
!= INVALID_SOCKET
)
431 LogPrint("net", "disconnecting peer=%d\n", id
);
432 CloseSocket(hSocket
);
435 // in case this fails, we'll empty the recv buffer when the CNode is deleted
436 TRY_LOCK(cs_vRecvMsg
, lockRecv
);
441 void CNode::PushVersion()
443 int nBestHeight
= g_signals
.GetHeight().get_value_or(0);
445 int64_t nTime
= (fInbound
? GetAdjustedTime() : GetTime());
446 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService("0.0.0.0",0)));
447 CAddress addrMe
= GetLocalAddress(&addr
);
448 GetRandBytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
450 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), addrYou
.ToString(), id
);
452 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), id
);
453 PushMessage("version", PROTOCOL_VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
454 nLocalHostNonce
, strSubVersion
, nBestHeight
, true);
461 banmap_t
CNode::setBanned
;
462 CCriticalSection
CNode::cs_setBanned
;
463 bool CNode::setBannedIsDirty
;
465 void CNode::ClearBanned()
469 setBannedIsDirty
= true;
472 bool CNode::IsBanned(CNetAddr ip
)
474 bool fResult
= false;
477 for (banmap_t::iterator it
= setBanned
.begin(); it
!= setBanned
.end(); it
++)
479 CSubNet subNet
= (*it
).first
;
480 CBanEntry banEntry
= (*it
).second
;
482 if(subNet
.Match(ip
) && GetTime() < banEntry
.nBanUntil
)
489 bool CNode::IsBanned(CSubNet subnet
)
491 bool fResult
= false;
494 banmap_t::iterator i
= setBanned
.find(subnet
);
495 if (i
!= setBanned
.end())
497 CBanEntry banEntry
= (*i
).second
;
498 if (GetTime() < banEntry
.nBanUntil
)
505 void CNode::Ban(const CNetAddr
& addr
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
506 CSubNet
subNet(addr
);
507 Ban(subNet
, banReason
, bantimeoffset
, sinceUnixEpoch
);
510 void CNode::Ban(const CSubNet
& subNet
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
511 CBanEntry
banEntry(GetTime());
512 banEntry
.banReason
= banReason
;
513 if (bantimeoffset
<= 0)
515 bantimeoffset
= GetArg("-bantime", 60*60*24); // Default 24-hour ban
516 sinceUnixEpoch
= false;
518 banEntry
.nBanUntil
= (sinceUnixEpoch
? 0 : GetTime() )+bantimeoffset
;
522 if (setBanned
[subNet
].nBanUntil
< banEntry
.nBanUntil
)
523 setBanned
[subNet
] = banEntry
;
525 setBannedIsDirty
= true;
528 bool CNode::Unban(const CNetAddr
&addr
) {
529 CSubNet
subNet(addr
);
530 return Unban(subNet
);
533 bool CNode::Unban(const CSubNet
&subNet
) {
535 if (setBanned
.erase(subNet
))
537 setBannedIsDirty
= true;
543 void CNode::GetBanned(banmap_t
&banMap
)
546 banMap
= setBanned
; //create a thread safe copy
549 void CNode::SetBanned(const banmap_t
&banMap
)
553 setBannedIsDirty
= true;
556 void CNode::SweepBanned()
558 int64_t now
= GetTime();
561 banmap_t::iterator it
= setBanned
.begin();
562 while(it
!= setBanned
.end())
564 CBanEntry banEntry
= (*it
).second
;
565 if(now
> banEntry
.nBanUntil
)
567 setBanned
.erase(it
++);
568 setBannedIsDirty
= true;
575 bool CNode::BannedSetIsDirty()
578 return setBannedIsDirty
;
581 void CNode::SetBannedSetDirty(bool dirty
)
583 LOCK(cs_setBanned
); //reuse setBanned lock for the isDirty flag
584 setBannedIsDirty
= dirty
;
588 std::vector
<CSubNet
> CNode::vWhitelistedRange
;
589 CCriticalSection
CNode::cs_vWhitelistedRange
;
591 bool CNode::IsWhitelistedRange(const CNetAddr
&addr
) {
592 LOCK(cs_vWhitelistedRange
);
593 BOOST_FOREACH(const CSubNet
& subnet
, vWhitelistedRange
) {
594 if (subnet
.Match(addr
))
600 void CNode::AddWhitelistedRange(const CSubNet
&subnet
) {
601 LOCK(cs_vWhitelistedRange
);
602 vWhitelistedRange
.push_back(subnet
);
606 #define X(name) stats.name = name
607 void CNode::copyStats(CNodeStats
&stats
)
609 stats
.nodeid
= this->GetId();
624 // It is common for nodes with good ping times to suddenly become lagged,
625 // due to a new block arriving or other large transfer.
626 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
627 // since pingtime does not update until the ping is complete, which might take a while.
628 // So, if a ping is taking an unusually long time in flight,
629 // the caller can immediately detect that this is happening.
630 int64_t nPingUsecWait
= 0;
631 if ((0 != nPingNonceSent
) && (0 != nPingUsecStart
)) {
632 nPingUsecWait
= GetTimeMicros() - nPingUsecStart
;
635 // 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 :)
636 stats
.dPingTime
= (((double)nPingUsecTime
) / 1e6
);
637 stats
.dPingMin
= (((double)nMinPingUsecTime
) / 1e6
);
638 stats
.dPingWait
= (((double)nPingUsecWait
) / 1e6
);
640 // Leave string empty if addrLocal invalid (not filled in yet)
641 stats
.addrLocal
= addrLocal
.IsValid() ? addrLocal
.ToString() : "";
645 // requires LOCK(cs_vRecvMsg)
646 bool CNode::ReceiveMsgBytes(const char *pch
, unsigned int nBytes
)
650 // get current incomplete message, or create a new one
651 if (vRecvMsg
.empty() ||
652 vRecvMsg
.back().complete())
653 vRecvMsg
.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK
, nRecvVersion
));
655 CNetMessage
& msg
= vRecvMsg
.back();
657 // absorb network data
660 handled
= msg
.readHeader(pch
, nBytes
);
662 handled
= msg
.readData(pch
, nBytes
);
667 if (msg
.in_data
&& msg
.hdr
.nMessageSize
> MAX_PROTOCOL_MESSAGE_LENGTH
) {
668 LogPrint("net", "Oversized message from peer=%i, disconnecting\n", GetId());
675 if (msg
.complete()) {
676 msg
.nTime
= GetTimeMicros();
677 messageHandlerCondition
.notify_one();
684 int CNetMessage::readHeader(const char *pch
, unsigned int nBytes
)
686 // copy data to temporary parsing buffer
687 unsigned int nRemaining
= 24 - nHdrPos
;
688 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
690 memcpy(&hdrbuf
[nHdrPos
], pch
, nCopy
);
693 // if header incomplete, exit
697 // deserialize to CMessageHeader
701 catch (const std::exception
&) {
705 // reject messages larger than MAX_SIZE
706 if (hdr
.nMessageSize
> MAX_SIZE
)
709 // switch state to reading message data
715 int CNetMessage::readData(const char *pch
, unsigned int nBytes
)
717 unsigned int nRemaining
= hdr
.nMessageSize
- nDataPos
;
718 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
720 if (vRecv
.size() < nDataPos
+ nCopy
) {
721 // Allocate up to 256 KiB ahead, but never more than the total message size.
722 vRecv
.resize(std::min(hdr
.nMessageSize
, nDataPos
+ nCopy
+ 256 * 1024));
725 memcpy(&vRecv
[nDataPos
], pch
, nCopy
);
739 // requires LOCK(cs_vSend)
740 void SocketSendData(CNode
*pnode
)
742 std::deque
<CSerializeData
>::iterator it
= pnode
->vSendMsg
.begin();
744 while (it
!= pnode
->vSendMsg
.end()) {
745 const CSerializeData
&data
= *it
;
746 assert(data
.size() > pnode
->nSendOffset
);
747 int nBytes
= send(pnode
->hSocket
, &data
[pnode
->nSendOffset
], data
.size() - pnode
->nSendOffset
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
749 pnode
->nLastSend
= GetTime();
750 pnode
->nSendBytes
+= nBytes
;
751 pnode
->nSendOffset
+= nBytes
;
752 pnode
->RecordBytesSent(nBytes
);
753 if (pnode
->nSendOffset
== data
.size()) {
754 pnode
->nSendOffset
= 0;
755 pnode
->nSendSize
-= data
.size();
758 // could not send full message; stop sending more
764 int nErr
= WSAGetLastError();
765 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
767 LogPrintf("socket send error %s\n", NetworkErrorString(nErr
));
768 pnode
->CloseSocketDisconnect();
771 // couldn't send anything at all
776 if (it
== pnode
->vSendMsg
.end()) {
777 assert(pnode
->nSendOffset
== 0);
778 assert(pnode
->nSendSize
== 0);
780 pnode
->vSendMsg
.erase(pnode
->vSendMsg
.begin(), it
);
783 static list
<CNode
*> vNodesDisconnected
;
787 CNodeRef(CNode
*pnode
) : _pnode(pnode
) {
797 CNode
& operator *() const {return *_pnode
;};
798 CNode
* operator ->() const {return _pnode
;};
800 CNodeRef
& operator =(const CNodeRef
& other
)
802 if (this != &other
) {
806 _pnode
= other
._pnode
;
812 CNodeRef(const CNodeRef
& other
):
822 static bool ReverseCompareNodeMinPingTime(const CNodeRef
&a
, const CNodeRef
&b
)
824 return a
->nMinPingUsecTime
> b
->nMinPingUsecTime
;
827 static bool ReverseCompareNodeTimeConnected(const CNodeRef
&a
, const CNodeRef
&b
)
829 return a
->nTimeConnected
> b
->nTimeConnected
;
832 class CompareNetGroupKeyed
834 std::vector
<unsigned char> vchSecretKey
;
836 CompareNetGroupKeyed()
838 vchSecretKey
.resize(32, 0);
839 GetRandBytes(vchSecretKey
.data(), vchSecretKey
.size());
842 bool operator()(const CNodeRef
&a
, const CNodeRef
&b
)
844 std::vector
<unsigned char> vchGroupA
, vchGroupB
;
845 CSHA256 hashA
, hashB
;
846 std::vector
<unsigned char> vchA(32), vchB(32);
848 vchGroupA
= a
->addr
.GetGroup();
849 vchGroupB
= b
->addr
.GetGroup();
851 hashA
.Write(begin_ptr(vchGroupA
), vchGroupA
.size());
852 hashB
.Write(begin_ptr(vchGroupB
), vchGroupB
.size());
854 hashA
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
855 hashB
.Write(begin_ptr(vchSecretKey
), vchSecretKey
.size());
857 hashA
.Finalize(begin_ptr(vchA
));
858 hashB
.Finalize(begin_ptr(vchB
));
864 static bool AttemptToEvictConnection(bool fPreferNewConnection
) {
865 std::vector
<CNodeRef
> vEvictionCandidates
;
869 BOOST_FOREACH(CNode
*node
, vNodes
) {
870 if (node
->fWhitelisted
)
874 if (node
->fDisconnect
)
876 if (node
->addr
.IsLocal())
878 vEvictionCandidates
.push_back(CNodeRef(node
));
882 if (vEvictionCandidates
.empty()) return false;
884 // Protect connections with certain characteristics
886 // Deterministically select 4 peers to protect by netgroup.
887 // An attacker cannot predict which netgroups will be protected.
888 static CompareNetGroupKeyed comparerNetGroupKeyed
;
889 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), comparerNetGroupKeyed
);
890 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(4, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
892 if (vEvictionCandidates
.empty()) return false;
894 // Protect the 8 nodes with the best ping times.
895 // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
896 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeMinPingTime
);
897 vEvictionCandidates
.erase(vEvictionCandidates
.end() - std::min(8, static_cast<int>(vEvictionCandidates
.size())), vEvictionCandidates
.end());
899 if (vEvictionCandidates
.empty()) return false;
901 // Protect the half of the remaining nodes which have been connected the longest.
902 // This replicates the existing implicit behavior.
903 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
904 vEvictionCandidates
.erase(vEvictionCandidates
.end() - static_cast<int>(vEvictionCandidates
.size() / 2), vEvictionCandidates
.end());
906 if (vEvictionCandidates
.empty()) return false;
908 // Identify the network group with the most connections
909 std::vector
<unsigned char> naMostConnections
;
910 unsigned int nMostConnections
= 0;
911 std::map
<std::vector
<unsigned char>, std::vector
<CNodeRef
> > mapAddrCounts
;
912 BOOST_FOREACH(const CNodeRef
&node
, vEvictionCandidates
) {
913 mapAddrCounts
[node
->addr
.GetGroup()].push_back(node
);
915 if (mapAddrCounts
[node
->addr
.GetGroup()].size() > nMostConnections
) {
916 nMostConnections
= mapAddrCounts
[node
->addr
.GetGroup()].size();
917 naMostConnections
= node
->addr
.GetGroup();
921 // Reduce to the network group with the most connections
922 vEvictionCandidates
= mapAddrCounts
[naMostConnections
];
924 // Do not disconnect peers if there is only 1 connection from their network group
925 if (vEvictionCandidates
.size() <= 1)
926 // unless we prefer the new connection (for whitelisted peers)
927 if (!fPreferNewConnection
)
930 // Disconnect the most recent connection from the network group with the most connections
931 std::sort(vEvictionCandidates
.begin(), vEvictionCandidates
.end(), ReverseCompareNodeTimeConnected
);
932 vEvictionCandidates
[0]->fDisconnect
= true;
937 static void AcceptConnection(const ListenSocket
& hListenSocket
) {
938 struct sockaddr_storage sockaddr
;
939 socklen_t len
= sizeof(sockaddr
);
940 SOCKET hSocket
= accept(hListenSocket
.socket
, (struct sockaddr
*)&sockaddr
, &len
);
943 int nMaxInbound
= nMaxConnections
- MAX_OUTBOUND_CONNECTIONS
;
945 if (hSocket
!= INVALID_SOCKET
)
946 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
947 LogPrintf("Warning: Unknown socket family\n");
949 bool whitelisted
= hListenSocket
.whitelisted
|| CNode::IsWhitelistedRange(addr
);
952 BOOST_FOREACH(CNode
* pnode
, vNodes
)
957 if (hSocket
== INVALID_SOCKET
)
959 int nErr
= WSAGetLastError();
960 if (nErr
!= WSAEWOULDBLOCK
)
961 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr
));
965 if (!IsSelectableSocket(hSocket
))
967 LogPrintf("connection from %s dropped: non-selectable socket\n", addr
.ToString());
968 CloseSocket(hSocket
);
972 // According to the internet TCP_NODELAY is not carried into accepted sockets
973 // on all platforms. Set it again here just to be sure.
976 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&set
, sizeof(int));
978 setsockopt(hSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&set
, sizeof(int));
981 if (CNode::IsBanned(addr
) && !whitelisted
)
983 LogPrintf("connection from %s dropped (banned)\n", addr
.ToString());
984 CloseSocket(hSocket
);
988 if (nInbound
>= nMaxInbound
)
990 if (!AttemptToEvictConnection(whitelisted
)) {
991 // No connection to evict, disconnect the new connection
992 LogPrint("net", "failed to find an eviction candidate - connection dropped (full)\n");
993 CloseSocket(hSocket
);
998 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
1000 pnode
->fWhitelisted
= whitelisted
;
1002 LogPrint("net", "connection from %s accepted\n", addr
.ToString());
1006 vNodes
.push_back(pnode
);
1010 void ThreadSocketHandler()
1012 unsigned int nPrevNodeCount
= 0;
1020 // Disconnect unused nodes
1021 vector
<CNode
*> vNodesCopy
= vNodes
;
1022 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1024 if (pnode
->fDisconnect
||
1025 (pnode
->GetRefCount() <= 0 && pnode
->vRecvMsg
.empty() && pnode
->nSendSize
== 0 && pnode
->ssSend
.empty()))
1027 // remove from vNodes
1028 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
1030 // release outbound grant (if any)
1031 pnode
->grantOutbound
.Release();
1033 // close socket and cleanup
1034 pnode
->CloseSocketDisconnect();
1036 // hold in disconnected pool until all refs are released
1037 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
1039 vNodesDisconnected
.push_back(pnode
);
1044 // Delete disconnected nodes
1045 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
1046 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
1048 // wait until threads are done using it
1049 if (pnode
->GetRefCount() <= 0)
1051 bool fDelete
= false;
1053 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1056 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1059 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
1067 vNodesDisconnected
.remove(pnode
);
1073 if(vNodes
.size() != nPrevNodeCount
) {
1074 nPrevNodeCount
= vNodes
.size();
1075 uiInterface
.NotifyNumConnectionsChanged(nPrevNodeCount
);
1079 // Find which sockets have data to receive
1081 struct timeval timeout
;
1083 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
1088 FD_ZERO(&fdsetRecv
);
1089 FD_ZERO(&fdsetSend
);
1090 FD_ZERO(&fdsetError
);
1091 SOCKET hSocketMax
= 0;
1092 bool have_fds
= false;
1094 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
) {
1095 FD_SET(hListenSocket
.socket
, &fdsetRecv
);
1096 hSocketMax
= max(hSocketMax
, hListenSocket
.socket
);
1102 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1104 if (pnode
->hSocket
== INVALID_SOCKET
)
1106 FD_SET(pnode
->hSocket
, &fdsetError
);
1107 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
1110 // Implement the following logic:
1111 // * If there is data to send, select() for sending data. As this only
1112 // happens when optimistic write failed, we choose to first drain the
1113 // write buffer in this case before receiving more. This avoids
1114 // needlessly queueing received data, if the remote peer is not themselves
1115 // receiving data. This means properly utilizing TCP flow control signalling.
1116 // * Otherwise, if there is no (complete) message in the receive buffer,
1117 // or there is space left in the buffer, select() for receiving data.
1118 // * (if neither of the above applies, there is certainly one message
1119 // in the receiver buffer ready to be processed).
1120 // Together, that means that at least one of the following is always possible,
1121 // so we don't deadlock:
1122 // * We send some data.
1123 // * We wait for data to be received (and disconnect after timeout).
1124 // * We process a message in the buffer (message handler thread).
1126 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1127 if (lockSend
&& !pnode
->vSendMsg
.empty()) {
1128 FD_SET(pnode
->hSocket
, &fdsetSend
);
1133 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1135 pnode
->vRecvMsg
.empty() || !pnode
->vRecvMsg
.front().complete() ||
1136 pnode
->GetTotalRecvSize() <= ReceiveFloodSize()))
1137 FD_SET(pnode
->hSocket
, &fdsetRecv
);
1142 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
1143 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
1144 boost::this_thread::interruption_point();
1146 if (nSelect
== SOCKET_ERROR
)
1150 int nErr
= WSAGetLastError();
1151 LogPrintf("socket select error %s\n", NetworkErrorString(nErr
));
1152 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
1153 FD_SET(i
, &fdsetRecv
);
1155 FD_ZERO(&fdsetSend
);
1156 FD_ZERO(&fdsetError
);
1157 MilliSleep(timeout
.tv_usec
/1000);
1161 // Accept new connections
1163 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
)
1165 if (hListenSocket
.socket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
.socket
, &fdsetRecv
))
1167 AcceptConnection(hListenSocket
);
1172 // Service each socket
1174 vector
<CNode
*> vNodesCopy
;
1177 vNodesCopy
= vNodes
;
1178 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1181 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1183 boost::this_thread::interruption_point();
1188 if (pnode
->hSocket
== INVALID_SOCKET
)
1190 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
1192 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1196 // typical socket buffer is 8K-64K
1197 char pchBuf
[0x10000];
1198 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
1201 if (!pnode
->ReceiveMsgBytes(pchBuf
, nBytes
))
1202 pnode
->CloseSocketDisconnect();
1203 pnode
->nLastRecv
= GetTime();
1204 pnode
->nRecvBytes
+= nBytes
;
1205 pnode
->RecordBytesRecv(nBytes
);
1207 else if (nBytes
== 0)
1209 // socket closed gracefully
1210 if (!pnode
->fDisconnect
)
1211 LogPrint("net", "socket closed\n");
1212 pnode
->CloseSocketDisconnect();
1214 else if (nBytes
< 0)
1217 int nErr
= WSAGetLastError();
1218 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
1220 if (!pnode
->fDisconnect
)
1221 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr
));
1222 pnode
->CloseSocketDisconnect();
1232 if (pnode
->hSocket
== INVALID_SOCKET
)
1234 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
1236 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1238 SocketSendData(pnode
);
1242 // Inactivity checking
1244 int64_t nTime
= GetTime();
1245 if (nTime
- pnode
->nTimeConnected
> 60)
1247 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
1249 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0, pnode
->id
);
1250 pnode
->fDisconnect
= true;
1252 else if (nTime
- pnode
->nLastSend
> TIMEOUT_INTERVAL
)
1254 LogPrintf("socket sending timeout: %is\n", nTime
- pnode
->nLastSend
);
1255 pnode
->fDisconnect
= true;
1257 else if (nTime
- pnode
->nLastRecv
> (pnode
->nVersion
> BIP0031_VERSION
? TIMEOUT_INTERVAL
: 90*60))
1259 LogPrintf("socket receive timeout: %is\n", nTime
- pnode
->nLastRecv
);
1260 pnode
->fDisconnect
= true;
1262 else if (pnode
->nPingNonceSent
&& pnode
->nPingUsecStart
+ TIMEOUT_INTERVAL
* 1000000 < GetTimeMicros())
1264 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode
->nPingUsecStart
));
1265 pnode
->fDisconnect
= true;
1271 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1286 void ThreadMapPort()
1288 std::string port
= strprintf("%u", GetListenPort());
1289 const char * multicastif
= 0;
1290 const char * minissdpdpath
= 0;
1291 struct UPNPDev
* devlist
= 0;
1294 #ifndef UPNPDISCOVER_SUCCESS
1296 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1297 #elif MINIUPNPC_API_VERSION < 14
1300 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1302 /* miniupnpc 1.9.20150730 */
1304 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, 2, &error
);
1307 struct UPNPUrls urls
;
1308 struct IGDdatas data
;
1311 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1315 char externalIPAddress
[40];
1316 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1317 if(r
!= UPNPCOMMAND_SUCCESS
)
1318 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1321 if(externalIPAddress
[0])
1323 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1324 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1327 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1331 string strDesc
= "Bitcoin " + FormatFullVersion();
1335 #ifndef UPNPDISCOVER_SUCCESS
1337 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1338 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1341 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1342 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1345 if(r
!=UPNPCOMMAND_SUCCESS
)
1346 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1347 port
, port
, lanaddr
, r
, strupnperror(r
));
1349 LogPrintf("UPnP Port Mapping successful.\n");;
1351 MilliSleep(20*60*1000); // Refresh every 20 minutes
1354 catch (const boost::thread_interrupted
&)
1356 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1357 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r
);
1358 freeUPNPDevlist(devlist
); devlist
= 0;
1359 FreeUPNPUrls(&urls
);
1363 LogPrintf("No valid UPnP IGDs found\n");
1364 freeUPNPDevlist(devlist
); devlist
= 0;
1366 FreeUPNPUrls(&urls
);
1370 void MapPort(bool fUseUPnP
)
1372 static boost::thread
* upnp_thread
= NULL
;
1377 upnp_thread
->interrupt();
1378 upnp_thread
->join();
1381 upnp_thread
= new boost::thread(boost::bind(&TraceThread
<void (*)()>, "upnp", &ThreadMapPort
));
1383 else if (upnp_thread
) {
1384 upnp_thread
->interrupt();
1385 upnp_thread
->join();
1394 // Intentionally left blank.
1403 void ThreadDNSAddressSeed()
1405 // goal: only query DNS seeds if address need is acute
1406 if ((addrman
.size() > 0) &&
1407 (!GetBoolArg("-forcednsseed", false))) {
1408 MilliSleep(11 * 1000);
1411 if (vNodes
.size() >= 2) {
1412 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1417 const vector
<CDNSSeedData
> &vSeeds
= Params().DNSSeeds();
1420 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1422 BOOST_FOREACH(const CDNSSeedData
&seed
, vSeeds
) {
1423 if (HaveNameProxy()) {
1424 AddOneShot(seed
.host
);
1426 vector
<CNetAddr
> vIPs
;
1427 vector
<CAddress
> vAdd
;
1428 if (LookupHost(seed
.host
.c_str(), vIPs
))
1430 BOOST_FOREACH(const CNetAddr
& ip
, vIPs
)
1432 int nOneDay
= 24*3600;
1433 CAddress addr
= CAddress(CService(ip
, Params().GetDefaultPort()));
1434 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1435 vAdd
.push_back(addr
);
1439 addrman
.Add(vAdd
, CNetAddr(seed
.name
, true));
1443 LogPrintf("%d addresses found from DNS seeds\n", found
);
1457 void DumpAddresses()
1459 int64_t nStart
= GetTimeMillis();
1464 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1465 addrman
.size(), GetTimeMillis() - nStart
);
1472 if (CNode::BannedSetIsDirty())
1475 CNode::SetBannedSetDirty(false);
1479 void static ProcessOneShot()
1484 if (vOneShots
.empty())
1486 strDest
= vOneShots
.front();
1487 vOneShots
.pop_front();
1490 CSemaphoreGrant
grant(*semOutbound
, true);
1492 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1493 AddOneShot(strDest
);
1497 void ThreadOpenConnections()
1499 // Connect to specific addresses
1500 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1502 for (int64_t nLoop
= 0;; nLoop
++)
1505 BOOST_FOREACH(const std::string
& strAddr
, mapMultiArgs
["-connect"])
1508 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1509 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1518 // Initiate network connections
1519 int64_t nStart
= GetTime();
1526 CSemaphoreGrant
grant(*semOutbound
);
1527 boost::this_thread::interruption_point();
1529 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1530 if (addrman
.size() == 0 && (GetTime() - nStart
> 60)) {
1531 static bool done
= false;
1533 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1534 addrman
.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1540 // Choose an address to connect to based on most recently seen
1542 CAddress addrConnect
;
1544 // Only connect out to one peer per network group (/16 for IPv4).
1545 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1547 set
<vector
<unsigned char> > setConnected
;
1550 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1551 if (!pnode
->fInbound
) {
1552 setConnected
.insert(pnode
->addr
.GetGroup());
1558 int64_t nANow
= GetAdjustedTime();
1563 CAddrInfo addr
= addrman
.Select();
1565 // if we selected an invalid address, restart
1566 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1569 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1570 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1571 // already-connected network ranges, ...) before trying new addrman addresses.
1576 if (IsLimited(addr
))
1579 // only consider very recently tried nodes after 30 failed attempts
1580 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1583 // do not allow non-default ports, unless after 50 invalid addresses selected already
1584 if (addr
.GetPort() != Params().GetDefaultPort() && nTries
< 50)
1591 if (addrConnect
.IsValid())
1592 OpenNetworkConnection(addrConnect
, &grant
);
1596 void ThreadOpenAddedConnections()
1599 LOCK(cs_vAddedNodes
);
1600 vAddedNodes
= mapMultiArgs
["-addnode"];
1603 if (HaveNameProxy()) {
1605 list
<string
> lAddresses(0);
1607 LOCK(cs_vAddedNodes
);
1608 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1609 lAddresses
.push_back(strAddNode
);
1611 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1613 CSemaphoreGrant
grant(*semOutbound
);
1614 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1617 MilliSleep(120000); // Retry every 2 minutes
1621 for (unsigned int i
= 0; true; i
++)
1623 list
<string
> lAddresses(0);
1625 LOCK(cs_vAddedNodes
);
1626 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1627 lAddresses
.push_back(strAddNode
);
1630 list
<vector
<CService
> > lservAddressesToAdd(0);
1631 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1632 vector
<CService
> vservNode(0);
1633 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
1635 lservAddressesToAdd
.push_back(vservNode
);
1637 LOCK(cs_setservAddNodeAddresses
);
1638 BOOST_FOREACH(const CService
& serv
, vservNode
)
1639 setservAddNodeAddresses
.insert(serv
);
1643 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1644 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1647 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1648 for (list
<vector
<CService
> >::iterator it
= lservAddressesToAdd
.begin(); it
!= lservAddressesToAdd
.end(); it
++)
1649 BOOST_FOREACH(const CService
& addrNode
, *(it
))
1650 if (pnode
->addr
== addrNode
)
1652 it
= lservAddressesToAdd
.erase(it
);
1657 BOOST_FOREACH(vector
<CService
>& vserv
, lservAddressesToAdd
)
1659 CSemaphoreGrant
grant(*semOutbound
);
1660 OpenNetworkConnection(CAddress(vserv
[i
% vserv
.size()]), &grant
);
1663 MilliSleep(120000); // Retry every 2 minutes
1667 // if successful, this moves the passed grant to the constructed node
1668 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *pszDest
, bool fOneShot
)
1671 // Initiate outbound network connection
1673 boost::this_thread::interruption_point();
1675 if (IsLocal(addrConnect
) ||
1676 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1677 FindNode(addrConnect
.ToStringIPPort()))
1679 } else if (FindNode(std::string(pszDest
)))
1682 CNode
* pnode
= ConnectNode(addrConnect
, pszDest
);
1683 boost::this_thread::interruption_point();
1688 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1689 pnode
->fNetworkNode
= true;
1691 pnode
->fOneShot
= true;
1697 void ThreadMessageHandler()
1699 boost::mutex condition_mutex
;
1700 boost::unique_lock
<boost::mutex
> lock(condition_mutex
);
1702 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1705 vector
<CNode
*> vNodesCopy
;
1708 vNodesCopy
= vNodes
;
1709 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
) {
1714 // Poll the connected nodes for messages
1715 CNode
* pnodeTrickle
= NULL
;
1716 if (!vNodesCopy
.empty())
1717 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1721 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1723 if (pnode
->fDisconnect
)
1728 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1731 if (!g_signals
.ProcessMessages(pnode
))
1732 pnode
->CloseSocketDisconnect();
1734 if (pnode
->nSendSize
< SendBufferSize())
1736 if (!pnode
->vRecvGetData
.empty() || (!pnode
->vRecvMsg
.empty() && pnode
->vRecvMsg
[0].complete()))
1743 boost::this_thread::interruption_point();
1747 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1749 g_signals
.SendMessages(pnode
, pnode
== pnodeTrickle
|| pnode
->fWhitelisted
);
1751 boost::this_thread::interruption_point();
1756 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1761 messageHandlerCondition
.timed_wait(lock
, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1770 bool BindListenPort(const CService
&addrBind
, string
& strError
, bool fWhitelisted
)
1775 // Create socket for listening for incoming connections
1776 struct sockaddr_storage sockaddr
;
1777 socklen_t len
= sizeof(sockaddr
);
1778 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1780 strError
= strprintf("Error: Bind address family for %s not supported", addrBind
.ToString());
1781 LogPrintf("%s\n", strError
);
1785 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1786 if (hListenSocket
== INVALID_SOCKET
)
1788 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1789 LogPrintf("%s\n", strError
);
1792 if (!IsSelectableSocket(hListenSocket
))
1794 strError
= "Error: Couldn't create a listenable socket for incoming connections";
1795 LogPrintf("%s\n", strError
);
1802 // Different way of disabling SIGPIPE on BSD
1803 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1805 // Allow binding if the port is still in TIME_WAIT state after
1806 // the program was closed and restarted.
1807 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1808 // Disable Nagle's algorithm
1809 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (void*)&nOne
, sizeof(int));
1811 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (const char*)&nOne
, sizeof(int));
1812 setsockopt(hListenSocket
, IPPROTO_TCP
, TCP_NODELAY
, (const char*)&nOne
, sizeof(int));
1815 // Set to non-blocking, incoming connections will also inherit this
1816 if (!SetSocketNonBlocking(hListenSocket
, true)) {
1817 strError
= strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1818 LogPrintf("%s\n", strError
);
1822 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1823 // and enable it by default or not. Try to enable it, if possible.
1824 if (addrBind
.IsIPv6()) {
1827 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (const char*)&nOne
, sizeof(int));
1829 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1833 int nProtLevel
= PROTECTION_LEVEL_UNRESTRICTED
;
1834 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_PROTECTION_LEVEL
, (const char*)&nProtLevel
, sizeof(int));
1838 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1840 int nErr
= WSAGetLastError();
1841 if (nErr
== WSAEADDRINUSE
)
1842 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind
.ToString());
1844 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind
.ToString(), NetworkErrorString(nErr
));
1845 LogPrintf("%s\n", strError
);
1846 CloseSocket(hListenSocket
);
1849 LogPrintf("Bound to %s\n", addrBind
.ToString());
1851 // Listen for incoming connections
1852 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1854 strError
= strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1855 LogPrintf("%s\n", strError
);
1856 CloseSocket(hListenSocket
);
1860 vhListenSocket
.push_back(ListenSocket(hListenSocket
, fWhitelisted
));
1862 if (addrBind
.IsRoutable() && fDiscover
&& !fWhitelisted
)
1863 AddLocal(addrBind
, LOCAL_BIND
);
1868 void static Discover(boost::thread_group
& threadGroup
)
1874 // Get local host IP
1875 char pszHostName
[256] = "";
1876 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1878 vector
<CNetAddr
> vaddr
;
1879 if (LookupHost(pszHostName
, vaddr
))
1881 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1883 if (AddLocal(addr
, LOCAL_IF
))
1884 LogPrintf("%s: %s - %s\n", __func__
, pszHostName
, addr
.ToString());
1889 // Get local host ip
1890 struct ifaddrs
* myaddrs
;
1891 if (getifaddrs(&myaddrs
) == 0)
1893 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1895 if (ifa
->ifa_addr
== NULL
) continue;
1896 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1897 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1898 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1899 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1901 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1902 CNetAddr
addr(s4
->sin_addr
);
1903 if (AddLocal(addr
, LOCAL_IF
))
1904 LogPrintf("%s: IPv4 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1906 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1908 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1909 CNetAddr
addr(s6
->sin6_addr
);
1910 if (AddLocal(addr
, LOCAL_IF
))
1911 LogPrintf("%s: IPv6 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1914 freeifaddrs(myaddrs
);
1919 void StartNode(boost::thread_group
& threadGroup
, CScheduler
& scheduler
)
1921 uiInterface
.InitMessage(_("Loading addresses..."));
1922 // Load addresses for peers.dat
1923 int64_t nStart
= GetTimeMillis();
1926 if (!adb
.Read(addrman
))
1927 LogPrintf("Invalid or missing peers.dat; recreating\n");
1930 //try to read stored banlist
1933 if (!bandb
.Read(banmap
))
1934 LogPrintf("Invalid or missing banlist.dat; recreating\n");
1936 CNode::SetBanned(banmap
); //thread save setter
1937 CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
1938 CNode::SweepBanned(); //sweap out unused entries
1940 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1941 addrman
.size(), GetTimeMillis() - nStart
);
1942 fAddressesInitialized
= true;
1944 if (semOutbound
== NULL
) {
1945 // initialize semaphore
1946 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, nMaxConnections
);
1947 semOutbound
= new CSemaphore(nMaxOutbound
);
1950 if (pnodeLocalHost
== NULL
)
1951 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1953 Discover(threadGroup
);
1959 if (!GetBoolArg("-dnsseed", true))
1960 LogPrintf("DNS seeding disabled\n");
1962 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "dnsseed", &ThreadDNSAddressSeed
));
1964 // Map ports with UPnP
1965 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP
));
1967 // Send and receive from sockets, accept connections
1968 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "net", &ThreadSocketHandler
));
1970 // Initiate outbound connections from -addnode
1971 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "addcon", &ThreadOpenAddedConnections
));
1973 // Initiate outbound connections
1974 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "opencon", &ThreadOpenConnections
));
1977 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "msghand", &ThreadMessageHandler
));
1979 // Dump network addresses
1980 scheduler
.scheduleEvery(&DumpData
, DUMP_ADDRESSES_INTERVAL
);
1985 LogPrintf("StopNode()\n");
1988 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1989 semOutbound
->post();
1991 if (fAddressesInitialized
)
1994 fAddressesInitialized
= false;
2008 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2009 if (pnode
->hSocket
!= INVALID_SOCKET
)
2010 CloseSocket(pnode
->hSocket
);
2011 BOOST_FOREACH(ListenSocket
& hListenSocket
, vhListenSocket
)
2012 if (hListenSocket
.socket
!= INVALID_SOCKET
)
2013 if (!CloseSocket(hListenSocket
.socket
))
2014 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
2016 // clean up some globals (to help leak detection)
2017 BOOST_FOREACH(CNode
*pnode
, vNodes
)
2019 BOOST_FOREACH(CNode
*pnode
, vNodesDisconnected
)
2022 vNodesDisconnected
.clear();
2023 vhListenSocket
.clear();
2026 delete pnodeLocalHost
;
2027 pnodeLocalHost
= NULL
;
2030 // Shutdown Windows Sockets
2035 instance_of_cnetcleanup
;
2043 void RelayTransaction(const CTransaction
& tx
)
2045 CDataStream
ss(SER_NETWORK
, PROTOCOL_VERSION
);
2048 RelayTransaction(tx
, ss
);
2051 void RelayTransaction(const CTransaction
& tx
, const CDataStream
& ss
)
2053 CInv
inv(MSG_TX
, tx
.GetHash());
2056 // Expire old relay messages
2057 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
2059 mapRelay
.erase(vRelayExpiration
.front().second
);
2060 vRelayExpiration
.pop_front();
2063 // Save original serialized message so newer versions are preserved
2064 mapRelay
.insert(std::make_pair(inv
, ss
));
2065 vRelayExpiration
.push_back(std::make_pair(GetTime() + 15 * 60, inv
));
2068 BOOST_FOREACH(CNode
* pnode
, vNodes
)
2070 if(!pnode
->fRelayTxes
)
2072 LOCK(pnode
->cs_filter
);
2075 if (pnode
->pfilter
->IsRelevantAndUpdate(tx
))
2076 pnode
->PushInventory(inv
);
2078 pnode
->PushInventory(inv
);
2082 void CNode::RecordBytesRecv(uint64_t bytes
)
2084 LOCK(cs_totalBytesRecv
);
2085 nTotalBytesRecv
+= bytes
;
2088 void CNode::RecordBytesSent(uint64_t bytes
)
2090 LOCK(cs_totalBytesSent
);
2091 nTotalBytesSent
+= bytes
;
2093 uint64_t now
= GetTime();
2094 if (nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
< now
)
2096 // timeframe expired, reset cycle
2097 nMaxOutboundCycleStartTime
= now
;
2098 nMaxOutboundTotalBytesSentInCycle
= 0;
2101 // TODO, exclude whitebind peers
2102 nMaxOutboundTotalBytesSentInCycle
+= bytes
;
2105 void CNode::SetMaxOutboundTarget(uint64_t limit
)
2107 LOCK(cs_totalBytesSent
);
2108 uint64_t recommendedMinimum
= (nMaxOutboundTimeframe
/ 600) * MAX_BLOCK_SIZE
;
2109 nMaxOutboundLimit
= limit
;
2111 if (limit
< recommendedMinimum
)
2112 LogPrintf("Max outbound target is very small (%s) and will be overshot. Recommended minimum is %s\n.", nMaxOutboundLimit
, recommendedMinimum
);
2115 uint64_t CNode::GetMaxOutboundTarget()
2117 LOCK(cs_totalBytesSent
);
2118 return nMaxOutboundLimit
;
2121 uint64_t CNode::GetMaxOutboundTimeframe()
2123 LOCK(cs_totalBytesSent
);
2124 return nMaxOutboundTimeframe
;
2127 uint64_t CNode::GetMaxOutboundTimeLeftInCycle()
2129 LOCK(cs_totalBytesSent
);
2130 if (nMaxOutboundLimit
== 0)
2133 if (nMaxOutboundCycleStartTime
== 0)
2134 return nMaxOutboundTimeframe
;
2136 uint64_t cycleEndTime
= nMaxOutboundCycleStartTime
+ nMaxOutboundTimeframe
;
2137 uint64_t now
= GetTime();
2138 return (cycleEndTime
< now
) ? 0 : cycleEndTime
- GetTime();
2141 void CNode::SetMaxOutboundTimeframe(uint64_t timeframe
)
2143 LOCK(cs_totalBytesSent
);
2144 if (nMaxOutboundTimeframe
!= timeframe
)
2146 // reset measure-cycle in case of changing
2148 nMaxOutboundCycleStartTime
= GetTime();
2150 nMaxOutboundTimeframe
= timeframe
;
2153 bool CNode::OutboundTargetReached(bool historicalBlockServingLimit
)
2155 LOCK(cs_totalBytesSent
);
2156 if (nMaxOutboundLimit
== 0)
2159 if (historicalBlockServingLimit
)
2161 // keep a large enought buffer to at least relay each block once
2162 uint64_t timeLeftInCycle
= GetMaxOutboundTimeLeftInCycle();
2163 uint64_t buffer
= timeLeftInCycle
/ 600 * MAX_BLOCK_SIZE
;
2164 if (buffer
>= nMaxOutboundLimit
|| nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
- buffer
)
2167 else if (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
)
2173 uint64_t CNode::GetOutboundTargetBytesLeft()
2175 LOCK(cs_totalBytesSent
);
2176 if (nMaxOutboundLimit
== 0)
2179 return (nMaxOutboundTotalBytesSentInCycle
>= nMaxOutboundLimit
) ? 0 : nMaxOutboundLimit
- nMaxOutboundTotalBytesSentInCycle
;
2182 uint64_t CNode::GetTotalBytesRecv()
2184 LOCK(cs_totalBytesRecv
);
2185 return nTotalBytesRecv
;
2188 uint64_t CNode::GetTotalBytesSent()
2190 LOCK(cs_totalBytesSent
);
2191 return nTotalBytesSent
;
2194 void CNode::Fuzz(int nChance
)
2196 if (!fSuccessfullyConnected
) return; // Don't fuzz initial handshake
2197 if (GetRand(nChance
) != 0) return; // Fuzz 1 of every nChance messages
2202 // xor a random byte with a random value:
2203 if (!ssSend
.empty()) {
2204 CDataStream::size_type pos
= GetRand(ssSend
.size());
2205 ssSend
[pos
] ^= (unsigned char)(GetRand(256));
2209 // delete a random byte:
2210 if (!ssSend
.empty()) {
2211 CDataStream::size_type pos
= GetRand(ssSend
.size());
2212 ssSend
.erase(ssSend
.begin()+pos
);
2216 // insert a random byte at a random position
2218 CDataStream::size_type pos
= GetRand(ssSend
.size());
2219 char ch
= (char)GetRand(256);
2220 ssSend
.insert(ssSend
.begin()+pos
, ch
);
2224 // Chance of more than one change half the time:
2225 // (more changes exponentially less likely):
2235 pathAddr
= GetDataDir() / "peers.dat";
2238 bool CAddrDB::Write(const CAddrMan
& addr
)
2240 // Generate random temporary filename
2241 unsigned short randv
= 0;
2242 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2243 std::string tmpfn
= strprintf("peers.dat.%04x", randv
);
2245 // serialize addresses, checksum data up to that point, then append csum
2246 CDataStream
ssPeers(SER_DISK
, CLIENT_VERSION
);
2247 ssPeers
<< FLATDATA(Params().MessageStart());
2249 uint256 hash
= Hash(ssPeers
.begin(), ssPeers
.end());
2252 // open temp output file, and associate with CAutoFile
2253 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2254 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2255 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2256 if (fileout
.IsNull())
2257 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2259 // Write and commit header, data
2263 catch (const std::exception
& e
) {
2264 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2266 FileCommit(fileout
.Get());
2269 // replace existing peers.dat, if any, with new peers.dat.XXXX
2270 if (!RenameOver(pathTmp
, pathAddr
))
2271 return error("%s: Rename-into-place failed", __func__
);
2276 bool CAddrDB::Read(CAddrMan
& addr
)
2278 // open input file, and associate with CAutoFile
2279 FILE *file
= fopen(pathAddr
.string().c_str(), "rb");
2280 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2281 if (filein
.IsNull())
2282 return error("%s: Failed to open file %s", __func__
, pathAddr
.string());
2284 // use file size to size memory buffer
2285 uint64_t fileSize
= boost::filesystem::file_size(pathAddr
);
2286 uint64_t dataSize
= 0;
2287 // Don't try to resize to a negative number if file is small
2288 if (fileSize
>= sizeof(uint256
))
2289 dataSize
= fileSize
- sizeof(uint256
);
2290 vector
<unsigned char> vchData
;
2291 vchData
.resize(dataSize
);
2294 // read data and checksum from file
2296 filein
.read((char *)&vchData
[0], dataSize
);
2299 catch (const std::exception
& e
) {
2300 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2304 CDataStream
ssPeers(vchData
, SER_DISK
, CLIENT_VERSION
);
2306 // verify stored checksum matches input data
2307 uint256 hashTmp
= Hash(ssPeers
.begin(), ssPeers
.end());
2308 if (hashIn
!= hashTmp
)
2309 return error("%s: Checksum mismatch, data corrupted", __func__
);
2311 unsigned char pchMsgTmp
[4];
2313 // de-serialize file header (network specific magic number) and ..
2314 ssPeers
>> FLATDATA(pchMsgTmp
);
2316 // ... verify the network matches ours
2317 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2318 return error("%s: Invalid network magic number", __func__
);
2320 // de-serialize address data into one CAddrMan object
2323 catch (const std::exception
& e
) {
2324 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2330 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2331 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2333 CNode::CNode(SOCKET hSocketIn
, const CAddress
& addrIn
, const std::string
& addrNameIn
, bool fInboundIn
) :
2334 ssSend(SER_NETWORK
, INIT_PROTO_VERSION
),
2335 addrKnown(5000, 0.001),
2336 setInventoryKnown(SendBufferSize() / 1000)
2339 hSocket
= hSocketIn
;
2340 nRecvVersion
= INIT_PROTO_VERSION
;
2345 nTimeConnected
= GetTime();
2348 addrName
= addrNameIn
== "" ? addr
.ToStringIPPort() : addrNameIn
;
2351 fWhitelisted
= false;
2353 fClient
= false; // set by version message
2354 fInbound
= fInboundIn
;
2355 fNetworkNode
= false;
2356 fSuccessfullyConnected
= false;
2357 fDisconnect
= false;
2361 hashContinue
= uint256();
2362 nStartingHeight
= -1;
2365 pfilter
= new CBloomFilter();
2369 fPingQueued
= false;
2370 nMinPingUsecTime
= std::numeric_limits
<int64_t>::max();
2373 LOCK(cs_nLastNodeId
);
2378 LogPrint("net", "Added connection to %s peer=%d\n", addrName
, id
);
2380 LogPrint("net", "Added connection peer=%d\n", id
);
2382 // Be shy and don't send version until we hear
2383 if (hSocket
!= INVALID_SOCKET
&& !fInbound
)
2386 GetNodeSignals().InitializeNode(GetId(), this);
2391 CloseSocket(hSocket
);
2396 GetNodeSignals().FinalizeNode(GetId());
2399 void CNode::AskFor(const CInv
& inv
)
2401 if (mapAskFor
.size() > MAPASKFOR_MAX_SZ
)
2403 // We're using mapAskFor as a priority queue,
2404 // the key is the earliest time the request can be sent
2405 int64_t nRequestTime
;
2406 limitedmap
<CInv
, int64_t>::const_iterator it
= mapAlreadyAskedFor
.find(inv
);
2407 if (it
!= mapAlreadyAskedFor
.end())
2408 nRequestTime
= it
->second
;
2411 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv
.ToString(), nRequestTime
, DateTimeStrFormat("%H:%M:%S", nRequestTime
/1000000), id
);
2413 // Make sure not to reuse time indexes to keep things in the same order
2414 int64_t nNow
= GetTimeMicros() - 1000000;
2415 static int64_t nLastTime
;
2417 nNow
= std::max(nNow
, nLastTime
);
2420 // Each retry is 2 minutes after the last
2421 nRequestTime
= std::max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
2422 if (it
!= mapAlreadyAskedFor
.end())
2423 mapAlreadyAskedFor
.update(it
, nRequestTime
);
2425 mapAlreadyAskedFor
.insert(std::make_pair(inv
, nRequestTime
));
2426 mapAskFor
.insert(std::make_pair(nRequestTime
, inv
));
2429 void CNode::BeginMessage(const char* pszCommand
) EXCLUSIVE_LOCK_FUNCTION(cs_vSend
)
2431 ENTER_CRITICAL_SECTION(cs_vSend
);
2432 assert(ssSend
.size() == 0);
2433 ssSend
<< CMessageHeader(Params().MessageStart(), pszCommand
, 0);
2434 LogPrint("net", "sending: %s ", SanitizeString(pszCommand
));
2437 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend
)
2441 LEAVE_CRITICAL_SECTION(cs_vSend
);
2443 LogPrint("net", "(aborted)\n");
2446 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend
)
2448 // The -*messagestest options are intentionally not documented in the help message,
2449 // since they are only used during development to debug the networking code and are
2450 // not intended for end-users.
2451 if (mapArgs
.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2453 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2457 if (mapArgs
.count("-fuzzmessagestest"))
2458 Fuzz(GetArg("-fuzzmessagestest", 10));
2460 if (ssSend
.size() == 0)
2462 LEAVE_CRITICAL_SECTION(cs_vSend
);
2466 unsigned int nSize
= ssSend
.size() - CMessageHeader::HEADER_SIZE
;
2467 WriteLE32((uint8_t*)&ssSend
[CMessageHeader::MESSAGE_SIZE_OFFSET
], nSize
);
2470 uint256 hash
= Hash(ssSend
.begin() + CMessageHeader::HEADER_SIZE
, ssSend
.end());
2471 unsigned int nChecksum
= 0;
2472 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
2473 assert(ssSend
.size () >= CMessageHeader::CHECKSUM_OFFSET
+ sizeof(nChecksum
));
2474 memcpy((char*)&ssSend
[CMessageHeader::CHECKSUM_OFFSET
], &nChecksum
, sizeof(nChecksum
));
2476 LogPrint("net", "(%d bytes) peer=%d\n", nSize
, id
);
2478 std::deque
<CSerializeData
>::iterator it
= vSendMsg
.insert(vSendMsg
.end(), CSerializeData());
2479 ssSend
.GetAndClear(*it
);
2480 nSendSize
+= (*it
).size();
2482 // If write queue empty, attempt "optimistic write"
2483 if (it
== vSendMsg
.begin())
2484 SocketSendData(this);
2486 LEAVE_CRITICAL_SECTION(cs_vSend
);
2495 pathBanlist
= GetDataDir() / "banlist.dat";
2498 bool CBanDB::Write(const banmap_t
& banSet
)
2500 // Generate random temporary filename
2501 unsigned short randv
= 0;
2502 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2503 std::string tmpfn
= strprintf("banlist.dat.%04x", randv
);
2505 // serialize banlist, checksum data up to that point, then append csum
2506 CDataStream
ssBanlist(SER_DISK
, CLIENT_VERSION
);
2507 ssBanlist
<< FLATDATA(Params().MessageStart());
2508 ssBanlist
<< banSet
;
2509 uint256 hash
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2512 // open temp output file, and associate with CAutoFile
2513 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2514 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2515 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2516 if (fileout
.IsNull())
2517 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2519 // Write and commit header, data
2521 fileout
<< ssBanlist
;
2523 catch (const std::exception
& e
) {
2524 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2526 FileCommit(fileout
.Get());
2529 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2530 if (!RenameOver(pathTmp
, pathBanlist
))
2531 return error("%s: Rename-into-place failed", __func__
);
2536 bool CBanDB::Read(banmap_t
& banSet
)
2538 // open input file, and associate with CAutoFile
2539 FILE *file
= fopen(pathBanlist
.string().c_str(), "rb");
2540 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2541 if (filein
.IsNull())
2542 return error("%s: Failed to open file %s", __func__
, pathBanlist
.string());
2544 // use file size to size memory buffer
2545 uint64_t fileSize
= boost::filesystem::file_size(pathBanlist
);
2546 uint64_t dataSize
= 0;
2547 // Don't try to resize to a negative number if file is small
2548 if (fileSize
>= sizeof(uint256
))
2549 dataSize
= fileSize
- sizeof(uint256
);
2550 vector
<unsigned char> vchData
;
2551 vchData
.resize(dataSize
);
2554 // read data and checksum from file
2556 filein
.read((char *)&vchData
[0], dataSize
);
2559 catch (const std::exception
& e
) {
2560 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2564 CDataStream
ssBanlist(vchData
, SER_DISK
, CLIENT_VERSION
);
2566 // verify stored checksum matches input data
2567 uint256 hashTmp
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2568 if (hashIn
!= hashTmp
)
2569 return error("%s: Checksum mismatch, data corrupted", __func__
);
2571 unsigned char pchMsgTmp
[4];
2573 // de-serialize file header (network specific magic number) and ..
2574 ssBanlist
>> FLATDATA(pchMsgTmp
);
2576 // ... verify the network matches ours
2577 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2578 return error("%s: Invalid network magic number", __func__
);
2580 // de-serialize address data into one CAddrMan object
2581 ssBanlist
>> banSet
;
2583 catch (const std::exception
& e
) {
2584 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2592 int64_t nStart
= GetTimeMillis();
2594 CNode::SweepBanned(); //clean unused entries (if bantime has expired)
2598 CNode::GetBanned(banmap
);
2599 bandb
.Write(banmap
);
2601 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
2602 banmap
.size(), GetTimeMillis() - nStart
);