]> Git Repo - VerusCoin.git/blame - src/net.cpp
Add my DNS seed domain
[VerusCoin.git] / src / net.cpp
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
b2120e22 2// Copyright (c) 2011 The Bitcoin developers
0a61b0df 3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
5
6#include "headers.h"
f23f9a03 7#include "irc.h"
1512d5ce 8#include "db.h"
40c2614e 9#include "net.h"
edd309e5 10#include "init.h"
fdd7d047 11#include "strlcpy.h"
0a61b0df 12
6853e627 13#ifdef WIN32
013df1cc
MC
14#include <string.h>
15#endif
16
8bb5edc1
MC
17#ifdef USE_UPNP
18#include <miniupnpc/miniwget.h>
19#include <miniupnpc/miniupnpc.h>
20#include <miniupnpc/upnpcommands.h>
21#include <miniupnpc/upnperrors.h>
22#endif
23
223b6f1b
WL
24using namespace std;
25using namespace boost;
26
0a61b0df 27static const int MAX_OUTBOUND_CONNECTIONS = 8;
28
29void ThreadMessageHandler2(void* parg);
30void ThreadSocketHandler2(void* parg);
31void ThreadOpenConnections2(void* parg);
8bb5edc1
MC
32#ifdef USE_UPNP
33void ThreadMapPort2(void* parg);
34#endif
2bc6cece 35void ThreadDNSAddressSeed2(void* parg);
0a61b0df 36bool OpenNetworkConnection(const CAddress& addrConnect);
37
38
39
40
41
42//
43// Global state variables
44//
45bool fClient = false;
a6a5bb7c 46bool fAllowDNS = false;
0a61b0df 47uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
a6a5bb7c 48CAddress addrLocalHost("0.0.0.0", 0, false, nLocalServices);
99860de3 49static CNode* pnodeLocalHost = NULL;
0a61b0df 50uint64 nLocalHostNonce = 0;
51array<int, 10> vnThreadsRunning;
99860de3 52static SOCKET hListenSocket = INVALID_SOCKET;
0a61b0df 53
54vector<CNode*> vNodes;
55CCriticalSection cs_vNodes;
56map<vector<unsigned char>, CAddress> mapAddresses;
57CCriticalSection cs_mapAddresses;
58map<CInv, CDataStream> mapRelay;
59deque<pair<int64, CInv> > vRelayExpiration;
60CCriticalSection cs_mapRelay;
61map<CInv, int64> mapAlreadyAskedFor;
62
63// Settings
64int fUseProxy = false;
76d660eb 65int nConnectTimeout = 5000;
a6a5bb7c 66CAddress addrProxy("127.0.0.1",9050);
0a61b0df 67
68
69
70
00bcfe0b
GA
71unsigned short GetListenPort()
72{
73 return (unsigned short)(GetArg("-port", GetDefaultPort()));
74}
0a61b0df 75
76void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
77{
78 // Filter out duplicate requests
79 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
80 return;
81 pindexLastGetBlocksBegin = pindexBegin;
82 hashLastGetBlocksEnd = hashEnd;
83
84 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
85}
86
87
88
89
90
76d660eb 91bool ConnectSocket(const CAddress& addrConnect, SOCKET& hSocketRet, int nTimeout)
0a61b0df 92{
93 hSocketRet = INVALID_SOCKET;
94
95 SOCKET hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
96 if (hSocket == INVALID_SOCKET)
97 return false;
ec93a0e2 98#ifdef SO_NOSIGPIPE
0a61b0df 99 int set = 1;
100 setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
101#endif
102
482cb656 103 bool fProxy = (fUseProxy && addrConnect.IsRoutable());
0a61b0df 104 struct sockaddr_in sockaddr = (fProxy ? addrProxy.GetSockAddr() : addrConnect.GetSockAddr());
105
6853e627 106#ifdef WIN32
76d660eb
PW
107 u_long fNonblock = 1;
108 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
109#else
110 int fFlags = fcntl(hSocket, F_GETFL, 0);
111 if (fcntl(hSocket, F_SETFL, fFlags | O_NONBLOCK) == -1)
112#endif
113 {
114 closesocket(hSocket);
115 return false;
116 }
117
118
0a61b0df 119 if (connect(hSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
76d660eb
PW
120 {
121 // WSAEINVAL is here because some legacy version of winsock uses it
122 if (WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAEINVAL)
123 {
124 struct timeval timeout;
125 timeout.tv_sec = nTimeout / 1000;
126 timeout.tv_usec = (nTimeout % 1000) * 1000;
127
128 fd_set fdset;
129 FD_ZERO(&fdset);
130 FD_SET(hSocket, &fdset);
131 int nRet = select(hSocket + 1, NULL, &fdset, NULL, &timeout);
132 if (nRet == 0)
133 {
134 printf("connection timeout\n");
135 closesocket(hSocket);
136 return false;
137 }
138 if (nRet == SOCKET_ERROR)
139 {
140 printf("select() for connection failed: %i\n",WSAGetLastError());
141 closesocket(hSocket);
142 return false;
143 }
144 socklen_t nRetSize = sizeof(nRet);
6853e627 145#ifdef WIN32
76d660eb
PW
146 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, (char*)(&nRet), &nRetSize) == SOCKET_ERROR)
147#else
148 if (getsockopt(hSocket, SOL_SOCKET, SO_ERROR, &nRet, &nRetSize) == SOCKET_ERROR)
149#endif
150 {
151 printf("getsockopt() for connection failed: %i\n",WSAGetLastError());
152 closesocket(hSocket);
153 return false;
154 }
155 if (nRet != 0)
156 {
013df1cc 157 printf("connect() failed after select(): %s\n",strerror(nRet));
76d660eb
PW
158 closesocket(hSocket);
159 return false;
160 }
161 }
6853e627 162#ifdef WIN32
76d660eb
PW
163 else if (WSAGetLastError() != WSAEISCONN)
164#else
165 else
166#endif
167 {
ecd3e728 168 printf("connect() failed: %i\n",WSAGetLastError());
76d660eb
PW
169 closesocket(hSocket);
170 return false;
171 }
172 }
173
174 /*
175 this isn't even strictly necessary
176 CNode::ConnectNode immediately turns the socket back to non-blocking
177 but we'll turn it back to blocking just in case
178 */
6853e627 179#ifdef WIN32
76d660eb
PW
180 fNonblock = 0;
181 if (ioctlsocket(hSocket, FIONBIO, &fNonblock) == SOCKET_ERROR)
182#else
183 fFlags = fcntl(hSocket, F_GETFL, 0);
184 if (fcntl(hSocket, F_SETFL, fFlags & !O_NONBLOCK) == SOCKET_ERROR)
185#endif
0a61b0df 186 {
187 closesocket(hSocket);
188 return false;
189 }
190
191 if (fProxy)
192 {
a6a5bb7c 193 printf("proxy connecting %s\n", addrConnect.ToString().c_str());
0a61b0df 194 char pszSocks4IP[] = "\4\1\0\0\0\0\0\0user";
195 memcpy(pszSocks4IP + 2, &addrConnect.port, 2);
196 memcpy(pszSocks4IP + 4, &addrConnect.ip, 4);
197 char* pszSocks4 = pszSocks4IP;
198 int nSize = sizeof(pszSocks4IP);
199
200 int ret = send(hSocket, pszSocks4, nSize, MSG_NOSIGNAL);
201 if (ret != nSize)
202 {
203 closesocket(hSocket);
204 return error("Error sending to proxy");
205 }
206 char pchRet[8];
207 if (recv(hSocket, pchRet, 8, 0) != 8)
208 {
209 closesocket(hSocket);
210 return error("Error reading proxy response");
211 }
212 if (pchRet[1] != 0x5a)
213 {
214 closesocket(hSocket);
215 if (pchRet[1] != 0x5b)
216 printf("ERROR: Proxy returned error %d\n", pchRet[1]);
217 return false;
218 }
a6a5bb7c 219 printf("proxy connected %s\n", addrConnect.ToString().c_str());
0a61b0df 220 }
221
222 hSocketRet = hSocket;
223 return true;
224}
225
a6a5bb7c
PW
226// portDefault is in host order
227bool Lookup(const char *pszName, vector<CAddress>& vaddr, int nServices, int nMaxSolutions, bool fAllowLookup, int portDefault, bool fAllowPort)
228{
229 vaddr.clear();
545a679a
PW
230 if (pszName[0] == 0)
231 return false;
a6a5bb7c
PW
232 int port = portDefault;
233 char psz[256];
234 char *pszHost = psz;
235 strlcpy(psz, pszName, sizeof(psz));
236 if (fAllowPort)
237 {
238 char* pszColon = strrchr(psz+1,':');
239 char *pszPortEnd = NULL;
240 int portParsed = pszColon ? strtoul(pszColon+1, &pszPortEnd, 10) : 0;
241 if (pszColon && pszPortEnd && pszPortEnd[0] == 0)
242 {
243 if (psz[0] == '[' && pszColon[-1] == ']')
244 {
245 // Future: enable IPv6 colon-notation inside []
246 pszHost = psz+1;
247 pszColon[-1] = 0;
248 }
249 else
250 pszColon[0] = 0;
251 port = portParsed;
252 if (port < 0 || port > USHRT_MAX)
253 port = USHRT_MAX;
254 }
255 }
256
545a679a
PW
257 unsigned int addrIP = inet_addr(pszHost);
258 if (addrIP != INADDR_NONE)
a6a5bb7c
PW
259 {
260 // valid IP address passed
545a679a 261 vaddr.push_back(CAddress(addrIP, port, nServices));
a6a5bb7c
PW
262 return true;
263 }
264
265 if (!fAllowLookup)
266 return false;
267
268 struct hostent* phostent = gethostbyname(pszHost);
269 if (!phostent)
270 return false;
271
272 if (phostent->h_addrtype != AF_INET)
273 return false;
0a61b0df 274
a6a5bb7c
PW
275 char** ppAddr = phostent->h_addr_list;
276 while (*ppAddr != NULL && vaddr.size() != nMaxSolutions)
277 {
278 CAddress addr(((struct in_addr*)ppAddr[0])->s_addr, port, nServices);
279 if (addr.IsValid())
280 vaddr.push_back(addr);
281 ppAddr++;
282 }
283
284 return (vaddr.size() > 0);
285}
286
287// portDefault is in host order
288bool Lookup(const char *pszName, CAddress& addr, int nServices, bool fAllowLookup, int portDefault, bool fAllowPort)
289{
290 vector<CAddress> vaddr;
291 bool fRet = Lookup(pszName, vaddr, nServices, 1, fAllowLookup, portDefault, fAllowPort);
292 if (fRet)
293 addr = vaddr[0];
294 return fRet;
295}
0a61b0df 296
297bool GetMyExternalIP2(const CAddress& addrConnect, const char* pszGet, const char* pszKeyword, unsigned int& ipRet)
298{
299 SOCKET hSocket;
300 if (!ConnectSocket(addrConnect, hSocket))
301 return error("GetMyExternalIP() : connection to %s failed", addrConnect.ToString().c_str());
302
303 send(hSocket, pszGet, strlen(pszGet), MSG_NOSIGNAL);
304
305 string strLine;
306 while (RecvLine(hSocket, strLine))
307 {
222e3de4 308 if (strLine.empty()) // HTTP response is separated from headers by blank line
0a61b0df 309 {
310 loop
311 {
312 if (!RecvLine(hSocket, strLine))
313 {
314 closesocket(hSocket);
315 return false;
316 }
222e3de4 317 if (pszKeyword == NULL)
318 break;
0a61b0df 319 if (strLine.find(pszKeyword) != -1)
320 {
321 strLine = strLine.substr(strLine.find(pszKeyword) + strlen(pszKeyword));
322 break;
323 }
324 }
325 closesocket(hSocket);
c891967b 326 if (strLine.find("<") != -1)
0a61b0df 327 strLine = strLine.substr(0, strLine.find("<"));
328 strLine = strLine.substr(strspn(strLine.c_str(), " \t\n\r"));
329 while (strLine.size() > 0 && isspace(strLine[strLine.size()-1]))
330 strLine.resize(strLine.size()-1);
a6a5bb7c 331 CAddress addr(strLine,0,true);
0a61b0df 332 printf("GetMyExternalIP() received [%s] %s\n", strLine.c_str(), addr.ToString().c_str());
333 if (addr.ip == 0 || addr.ip == INADDR_NONE || !addr.IsRoutable())
334 return false;
335 ipRet = addr.ip;
336 return true;
337 }
338 }
339 closesocket(hSocket);
340 return error("GetMyExternalIP() : connection closed");
341}
342
629e37dd 343// We now get our external IP from the IRC server first and only use this as a backup
0a61b0df 344bool GetMyExternalIP(unsigned int& ipRet)
345{
346 CAddress addrConnect;
347 const char* pszGet;
348 const char* pszKeyword;
349
350 if (fUseProxy)
351 return false;
352
353 for (int nLookup = 0; nLookup <= 1; nLookup++)
354 for (int nHost = 1; nHost <= 2; nHost++)
355 {
629e37dd 356 // We should be phasing out our use of sites like these. If we need
357 // replacements, we should ask for volunteers to put this simple
358 // php file on their webserver that prints the client IP:
359 // <?php echo $_SERVER["REMOTE_ADDR"]; ?>
0a61b0df 360 if (nHost == 1)
361 {
a6a5bb7c 362 addrConnect = CAddress("91.198.22.70",80); // checkip.dyndns.org
0a61b0df 363
364 if (nLookup == 1)
365 {
a6a5bb7c
PW
366 CAddress addrIP("checkip.dyndns.org", 80, true);
367 if (addrIP.IsValid())
368 addrConnect = addrIP;
0a61b0df 369 }
370
683bcb91 371 pszGet = "GET / HTTP/1.1\r\n"
372 "Host: checkip.dyndns.org\r\n"
373 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
0a61b0df 374 "Connection: close\r\n"
375 "\r\n";
376
683bcb91 377 pszKeyword = "Address:";
0a61b0df 378 }
379 else if (nHost == 2)
380 {
a6a5bb7c 381 addrConnect = CAddress("74.208.43.192", 80); // www.showmyip.com
0a61b0df 382
383 if (nLookup == 1)
384 {
a6a5bb7c
PW
385 CAddress addrIP("www.showmyip.com", 80, true);
386 if (addrIP.IsValid())
387 addrConnect = addrIP;
0a61b0df 388 }
389
683bcb91 390 pszGet = "GET /simple/ HTTP/1.1\r\n"
391 "Host: www.showmyip.com\r\n"
0a61b0df 392 "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
393 "Connection: close\r\n"
394 "\r\n";
395
683bcb91 396 pszKeyword = NULL; // Returns just IP address
0a61b0df 397 }
398
399 if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet))
400 return true;
401 }
402
403 return false;
404}
405
629e37dd 406void ThreadGetMyExternalIP(void* parg)
407{
408 // Wait for IRC to get it first
409 if (!GetBoolArg("-noirc"))
410 {
411 for (int i = 0; i < 2 * 60; i++)
412 {
413 Sleep(1000);
414 if (fGotExternalIP || fShutdown)
415 return;
416 }
417 }
418
419 // Fallback in case IRC fails to get it
420 if (GetMyExternalIP(addrLocalHost.ip))
421 {
422 printf("GetMyExternalIP() returned %s\n", addrLocalHost.ToStringIP().c_str());
423 if (addrLocalHost.IsRoutable())
424 {
425 // If we already connected to a few before we had our IP, go back and addr them.
426 // setAddrKnown automatically filters any duplicate sends.
427 CAddress addr(addrLocalHost);
428 addr.nTime = GetAdjustedTime();
429 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 430 BOOST_FOREACH(CNode* pnode, vNodes)
629e37dd 431 pnode->PushAddress(addr);
432 }
433 }
434}
435
0a61b0df 436
437
438
439
8c414691 440bool AddAddress(CAddress addr, int64 nTimePenalty, CAddrDB *pAddrDB)
0a61b0df 441{
442 if (!addr.IsRoutable())
443 return false;
444 if (addr.ip == addrLocalHost.ip)
445 return false;
c891967b 446 addr.nTime = max((int64)0, (int64)addr.nTime - nTimePenalty);
94066965
GA
447 bool fUpdated = false;
448 bool fNew = false;
449 CAddress addrFound = addr;
450
0a61b0df 451 CRITICAL_BLOCK(cs_mapAddresses)
452 {
453 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
454 if (it == mapAddresses.end())
455 {
456 // New address
a6a5bb7c 457 printf("AddAddress(%s)\n", addr.ToString().c_str());
0a61b0df 458 mapAddresses.insert(make_pair(addr.GetKey(), addr));
94066965
GA
459 fUpdated = true;
460 fNew = true;
0a61b0df 461 }
462 else
463 {
94066965 464 addrFound = (*it).second;
0a61b0df 465 if ((addrFound.nServices | addr.nServices) != addrFound.nServices)
466 {
467 // Services have been added
468 addrFound.nServices |= addr.nServices;
469 fUpdated = true;
470 }
471 bool fCurrentlyOnline = (GetAdjustedTime() - addr.nTime < 24 * 60 * 60);
472 int64 nUpdateInterval = (fCurrentlyOnline ? 60 * 60 : 24 * 60 * 60);
473 if (addrFound.nTime < addr.nTime - nUpdateInterval)
474 {
475 // Periodically update most recently seen time
476 addrFound.nTime = addr.nTime;
477 fUpdated = true;
478 }
0a61b0df 479 }
480 }
94066965
GA
481 // There is a nasty deadlock bug if this is done inside the cs_mapAddresses
482 // CRITICAL_BLOCK:
483 // Thread 1: begin db transaction (locks inside-db-mutex)
484 // then AddAddress (locks cs_mapAddresses)
485 // Thread 2: AddAddress (locks cs_mapAddresses)
486 // ... then db operation hangs waiting for inside-db-mutex
487 if (fUpdated)
488 {
489 if (pAddrDB)
490 pAddrDB->WriteAddress(addrFound);
491 else
492 CAddrDB().WriteAddress(addrFound);
493 }
494 return fNew;
0a61b0df 495}
496
497void AddressCurrentlyConnected(const CAddress& addr)
498{
499 CRITICAL_BLOCK(cs_mapAddresses)
500 {
501 // Only if it's been published already
502 map<vector<unsigned char>, CAddress>::iterator it = mapAddresses.find(addr.GetKey());
503 if (it != mapAddresses.end())
504 {
505 CAddress& addrFound = (*it).second;
506 int64 nUpdateInterval = 20 * 60;
507 if (addrFound.nTime < GetAdjustedTime() - nUpdateInterval)
508 {
509 // Periodically update most recently seen time
510 addrFound.nTime = GetAdjustedTime();
511 CAddrDB addrdb;
512 addrdb.WriteAddress(addrFound);
513 }
514 }
515 }
516}
517
518
519
520
521
522void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
523{
524 // If the dialog might get closed before the reply comes back,
525 // call this in the destructor so it doesn't get called after it's deleted.
526 CRITICAL_BLOCK(cs_vNodes)
527 {
223b6f1b 528 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 529 {
530 CRITICAL_BLOCK(pnode->cs_mapRequests)
531 {
532 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
533 {
534 CRequestTracker& tracker = (*mi).second;
535 if (tracker.fn == fn && tracker.param1 == param1)
536 pnode->mapRequests.erase(mi++);
537 else
538 mi++;
539 }
540 }
541 }
542 }
543}
544
545
546
547
548
549
550
551//
552// Subscription methods for the broadcast and subscription system.
553// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
554//
555// The subscription system uses a meet-in-the-middle strategy.
556// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
557// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
558//
559
560bool AnySubscribed(unsigned int nChannel)
561{
562 if (pnodeLocalHost->IsSubscribed(nChannel))
563 return true;
564 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 565 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 566 if (pnode->IsSubscribed(nChannel))
567 return true;
568 return false;
569}
570
571bool CNode::IsSubscribed(unsigned int nChannel)
572{
573 if (nChannel >= vfSubscribe.size())
574 return false;
575 return vfSubscribe[nChannel];
576}
577
578void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
579{
580 if (nChannel >= vfSubscribe.size())
581 return;
582
583 if (!AnySubscribed(nChannel))
584 {
585 // Relay subscribe
586 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 587 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 588 if (pnode != this)
589 pnode->PushMessage("subscribe", nChannel, nHops);
590 }
591
592 vfSubscribe[nChannel] = true;
593}
594
595void CNode::CancelSubscribe(unsigned int nChannel)
596{
597 if (nChannel >= vfSubscribe.size())
598 return;
599
600 // Prevent from relaying cancel if wasn't subscribed
601 if (!vfSubscribe[nChannel])
602 return;
603 vfSubscribe[nChannel] = false;
604
605 if (!AnySubscribed(nChannel))
606 {
607 // Relay subscription cancel
608 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 609 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 610 if (pnode != this)
611 pnode->PushMessage("sub-cancel", nChannel);
612 }
613}
614
615
616
617
618
619
620
621
622
623CNode* FindNode(unsigned int ip)
624{
625 CRITICAL_BLOCK(cs_vNodes)
626 {
223b6f1b 627 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 628 if (pnode->addr.ip == ip)
629 return (pnode);
630 }
631 return NULL;
632}
633
634CNode* FindNode(CAddress addr)
635{
636 CRITICAL_BLOCK(cs_vNodes)
637 {
223b6f1b 638 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 639 if (pnode->addr == addr)
640 return (pnode);
641 }
642 return NULL;
643}
644
645CNode* ConnectNode(CAddress addrConnect, int64 nTimeout)
646{
647 if (addrConnect.ip == addrLocalHost.ip)
648 return NULL;
649
650 // Look for an existing connection
651 CNode* pnode = FindNode(addrConnect.ip);
652 if (pnode)
653 {
654 if (nTimeout != 0)
655 pnode->AddRef(nTimeout);
656 else
657 pnode->AddRef();
658 return pnode;
659 }
660
661 /// debug print
662 printf("trying connection %s lastseen=%.1fhrs lasttry=%.1fhrs\n",
a6a5bb7c 663 addrConnect.ToString().c_str(),
0a61b0df 664 (double)(addrConnect.nTime - GetAdjustedTime())/3600.0,
665 (double)(addrConnect.nLastTry - GetAdjustedTime())/3600.0);
666
667 CRITICAL_BLOCK(cs_mapAddresses)
668 mapAddresses[addrConnect.GetKey()].nLastTry = GetAdjustedTime();
669
670 // Connect
671 SOCKET hSocket;
672 if (ConnectSocket(addrConnect, hSocket))
673 {
674 /// debug print
a6a5bb7c 675 printf("connected %s\n", addrConnect.ToString().c_str());
0a61b0df 676
677 // Set to nonblocking
6853e627 678#ifdef WIN32
0a61b0df 679 u_long nOne = 1;
680 if (ioctlsocket(hSocket, FIONBIO, &nOne) == SOCKET_ERROR)
681 printf("ConnectSocket() : ioctlsocket nonblocking setting failed, error %d\n", WSAGetLastError());
682#else
683 if (fcntl(hSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
684 printf("ConnectSocket() : fcntl nonblocking setting failed, error %d\n", errno);
685#endif
686
687 // Add node
688 CNode* pnode = new CNode(hSocket, addrConnect, false);
689 if (nTimeout != 0)
690 pnode->AddRef(nTimeout);
691 else
692 pnode->AddRef();
693 CRITICAL_BLOCK(cs_vNodes)
694 vNodes.push_back(pnode);
695
696 pnode->nTimeConnected = GetTime();
697 return pnode;
698 }
699 else
700 {
701 return NULL;
702 }
703}
704
705void CNode::CloseSocketDisconnect()
706{
707 fDisconnect = true;
708 if (hSocket != INVALID_SOCKET)
709 {
710 if (fDebug)
711 printf("%s ", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
a6a5bb7c 712 printf("disconnecting node %s\n", addr.ToString().c_str());
0a61b0df 713 closesocket(hSocket);
714 hSocket = INVALID_SOCKET;
715 }
716}
717
718void CNode::Cleanup()
719{
720 // All of a nodes broadcasts and subscriptions are automatically torn down
721 // when it goes down, so a node has to stay up to keep its broadcast going.
722
723 // Cancel subscriptions
724 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
725 if (vfSubscribe[nChannel])
726 CancelSubscribe(nChannel);
727}
728
729
15f3ad4d
GA
730std::map<unsigned int, int64> CNode::setBanned;
731CCriticalSection CNode::cs_setBanned;
732
733void CNode::ClearBanned()
734{
735 setBanned.clear();
736}
737
738bool CNode::IsBanned(unsigned int ip)
739{
740 bool fResult = false;
741 CRITICAL_BLOCK(cs_setBanned)
742 {
743 std::map<unsigned int, int64>::iterator i = setBanned.find(ip);
744 if (i != setBanned.end())
745 {
746 int64 t = (*i).second;
747 if (GetTime() < t)
748 fResult = true;
749 }
750 }
751 return fResult;
752}
753
754bool CNode::Misbehaving(int howmuch)
755{
756 if (addr.IsLocal())
757 {
758 printf("Warning: local node %s misbehaving\n", addr.ToString().c_str());
759 return false;
760 }
761
762 nMisbehavior += howmuch;
763 if (nMisbehavior >= GetArg("-banscore", 100))
764 {
765 int64 banTime = GetTime()+GetArg("-bantime", 60*60*24); // Default 24-hour ban
766 CRITICAL_BLOCK(cs_setBanned)
767 if (setBanned[addr.ip] < banTime)
768 setBanned[addr.ip] = banTime;
769 CloseSocketDisconnect();
770 printf("Disconnected %s for misbehavior (score=%d)\n", addr.ToString().c_str(), nMisbehavior);
771 return true;
772 }
773 return false;
774}
775
0a61b0df 776
777
778
779
780
781
782
783
784
785
786
787void ThreadSocketHandler(void* parg)
788{
789 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
790 try
791 {
792 vnThreadsRunning[0]++;
793 ThreadSocketHandler2(parg);
794 vnThreadsRunning[0]--;
795 }
796 catch (std::exception& e) {
797 vnThreadsRunning[0]--;
798 PrintException(&e, "ThreadSocketHandler()");
799 } catch (...) {
800 vnThreadsRunning[0]--;
801 throw; // support pthread_cancel()
802 }
803 printf("ThreadSocketHandler exiting\n");
804}
805
806void ThreadSocketHandler2(void* parg)
807{
808 printf("ThreadSocketHandler started\n");
809 list<CNode*> vNodesDisconnected;
810 int nPrevNodeCount = 0;
811
812 loop
813 {
814 //
815 // Disconnect nodes
816 //
817 CRITICAL_BLOCK(cs_vNodes)
818 {
819 // Disconnect unused nodes
820 vector<CNode*> vNodesCopy = vNodes;
223b6f1b 821 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 822 {
823 if (pnode->fDisconnect ||
824 (pnode->GetRefCount() <= 0 && pnode->vRecv.empty() && pnode->vSend.empty()))
825 {
826 // remove from vNodes
827 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
828
829 // close socket and cleanup
830 pnode->CloseSocketDisconnect();
831 pnode->Cleanup();
832
833 // hold in disconnected pool until all refs are released
834 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 15 * 60);
835 if (pnode->fNetworkNode || pnode->fInbound)
836 pnode->Release();
837 vNodesDisconnected.push_back(pnode);
838 }
839 }
840
841 // Delete disconnected nodes
842 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
223b6f1b 843 BOOST_FOREACH(CNode* pnode, vNodesDisconnectedCopy)
0a61b0df 844 {
845 // wait until threads are done using it
846 if (pnode->GetRefCount() <= 0)
847 {
848 bool fDelete = false;
849 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
850 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
851 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
852 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
853 fDelete = true;
854 if (fDelete)
855 {
856 vNodesDisconnected.remove(pnode);
857 delete pnode;
858 }
859 }
860 }
861 }
862 if (vNodes.size() != nPrevNodeCount)
863 {
864 nPrevNodeCount = vNodes.size();
865 MainFrameRepaint();
866 }
867
868
869 //
870 // Find which sockets have data to receive
871 //
872 struct timeval timeout;
873 timeout.tv_sec = 0;
874 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
875
876 fd_set fdsetRecv;
877 fd_set fdsetSend;
878 fd_set fdsetError;
879 FD_ZERO(&fdsetRecv);
880 FD_ZERO(&fdsetSend);
881 FD_ZERO(&fdsetError);
882 SOCKET hSocketMax = 0;
5f88e888
W
883
884 if(hListenSocket != INVALID_SOCKET)
885 FD_SET(hListenSocket, &fdsetRecv);
0a61b0df 886 hSocketMax = max(hSocketMax, hListenSocket);
887 CRITICAL_BLOCK(cs_vNodes)
888 {
223b6f1b 889 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 890 {
d7f1d200 891 if (pnode->hSocket == INVALID_SOCKET)
0a61b0df 892 continue;
893 FD_SET(pnode->hSocket, &fdsetRecv);
894 FD_SET(pnode->hSocket, &fdsetError);
895 hSocketMax = max(hSocketMax, pnode->hSocket);
896 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
897 if (!pnode->vSend.empty())
898 FD_SET(pnode->hSocket, &fdsetSend);
899 }
900 }
901
902 vnThreadsRunning[0]--;
903 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, &fdsetError, &timeout);
904 vnThreadsRunning[0]++;
905 if (fShutdown)
906 return;
907 if (nSelect == SOCKET_ERROR)
908 {
909 int nErr = WSAGetLastError();
c6710c7a
MC
910 if (hSocketMax > -1)
911 {
912 printf("socket select error %d\n", nErr);
913 for (int i = 0; i <= hSocketMax; i++)
914 FD_SET(i, &fdsetRecv);
915 }
0a61b0df 916 FD_ZERO(&fdsetSend);
917 FD_ZERO(&fdsetError);
918 Sleep(timeout.tv_usec/1000);
919 }
920
921
922 //
923 // Accept new connections
924 //
5f88e888 925 if (hListenSocket != INVALID_SOCKET && FD_ISSET(hListenSocket, &fdsetRecv))
0a61b0df 926 {
927 struct sockaddr_in sockaddr;
928 socklen_t len = sizeof(sockaddr);
929 SOCKET hSocket = accept(hListenSocket, (struct sockaddr*)&sockaddr, &len);
930 CAddress addr(sockaddr);
4698dd9a
CM
931 int nInbound = 0;
932
5a3e82f9 933 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 934 BOOST_FOREACH(CNode* pnode, vNodes)
5a3e82f9
GA
935 if (pnode->fInbound)
936 nInbound++;
0a61b0df 937 if (hSocket == INVALID_SOCKET)
938 {
939 if (WSAGetLastError() != WSAEWOULDBLOCK)
940 printf("socket error accept failed: %d\n", WSAGetLastError());
941 }
5a3e82f9 942 else if (nInbound >= GetArg("-maxconnections", 125) - MAX_OUTBOUND_CONNECTIONS)
0a61b0df 943 {
944 closesocket(hSocket);
945 }
15f3ad4d
GA
946 else if (CNode::IsBanned(addr.ip))
947 {
948 printf("connetion from %s dropped (banned)\n", addr.ToString().c_str());
949 closesocket(hSocket);
950 }
0a61b0df 951 else
952 {
a6a5bb7c 953 printf("accepted connection %s\n", addr.ToString().c_str());
0a61b0df 954 CNode* pnode = new CNode(hSocket, addr, true);
955 pnode->AddRef();
956 CRITICAL_BLOCK(cs_vNodes)
957 vNodes.push_back(pnode);
958 }
959 }
960
961
962 //
963 // Service each socket
964 //
965 vector<CNode*> vNodesCopy;
966 CRITICAL_BLOCK(cs_vNodes)
967 {
968 vNodesCopy = vNodes;
223b6f1b 969 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 970 pnode->AddRef();
971 }
223b6f1b 972 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 973 {
974 if (fShutdown)
975 return;
976
977 //
978 // Receive
979 //
980 if (pnode->hSocket == INVALID_SOCKET)
981 continue;
982 if (FD_ISSET(pnode->hSocket, &fdsetRecv) || FD_ISSET(pnode->hSocket, &fdsetError))
983 {
984 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
985 {
986 CDataStream& vRecv = pnode->vRecv;
987 unsigned int nPos = vRecv.size();
988
49731745 989 if (nPos > ReceiveBufferSize()) {
0a61b0df 990 if (!pnode->fDisconnect)
9cbae55a 991 printf("socket recv flood control disconnect (%d bytes)\n", vRecv.size());
0a61b0df 992 pnode->CloseSocketDisconnect();
993 }
9cbae55a
GA
994 else {
995 // typical socket buffer is 8K-64K
996 char pchBuf[0x10000];
997 int nBytes = recv(pnode->hSocket, pchBuf, sizeof(pchBuf), MSG_DONTWAIT);
998 if (nBytes > 0)
0a61b0df 999 {
9cbae55a
GA
1000 vRecv.resize(nPos + nBytes);
1001 memcpy(&vRecv[nPos], pchBuf, nBytes);
1002 pnode->nLastRecv = GetTime();
1003 }
1004 else if (nBytes == 0)
1005 {
1006 // socket closed gracefully
0a61b0df 1007 if (!pnode->fDisconnect)
9cbae55a 1008 printf("socket closed\n");
0a61b0df 1009 pnode->CloseSocketDisconnect();
1010 }
9cbae55a
GA
1011 else if (nBytes < 0)
1012 {
1013 // error
1014 int nErr = WSAGetLastError();
1015 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1016 {
1017 if (!pnode->fDisconnect)
1018 printf("socket recv error %d\n", nErr);
1019 pnode->CloseSocketDisconnect();
1020 }
1021 }
0a61b0df 1022 }
1023 }
1024 }
1025
1026 //
1027 // Send
1028 //
1029 if (pnode->hSocket == INVALID_SOCKET)
1030 continue;
1031 if (FD_ISSET(pnode->hSocket, &fdsetSend))
1032 {
1033 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1034 {
1035 CDataStream& vSend = pnode->vSend;
1036 if (!vSend.empty())
1037 {
1038 int nBytes = send(pnode->hSocket, &vSend[0], vSend.size(), MSG_NOSIGNAL | MSG_DONTWAIT);
1039 if (nBytes > 0)
1040 {
1041 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1042 pnode->nLastSend = GetTime();
1043 }
1044 else if (nBytes < 0)
1045 {
1046 // error
1047 int nErr = WSAGetLastError();
1048 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1049 {
1050 printf("socket send error %d\n", nErr);
1051 pnode->CloseSocketDisconnect();
1052 }
1053 }
49731745 1054 if (vSend.size() > SendBufferSize()) {
9cbae55a
GA
1055 if (!pnode->fDisconnect)
1056 printf("socket send flood control disconnect (%d bytes)\n", vSend.size());
1057 pnode->CloseSocketDisconnect();
1058 }
0a61b0df 1059 }
1060 }
1061 }
1062
1063 //
1064 // Inactivity checking
1065 //
1066 if (pnode->vSend.empty())
1067 pnode->nLastSendEmpty = GetTime();
1068 if (GetTime() - pnode->nTimeConnected > 60)
1069 {
1070 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1071 {
1072 printf("socket no message in first 60 seconds, %d %d\n", pnode->nLastRecv != 0, pnode->nLastSend != 0);
1073 pnode->fDisconnect = true;
1074 }
1075 else if (GetTime() - pnode->nLastSend > 90*60 && GetTime() - pnode->nLastSendEmpty > 90*60)
1076 {
1077 printf("socket not sending\n");
1078 pnode->fDisconnect = true;
1079 }
1080 else if (GetTime() - pnode->nLastRecv > 90*60)
1081 {
1082 printf("socket inactivity timeout\n");
1083 pnode->fDisconnect = true;
1084 }
1085 }
1086 }
1087 CRITICAL_BLOCK(cs_vNodes)
1088 {
223b6f1b 1089 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 1090 pnode->Release();
1091 }
1092
0a61b0df 1093 Sleep(10);
1094 }
1095}
1096
1097
1098
1099
1100
1101
1102
1103
1104
8bb5edc1
MC
1105#ifdef USE_UPNP
1106void ThreadMapPort(void* parg)
1107{
1108 IMPLEMENT_RANDOMIZE_STACK(ThreadMapPort(parg));
1109 try
1110 {
1111 vnThreadsRunning[5]++;
1112 ThreadMapPort2(parg);
1113 vnThreadsRunning[5]--;
1114 }
1115 catch (std::exception& e) {
1116 vnThreadsRunning[5]--;
1117 PrintException(&e, "ThreadMapPort()");
1118 } catch (...) {
1119 vnThreadsRunning[5]--;
1120 PrintException(NULL, "ThreadMapPort()");
1121 }
1122 printf("ThreadMapPort exiting\n");
1123}
1124
1125void ThreadMapPort2(void* parg)
1126{
1127 printf("ThreadMapPort started\n");
1128
1129 char port[6];
00bcfe0b 1130 sprintf(port, "%d", GetListenPort());
8bb5edc1
MC
1131
1132 const char * rootdescurl = 0;
1133 const char * multicastif = 0;
1134 const char * minissdpdpath = 0;
1135 struct UPNPDev * devlist = 0;
1136 char lanaddr[64];
1137
94b97046
LD
1138#ifndef UPNPDISCOVER_SUCCESS
1139 /* miniupnpc 1.5 */
1140 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);
1141#else
1142 /* miniupnpc 1.6 */
1143 int error = 0;
b4ada906 1144 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);
94b97046 1145#endif
8bb5edc1
MC
1146
1147 struct UPNPUrls urls;
1148 struct IGDdatas data;
1149 int r;
1150
f285d4f4
DH
1151 r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));
1152 if (r == 1)
8bb5edc1
MC
1153 {
1154 char intClient[16];
1155 char intPort[6];
15656981 1156 string strDesc = "Bitcoin " + FormatFullVersion();
94b97046
LD
1157#ifndef UPNPDISCOVER_SUCCESS
1158 /* miniupnpc 1.5 */
1159 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
1160 port, port, lanaddr, strDesc.c_str(), "TCP", 0);
1161#else
1162 /* miniupnpc 1.6 */
8bb5edc1 1163 r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
15656981 1164 port, port, lanaddr, strDesc.c_str(), "TCP", 0, "0");
94b97046 1165#endif
b4ada906 1166
8bb5edc1
MC
1167 if(r!=UPNPCOMMAND_SUCCESS)
1168 printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
1169 port, port, lanaddr, r, strupnperror(r));
1170 else
1171 printf("UPnP Port Mapping successful.\n");
1172 loop {
1173 if (fShutdown || !fUseUPnP)
1174 {
1175 r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port, "TCP", 0);
1176 printf("UPNP_DeletePortMapping() returned : %d\n", r);
1177 freeUPNPDevlist(devlist); devlist = 0;
1178 FreeUPNPUrls(&urls);
1179 return;
1180 }
1181 Sleep(2000);
1182 }
1183 } else {
1184 printf("No valid UPnP IGDs found\n");
1185 freeUPNPDevlist(devlist); devlist = 0;
f285d4f4
DH
1186 if (r != 0)
1187 FreeUPNPUrls(&urls);
8bb5edc1 1188 loop {
973800b5 1189 if (fShutdown || !fUseUPnP)
8bb5edc1
MC
1190 return;
1191 Sleep(2000);
1192 }
1193 }
1194}
1195
1196void MapPort(bool fMapPort)
1197{
1198 if (fUseUPnP != fMapPort)
1199 {
1200 fUseUPnP = fMapPort;
64c7ee7e 1201 WriteSetting("fUseUPnP", fUseUPnP);
8bb5edc1
MC
1202 }
1203 if (fUseUPnP && vnThreadsRunning[5] < 1)
1204 {
1205 if (!CreateThread(ThreadMapPort, NULL))
1206 printf("Error: ThreadMapPort(ThreadMapPort) failed\n");
1207 }
1208}
9f0ac169
GA
1209#else
1210void MapPort(bool /* unused fMapPort */)
1211{
1212 // Intentionally left blank.
1213}
8bb5edc1
MC
1214#endif
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
f684aec4
JG
1225static const char *strDNSSeed[] = {
1226 "bitseed.xf2.org",
f03c31db 1227 "dnsseed.bluematt.me",
61a8c056 1228 "seed.bitcoin.sipa.be",
64773488 1229 "dnsseed.bitcoin.dashjr.org",
f684aec4 1230};
0a61b0df 1231
2bc6cece 1232void ThreadDNSAddressSeed(void* parg)
f684aec4 1233{
2bc6cece
MC
1234 IMPLEMENT_RANDOMIZE_STACK(ThreadDNSAddressSeed(parg));
1235 try
1236 {
1237 vnThreadsRunning[6]++;
1238 ThreadDNSAddressSeed2(parg);
1239 vnThreadsRunning[6]--;
1240 }
1241 catch (std::exception& e) {
1242 vnThreadsRunning[6]--;
1243 PrintException(&e, "ThreadDNSAddressSeed()");
1244 } catch (...) {
1245 vnThreadsRunning[6]--;
1246 throw; // support pthread_cancel()
1247 }
1248 printf("ThreadDNSAddressSeed exiting\n");
1249}
1250
1251void ThreadDNSAddressSeed2(void* parg)
1252{
1253 printf("ThreadDNSAddressSeed started\n");
f684aec4
JG
1254 int found = 0;
1255
ce8f78a7
MC
1256 if (!fTestNet)
1257 {
1258 printf("Loading addresses from DNS seeds (could take a while)\n");
d655a26c
SG
1259 CAddrDB addrDB;
1260 addrDB.TxnBegin();
f684aec4 1261
ce8f78a7
MC
1262 for (int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) {
1263 vector<CAddress> vaddr;
1264 if (Lookup(strDNSSeed[seed_idx], vaddr, NODE_NETWORK, -1, true))
a6a5bb7c 1265 {
ce8f78a7 1266 BOOST_FOREACH (CAddress& addr, vaddr)
a6a5bb7c 1267 {
ce8f78a7
MC
1268 if (addr.GetByte(3) != 127)
1269 {
1270 addr.nTime = 0;
d655a26c 1271 AddAddress(addr, 0, &addrDB);
ce8f78a7
MC
1272 found++;
1273 }
a6a5bb7c 1274 }
f684aec4
JG
1275 }
1276 }
d655a26c
SG
1277
1278 addrDB.TxnCommit(); // Save addresses (it's ok if this fails)
f684aec4
JG
1279 }
1280
448b4516 1281 printf("%d addresses found from DNS seeds\n", found);
f684aec4 1282}
0a61b0df 1283
1284
1285
2bc6cece
MC
1286
1287
1288
1289
1290
1291
1292
1293
1294
0a61b0df 1295unsigned int pnSeed[] =
1296{
bca179e8
DF
1297 0x6884ac63, 0x3ffecead, 0x2919b953, 0x0942fe50, 0x7a1d922e, 0xcdd6734a, 0x953a5bb6, 0x2c46922e,
1298 0xe2a5f143, 0xaa39103a, 0xa06afa5c, 0x135ffd59, 0xe8e82863, 0xf61ef029, 0xf75f042e, 0x2b363532,
1299 0x29b2df42, 0x16b1f64e, 0xd46e281b, 0x5280bf58, 0x60372229, 0x1be58e4f, 0xa8496f45, 0x1fb1a057,
1300 0x756b3844, 0x3bb79445, 0x0b375518, 0xcccb0102, 0xb682bf2e, 0x46431c02, 0x3a81073a, 0xa3771f1f,
1301 0x213a121f, 0x85dc2c1b, 0x56b4323b, 0xb34e8945, 0x3c40b33d, 0xfa276418, 0x1f818d29, 0xebe1e344,
1302 0xf6160a18, 0xf4fa384a, 0x34b09558, 0xb882b543, 0xe3ce2253, 0x6abf56d8, 0xe91b1155, 0x688ee6ad,
1303 0x2efc6058, 0x4792cd47, 0x0c32f757, 0x4c813a46, 0x8c93644a, 0x37507444, 0x813ad218, 0xdac06d4a,
1304 0xe4c63e4b, 0x21a1ea3c, 0x8d88556f, 0x30e9173a, 0x041f681b, 0xdc77ba50, 0xc0072753, 0xceddd44f,
1305 0x052d1743, 0xe3c77a4a, 0x13981c3a, 0x5685d918, 0x3c0e4e70, 0x3e56fb54, 0xb676ae0c, 0xac93c859,
1306 0x22279f43, 0x975a4542, 0xe527f071, 0xea162f2e, 0x3c65a32e, 0x5be5713b, 0x961ec418, 0xb202922e,
1307 0x5ef7be50, 0xce49f53e, 0x05803b47, 0x8463b055, 0x78576153, 0x3ec2ae3a, 0x4bbd7118, 0xafcee043,
1308 0x56a3e8ba, 0x6174de4d, 0x8d01ba4b, 0xc9af564e, 0xdbc9c547, 0xa627474d, 0xdada9244, 0xd3b3083a,
1309 0x523e071f, 0xd6b96f18, 0xbd527c46, 0xdf2bbb4d, 0xd37b4a4b, 0x3a6a2158, 0xc064b055, 0x18a8e055,
1310 0xec4dae3b, 0x0540416c, 0x475b4fbe, 0x064803b2, 0x48e9f062, 0x2898524b, 0xd315ff43, 0xf786d247,
1311 0xc7ea2f3e, 0xc087f043, 0xc163354b, 0x8250284d, 0xed300029, 0xbf36e05c, 0x8eb3ae4c, 0xe7aa623e,
1312 0x7ced0274, 0xdd362c1b, 0x362b995a, 0xca26b629, 0x3fc41618, 0xb97b364e, 0xa05b8729, 0x0f5e3c43,
1313 0xdf942618, 0x6aeb9b5b, 0xbf04762e, 0xfaaeb118, 0x87579958, 0x76520044, 0xc2660c5b, 0x628b201b,
1314 0xf193932e, 0x1c0ad045, 0xff908346, 0x8da9d4da, 0xed201c1f, 0xa47a2b1b, 0x330007d4, 0x8ba1ed47,
1315 0xb2f02d44, 0x7db62c1b, 0x781c454b, 0xc0300029, 0xb7062a45, 0x88b52e3a, 0x78dd6b63, 0x1cb9b718,
1316 0x5d358e47, 0x59912c3b, 0x79607544, 0x5197f759, 0xc023be48, 0xd1013743, 0x0f354057, 0x8e3aac3b,
1317 0x4114693e, 0x22316318, 0xe27dda50, 0x878eac3b, 0x4948a21f, 0x5db7f24c, 0x8ccb6157, 0x26a5de18,
1318 0x0a11bd43, 0x27bb1e41, 0x60a7a951, 0x3e16b35e, 0x07888b53, 0x5648a853, 0x0149fe50, 0xd070a34f,
1319 0x6454c96d, 0xd6e54758, 0xa96dc152, 0x65447861, 0xf6bdf95e, 0x10400202, 0x2c29d483, 0x18174732,
1320 0x1d840618, 0x12e61818, 0x089d3f3c, 0x917e931f, 0xd1b0c90e, 0x25bd3c42, 0xeb05775b, 0x7d550c59,
1321 0x6cfacb01, 0xe4224444, 0xa41dd943, 0x0f5aa643, 0x5e33731b, 0x81036d50, 0x6f46a0d1, 0x7731be43,
1322 0x14840e18, 0xf1e8d059, 0x661d2b1f, 0x40a3201b, 0x9407b843, 0xedf0254d, 0x7bd1a5bc, 0x073dbe51,
1323 0xe864a97b, 0x2efd947b, 0xb9ca0e45, 0x4e2113ad, 0xcc305731, 0xd39ca63c, 0x733df918, 0xda172b1f,
1324 0xaa03b34d, 0x7230fd4d, 0xf1ce6e3a, 0x2e9fab43, 0xa4010750, 0xa928bd18, 0x6809be42, 0xb19de348,
1325 0xff956270, 0x0d795f51, 0xd2dec247, 0x6df5774b, 0xbac11f79, 0xdfb05c75, 0x887683d8, 0xa1e83632,
1326 0x2c0f7671, 0x28bcb65d, 0xac2a7545, 0x3eebfc60, 0x304ad7c4, 0xa215a462, 0xc86f0f58, 0xcfb92ebe,
1327 0x5e23ed82, 0xf506184b, 0xec0f19b7, 0x060c59ad, 0x86ee3174, 0x85380774, 0xa199a562, 0x02b507ae,
1328 0x33eb2163, 0xf2112b1f, 0xb702ba50, 0x131b9618, 0x90ccd04a, 0x08f3273b, 0xecb61718, 0x64b8b44d,
1329 0x182bf4dc, 0xc7b68286, 0x6e318d5f, 0xfdb03654, 0xb3272e54, 0xe014ad4b, 0x274e4a31, 0x7806375c,
1330 0xbc34a748, 0x1b5ad94a, 0x6b54d10e, 0x73e2ae6e, 0x5529d483, 0x8455a76d, 0x99c13f47, 0x1d811741,
1331 0xa9782a78, 0x0b00464d, 0x7266ea50, 0x532dab46, 0x33e1413e, 0x780d0c18, 0x0fb0854e, 0x03370155,
1332 0x2693042e, 0xfa3d824a, 0x2bb1681b, 0x37ea2a18, 0x7fb8414b, 0x32e0713b, 0xacf38d3f, 0xa282716f,
1333 0xb1a09d7b, 0xa04b764b, 0x83c94d18, 0x05ee4c6d, 0x0e795f51, 0x46984352, 0xf80fc247, 0x3fccb946,
1334 0xd7ae244b, 0x0a8e0a4c, 0x57b141bc, 0x3647bed1, 0x1431b052, 0x803a8bbb, 0xfc69056b, 0xf5991862,
1335 0x14963b2e, 0xd35d5dda, 0xc6c73574, 0xc8f1405b, 0x0ca4224d, 0xecd36071, 0xa9461754, 0xe7a0ed72,
1336 0x559e8346, 0x1c9beec1, 0xc786ea4a, 0x9561b44d, 0x9788074d, 0x1a69934f, 0x23c5614c, 0x07c79d4b,
1337 0xc7ee52db, 0xc72df351, 0xcb135e44, 0xa0988346, 0xc211fc4c, 0x87dec34b, 0x1381074d, 0x04a65cb7,
1338 0x4409083a, 0x4a407a4c, 0x92b8d37d, 0xacf50b4d, 0xa58aa5bc, 0x448f801f, 0x9c83762e, 0x6fd5734a,
1339 0xfe2d454b, 0x84144c55, 0x05190e4c, 0xb2151448, 0x63867a3e, 0x16099018, 0x9c010d3c, 0x962d8f3d,
1340 0xd51ee453, 0x9d86801f, 0x68e87b47, 0x6bf7bb73, 0x5fc7910e, 0x10d90118, 0x3db04442, 0x729d3e4b,
1341 0xc397d842, 0x57bb15ad, 0x72f31f4e, 0xc9380043, 0x2bb24e18, 0xd9b8ab50, 0xb786801f, 0xf4dc4847,
1342 0x85f4bb51, 0x4435995b, 0x5ba07e40, 0x2c57392e, 0x3628124b, 0x9839b64b, 0x6fe8b24d, 0xaddce847,
1343 0x75260e45, 0x0c572a43, 0xfea21902, 0xb9f9742e, 0x5a70d443, 0x8fc5910e, 0x868d4744, 0x56245e02,
1344 0xd7eb5f02, 0x35c12c1b, 0x4373034b, 0x8786554c, 0xa6facf18, 0x4b11a31f, 0x3570664e, 0x5a64bc42,
1345 0x0b03983f, 0x8f457e4c, 0x0fd874c3, 0xb6cf31b2, 0x2bbc2d4e, 0x146ca5b2, 0x9d00b150, 0x048a4153,
1346 0xca4dcd43, 0xc1607cca, 0x8234cf57, 0x9c7daead, 0x3dc07658, 0xea5c6e4c, 0xf1a0084e, 0x16d2ee53,
1347 0x1b849418, 0xfe913a47, 0x1e988f62, 0x208b644c, 0xc55ee980, 0xbdbce747, 0xf59a384e, 0x0f56091b,
1348 0x7417b745, 0x0c37344e, 0x2c62ab47, 0xf8533a4d, 0x8030084d, 0x76b93c4b, 0xda6ea0ad, 0x3c54f618,
1349 0x63b0de1f, 0x7370d858, 0x1a70bb4c, 0xdda63b2e, 0x60b2ba50, 0x1ba7d048, 0xbe1b2c1b, 0xabea5747,
1350 0x29ad2e4d, 0xe8cd7642, 0x66c80e18, 0x138bf34a, 0xc6145e44, 0x2586794c, 0x07bc5478, 0x0da0b14d,
1351 0x8f95354e, 0x9eb11c62, 0xa1545e46, 0x2e7a2602, 0x408c9c3d, 0x59065d55, 0xf51d1a4c, 0x3bbc6a4e,
1352 0xc71b2a2e, 0xcdaaa545, 0x17d659d0, 0x5202e7ad, 0xf1b68445, 0x93375961, 0xbd88a043, 0x066ad655,
1353 0x890f6318, 0x7b7dca47, 0x99bdd662, 0x3bb4fc53, 0x1231efdc, 0xc0a99444, 0x96bbea47, 0x61ed8748,
1354 0x27dfa73b, 0x8d4d1754, 0x3460042e, 0x551f0c4c, 0x8d0e0718, 0x162ddc53, 0x53231718, 0x1ecd65d0,
1355 0x944d28bc, 0x3b79d058, 0xaff97fbc, 0x4860006c, 0xc101c90e, 0xace41743, 0xa5975d4c, 0x5cc2703e,
1356 0xb55a4450, 0x02d18840, 0xee2765ae, 0xd6012fd5, 0x24c94d7d, 0x8c6eec47, 0x7520ba5d, 0x9e15e460,
1357 0x8510b04c, 0x75ec3847, 0x1dfa6661, 0xe172b3ad, 0x5744c90e, 0x52a0a152, 0x8d6fad18, 0x67b74b6d,
1358 0x93a089b2, 0x0f3ac5d5, 0xe5de1855, 0x43d25747, 0x4bad804a, 0x55b408d8, 0x60a36441, 0xf553e860,
1359 0xdb2fa2c8, 0x03152b32, 0xdd27a7d5, 0x3116a8b8, 0x0a1d708c, 0xeee2f13c, 0x6acf436f, 0xce6eb4ca,
1360 0x101cd3d9, 0x1c48a6b8, 0xe57d6f44, 0x93dcf562,
0a61b0df 1361};
1362
1363
1364
1365void ThreadOpenConnections(void* parg)
1366{
1367 IMPLEMENT_RANDOMIZE_STACK(ThreadOpenConnections(parg));
1368 try
1369 {
1370 vnThreadsRunning[1]++;
1371 ThreadOpenConnections2(parg);
1372 vnThreadsRunning[1]--;
1373 }
1374 catch (std::exception& e) {
1375 vnThreadsRunning[1]--;
1376 PrintException(&e, "ThreadOpenConnections()");
1377 } catch (...) {
1378 vnThreadsRunning[1]--;
1379 PrintException(NULL, "ThreadOpenConnections()");
1380 }
1381 printf("ThreadOpenConnections exiting\n");
1382}
1383
1384void ThreadOpenConnections2(void* parg)
1385{
1386 printf("ThreadOpenConnections started\n");
1387
1388 // Connect to specific addresses
1389 if (mapArgs.count("-connect"))
1390 {
1391 for (int64 nLoop = 0;; nLoop++)
1392 {
223b6f1b 1393 BOOST_FOREACH(string strAddr, mapMultiArgs["-connect"])
0a61b0df 1394 {
a6a5bb7c 1395 CAddress addr(strAddr, fAllowDNS);
0a61b0df 1396 if (addr.IsValid())
1397 OpenNetworkConnection(addr);
1398 for (int i = 0; i < 10 && i < nLoop; i++)
1399 {
1400 Sleep(500);
1401 if (fShutdown)
1402 return;
1403 }
1404 }
1405 }
1406 }
1407
1408 // Connect to manually added nodes first
1409 if (mapArgs.count("-addnode"))
1410 {
223b6f1b 1411 BOOST_FOREACH(string strAddr, mapMultiArgs["-addnode"])
0a61b0df 1412 {
a6a5bb7c 1413 CAddress addr(strAddr, fAllowDNS);
0a61b0df 1414 if (addr.IsValid())
1415 {
1416 OpenNetworkConnection(addr);
1417 Sleep(500);
1418 if (fShutdown)
1419 return;
1420 }
1421 }
1422 }
1423
1424 // Initiate network connections
1425 int64 nStart = GetTime();
1426 loop
1427 {
1428 // Limit outbound connections
1429 vnThreadsRunning[1]--;
1430 Sleep(500);
1431 loop
1432 {
1433 int nOutbound = 0;
1434 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 1435 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 1436 if (!pnode->fInbound)
1437 nOutbound++;
1438 int nMaxOutboundConnections = MAX_OUTBOUND_CONNECTIONS;
5a3e82f9 1439 nMaxOutboundConnections = min(nMaxOutboundConnections, (int)GetArg("-maxconnections", 125));
0a61b0df 1440 if (nOutbound < nMaxOutboundConnections)
1441 break;
1442 Sleep(2000);
1443 if (fShutdown)
1444 return;
1445 }
1446 vnThreadsRunning[1]++;
1447 if (fShutdown)
1448 return;
1449
1450 CRITICAL_BLOCK(cs_mapAddresses)
1451 {
1452 // Add seed nodes if IRC isn't working
0a61b0df 1453 bool fTOR = (fUseProxy && addrProxy.port == htons(9050));
5cbf7532 1454 if (mapAddresses.empty() && (GetTime() - nStart > 60 || fTOR) && !fTestNet)
0a61b0df 1455 {
1456 for (int i = 0; i < ARRAYLEN(pnSeed); i++)
1457 {
1458 // It'll only connect to one or two seed nodes because once it connects,
1459 // it'll get a pile of addresses with newer timestamps.
86fd7c5a
GA
1460 // Seed nodes are given a random 'last seen time' of between one and two
1461 // weeks ago.
1462 const int64 nOneWeek = 7*24*60*60;
0a61b0df 1463 CAddress addr;
1464 addr.ip = pnSeed[i];
86fd7c5a 1465 addr.nTime = GetTime()-GetRand(nOneWeek)-nOneWeek;
0a61b0df 1466 AddAddress(addr);
1467 }
0a61b0df 1468 }
1469 }
1470
1471
1472 //
1473 // Choose an address to connect to based on most recently seen
1474 //
1475 CAddress addrConnect;
1476 int64 nBest = INT64_MIN;
1477
1478 // Only connect to one address per a.b.?.? range.
1479 // Do this here so we don't have to critsect vNodes inside mapAddresses critsect.
1480 set<unsigned int> setConnected;
1481 CRITICAL_BLOCK(cs_vNodes)
223b6f1b 1482 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 1483 setConnected.insert(pnode->addr.ip & 0x0000ffff);
1484
a4e6ae10
LD
1485 int64 nANow = GetAdjustedTime();
1486
0a61b0df 1487 CRITICAL_BLOCK(cs_mapAddresses)
1488 {
223b6f1b 1489 BOOST_FOREACH(const PAIRTYPE(vector<unsigned char>, CAddress)& item, mapAddresses)
0a61b0df 1490 {
1491 const CAddress& addr = item.second;
1492 if (!addr.IsIPv4() || !addr.IsValid() || setConnected.count(addr.ip & 0x0000ffff))
1493 continue;
a4e6ae10
LD
1494 int64 nSinceLastSeen = nANow - addr.nTime;
1495 int64 nSinceLastTry = nANow - addr.nLastTry;
0a61b0df 1496
1497 // Randomize the order in a deterministic way, putting the standard port first
1498 int64 nRandomizer = (uint64)(nStart * 4951 + addr.nLastTry * 9567851 + addr.ip * 7789) % (2 * 60 * 60);
a6a5bb7c 1499 if (addr.port != htons(GetDefaultPort()))
0a61b0df 1500 nRandomizer += 2 * 60 * 60;
1501
1502 // Last seen Base retry frequency
1503 // <1 hour 10 min
1504 // 1 hour 1 hour
1505 // 4 hours 2 hours
1506 // 24 hours 5 hours
1507 // 48 hours 7 hours
1508 // 7 days 13 hours
1509 // 30 days 27 hours
1510 // 90 days 46 hours
1511 // 365 days 93 hours
1512 int64 nDelay = (int64)(3600.0 * sqrt(fabs((double)nSinceLastSeen) / 3600.0) + nRandomizer);
1513
1514 // Fast reconnect for one hour after last seen
1515 if (nSinceLastSeen < 60 * 60)
1516 nDelay = 10 * 60;
1517
1518 // Limit retry frequency
1519 if (nSinceLastTry < nDelay)
1520 continue;
1521
1522 // If we have IRC, we'll be notified when they first come online,
1523 // and again every 24 hours by the refresh broadcast.
1524 if (nGotIRCAddresses > 0 && vNodes.size() >= 2 && nSinceLastSeen > 24 * 60 * 60)
1525 continue;
1526
1527 // Only try the old stuff if we don't have enough connections
1528 if (vNodes.size() >= 8 && nSinceLastSeen > 24 * 60 * 60)
1529 continue;
1530
1531 // If multiple addresses are ready, prioritize by time since
1532 // last seen and time since last tried.
1533 int64 nScore = min(nSinceLastTry, (int64)24 * 60 * 60) - nSinceLastSeen - nRandomizer;
1534 if (nScore > nBest)
1535 {
1536 nBest = nScore;
1537 addrConnect = addr;
1538 }
1539 }
1540 }
1541
1542 if (addrConnect.IsValid())
1543 OpenNetworkConnection(addrConnect);
1544 }
1545}
1546
1547bool OpenNetworkConnection(const CAddress& addrConnect)
1548{
1549 //
1550 // Initiate outbound network connection
1551 //
1552 if (fShutdown)
1553 return false;
15f3ad4d
GA
1554 if (addrConnect.ip == addrLocalHost.ip || !addrConnect.IsIPv4() ||
1555 FindNode(addrConnect.ip) || CNode::IsBanned(addrConnect.ip))
0a61b0df 1556 return false;
1557
1558 vnThreadsRunning[1]--;
1559 CNode* pnode = ConnectNode(addrConnect);
1560 vnThreadsRunning[1]++;
1561 if (fShutdown)
1562 return false;
1563 if (!pnode)
1564 return false;
1565 pnode->fNetworkNode = true;
1566
0a61b0df 1567 return true;
1568}
1569
1570
1571
1572
1573
1574
1575
1576
1577void ThreadMessageHandler(void* parg)
1578{
1579 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1580 try
1581 {
1582 vnThreadsRunning[2]++;
1583 ThreadMessageHandler2(parg);
1584 vnThreadsRunning[2]--;
1585 }
1586 catch (std::exception& e) {
1587 vnThreadsRunning[2]--;
1588 PrintException(&e, "ThreadMessageHandler()");
1589 } catch (...) {
1590 vnThreadsRunning[2]--;
1591 PrintException(NULL, "ThreadMessageHandler()");
1592 }
1593 printf("ThreadMessageHandler exiting\n");
1594}
1595
1596void ThreadMessageHandler2(void* parg)
1597{
1598 printf("ThreadMessageHandler started\n");
1599 SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
1600 while (!fShutdown)
1601 {
1602 vector<CNode*> vNodesCopy;
1603 CRITICAL_BLOCK(cs_vNodes)
1604 {
1605 vNodesCopy = vNodes;
223b6f1b 1606 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 1607 pnode->AddRef();
1608 }
1609
1610 // Poll the connected nodes for messages
1611 CNode* pnodeTrickle = NULL;
1612 if (!vNodesCopy.empty())
1613 pnodeTrickle = vNodesCopy[GetRand(vNodesCopy.size())];
223b6f1b 1614 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 1615 {
1616 // Receive messages
1617 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1618 ProcessMessages(pnode);
1619 if (fShutdown)
1620 return;
1621
1622 // Send messages
1623 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1624 SendMessages(pnode, pnode == pnodeTrickle);
1625 if (fShutdown)
1626 return;
1627 }
1628
1629 CRITICAL_BLOCK(cs_vNodes)
1630 {
223b6f1b 1631 BOOST_FOREACH(CNode* pnode, vNodesCopy)
0a61b0df 1632 pnode->Release();
1633 }
1634
7629d36a 1635 // Wait and allow messages to bunch up.
1636 // Reduce vnThreadsRunning so StopNode has permission to exit while
1637 // we're sleeping, but we must always check fShutdown after doing this.
0a61b0df 1638 vnThreadsRunning[2]--;
1639 Sleep(100);
3f647537 1640 if (fRequestShutdown)
1641 Shutdown(NULL);
0a61b0df 1642 vnThreadsRunning[2]++;
1643 if (fShutdown)
1644 return;
1645 }
1646}
1647
1648
1649
1650
1651
1652
0a61b0df 1653bool BindListenPort(string& strError)
1654{
1655 strError = "";
1656 int nOne = 1;
00bcfe0b 1657 addrLocalHost.port = htons(GetListenPort());
0a61b0df 1658
6853e627 1659#ifdef WIN32
0a61b0df 1660 // Initialize Windows Sockets
1661 WSADATA wsadata;
1662 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1663 if (ret != NO_ERROR)
1664 {
1665 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1666 printf("%s\n", strError.c_str());
1667 return false;
1668 }
1669#endif
1670
1671 // Create socket for listening for incoming connections
1672 hListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1673 if (hListenSocket == INVALID_SOCKET)
1674 {
1675 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1676 printf("%s\n", strError.c_str());
1677 return false;
1678 }
1679
ec93a0e2 1680#ifdef SO_NOSIGPIPE
0a61b0df 1681 // Different way of disabling SIGPIPE on BSD
1682 setsockopt(hListenSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&nOne, sizeof(int));
1683#endif
1684
6853e627 1685#ifndef WIN32
0a61b0df 1686 // Allow binding if the port is still in TIME_WAIT state after
1687 // the program was closed and restarted. Not an issue on windows.
1688 setsockopt(hListenSocket, SOL_SOCKET, SO_REUSEADDR, (void*)&nOne, sizeof(int));
1689#endif
1690
6853e627 1691#ifdef WIN32
0a61b0df 1692 // Set to nonblocking, incoming connections will also inherit this
1693 if (ioctlsocket(hListenSocket, FIONBIO, (u_long*)&nOne) == SOCKET_ERROR)
1694#else
1695 if (fcntl(hListenSocket, F_SETFL, O_NONBLOCK) == SOCKET_ERROR)
1696#endif
1697 {
1698 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (error %d)", WSAGetLastError());
1699 printf("%s\n", strError.c_str());
1700 return false;
1701 }
1702
1703 // The sockaddr_in structure specifies the address family,
1704 // IP address, and port for the socket that is being bound
1705 struct sockaddr_in sockaddr;
1706 memset(&sockaddr, 0, sizeof(sockaddr));
1707 sockaddr.sin_family = AF_INET;
1708 sockaddr.sin_addr.s_addr = INADDR_ANY; // bind to all IPs on this computer
00bcfe0b 1709 sockaddr.sin_port = htons(GetListenPort());
0a61b0df 1710 if (::bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1711 {
1712 int nErr = WSAGetLastError();
1713 if (nErr == WSAEADDRINUSE)
d9c6b09a 1714 strError = strprintf(_("Unable to bind to port %d on this computer. Bitcoin is probably already running."), ntohs(sockaddr.sin_port));
0a61b0df 1715 else
1716 strError = strprintf("Error: Unable to bind to port %d on this computer (bind returned error %d)", ntohs(sockaddr.sin_port), nErr);
1717 printf("%s\n", strError.c_str());
1718 return false;
1719 }
1720 printf("Bound to port %d\n", ntohs(sockaddr.sin_port));
1721
1722 // Listen for incoming connections
1723 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1724 {
1725 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1726 printf("%s\n", strError.c_str());
1727 return false;
1728 }
1729
1730 return true;
1731}
1732
1733void StartNode(void* parg)
1734{
1735 if (pnodeLocalHost == NULL)
a6a5bb7c 1736 pnodeLocalHost = new CNode(INVALID_SOCKET, CAddress("127.0.0.1", 0, false, nLocalServices));
0a61b0df 1737
6853e627 1738#ifdef WIN32
0a61b0df 1739 // Get local host ip
1740 char pszHostName[1000] = "";
1741 if (gethostname(pszHostName, sizeof(pszHostName)) != SOCKET_ERROR)
1742 {
a6a5bb7c 1743 vector<CAddress> vaddr;
545a679a 1744 if (Lookup(pszHostName, vaddr, nLocalServices, -1, true))
223b6f1b 1745 BOOST_FOREACH (const CAddress &addr, vaddr)
a6a5bb7c 1746 if (addr.GetByte(3) != 127)
0a61b0df 1747 {
1748 addrLocalHost = addr;
1749 break;
1750 }
0a61b0df 1751 }
1752#else
1753 // Get local host ip
1754 struct ifaddrs* myaddrs;
1755 if (getifaddrs(&myaddrs) == 0)
1756 {
1757 for (struct ifaddrs* ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next)
1758 {
1759 if (ifa->ifa_addr == NULL) continue;
1760 if ((ifa->ifa_flags & IFF_UP) == 0) continue;
1761 if (strcmp(ifa->ifa_name, "lo") == 0) continue;
1762 if (strcmp(ifa->ifa_name, "lo0") == 0) continue;
1763 char pszIP[100];
1764 if (ifa->ifa_addr->sa_family == AF_INET)
1765 {
1766 struct sockaddr_in* s4 = (struct sockaddr_in*)(ifa->ifa_addr);
1767 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s4->sin_addr), pszIP, sizeof(pszIP)) != NULL)
1768 printf("ipv4 %s: %s\n", ifa->ifa_name, pszIP);
1769
1770 // Take the first IP that isn't loopback 127.x.x.x
00bcfe0b 1771 CAddress addr(*(unsigned int*)&s4->sin_addr, GetListenPort(), nLocalServices);
0a61b0df 1772 if (addr.IsValid() && addr.GetByte(3) != 127)
1773 {
1774 addrLocalHost = addr;
1775 break;
1776 }
1777 }
1778 else if (ifa->ifa_addr->sa_family == AF_INET6)
1779 {
1780 struct sockaddr_in6* s6 = (struct sockaddr_in6*)(ifa->ifa_addr);
1781 if (inet_ntop(ifa->ifa_addr->sa_family, (void*)&(s6->sin6_addr), pszIP, sizeof(pszIP)) != NULL)
1782 printf("ipv6 %s: %s\n", ifa->ifa_name, pszIP);
1783 }
1784 }
1785 freeifaddrs(myaddrs);
1786 }
1787#endif
1788 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1789
5f88e888 1790 if (fUseProxy || mapArgs.count("-connect") || fNoListen)
0a61b0df 1791 {
1792 // Proxies can't take incoming connections
1793 addrLocalHost.ip = CAddress("0.0.0.0").ip;
1794 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1795 }
1796 else
1797 {
629e37dd 1798 CreateThread(ThreadGetMyExternalIP, NULL);
0a61b0df 1799 }
1800
1801 //
1802 // Start threads
1803 //
1804
2bc6cece
MC
1805 if (GetBoolArg("-nodnsseed"))
1806 printf("DNS seeding disabled\n");
1807 else
1808 if (!CreateThread(ThreadDNSAddressSeed, NULL))
1809 printf("Error: CreateThread(ThreadDNSAddressSeed) failed\n");
1810
8bb5edc1
MC
1811 // Map ports with UPnP
1812 if (fHaveUPnP)
1813 MapPort(fUseUPnP);
1814
0a61b0df 1815 // Get addresses from IRC and advertise ours
1816 if (!CreateThread(ThreadIRCSeed, NULL))
1817 printf("Error: CreateThread(ThreadIRCSeed) failed\n");
1818
1819 // Send and receive from sockets, accept connections
65ba3e2f
LD
1820 if (!CreateThread(ThreadSocketHandler, NULL))
1821 printf("Error: CreateThread(ThreadSocketHandler) failed\n");
0a61b0df 1822
1823 // Initiate outbound connections
1824 if (!CreateThread(ThreadOpenConnections, NULL))
1825 printf("Error: CreateThread(ThreadOpenConnections) failed\n");
1826
1827 // Process messages
1828 if (!CreateThread(ThreadMessageHandler, NULL))
1829 printf("Error: CreateThread(ThreadMessageHandler) failed\n");
1830
1831 // Generate coins in the background
64c7ee7e 1832 GenerateBitcoins(fGenerateBitcoins, pwalletMain);
0a61b0df 1833}
1834
1835bool StopNode()
1836{
1837 printf("StopNode()\n");
1838 fShutdown = true;
1839 nTransactionsUpdated++;
1840 int64 nStart = GetTime();
8bb5edc1
MC
1841 while (vnThreadsRunning[0] > 0 || vnThreadsRunning[2] > 0 || vnThreadsRunning[3] > 0 || vnThreadsRunning[4] > 0
1842#ifdef USE_UPNP
1843 || vnThreadsRunning[5] > 0
1844#endif
1845 )
0a61b0df 1846 {
1847 if (GetTime() - nStart > 20)
1848 break;
1849 Sleep(20);
1850 }
1851 if (vnThreadsRunning[0] > 0) printf("ThreadSocketHandler still running\n");
1852 if (vnThreadsRunning[1] > 0) printf("ThreadOpenConnections still running\n");
1853 if (vnThreadsRunning[2] > 0) printf("ThreadMessageHandler still running\n");
1854 if (vnThreadsRunning[3] > 0) printf("ThreadBitcoinMiner still running\n");
1855 if (vnThreadsRunning[4] > 0) printf("ThreadRPCServer still running\n");
8bb5edc1 1856 if (fHaveUPnP && vnThreadsRunning[5] > 0) printf("ThreadMapPort still running\n");
2bc6cece 1857 if (vnThreadsRunning[6] > 0) printf("ThreadDNSAddressSeed still running\n");
0a61b0df 1858 while (vnThreadsRunning[2] > 0 || vnThreadsRunning[4] > 0)
1859 Sleep(20);
1860 Sleep(50);
1861
1862 return true;
1863}
1864
1865class CNetCleanup
1866{
1867public:
1868 CNetCleanup()
1869 {
1870 }
1871 ~CNetCleanup()
1872 {
1873 // Close sockets
223b6f1b 1874 BOOST_FOREACH(CNode* pnode, vNodes)
0a61b0df 1875 if (pnode->hSocket != INVALID_SOCKET)
1876 closesocket(pnode->hSocket);
1877 if (hListenSocket != INVALID_SOCKET)
1878 if (closesocket(hListenSocket) == SOCKET_ERROR)
1879 printf("closesocket(hListenSocket) failed with error %d\n", WSAGetLastError());
1880
6853e627 1881#ifdef WIN32
0a61b0df 1882 // Shutdown Windows Sockets
1883 WSACleanup();
1884#endif
1885 }
1886}
1887instance_of_cnetcleanup;
This page took 0.319011 seconds and 4 git commands to generate.