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 "primitives/transaction.h"
16 #include "scheduler.h"
17 #include "ui_interface.h"
18 #include "crypto/common.h"
27 #include <miniupnpc/miniupnpc.h>
28 #include <miniupnpc/miniwget.h>
29 #include <miniupnpc/upnpcommands.h>
30 #include <miniupnpc/upnperrors.h>
33 #include <boost/filesystem.hpp>
34 #include <boost/thread.hpp>
36 // Dump addresses to peers.dat every 15 minutes (900s)
37 #define DUMP_ADDRESSES_INTERVAL 900
39 #if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL)
40 #define MSG_NOSIGNAL 0
43 // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h.
44 // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version.
46 #ifndef PROTECTION_LEVEL_UNRESTRICTED
47 #define PROTECTION_LEVEL_UNRESTRICTED 10
49 #ifndef IPV6_PROTECTION_LEVEL
50 #define IPV6_PROTECTION_LEVEL 23
57 const int MAX_OUTBOUND_CONNECTIONS
= 8;
63 ListenSocket(SOCKET socket
, bool whitelisted
) : socket(socket
), whitelisted(whitelisted
) {}
68 // Global state variables
70 bool fDiscover
= true;
72 uint64_t nLocalServices
= NODE_NETWORK
;
73 CCriticalSection cs_mapLocalHost
;
74 map
<CNetAddr
, LocalServiceInfo
> mapLocalHost
;
75 static bool vfReachable
[NET_MAX
] = {};
76 static bool vfLimited
[NET_MAX
] = {};
77 static CNode
* pnodeLocalHost
= NULL
;
78 uint64_t nLocalHostNonce
= 0;
79 static std::vector
<ListenSocket
> vhListenSocket
;
81 int nMaxConnections
= 125;
82 bool fAddressesInitialized
= false;
84 vector
<CNode
*> vNodes
;
85 CCriticalSection cs_vNodes
;
86 map
<CInv
, CDataStream
> mapRelay
;
87 deque
<pair
<int64_t, CInv
> > vRelayExpiration
;
88 CCriticalSection cs_mapRelay
;
89 limitedmap
<CInv
, int64_t> mapAlreadyAskedFor(MAX_INV_SZ
);
91 static deque
<string
> vOneShots
;
92 CCriticalSection cs_vOneShots
;
94 set
<CNetAddr
> setservAddNodeAddresses
;
95 CCriticalSection cs_setservAddNodeAddresses
;
97 vector
<std::string
> vAddedNodes
;
98 CCriticalSection cs_vAddedNodes
;
100 NodeId nLastNodeId
= 0;
101 CCriticalSection cs_nLastNodeId
;
103 static CSemaphore
*semOutbound
= NULL
;
104 boost::condition_variable messageHandlerCondition
;
106 // Signals for message handling
107 static CNodeSignals g_signals
;
108 CNodeSignals
& GetNodeSignals() { return g_signals
; }
110 void AddOneShot(const std::string
& strDest
)
113 vOneShots
.push_back(strDest
);
116 unsigned short GetListenPort()
118 return (unsigned short)(GetArg("-port", Params().GetDefaultPort()));
121 // find 'best' local address for a particular peer
122 bool GetLocal(CService
& addr
, const CNetAddr
*paddrPeer
)
128 int nBestReachability
= -1;
130 LOCK(cs_mapLocalHost
);
131 for (map
<CNetAddr
, LocalServiceInfo
>::iterator it
= mapLocalHost
.begin(); it
!= mapLocalHost
.end(); it
++)
133 int nScore
= (*it
).second
.nScore
;
134 int nReachability
= (*it
).first
.GetReachabilityFrom(paddrPeer
);
135 if (nReachability
> nBestReachability
|| (nReachability
== nBestReachability
&& nScore
> nBestScore
))
137 addr
= CService((*it
).first
, (*it
).second
.nPort
);
138 nBestReachability
= nReachability
;
143 return nBestScore
>= 0;
146 //! Convert the pnSeeds6 array into usable address objects.
147 static std::vector
<CAddress
> convertSeed6(const std::vector
<SeedSpec6
> &vSeedsIn
)
149 // It'll only connect to one or two seed nodes because once it connects,
150 // it'll get a pile of addresses with newer timestamps.
151 // Seed nodes are given a random 'last seen time' of between one and two
153 const int64_t nOneWeek
= 7*24*60*60;
154 std::vector
<CAddress
> vSeedsOut
;
155 vSeedsOut
.reserve(vSeedsIn
.size());
156 for (std::vector
<SeedSpec6
>::const_iterator
i(vSeedsIn
.begin()); i
!= vSeedsIn
.end(); ++i
)
159 memcpy(&ip
, i
->addr
, sizeof(ip
));
160 CAddress
addr(CService(ip
, i
->port
));
161 addr
.nTime
= GetTime() - GetRand(nOneWeek
) - nOneWeek
;
162 vSeedsOut
.push_back(addr
);
167 // get best local address for a particular peer as a CAddress
168 // Otherwise, return the unroutable 0.0.0.0 but filled in with
169 // the normal parameters, since the IP may be changed to a useful
171 CAddress
GetLocalAddress(const CNetAddr
*paddrPeer
)
173 CAddress
ret(CService("0.0.0.0",GetListenPort()),0);
175 if (GetLocal(addr
, paddrPeer
))
177 ret
= CAddress(addr
);
179 ret
.nServices
= nLocalServices
;
180 ret
.nTime
= GetAdjustedTime();
184 int GetnScore(const CService
& addr
)
186 LOCK(cs_mapLocalHost
);
187 if (mapLocalHost
.count(addr
) == LOCAL_NONE
)
189 return mapLocalHost
[addr
].nScore
;
192 // Is our peer's addrLocal potentially useful as an external IP source?
193 bool IsPeerAddrLocalGood(CNode
*pnode
)
195 return fDiscover
&& pnode
->addr
.IsRoutable() && pnode
->addrLocal
.IsRoutable() &&
196 !IsLimited(pnode
->addrLocal
.GetNetwork());
199 // pushes our own address to a peer
200 void AdvertizeLocal(CNode
*pnode
)
202 if (fListen
&& pnode
->fSuccessfullyConnected
)
204 CAddress addrLocal
= GetLocalAddress(&pnode
->addr
);
205 // If discovery is enabled, sometimes give our peer the address it
206 // tells us that it sees us as in case it has a better idea of our
207 // address than we do.
208 if (IsPeerAddrLocalGood(pnode
) && (!addrLocal
.IsRoutable() ||
209 GetRand((GetnScore(addrLocal
) > LOCAL_MANUAL
) ? 8:2) == 0))
211 addrLocal
.SetIP(pnode
->addrLocal
);
213 if (addrLocal
.IsRoutable())
215 pnode
->PushAddress(addrLocal
);
220 void SetReachable(enum Network net
, bool fFlag
)
222 LOCK(cs_mapLocalHost
);
223 vfReachable
[net
] = fFlag
;
224 if (net
== NET_IPV6
&& fFlag
)
225 vfReachable
[NET_IPV4
] = true;
228 // learn a new local address
229 bool AddLocal(const CService
& addr
, int nScore
)
231 if (!addr
.IsRoutable())
234 if (!fDiscover
&& nScore
< LOCAL_MANUAL
)
240 LogPrintf("AddLocal(%s,%i)\n", addr
.ToString(), nScore
);
243 LOCK(cs_mapLocalHost
);
244 bool fAlready
= mapLocalHost
.count(addr
) > 0;
245 LocalServiceInfo
&info
= mapLocalHost
[addr
];
246 if (!fAlready
|| nScore
>= info
.nScore
) {
247 info
.nScore
= nScore
+ (fAlready
? 1 : 0);
248 info
.nPort
= addr
.GetPort();
250 SetReachable(addr
.GetNetwork());
256 bool AddLocal(const CNetAddr
&addr
, int nScore
)
258 return AddLocal(CService(addr
, GetListenPort()), nScore
);
261 /** Make a particular network entirely off-limits (no automatic connects to it) */
262 void SetLimited(enum Network net
, bool fLimited
)
264 if (net
== NET_UNROUTABLE
)
266 LOCK(cs_mapLocalHost
);
267 vfLimited
[net
] = fLimited
;
270 bool IsLimited(enum Network net
)
272 LOCK(cs_mapLocalHost
);
273 return vfLimited
[net
];
276 bool IsLimited(const CNetAddr
&addr
)
278 return IsLimited(addr
.GetNetwork());
281 /** vote for a local address */
282 bool SeenLocal(const CService
& addr
)
285 LOCK(cs_mapLocalHost
);
286 if (mapLocalHost
.count(addr
) == 0)
288 mapLocalHost
[addr
].nScore
++;
294 /** check whether a given address is potentially local */
295 bool IsLocal(const CService
& addr
)
297 LOCK(cs_mapLocalHost
);
298 return mapLocalHost
.count(addr
) > 0;
301 /** check whether a given network is one we can probably connect to */
302 bool IsReachable(enum Network net
)
304 LOCK(cs_mapLocalHost
);
305 return vfReachable
[net
] && !vfLimited
[net
];
308 /** check whether a given address is in a network we can probably connect to */
309 bool IsReachable(const CNetAddr
& addr
)
311 enum Network net
= addr
.GetNetwork();
312 return IsReachable(net
);
315 void AddressCurrentlyConnected(const CService
& addr
)
317 addrman
.Connected(addr
);
321 uint64_t CNode::nTotalBytesRecv
= 0;
322 uint64_t CNode::nTotalBytesSent
= 0;
323 CCriticalSection
CNode::cs_totalBytesRecv
;
324 CCriticalSection
CNode::cs_totalBytesSent
;
326 CNode
* FindNode(const CNetAddr
& ip
)
329 BOOST_FOREACH(CNode
* pnode
, vNodes
)
330 if ((CNetAddr
)pnode
->addr
== ip
)
335 CNode
* FindNode(const CSubNet
& subNet
)
338 BOOST_FOREACH(CNode
* pnode
, vNodes
)
339 if (subNet
.Match((CNetAddr
)pnode
->addr
))
344 CNode
* FindNode(const std::string
& addrName
)
347 BOOST_FOREACH(CNode
* pnode
, vNodes
)
348 if (pnode
->addrName
== addrName
)
353 CNode
* FindNode(const CService
& addr
)
356 BOOST_FOREACH(CNode
* pnode
, vNodes
)
357 if ((CService
)pnode
->addr
== addr
)
362 CNode
* ConnectNode(CAddress addrConnect
, const char *pszDest
)
364 if (pszDest
== NULL
) {
365 if (IsLocal(addrConnect
))
368 // Look for an existing connection
369 CNode
* pnode
= FindNode((CService
)addrConnect
);
378 LogPrint("net", "trying connection %s lastseen=%.1fhrs\n",
379 pszDest
? pszDest
: addrConnect
.ToString(),
380 pszDest
? 0.0 : (double)(GetAdjustedTime() - addrConnect
.nTime
)/3600.0);
384 bool proxyConnectionFailed
= false;
385 if (pszDest
? ConnectSocketByName(addrConnect
, hSocket
, pszDest
, Params().GetDefaultPort(), nConnectTimeout
, &proxyConnectionFailed
) :
386 ConnectSocket(addrConnect
, hSocket
, nConnectTimeout
, &proxyConnectionFailed
))
388 addrman
.Attempt(addrConnect
);
391 CNode
* pnode
= new CNode(hSocket
, addrConnect
, pszDest
? pszDest
: "", false);
396 vNodes
.push_back(pnode
);
399 pnode
->nTimeConnected
= GetTime();
402 } else if (!proxyConnectionFailed
) {
403 // If connecting to the node failed, and failure is not caused by a problem connecting to
404 // the proxy, mark this as an attempt.
405 addrman
.Attempt(addrConnect
);
411 void CNode::CloseSocketDisconnect()
414 if (hSocket
!= INVALID_SOCKET
)
416 LogPrint("net", "disconnecting peer=%d\n", id
);
417 CloseSocket(hSocket
);
420 // in case this fails, we'll empty the recv buffer when the CNode is deleted
421 TRY_LOCK(cs_vRecvMsg
, lockRecv
);
426 void CNode::PushVersion()
428 int nBestHeight
= g_signals
.GetHeight().get_value_or(0);
430 int64_t nTime
= (fInbound
? GetAdjustedTime() : GetTime());
431 CAddress addrYou
= (addr
.IsRoutable() && !IsProxy(addr
) ? addr
: CAddress(CService("0.0.0.0",0)));
432 CAddress addrMe
= GetLocalAddress(&addr
);
433 GetRandBytes((unsigned char*)&nLocalHostNonce
, sizeof(nLocalHostNonce
));
435 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), addrYou
.ToString(), id
);
437 LogPrint("net", "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION
, nBestHeight
, addrMe
.ToString(), id
);
438 PushMessage("version", PROTOCOL_VERSION
, nLocalServices
, nTime
, addrYou
, addrMe
,
439 nLocalHostNonce
, FormatSubVersion(CLIENT_NAME
, CLIENT_VERSION
, std::vector
<string
>()), nBestHeight
, true);
446 banmap_t
CNode::setBanned
;
447 CCriticalSection
CNode::cs_setBanned
;
448 bool CNode::setBannedIsDirty
;
450 void CNode::ClearBanned()
454 setBannedIsDirty
= true;
457 bool CNode::IsBanned(CNetAddr ip
)
459 bool fResult
= false;
462 for (banmap_t::iterator it
= setBanned
.begin(); it
!= setBanned
.end(); it
++)
464 CSubNet subNet
= (*it
).first
;
465 CBanEntry banEntry
= (*it
).second
;
467 if(subNet
.Match(ip
) && GetTime() < banEntry
.nBanUntil
)
474 bool CNode::IsBanned(CSubNet subnet
)
476 bool fResult
= false;
479 banmap_t::iterator i
= setBanned
.find(subnet
);
480 if (i
!= setBanned
.end())
482 CBanEntry banEntry
= (*i
).second
;
483 if (GetTime() < banEntry
.nBanUntil
)
490 void CNode::Ban(const CNetAddr
& addr
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
491 CSubNet
subNet(addr
);
492 Ban(subNet
, banReason
, bantimeoffset
, sinceUnixEpoch
);
495 void CNode::Ban(const CSubNet
& subNet
, const BanReason
&banReason
, int64_t bantimeoffset
, bool sinceUnixEpoch
) {
496 CBanEntry
banEntry(GetTime());
497 banEntry
.banReason
= banReason
;
498 if (bantimeoffset
<= 0)
500 bantimeoffset
= GetArg("-bantime", 60*60*24); // Default 24-hour ban
501 sinceUnixEpoch
= false;
503 banEntry
.nBanUntil
= (sinceUnixEpoch
? 0 : GetTime() )+bantimeoffset
;
507 if (setBanned
[subNet
].nBanUntil
< banEntry
.nBanUntil
)
508 setBanned
[subNet
] = banEntry
;
510 setBannedIsDirty
= true;
513 bool CNode::Unban(const CNetAddr
&addr
) {
514 CSubNet
subNet(addr
);
515 return Unban(subNet
);
518 bool CNode::Unban(const CSubNet
&subNet
) {
520 if (setBanned
.erase(subNet
))
522 setBannedIsDirty
= true;
528 void CNode::GetBanned(banmap_t
&banMap
)
531 banMap
= setBanned
; //create a thread safe copy
534 void CNode::SetBanned(const banmap_t
&banMap
)
538 setBannedIsDirty
= true;
541 void CNode::SweepBanned()
543 int64_t now
= GetTime();
546 banmap_t::iterator it
= setBanned
.begin();
547 while(it
!= setBanned
.end())
549 CBanEntry banEntry
= (*it
).second
;
550 if(now
> banEntry
.nBanUntil
)
552 setBanned
.erase(it
++);
553 setBannedIsDirty
= true;
560 bool CNode::BannedSetIsDirty()
563 return setBannedIsDirty
;
566 void CNode::SetBannedSetDirty(bool dirty
)
568 LOCK(cs_setBanned
); //reuse setBanned lock for the isDirty flag
569 setBannedIsDirty
= dirty
;
573 std::vector
<CSubNet
> CNode::vWhitelistedRange
;
574 CCriticalSection
CNode::cs_vWhitelistedRange
;
576 bool CNode::IsWhitelistedRange(const CNetAddr
&addr
) {
577 LOCK(cs_vWhitelistedRange
);
578 BOOST_FOREACH(const CSubNet
& subnet
, vWhitelistedRange
) {
579 if (subnet
.Match(addr
))
585 void CNode::AddWhitelistedRange(const CSubNet
&subnet
) {
586 LOCK(cs_vWhitelistedRange
);
587 vWhitelistedRange
.push_back(subnet
);
591 #define X(name) stats.name = name
592 void CNode::copyStats(CNodeStats
&stats
)
594 stats
.nodeid
= this->GetId();
609 // It is common for nodes with good ping times to suddenly become lagged,
610 // due to a new block arriving or other large transfer.
611 // Merely reporting pingtime might fool the caller into thinking the node was still responsive,
612 // since pingtime does not update until the ping is complete, which might take a while.
613 // So, if a ping is taking an unusually long time in flight,
614 // the caller can immediately detect that this is happening.
615 int64_t nPingUsecWait
= 0;
616 if ((0 != nPingNonceSent
) && (0 != nPingUsecStart
)) {
617 nPingUsecWait
= GetTimeMicros() - nPingUsecStart
;
620 // 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 :)
621 stats
.dPingTime
= (((double)nPingUsecTime
) / 1e6
);
622 stats
.dPingWait
= (((double)nPingUsecWait
) / 1e6
);
624 // Leave string empty if addrLocal invalid (not filled in yet)
625 stats
.addrLocal
= addrLocal
.IsValid() ? addrLocal
.ToString() : "";
629 // requires LOCK(cs_vRecvMsg)
630 bool CNode::ReceiveMsgBytes(const char *pch
, unsigned int nBytes
)
634 // get current incomplete message, or create a new one
635 if (vRecvMsg
.empty() ||
636 vRecvMsg
.back().complete())
637 vRecvMsg
.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK
, nRecvVersion
));
639 CNetMessage
& msg
= vRecvMsg
.back();
641 // absorb network data
644 handled
= msg
.readHeader(pch
, nBytes
);
646 handled
= msg
.readData(pch
, nBytes
);
651 if (msg
.in_data
&& msg
.hdr
.nMessageSize
> MAX_PROTOCOL_MESSAGE_LENGTH
) {
652 LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
659 if (msg
.complete()) {
660 msg
.nTime
= GetTimeMicros();
661 messageHandlerCondition
.notify_one();
668 int CNetMessage::readHeader(const char *pch
, unsigned int nBytes
)
670 // copy data to temporary parsing buffer
671 unsigned int nRemaining
= 24 - nHdrPos
;
672 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
674 memcpy(&hdrbuf
[nHdrPos
], pch
, nCopy
);
677 // if header incomplete, exit
681 // deserialize to CMessageHeader
685 catch (const std::exception
&) {
689 // reject messages larger than MAX_SIZE
690 if (hdr
.nMessageSize
> MAX_SIZE
)
693 // switch state to reading message data
699 int CNetMessage::readData(const char *pch
, unsigned int nBytes
)
701 unsigned int nRemaining
= hdr
.nMessageSize
- nDataPos
;
702 unsigned int nCopy
= std::min(nRemaining
, nBytes
);
704 if (vRecv
.size() < nDataPos
+ nCopy
) {
705 // Allocate up to 256 KiB ahead, but never more than the total message size.
706 vRecv
.resize(std::min(hdr
.nMessageSize
, nDataPos
+ nCopy
+ 256 * 1024));
709 memcpy(&vRecv
[nDataPos
], pch
, nCopy
);
723 // requires LOCK(cs_vSend)
724 void SocketSendData(CNode
*pnode
)
726 std::deque
<CSerializeData
>::iterator it
= pnode
->vSendMsg
.begin();
728 while (it
!= pnode
->vSendMsg
.end()) {
729 const CSerializeData
&data
= *it
;
730 assert(data
.size() > pnode
->nSendOffset
);
731 int nBytes
= send(pnode
->hSocket
, &data
[pnode
->nSendOffset
], data
.size() - pnode
->nSendOffset
, MSG_NOSIGNAL
| MSG_DONTWAIT
);
733 pnode
->nLastSend
= GetTime();
734 pnode
->nSendBytes
+= nBytes
;
735 pnode
->nSendOffset
+= nBytes
;
736 pnode
->RecordBytesSent(nBytes
);
737 if (pnode
->nSendOffset
== data
.size()) {
738 pnode
->nSendOffset
= 0;
739 pnode
->nSendSize
-= data
.size();
742 // could not send full message; stop sending more
748 int nErr
= WSAGetLastError();
749 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
751 LogPrintf("socket send error %s\n", NetworkErrorString(nErr
));
752 pnode
->CloseSocketDisconnect();
755 // couldn't send anything at all
760 if (it
== pnode
->vSendMsg
.end()) {
761 assert(pnode
->nSendOffset
== 0);
762 assert(pnode
->nSendSize
== 0);
764 pnode
->vSendMsg
.erase(pnode
->vSendMsg
.begin(), it
);
767 static list
<CNode
*> vNodesDisconnected
;
769 void ThreadSocketHandler()
771 unsigned int nPrevNodeCount
= 0;
779 // Disconnect unused nodes
780 vector
<CNode
*> vNodesCopy
= vNodes
;
781 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
783 if (pnode
->fDisconnect
||
784 (pnode
->GetRefCount() <= 0 && pnode
->vRecvMsg
.empty() && pnode
->nSendSize
== 0 && pnode
->ssSend
.empty()))
786 // remove from vNodes
787 vNodes
.erase(remove(vNodes
.begin(), vNodes
.end(), pnode
), vNodes
.end());
789 // release outbound grant (if any)
790 pnode
->grantOutbound
.Release();
792 // close socket and cleanup
793 pnode
->CloseSocketDisconnect();
795 // hold in disconnected pool until all refs are released
796 if (pnode
->fNetworkNode
|| pnode
->fInbound
)
798 vNodesDisconnected
.push_back(pnode
);
803 // Delete disconnected nodes
804 list
<CNode
*> vNodesDisconnectedCopy
= vNodesDisconnected
;
805 BOOST_FOREACH(CNode
* pnode
, vNodesDisconnectedCopy
)
807 // wait until threads are done using it
808 if (pnode
->GetRefCount() <= 0)
810 bool fDelete
= false;
812 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
815 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
818 TRY_LOCK(pnode
->cs_inventory
, lockInv
);
826 vNodesDisconnected
.remove(pnode
);
832 if(vNodes
.size() != nPrevNodeCount
) {
833 nPrevNodeCount
= vNodes
.size();
834 uiInterface
.NotifyNumConnectionsChanged(nPrevNodeCount
);
838 // Find which sockets have data to receive
840 struct timeval timeout
;
842 timeout
.tv_usec
= 50000; // frequency to poll pnode->vSend
849 FD_ZERO(&fdsetError
);
850 SOCKET hSocketMax
= 0;
851 bool have_fds
= false;
853 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
) {
854 FD_SET(hListenSocket
.socket
, &fdsetRecv
);
855 hSocketMax
= max(hSocketMax
, hListenSocket
.socket
);
861 BOOST_FOREACH(CNode
* pnode
, vNodes
)
863 if (pnode
->hSocket
== INVALID_SOCKET
)
865 FD_SET(pnode
->hSocket
, &fdsetError
);
866 hSocketMax
= max(hSocketMax
, pnode
->hSocket
);
869 // Implement the following logic:
870 // * If there is data to send, select() for sending data. As this only
871 // happens when optimistic write failed, we choose to first drain the
872 // write buffer in this case before receiving more. This avoids
873 // needlessly queueing received data, if the remote peer is not themselves
874 // receiving data. This means properly utilizing TCP flow control signalling.
875 // * Otherwise, if there is no (complete) message in the receive buffer,
876 // or there is space left in the buffer, select() for receiving data.
877 // * (if neither of the above applies, there is certainly one message
878 // in the receiver buffer ready to be processed).
879 // Together, that means that at least one of the following is always possible,
880 // so we don't deadlock:
881 // * We send some data.
882 // * We wait for data to be received (and disconnect after timeout).
883 // * We process a message in the buffer (message handler thread).
885 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
886 if (lockSend
&& !pnode
->vSendMsg
.empty()) {
887 FD_SET(pnode
->hSocket
, &fdsetSend
);
892 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
894 pnode
->vRecvMsg
.empty() || !pnode
->vRecvMsg
.front().complete() ||
895 pnode
->GetTotalRecvSize() <= ReceiveFloodSize()))
896 FD_SET(pnode
->hSocket
, &fdsetRecv
);
901 int nSelect
= select(have_fds
? hSocketMax
+ 1 : 0,
902 &fdsetRecv
, &fdsetSend
, &fdsetError
, &timeout
);
903 boost::this_thread::interruption_point();
905 if (nSelect
== SOCKET_ERROR
)
909 int nErr
= WSAGetLastError();
910 LogPrintf("socket select error %s\n", NetworkErrorString(nErr
));
911 for (unsigned int i
= 0; i
<= hSocketMax
; i
++)
912 FD_SET(i
, &fdsetRecv
);
915 FD_ZERO(&fdsetError
);
916 MilliSleep(timeout
.tv_usec
/1000);
920 // Accept new connections
922 BOOST_FOREACH(const ListenSocket
& hListenSocket
, vhListenSocket
)
924 if (hListenSocket
.socket
!= INVALID_SOCKET
&& FD_ISSET(hListenSocket
.socket
, &fdsetRecv
))
926 struct sockaddr_storage sockaddr
;
927 socklen_t len
= sizeof(sockaddr
);
928 SOCKET hSocket
= accept(hListenSocket
.socket
, (struct sockaddr
*)&sockaddr
, &len
);
932 if (hSocket
!= INVALID_SOCKET
)
933 if (!addr
.SetSockAddr((const struct sockaddr
*)&sockaddr
))
934 LogPrintf("Warning: Unknown socket family\n");
936 bool whitelisted
= hListenSocket
.whitelisted
|| CNode::IsWhitelistedRange(addr
);
939 BOOST_FOREACH(CNode
* pnode
, vNodes
)
944 if (hSocket
== INVALID_SOCKET
)
946 int nErr
= WSAGetLastError();
947 if (nErr
!= WSAEWOULDBLOCK
)
948 LogPrintf("socket error accept failed: %s\n", NetworkErrorString(nErr
));
950 else if (nInbound
>= nMaxConnections
- MAX_OUTBOUND_CONNECTIONS
)
952 CloseSocket(hSocket
);
954 else if (CNode::IsBanned(addr
) && !whitelisted
)
956 LogPrintf("connection from %s dropped (banned)\n", addr
.ToString());
957 CloseSocket(hSocket
);
961 CNode
* pnode
= new CNode(hSocket
, addr
, "", true);
963 pnode
->fWhitelisted
= whitelisted
;
967 vNodes
.push_back(pnode
);
974 // Service each socket
976 vector
<CNode
*> vNodesCopy
;
980 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
983 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
985 boost::this_thread::interruption_point();
990 if (pnode
->hSocket
== INVALID_SOCKET
)
992 if (FD_ISSET(pnode
->hSocket
, &fdsetRecv
) || FD_ISSET(pnode
->hSocket
, &fdsetError
))
994 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
998 // typical socket buffer is 8K-64K
999 char pchBuf
[0x10000];
1000 int nBytes
= recv(pnode
->hSocket
, pchBuf
, sizeof(pchBuf
), MSG_DONTWAIT
);
1003 if (!pnode
->ReceiveMsgBytes(pchBuf
, nBytes
))
1004 pnode
->CloseSocketDisconnect();
1005 pnode
->nLastRecv
= GetTime();
1006 pnode
->nRecvBytes
+= nBytes
;
1007 pnode
->RecordBytesRecv(nBytes
);
1009 else if (nBytes
== 0)
1011 // socket closed gracefully
1012 if (!pnode
->fDisconnect
)
1013 LogPrint("net", "socket closed\n");
1014 pnode
->CloseSocketDisconnect();
1016 else if (nBytes
< 0)
1019 int nErr
= WSAGetLastError();
1020 if (nErr
!= WSAEWOULDBLOCK
&& nErr
!= WSAEMSGSIZE
&& nErr
!= WSAEINTR
&& nErr
!= WSAEINPROGRESS
)
1022 if (!pnode
->fDisconnect
)
1023 LogPrintf("socket recv error %s\n", NetworkErrorString(nErr
));
1024 pnode
->CloseSocketDisconnect();
1034 if (pnode
->hSocket
== INVALID_SOCKET
)
1036 if (FD_ISSET(pnode
->hSocket
, &fdsetSend
))
1038 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1040 SocketSendData(pnode
);
1044 // Inactivity checking
1046 int64_t nTime
= GetTime();
1047 if (nTime
- pnode
->nTimeConnected
> 60)
1049 if (pnode
->nLastRecv
== 0 || pnode
->nLastSend
== 0)
1051 LogPrint("net", "socket no message in first 60 seconds, %d %d from %d\n", pnode
->nLastRecv
!= 0, pnode
->nLastSend
!= 0, pnode
->id
);
1052 pnode
->fDisconnect
= true;
1054 else if (nTime
- pnode
->nLastSend
> TIMEOUT_INTERVAL
)
1056 LogPrintf("socket sending timeout: %is\n", nTime
- pnode
->nLastSend
);
1057 pnode
->fDisconnect
= true;
1059 else if (nTime
- pnode
->nLastRecv
> (pnode
->nVersion
> BIP0031_VERSION
? TIMEOUT_INTERVAL
: 90*60))
1061 LogPrintf("socket receive timeout: %is\n", nTime
- pnode
->nLastRecv
);
1062 pnode
->fDisconnect
= true;
1064 else if (pnode
->nPingNonceSent
&& pnode
->nPingUsecStart
+ TIMEOUT_INTERVAL
* 1000000 < GetTimeMicros())
1066 LogPrintf("ping timeout: %fs\n", 0.000001 * (GetTimeMicros() - pnode
->nPingUsecStart
));
1067 pnode
->fDisconnect
= true;
1073 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1088 void ThreadMapPort()
1090 std::string port
= strprintf("%u", GetListenPort());
1091 const char * multicastif
= 0;
1092 const char * minissdpdpath
= 0;
1093 struct UPNPDev
* devlist
= 0;
1096 #ifndef UPNPDISCOVER_SUCCESS
1098 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0);
1102 devlist
= upnpDiscover(2000, multicastif
, minissdpdpath
, 0, 0, &error
);
1105 struct UPNPUrls urls
;
1106 struct IGDdatas data
;
1109 r
= UPNP_GetValidIGD(devlist
, &urls
, &data
, lanaddr
, sizeof(lanaddr
));
1113 char externalIPAddress
[40];
1114 r
= UPNP_GetExternalIPAddress(urls
.controlURL
, data
.first
.servicetype
, externalIPAddress
);
1115 if(r
!= UPNPCOMMAND_SUCCESS
)
1116 LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r
);
1119 if(externalIPAddress
[0])
1121 LogPrintf("UPnP: ExternalIPAddress = %s\n", externalIPAddress
);
1122 AddLocal(CNetAddr(externalIPAddress
), LOCAL_UPNP
);
1125 LogPrintf("UPnP: GetExternalIPAddress failed.\n");
1129 string strDesc
= "Bitcoin " + FormatFullVersion();
1133 #ifndef UPNPDISCOVER_SUCCESS
1135 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1136 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0);
1139 r
= UPNP_AddPortMapping(urls
.controlURL
, data
.first
.servicetype
,
1140 port
.c_str(), port
.c_str(), lanaddr
, strDesc
.c_str(), "TCP", 0, "0");
1143 if(r
!=UPNPCOMMAND_SUCCESS
)
1144 LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1145 port
, port
, lanaddr
, r
, strupnperror(r
));
1147 LogPrintf("UPnP Port Mapping successful.\n");;
1149 MilliSleep(20*60*1000); // Refresh every 20 minutes
1152 catch (const boost::thread_interrupted
&)
1154 r
= UPNP_DeletePortMapping(urls
.controlURL
, data
.first
.servicetype
, port
.c_str(), "TCP", 0);
1155 LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r
);
1156 freeUPNPDevlist(devlist
); devlist
= 0;
1157 FreeUPNPUrls(&urls
);
1161 LogPrintf("No valid UPnP IGDs found\n");
1162 freeUPNPDevlist(devlist
); devlist
= 0;
1164 FreeUPNPUrls(&urls
);
1168 void MapPort(bool fUseUPnP
)
1170 static boost::thread
* upnp_thread
= NULL
;
1175 upnp_thread
->interrupt();
1176 upnp_thread
->join();
1179 upnp_thread
= new boost::thread(boost::bind(&TraceThread
<void (*)()>, "upnp", &ThreadMapPort
));
1181 else if (upnp_thread
) {
1182 upnp_thread
->interrupt();
1183 upnp_thread
->join();
1192 // Intentionally left blank.
1201 void ThreadDNSAddressSeed()
1203 // goal: only query DNS seeds if address need is acute
1204 if ((addrman
.size() > 0) &&
1205 (!GetBoolArg("-forcednsseed", false))) {
1206 MilliSleep(11 * 1000);
1209 if (vNodes
.size() >= 2) {
1210 LogPrintf("P2P peers available. Skipped DNS seeding.\n");
1215 const vector
<CDNSSeedData
> &vSeeds
= Params().DNSSeeds();
1218 LogPrintf("Loading addresses from DNS seeds (could take a while)\n");
1220 BOOST_FOREACH(const CDNSSeedData
&seed
, vSeeds
) {
1221 if (HaveNameProxy()) {
1222 AddOneShot(seed
.host
);
1224 vector
<CNetAddr
> vIPs
;
1225 vector
<CAddress
> vAdd
;
1226 if (LookupHost(seed
.host
.c_str(), vIPs
))
1228 BOOST_FOREACH(const CNetAddr
& ip
, vIPs
)
1230 int nOneDay
= 24*3600;
1231 CAddress addr
= CAddress(CService(ip
, Params().GetDefaultPort()));
1232 addr
.nTime
= GetTime() - 3*nOneDay
- GetRand(4*nOneDay
); // use a random age between 3 and 7 days old
1233 vAdd
.push_back(addr
);
1237 addrman
.Add(vAdd
, CNetAddr(seed
.name
, true));
1241 LogPrintf("%d addresses found from DNS seeds\n", found
);
1255 void DumpAddresses()
1257 int64_t nStart
= GetTimeMillis();
1262 LogPrint("net", "Flushed %d addresses to peers.dat %dms\n",
1263 addrman
.size(), GetTimeMillis() - nStart
);
1270 if (CNode::BannedSetIsDirty())
1273 CNode::SetBannedSetDirty(false);
1277 void static ProcessOneShot()
1282 if (vOneShots
.empty())
1284 strDest
= vOneShots
.front();
1285 vOneShots
.pop_front();
1288 CSemaphoreGrant
grant(*semOutbound
, true);
1290 if (!OpenNetworkConnection(addr
, &grant
, strDest
.c_str(), true))
1291 AddOneShot(strDest
);
1295 void ThreadOpenConnections()
1297 // Connect to specific addresses
1298 if (mapArgs
.count("-connect") && mapMultiArgs
["-connect"].size() > 0)
1300 for (int64_t nLoop
= 0;; nLoop
++)
1303 BOOST_FOREACH(const std::string
& strAddr
, mapMultiArgs
["-connect"])
1306 OpenNetworkConnection(addr
, NULL
, strAddr
.c_str());
1307 for (int i
= 0; i
< 10 && i
< nLoop
; i
++)
1316 // Initiate network connections
1317 int64_t nStart
= GetTime();
1324 CSemaphoreGrant
grant(*semOutbound
);
1325 boost::this_thread::interruption_point();
1327 // Add seed nodes if DNS seeds are all down (an infrastructure attack?).
1328 if (addrman
.size() == 0 && (GetTime() - nStart
> 60)) {
1329 static bool done
= false;
1331 LogPrintf("Adding fixed seed nodes as DNS doesn't seem to be available.\n");
1332 addrman
.Add(convertSeed6(Params().FixedSeeds()), CNetAddr("127.0.0.1"));
1338 // Choose an address to connect to based on most recently seen
1340 CAddress addrConnect
;
1342 // Only connect out to one peer per network group (/16 for IPv4).
1343 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1345 set
<vector
<unsigned char> > setConnected
;
1348 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
1349 if (!pnode
->fInbound
) {
1350 setConnected
.insert(pnode
->addr
.GetGroup());
1356 int64_t nANow
= GetAdjustedTime();
1361 CAddrInfo addr
= addrman
.Select();
1363 // if we selected an invalid address, restart
1364 if (!addr
.IsValid() || setConnected
.count(addr
.GetGroup()) || IsLocal(addr
))
1367 // If we didn't find an appropriate destination after trying 100 addresses fetched from addrman,
1368 // stop this loop, and let the outer loop run again (which sleeps, adds seed nodes, recalculates
1369 // already-connected network ranges, ...) before trying new addrman addresses.
1374 if (IsLimited(addr
))
1377 // only consider very recently tried nodes after 30 failed attempts
1378 if (nANow
- addr
.nLastTry
< 600 && nTries
< 30)
1381 // do not allow non-default ports, unless after 50 invalid addresses selected already
1382 if (addr
.GetPort() != Params().GetDefaultPort() && nTries
< 50)
1389 if (addrConnect
.IsValid())
1390 OpenNetworkConnection(addrConnect
, &grant
);
1394 void ThreadOpenAddedConnections()
1397 LOCK(cs_vAddedNodes
);
1398 vAddedNodes
= mapMultiArgs
["-addnode"];
1401 if (HaveNameProxy()) {
1403 list
<string
> lAddresses(0);
1405 LOCK(cs_vAddedNodes
);
1406 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1407 lAddresses
.push_back(strAddNode
);
1409 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1411 CSemaphoreGrant
grant(*semOutbound
);
1412 OpenNetworkConnection(addr
, &grant
, strAddNode
.c_str());
1415 MilliSleep(120000); // Retry every 2 minutes
1419 for (unsigned int i
= 0; true; i
++)
1421 list
<string
> lAddresses(0);
1423 LOCK(cs_vAddedNodes
);
1424 BOOST_FOREACH(const std::string
& strAddNode
, vAddedNodes
)
1425 lAddresses
.push_back(strAddNode
);
1428 list
<vector
<CService
> > lservAddressesToAdd(0);
1429 BOOST_FOREACH(const std::string
& strAddNode
, lAddresses
) {
1430 vector
<CService
> vservNode(0);
1431 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
1433 lservAddressesToAdd
.push_back(vservNode
);
1435 LOCK(cs_setservAddNodeAddresses
);
1436 BOOST_FOREACH(const CService
& serv
, vservNode
)
1437 setservAddNodeAddresses
.insert(serv
);
1441 // Attempt to connect to each IP for each addnode entry until at least one is successful per addnode entry
1442 // (keeping in mind that addnode entries can have many IPs if fNameLookup)
1445 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1446 for (list
<vector
<CService
> >::iterator it
= lservAddressesToAdd
.begin(); it
!= lservAddressesToAdd
.end(); it
++)
1447 BOOST_FOREACH(const CService
& addrNode
, *(it
))
1448 if (pnode
->addr
== addrNode
)
1450 it
= lservAddressesToAdd
.erase(it
);
1455 BOOST_FOREACH(vector
<CService
>& vserv
, lservAddressesToAdd
)
1457 CSemaphoreGrant
grant(*semOutbound
);
1458 OpenNetworkConnection(CAddress(vserv
[i
% vserv
.size()]), &grant
);
1461 MilliSleep(120000); // Retry every 2 minutes
1465 // if successful, this moves the passed grant to the constructed node
1466 bool OpenNetworkConnection(const CAddress
& addrConnect
, CSemaphoreGrant
*grantOutbound
, const char *pszDest
, bool fOneShot
)
1469 // Initiate outbound network connection
1471 boost::this_thread::interruption_point();
1473 if (IsLocal(addrConnect
) ||
1474 FindNode((CNetAddr
)addrConnect
) || CNode::IsBanned(addrConnect
) ||
1475 FindNode(addrConnect
.ToStringIPPort()))
1477 } else if (FindNode(std::string(pszDest
)))
1480 CNode
* pnode
= ConnectNode(addrConnect
, pszDest
);
1481 boost::this_thread::interruption_point();
1486 grantOutbound
->MoveTo(pnode
->grantOutbound
);
1487 pnode
->fNetworkNode
= true;
1489 pnode
->fOneShot
= true;
1495 void ThreadMessageHandler()
1497 boost::mutex condition_mutex
;
1498 boost::unique_lock
<boost::mutex
> lock(condition_mutex
);
1500 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL
);
1503 vector
<CNode
*> vNodesCopy
;
1506 vNodesCopy
= vNodes
;
1507 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
) {
1512 // Poll the connected nodes for messages
1513 CNode
* pnodeTrickle
= NULL
;
1514 if (!vNodesCopy
.empty())
1515 pnodeTrickle
= vNodesCopy
[GetRand(vNodesCopy
.size())];
1519 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1521 if (pnode
->fDisconnect
)
1526 TRY_LOCK(pnode
->cs_vRecvMsg
, lockRecv
);
1529 if (!g_signals
.ProcessMessages(pnode
))
1530 pnode
->CloseSocketDisconnect();
1532 if (pnode
->nSendSize
< SendBufferSize())
1534 if (!pnode
->vRecvGetData
.empty() || (!pnode
->vRecvMsg
.empty() && pnode
->vRecvMsg
[0].complete()))
1541 boost::this_thread::interruption_point();
1545 TRY_LOCK(pnode
->cs_vSend
, lockSend
);
1547 g_signals
.SendMessages(pnode
, pnode
== pnodeTrickle
|| pnode
->fWhitelisted
);
1549 boost::this_thread::interruption_point();
1554 BOOST_FOREACH(CNode
* pnode
, vNodesCopy
)
1559 messageHandlerCondition
.timed_wait(lock
, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::milliseconds(100));
1568 bool BindListenPort(const CService
&addrBind
, string
& strError
, bool fWhitelisted
)
1573 // Create socket for listening for incoming connections
1574 struct sockaddr_storage sockaddr
;
1575 socklen_t len
= sizeof(sockaddr
);
1576 if (!addrBind
.GetSockAddr((struct sockaddr
*)&sockaddr
, &len
))
1578 strError
= strprintf("Error: Bind address family for %s not supported", addrBind
.ToString());
1579 LogPrintf("%s\n", strError
);
1583 SOCKET hListenSocket
= socket(((struct sockaddr
*)&sockaddr
)->sa_family
, SOCK_STREAM
, IPPROTO_TCP
);
1584 if (hListenSocket
== INVALID_SOCKET
)
1586 strError
= strprintf("Error: Couldn't open socket for incoming connections (socket returned error %s)", NetworkErrorString(WSAGetLastError()));
1587 LogPrintf("%s\n", strError
);
1593 // Different way of disabling SIGPIPE on BSD
1594 setsockopt(hListenSocket
, SOL_SOCKET
, SO_NOSIGPIPE
, (void*)&nOne
, sizeof(int));
1596 // Allow binding if the port is still in TIME_WAIT state after
1597 // the program was closed and restarted. Not an issue on windows!
1598 setsockopt(hListenSocket
, SOL_SOCKET
, SO_REUSEADDR
, (void*)&nOne
, sizeof(int));
1601 // Set to non-blocking, incoming connections will also inherit this
1602 if (!SetSocketNonBlocking(hListenSocket
, true)) {
1603 strError
= strprintf("BindListenPort: Setting listening socket to non-blocking failed, error %s\n", NetworkErrorString(WSAGetLastError()));
1604 LogPrintf("%s\n", strError
);
1608 // some systems don't have IPV6_V6ONLY but are always v6only; others do have the option
1609 // and enable it by default or not. Try to enable it, if possible.
1610 if (addrBind
.IsIPv6()) {
1613 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (const char*)&nOne
, sizeof(int));
1615 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_V6ONLY
, (void*)&nOne
, sizeof(int));
1619 int nProtLevel
= PROTECTION_LEVEL_UNRESTRICTED
;
1620 setsockopt(hListenSocket
, IPPROTO_IPV6
, IPV6_PROTECTION_LEVEL
, (const char*)&nProtLevel
, sizeof(int));
1624 if (::bind(hListenSocket
, (struct sockaddr
*)&sockaddr
, len
) == SOCKET_ERROR
)
1626 int nErr
= WSAGetLastError();
1627 if (nErr
== WSAEADDRINUSE
)
1628 strError
= strprintf(_("Unable to bind to %s on this computer. Bitcoin Core is probably already running."), addrBind
.ToString());
1630 strError
= strprintf(_("Unable to bind to %s on this computer (bind returned error %s)"), addrBind
.ToString(), NetworkErrorString(nErr
));
1631 LogPrintf("%s\n", strError
);
1632 CloseSocket(hListenSocket
);
1635 LogPrintf("Bound to %s\n", addrBind
.ToString());
1637 // Listen for incoming connections
1638 if (listen(hListenSocket
, SOMAXCONN
) == SOCKET_ERROR
)
1640 strError
= strprintf(_("Error: Listening for incoming connections failed (listen returned error %s)"), NetworkErrorString(WSAGetLastError()));
1641 LogPrintf("%s\n", strError
);
1642 CloseSocket(hListenSocket
);
1646 vhListenSocket
.push_back(ListenSocket(hListenSocket
, fWhitelisted
));
1648 if (addrBind
.IsRoutable() && fDiscover
&& !fWhitelisted
)
1649 AddLocal(addrBind
, LOCAL_BIND
);
1654 void static Discover(boost::thread_group
& threadGroup
)
1660 // Get local host IP
1661 char pszHostName
[256] = "";
1662 if (gethostname(pszHostName
, sizeof(pszHostName
)) != SOCKET_ERROR
)
1664 vector
<CNetAddr
> vaddr
;
1665 if (LookupHost(pszHostName
, vaddr
))
1667 BOOST_FOREACH (const CNetAddr
&addr
, vaddr
)
1669 if (AddLocal(addr
, LOCAL_IF
))
1670 LogPrintf("%s: %s - %s\n", __func__
, pszHostName
, addr
.ToString());
1675 // Get local host ip
1676 struct ifaddrs
* myaddrs
;
1677 if (getifaddrs(&myaddrs
) == 0)
1679 for (struct ifaddrs
* ifa
= myaddrs
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
1681 if (ifa
->ifa_addr
== NULL
) continue;
1682 if ((ifa
->ifa_flags
& IFF_UP
) == 0) continue;
1683 if (strcmp(ifa
->ifa_name
, "lo") == 0) continue;
1684 if (strcmp(ifa
->ifa_name
, "lo0") == 0) continue;
1685 if (ifa
->ifa_addr
->sa_family
== AF_INET
)
1687 struct sockaddr_in
* s4
= (struct sockaddr_in
*)(ifa
->ifa_addr
);
1688 CNetAddr
addr(s4
->sin_addr
);
1689 if (AddLocal(addr
, LOCAL_IF
))
1690 LogPrintf("%s: IPv4 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1692 else if (ifa
->ifa_addr
->sa_family
== AF_INET6
)
1694 struct sockaddr_in6
* s6
= (struct sockaddr_in6
*)(ifa
->ifa_addr
);
1695 CNetAddr
addr(s6
->sin6_addr
);
1696 if (AddLocal(addr
, LOCAL_IF
))
1697 LogPrintf("%s: IPv6 %s: %s\n", __func__
, ifa
->ifa_name
, addr
.ToString());
1700 freeifaddrs(myaddrs
);
1705 void StartNode(boost::thread_group
& threadGroup
, CScheduler
& scheduler
)
1707 uiInterface
.InitMessage(_("Loading addresses..."));
1708 // Load addresses for peers.dat
1709 int64_t nStart
= GetTimeMillis();
1712 if (!adb
.Read(addrman
))
1713 LogPrintf("Invalid or missing peers.dat; recreating\n");
1716 //try to read stored banlist
1719 if (!bandb
.Read(banmap
))
1720 LogPrintf("Invalid or missing banlist.dat; recreating\n");
1722 CNode::SetBanned(banmap
); //thread save setter
1723 CNode::SetBannedSetDirty(false); //no need to write down just read or nonexistent data
1724 CNode::SweepBanned(); //sweap out unused entries
1726 LogPrintf("Loaded %i addresses from peers.dat %dms\n",
1727 addrman
.size(), GetTimeMillis() - nStart
);
1728 fAddressesInitialized
= true;
1730 if (semOutbound
== NULL
) {
1731 // initialize semaphore
1732 int nMaxOutbound
= min(MAX_OUTBOUND_CONNECTIONS
, nMaxConnections
);
1733 semOutbound
= new CSemaphore(nMaxOutbound
);
1736 if (pnodeLocalHost
== NULL
)
1737 pnodeLocalHost
= new CNode(INVALID_SOCKET
, CAddress(CService("127.0.0.1", 0), nLocalServices
));
1739 Discover(threadGroup
);
1745 if (!GetBoolArg("-dnsseed", true))
1746 LogPrintf("DNS seeding disabled\n");
1748 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "dnsseed", &ThreadDNSAddressSeed
));
1750 // Map ports with UPnP
1751 MapPort(GetBoolArg("-upnp", DEFAULT_UPNP
));
1753 // Send and receive from sockets, accept connections
1754 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "net", &ThreadSocketHandler
));
1756 // Initiate outbound connections from -addnode
1757 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "addcon", &ThreadOpenAddedConnections
));
1759 // Initiate outbound connections
1760 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "opencon", &ThreadOpenConnections
));
1763 threadGroup
.create_thread(boost::bind(&TraceThread
<void (*)()>, "msghand", &ThreadMessageHandler
));
1765 // Dump network addresses
1766 scheduler
.scheduleEvery(&DumpData
, DUMP_ADDRESSES_INTERVAL
);
1771 LogPrintf("StopNode()\n");
1774 for (int i
=0; i
<MAX_OUTBOUND_CONNECTIONS
; i
++)
1775 semOutbound
->post();
1777 if (fAddressesInitialized
)
1780 fAddressesInitialized
= false;
1794 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1795 if (pnode
->hSocket
!= INVALID_SOCKET
)
1796 CloseSocket(pnode
->hSocket
);
1797 BOOST_FOREACH(ListenSocket
& hListenSocket
, vhListenSocket
)
1798 if (hListenSocket
.socket
!= INVALID_SOCKET
)
1799 if (!CloseSocket(hListenSocket
.socket
))
1800 LogPrintf("CloseSocket(hListenSocket) failed with error %s\n", NetworkErrorString(WSAGetLastError()));
1802 // clean up some globals (to help leak detection)
1803 BOOST_FOREACH(CNode
*pnode
, vNodes
)
1805 BOOST_FOREACH(CNode
*pnode
, vNodesDisconnected
)
1808 vNodesDisconnected
.clear();
1809 vhListenSocket
.clear();
1812 delete pnodeLocalHost
;
1813 pnodeLocalHost
= NULL
;
1816 // Shutdown Windows Sockets
1821 instance_of_cnetcleanup
;
1829 void RelayTransaction(const CTransaction
& tx
)
1831 CDataStream
ss(SER_NETWORK
, PROTOCOL_VERSION
);
1834 RelayTransaction(tx
, ss
);
1837 void RelayTransaction(const CTransaction
& tx
, const CDataStream
& ss
)
1839 CInv
inv(MSG_TX
, tx
.GetHash());
1842 // Expire old relay messages
1843 while (!vRelayExpiration
.empty() && vRelayExpiration
.front().first
< GetTime())
1845 mapRelay
.erase(vRelayExpiration
.front().second
);
1846 vRelayExpiration
.pop_front();
1849 // Save original serialized message so newer versions are preserved
1850 mapRelay
.insert(std::make_pair(inv
, ss
));
1851 vRelayExpiration
.push_back(std::make_pair(GetTime() + 15 * 60, inv
));
1854 BOOST_FOREACH(CNode
* pnode
, vNodes
)
1856 if(!pnode
->fRelayTxes
)
1858 LOCK(pnode
->cs_filter
);
1861 if (pnode
->pfilter
->IsRelevantAndUpdate(tx
))
1862 pnode
->PushInventory(inv
);
1864 pnode
->PushInventory(inv
);
1868 void CNode::RecordBytesRecv(uint64_t bytes
)
1870 LOCK(cs_totalBytesRecv
);
1871 nTotalBytesRecv
+= bytes
;
1874 void CNode::RecordBytesSent(uint64_t bytes
)
1876 LOCK(cs_totalBytesSent
);
1877 nTotalBytesSent
+= bytes
;
1880 uint64_t CNode::GetTotalBytesRecv()
1882 LOCK(cs_totalBytesRecv
);
1883 return nTotalBytesRecv
;
1886 uint64_t CNode::GetTotalBytesSent()
1888 LOCK(cs_totalBytesSent
);
1889 return nTotalBytesSent
;
1892 void CNode::Fuzz(int nChance
)
1894 if (!fSuccessfullyConnected
) return; // Don't fuzz initial handshake
1895 if (GetRand(nChance
) != 0) return; // Fuzz 1 of every nChance messages
1900 // xor a random byte with a random value:
1901 if (!ssSend
.empty()) {
1902 CDataStream::size_type pos
= GetRand(ssSend
.size());
1903 ssSend
[pos
] ^= (unsigned char)(GetRand(256));
1907 // delete a random byte:
1908 if (!ssSend
.empty()) {
1909 CDataStream::size_type pos
= GetRand(ssSend
.size());
1910 ssSend
.erase(ssSend
.begin()+pos
);
1914 // insert a random byte at a random position
1916 CDataStream::size_type pos
= GetRand(ssSend
.size());
1917 char ch
= (char)GetRand(256);
1918 ssSend
.insert(ssSend
.begin()+pos
, ch
);
1922 // Chance of more than one change half the time:
1923 // (more changes exponentially less likely):
1933 pathAddr
= GetDataDir() / "peers.dat";
1936 bool CAddrDB::Write(const CAddrMan
& addr
)
1938 // Generate random temporary filename
1939 unsigned short randv
= 0;
1940 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
1941 std::string tmpfn
= strprintf("peers.dat.%04x", randv
);
1943 // serialize addresses, checksum data up to that point, then append csum
1944 CDataStream
ssPeers(SER_DISK
, CLIENT_VERSION
);
1945 ssPeers
<< FLATDATA(Params().MessageStart());
1947 uint256 hash
= Hash(ssPeers
.begin(), ssPeers
.end());
1950 // open temp output file, and associate with CAutoFile
1951 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
1952 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
1953 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
1954 if (fileout
.IsNull())
1955 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
1957 // Write and commit header, data
1961 catch (const std::exception
& e
) {
1962 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
1964 FileCommit(fileout
.Get());
1967 // replace existing peers.dat, if any, with new peers.dat.XXXX
1968 if (!RenameOver(pathTmp
, pathAddr
))
1969 return error("%s: Rename-into-place failed", __func__
);
1974 bool CAddrDB::Read(CAddrMan
& addr
)
1976 // open input file, and associate with CAutoFile
1977 FILE *file
= fopen(pathAddr
.string().c_str(), "rb");
1978 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
1979 if (filein
.IsNull())
1980 return error("%s: Failed to open file %s", __func__
, pathAddr
.string());
1982 // use file size to size memory buffer
1983 uint64_t fileSize
= boost::filesystem::file_size(pathAddr
);
1984 uint64_t dataSize
= 0;
1985 // Don't try to resize to a negative number if file is small
1986 if (fileSize
>= sizeof(uint256
))
1987 dataSize
= fileSize
- sizeof(uint256
);
1988 vector
<unsigned char> vchData
;
1989 vchData
.resize(dataSize
);
1992 // read data and checksum from file
1994 filein
.read((char *)&vchData
[0], dataSize
);
1997 catch (const std::exception
& e
) {
1998 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2002 CDataStream
ssPeers(vchData
, SER_DISK
, CLIENT_VERSION
);
2004 // verify stored checksum matches input data
2005 uint256 hashTmp
= Hash(ssPeers
.begin(), ssPeers
.end());
2006 if (hashIn
!= hashTmp
)
2007 return error("%s: Checksum mismatch, data corrupted", __func__
);
2009 unsigned char pchMsgTmp
[4];
2011 // de-serialize file header (network specific magic number) and ..
2012 ssPeers
>> FLATDATA(pchMsgTmp
);
2014 // ... verify the network matches ours
2015 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2016 return error("%s: Invalid network magic number", __func__
);
2018 // de-serialize address data into one CAddrMan object
2021 catch (const std::exception
& e
) {
2022 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2028 unsigned int ReceiveFloodSize() { return 1000*GetArg("-maxreceivebuffer", 5*1000); }
2029 unsigned int SendBufferSize() { return 1000*GetArg("-maxsendbuffer", 1*1000); }
2031 CNode::CNode(SOCKET hSocketIn
, const CAddress
& addrIn
, const std::string
& addrNameIn
, bool fInboundIn
) :
2032 ssSend(SER_NETWORK
, INIT_PROTO_VERSION
),
2033 addrKnown(5000, 0.001, insecure_rand()),
2034 setInventoryKnown(SendBufferSize() / 1000)
2037 hSocket
= hSocketIn
;
2038 nRecvVersion
= INIT_PROTO_VERSION
;
2043 nTimeConnected
= GetTime();
2046 addrName
= addrNameIn
== "" ? addr
.ToStringIPPort() : addrNameIn
;
2049 fWhitelisted
= false;
2051 fClient
= false; // set by version message
2052 fInbound
= fInboundIn
;
2053 fNetworkNode
= false;
2054 fSuccessfullyConnected
= false;
2055 fDisconnect
= false;
2059 hashContinue
= uint256();
2060 nStartingHeight
= -1;
2063 pfilter
= new CBloomFilter();
2067 fPingQueued
= false;
2070 LOCK(cs_nLastNodeId
);
2075 LogPrint("net", "Added connection to %s peer=%d\n", addrName
, id
);
2077 LogPrint("net", "Added connection peer=%d\n", id
);
2079 // Be shy and don't send version until we hear
2080 if (hSocket
!= INVALID_SOCKET
&& !fInbound
)
2083 GetNodeSignals().InitializeNode(GetId(), this);
2088 CloseSocket(hSocket
);
2093 GetNodeSignals().FinalizeNode(GetId());
2096 void CNode::AskFor(const CInv
& inv
)
2098 if (mapAskFor
.size() > MAPASKFOR_MAX_SZ
)
2100 // We're using mapAskFor as a priority queue,
2101 // the key is the earliest time the request can be sent
2102 int64_t nRequestTime
;
2103 limitedmap
<CInv
, int64_t>::const_iterator it
= mapAlreadyAskedFor
.find(inv
);
2104 if (it
!= mapAlreadyAskedFor
.end())
2105 nRequestTime
= it
->second
;
2108 LogPrint("net", "askfor %s %d (%s) peer=%d\n", inv
.ToString(), nRequestTime
, DateTimeStrFormat("%H:%M:%S", nRequestTime
/1000000), id
);
2110 // Make sure not to reuse time indexes to keep things in the same order
2111 int64_t nNow
= GetTimeMicros() - 1000000;
2112 static int64_t nLastTime
;
2114 nNow
= std::max(nNow
, nLastTime
);
2117 // Each retry is 2 minutes after the last
2118 nRequestTime
= std::max(nRequestTime
+ 2 * 60 * 1000000, nNow
);
2119 if (it
!= mapAlreadyAskedFor
.end())
2120 mapAlreadyAskedFor
.update(it
, nRequestTime
);
2122 mapAlreadyAskedFor
.insert(std::make_pair(inv
, nRequestTime
));
2123 mapAskFor
.insert(std::make_pair(nRequestTime
, inv
));
2126 void CNode::BeginMessage(const char* pszCommand
) EXCLUSIVE_LOCK_FUNCTION(cs_vSend
)
2128 ENTER_CRITICAL_SECTION(cs_vSend
);
2129 assert(ssSend
.size() == 0);
2130 ssSend
<< CMessageHeader(Params().MessageStart(), pszCommand
, 0);
2131 LogPrint("net", "sending: %s ", SanitizeString(pszCommand
));
2134 void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend
)
2138 LEAVE_CRITICAL_SECTION(cs_vSend
);
2140 LogPrint("net", "(aborted)\n");
2143 void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend
)
2145 // The -*messagestest options are intentionally not documented in the help message,
2146 // since they are only used during development to debug the networking code and are
2147 // not intended for end-users.
2148 if (mapArgs
.count("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 2)) == 0)
2150 LogPrint("net", "dropmessages DROPPING SEND MESSAGE\n");
2154 if (mapArgs
.count("-fuzzmessagestest"))
2155 Fuzz(GetArg("-fuzzmessagestest", 10));
2157 if (ssSend
.size() == 0)
2161 unsigned int nSize
= ssSend
.size() - CMessageHeader::HEADER_SIZE
;
2162 WriteLE32((uint8_t*)&ssSend
[CMessageHeader::MESSAGE_SIZE_OFFSET
], nSize
);
2165 uint256 hash
= Hash(ssSend
.begin() + CMessageHeader::HEADER_SIZE
, ssSend
.end());
2166 unsigned int nChecksum
= 0;
2167 memcpy(&nChecksum
, &hash
, sizeof(nChecksum
));
2168 assert(ssSend
.size () >= CMessageHeader::CHECKSUM_OFFSET
+ sizeof(nChecksum
));
2169 memcpy((char*)&ssSend
[CMessageHeader::CHECKSUM_OFFSET
], &nChecksum
, sizeof(nChecksum
));
2171 LogPrint("net", "(%d bytes) peer=%d\n", nSize
, id
);
2173 std::deque
<CSerializeData
>::iterator it
= vSendMsg
.insert(vSendMsg
.end(), CSerializeData());
2174 ssSend
.GetAndClear(*it
);
2175 nSendSize
+= (*it
).size();
2177 // If write queue empty, attempt "optimistic write"
2178 if (it
== vSendMsg
.begin())
2179 SocketSendData(this);
2181 LEAVE_CRITICAL_SECTION(cs_vSend
);
2190 pathBanlist
= GetDataDir() / "banlist.dat";
2193 bool CBanDB::Write(const banmap_t
& banSet
)
2195 // Generate random temporary filename
2196 unsigned short randv
= 0;
2197 GetRandBytes((unsigned char*)&randv
, sizeof(randv
));
2198 std::string tmpfn
= strprintf("banlist.dat.%04x", randv
);
2200 // serialize banlist, checksum data up to that point, then append csum
2201 CDataStream
ssBanlist(SER_DISK
, CLIENT_VERSION
);
2202 ssBanlist
<< FLATDATA(Params().MessageStart());
2203 ssBanlist
<< banSet
;
2204 uint256 hash
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2207 // open temp output file, and associate with CAutoFile
2208 boost::filesystem::path pathTmp
= GetDataDir() / tmpfn
;
2209 FILE *file
= fopen(pathTmp
.string().c_str(), "wb");
2210 CAutoFile
fileout(file
, SER_DISK
, CLIENT_VERSION
);
2211 if (fileout
.IsNull())
2212 return error("%s: Failed to open file %s", __func__
, pathTmp
.string());
2214 // Write and commit header, data
2216 fileout
<< ssBanlist
;
2218 catch (const std::exception
& e
) {
2219 return error("%s: Serialize or I/O error - %s", __func__
, e
.what());
2221 FileCommit(fileout
.Get());
2224 // replace existing banlist.dat, if any, with new banlist.dat.XXXX
2225 if (!RenameOver(pathTmp
, pathBanlist
))
2226 return error("%s: Rename-into-place failed", __func__
);
2231 bool CBanDB::Read(banmap_t
& banSet
)
2233 // open input file, and associate with CAutoFile
2234 FILE *file
= fopen(pathBanlist
.string().c_str(), "rb");
2235 CAutoFile
filein(file
, SER_DISK
, CLIENT_VERSION
);
2236 if (filein
.IsNull())
2237 return error("%s: Failed to open file %s", __func__
, pathBanlist
.string());
2239 // use file size to size memory buffer
2240 uint64_t fileSize
= boost::filesystem::file_size(pathBanlist
);
2241 uint64_t dataSize
= 0;
2242 // Don't try to resize to a negative number if file is small
2243 if (fileSize
>= sizeof(uint256
))
2244 dataSize
= fileSize
- sizeof(uint256
);
2245 vector
<unsigned char> vchData
;
2246 vchData
.resize(dataSize
);
2249 // read data and checksum from file
2251 filein
.read((char *)&vchData
[0], dataSize
);
2254 catch (const std::exception
& e
) {
2255 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2259 CDataStream
ssBanlist(vchData
, SER_DISK
, CLIENT_VERSION
);
2261 // verify stored checksum matches input data
2262 uint256 hashTmp
= Hash(ssBanlist
.begin(), ssBanlist
.end());
2263 if (hashIn
!= hashTmp
)
2264 return error("%s: Checksum mismatch, data corrupted", __func__
);
2266 unsigned char pchMsgTmp
[4];
2268 // de-serialize file header (network specific magic number) and ..
2269 ssBanlist
>> FLATDATA(pchMsgTmp
);
2271 // ... verify the network matches ours
2272 if (memcmp(pchMsgTmp
, Params().MessageStart(), sizeof(pchMsgTmp
)))
2273 return error("%s: Invalid network magic number", __func__
);
2275 // de-serialize address data into one CAddrMan object
2276 ssBanlist
>> banSet
;
2278 catch (const std::exception
& e
) {
2279 return error("%s: Deserialize or I/O error - %s", __func__
, e
.what());
2287 int64_t nStart
= GetTimeMillis();
2289 CNode::SweepBanned(); //clean unused entires (if bantime has expired)
2293 CNode::GetBanned(banmap
);
2294 bandb
.Write(banmap
);
2296 LogPrint("net", "Flushed %d banned node ips/subnets to banlist.dat %dms\n",
2297 banmap
.size(), GetTimeMillis() - nStart
);