upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/net.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/net.cpp')
-rw-r--r--src/net.cpp2039
1 files changed, 2039 insertions, 0 deletions
diff --git a/src/net.cpp b/src/net.cpp
new file mode 100644
index 0000000..449d91c
--- /dev/null
+++ b/src/net.cpp
@@ -0,0 +1,2039 @@
1// Copyright (c) 2009 Satoshi Nakamoto
2// Distributed under the MIT/X11 software license, see the accompanying
3// file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5#pragma push_macro("snprintf")
6#undef snprintf
7#include <nlohmann/json.hpp>
8#pragma pop_macro("snprintf")
9#ifdef snprintf
10#undef snprintf
11#endif
12#include "headers.h"
13#include <thread> // hardware_concurrency, for the miner thread count
14#ifdef _WIN32
15#include <winsock2.h>
16#endif
17#include <openssl/rand.h>
18#include "btfaddr.h"
19#include "btftunnel.h"
20
21void ThreadReconnectCachedBtfPeers(void* parg);
22void ThreadMessageHandler2(void* parg);
23void ThreadSocketHandler2(void* parg);
24
25
26
27
28
29
30//
31// Global state variables
32//
33bool fClient = false;
34uint64 nLocalServices = (fClient ? 0 : NODE_NETWORK);
35CAddress addrLocalHost(0, DEFAULT_PORT, nLocalServices);
36unsigned short nListenPort = DEFAULT_PORT; // local P2P port (tunable via /port)
37CNode nodeLocalHost(INVALID_SOCKET, CAddress("127.0.0.1", nLocalServices));
38CNode* pnodeLocalHost = &nodeLocalHost;
39bool fShutdown = false;
40array<bool, 10> vfThreadRunning;
41vector<CNode*> vNodes;
42CCriticalSection cs_vNodes;
43map<CInv, CDataStream> mapRelay;
44deque<pair<int64, CInv> > vRelayExpiration;
45CCriticalSection cs_mapRelay;
46map<CInv, int64> mapAlreadyAskedFor;
47string strBtfConnect; // .btf peer to keep connected to (from /connectbtf)
48
49int nPeersWatched = 0;
50int64 nBlocksReceived = 0;
51int64 nBlocksWithoutParent = 0;
52static int64 nNodeStartTime = 0;
53
54static CCriticalSection cs_btfChurn;
55static int64 nBtfResolveAttempts = 0;
56static int64 nBtfResolveOk = 0;
57static int64 nBtfResolveMiss = 0;
58static int64 nBtfDialAttempts = 0;
59static int64 nBtfDialOk = 0;
60static int64 nBtfDialFailed = 0;
61static int64 nBtfRegisterOk = 0;
62static int64 nBtfRegisterFailed = 0;
63static int64 nBtfPairOk = 0;
64static int64 nBtfPairFailed = 0;
65static int64 nBtfHandshakeNoRecv = 0;
66static int64 nBtfHandshakeNoSend = 0;
67static int64 nBtfHandshakeSilent = 0;
68static string strBtfLastDialFail;
69static string strBtfLastHandshakeTimeout;
70
71void BtfChurnNoteResolveAttempt()
72{
73 CRITICAL_BLOCK(cs_btfChurn)
74 nBtfResolveAttempts++;
75}
76
77void BtfChurnNoteResolveResult(bool fOk)
78{
79 CRITICAL_BLOCK(cs_btfChurn)
80 {
81 if (fOk) nBtfResolveOk++;
82 else nBtfResolveMiss++;
83 }
84}
85
86void BtfChurnNoteDialAttempt(const string& strBtfAddr, const string& strMeeting)
87{
88 CRITICAL_BLOCK(cs_btfChurn)
89 nBtfDialAttempts++;
90 LogPrint("net", "btfchurn: dial attempt addr=%s meeting=%s\n",
91 strBtfAddr.c_str(), strMeeting.c_str());
92}
93
94void BtfChurnNoteDialResult(const string& strBtfAddr, const string& strMeeting, bool fOk)
95{
96 CRITICAL_BLOCK(cs_btfChurn)
97 {
98 if (fOk)
99 nBtfDialOk++;
100 else
101 {
102 nBtfDialFailed++;
103 strBtfLastDialFail = strBtfAddr + " via " + strMeeting;
104 }
105 }
106 LogPrint("net", "btfchurn: dial %s addr=%s meeting=%s\n",
107 fOk ? "ok" : "failed", strBtfAddr.c_str(), strMeeting.c_str());
108}
109
110void BtfChurnNoteRegisterResult(const string& strMeeting, bool fOk)
111{
112 CRITICAL_BLOCK(cs_btfChurn)
113 {
114 if (fOk) nBtfRegisterOk++;
115 else nBtfRegisterFailed++;
116 }
117 LogPrint("net", "btfchurn: register %s meeting=%s\n",
118 fOk ? "ok" : "failed", strMeeting.c_str());
119}
120
121void BtfChurnNotePairResult(const string& strMeeting, bool fOk)
122{
123 CRITICAL_BLOCK(cs_btfChurn)
124 {
125 if (fOk) nBtfPairOk++;
126 else nBtfPairFailed++;
127 }
128 LogPrint("net", "btfchurn: pair %s meeting=%s\n",
129 fOk ? "ok" : "timeout-or-drop", strMeeting.c_str());
130}
131
132void BtfChurnNoteHandshakeTimeout(const string& strBtfAddr, const string& strMeeting,
133 bool fRecv, bool fSend)
134{
135 CRITICAL_BLOCK(cs_btfChurn)
136 {
137 if (!fRecv && !fSend)
138 nBtfHandshakeSilent++;
139 else
140 {
141 if (!fRecv) nBtfHandshakeNoRecv++;
142 if (!fSend) nBtfHandshakeNoSend++;
143 }
144 strBtfLastHandshakeTimeout = strprintf("%s via %s recv=%d send=%d",
145 strBtfAddr.empty() ? "unknown" : strBtfAddr.c_str(),
146 strMeeting.empty() ? "unknown" : strMeeting.c_str(),
147 fRecv, fSend);
148 }
149}
150
151// --- Socket accounting (implementation lives in sockcount.h) --------------
152static const char* pszSockSite[SOCK_SITES] = {
153 "external-ip probe", "listen socket", "inbound accept",
154 "rendezvous dial", "rendezvous listen", "rendezvous accept",
155 "loopback pair listener", "loopback pair app end", "loopback pair pump end",
156 "nostr relay"
157};
158
159static string SockAccountingText()
160{
161 long long nOpened[SOCK_SITES], nClosed[SOCK_SITES], nFailed[SOCK_SITES];
162 long long nCollided[SOCK_SITES], nUntagged = 0;
163 BtfSockSnapshot(nOpened, nClosed, nFailed, nCollided, &nUntagged);
164
165 long long nUnconn[SOCK_SITES];
166 BtfSockLiveUnconnected(nUnconn);
167
168 string str = "\n sockets by where they were created\n";
169 str += " site opened closed live close failed live unconn\n";
170 long long nTotalOpened = 0, nTotalClosed = 0, nTotalFailed = 0, nTotalUnconn = 0;
171 for (int i = 0; i < SOCK_SITES; i++)
172 {
173 nTotalOpened += nOpened[i];
174 nTotalClosed += nClosed[i];
175 nTotalFailed += nFailed[i];
176 nTotalUnconn += nUnconn[i];
177 if (nOpened[i] == 0)
178 continue;
179 str += strprintf(" %-24s %8lld %8lld %8lld %13lld %12lld\n", pszSockSite[i],
180 nOpened[i], nClosed[i], nOpened[i] - nClosed[i], nFailed[i], nUnconn[i]);
181 }
182 str += strprintf(" %-24s %8s %8lld %8s %13s %12s\n", "closed but never tagged",
183 "-", nUntagged, "-", "-", "-");
184 str += strprintf(" %-24s %8lld %8lld %8lld %13lld %12lld\n", "TOTAL",
185 nTotalOpened, nTotalClosed, nTotalOpened - nTotalClosed,
186 nTotalFailed, nTotalUnconn);
187
188 // The live total is what this program believes it is holding. Comparing it
189 // against `Get-NetTCPConnection | ? OwningProcess -eq <pid>` needs the note
190 // in sockcount.h first: that table lists a wildcard-bound socket twice, so
191 // a raw row count always looks larger than this. Count orphans, not rows.
192 //
193 // "live unconn" is a getpeername on every tagged socket. Anything above 1
194 // -- the listening socket -- means this program is holding a socket it
195 // never connected, which is the shape the leak hunt was looking for and
196 // never found.
197 if (nTotalFailed > 0)
198 {
199 str += " close failures by code\n";
200 for (int i = 0; i < SOCK_SITES; i++)
201 {
202 if (nFailed[i] == 0)
203 continue;
204 map<int, long long> mapErr;
205 BtfSockCloseErrors(i, mapErr);
206 string strCodes;
207 for (map<int, long long>::const_iterator mi = mapErr.begin(); mi != mapErr.end(); ++mi)
208 strCodes += strprintf("%s%d x%lld", strCodes.empty() ? "" : ", ",
209 mi->first, mi->second);
210 str += strprintf(" %-24s %s\n", pszSockSite[i], strCodes.c_str());
211 }
212 }
213
214 // A handle number handed out again while a site still claimed it. Windows
215 // only reuses a number after the last close, so this says that site's
216 // bookkeeping outlived its socket -- and it will close that number again,
217 // on somebody else's connection. Any value above zero is a bug with a name
218 // attached.
219 for (int i = 0; i < SOCK_SITES; i++)
220 {
221 if (nCollided[i] == 0)
222 continue;
223 str += strprintf(" handle reused while %s still claimed it: %lld\n",
224 pszSockSite[i], nCollided[i]);
225 }
226 return str;
227}
228
229// Defined further down, next to the counter it reads. The miner keeps its own
230// live count -- threads bump it on the way in and on the way out -- which is
231// the honest number here: how many are hashing now, not how many were asked to.
232static int MinersRunningCount();
233
234// Seconds rendered the way a person reads them off a screen.
235static string FormatAge(int64 nSeconds)
236{
237 if (nSeconds < 0) return "never";
238 if (nSeconds < 60) return strprintf("%llds", (long long)nSeconds);
239 if (nSeconds < 3600)
240 return strprintf("%lldm%02llds", (long long)(nSeconds / 60), (long long)(nSeconds % 60));
241 return strprintf("%lldh%02lldm", (long long)(nSeconds / 3600), (long long)((nSeconds % 3600) / 60));
242}
243
244string GetDiagnosticsText()
245{
246 int64 nNow = GetTime();
247 string str;
248
249 int nInbound = 0, nHeld = 0;
250 vector<CNode*> vCopy;
251 CRITICAL_BLOCK(cs_vNodes)
252 {
253 vCopy = vNodes;
254 nHeld = (int)vNodes.size();
255 foreach(CNode* pnode, vNodes)
256 if (pnode->fInbound)
257 nInbound++;
258 }
259
260 int nMedian = GetPeerMedianHeight();
261
262 str += "Bitflash node diagnostics\n";
263 str += strprintf(" uptime %s\n",
264 FormatAge(nNodeStartTime ? nNow - nNodeStartTime : -1).c_str());
265 if (nMedian < 0)
266 str += strprintf(" height %d (no peer has said where it is)\n", nBestHeight);
267 else
268 str += strprintf(" height %d (peers report %d, %s)\n",
269 nBestHeight, nMedian,
270 nBestHeight >= nMedian ? "level or ahead"
271 : strprintf("behind by %d", nMedian - nBestHeight).c_str());
272 str += strprintf(" peers held %d (%d inbound, %d outbound)\n",
273 nHeld, nInbound, nHeld - nInbound);
274
275 // The number that would have made the deafness obvious. Anything held but
276 // not watched is a socket this node will never read again.
277 str += strprintf(" peers watched %d of %d that select() can hold%s\n",
278 nPeersWatched, (int)FD_SETSIZE - 1,
279 nHeld > nPeersWatched ? " <-- NOT ALL PEERS ARE BEING READ" : "");
280
281 if (nBlocksReceived > 0)
282 str += strprintf(" blocks received %lld (%lld arrived without a parent, %.1f%%)\n",
283 (long long)nBlocksReceived, (long long)nBlocksWithoutParent,
284 100.0 * nBlocksWithoutParent / nBlocksReceived);
285 else
286 str += " blocks received 0\n";
287
288 int nMining = MinersRunningCount();
289 str += strprintf(" proof of work %s mode%s\n",
290 RandomXFastReady() ? "fast (2 GB dataset)" : "light (256 MB cache)",
291 nMining > 0
292 ? strprintf(", mining on %d thread(s), about %d MB",
293 nMining,
294 (RandomXFastReady() ? 2080 : 256) + 2 * nMining).c_str()
295 : ", not mining");
296
297 str += SockAccountingText();
298
299 int64 nResolveAttempts, nResolveOk, nResolveMiss;
300 int64 nDialAttempts, nDialOk, nDialFailed;
301 int64 nRegisterOk, nRegisterFailed, nPairOk, nPairFailed;
302 int64 nHandshakeNoRecv, nHandshakeNoSend, nHandshakeSilent;
303 string strLastDialFail, strLastHandshakeTimeout;
304 CRITICAL_BLOCK(cs_btfChurn)
305 {
306 nResolveAttempts = nBtfResolveAttempts;
307 nResolveOk = nBtfResolveOk;
308 nResolveMiss = nBtfResolveMiss;
309 nDialAttempts = nBtfDialAttempts;
310 nDialOk = nBtfDialOk;
311 nDialFailed = nBtfDialFailed;
312 nRegisterOk = nBtfRegisterOk;
313 nRegisterFailed = nBtfRegisterFailed;
314 nPairOk = nBtfPairOk;
315 nPairFailed = nBtfPairFailed;
316 nHandshakeNoRecv = nBtfHandshakeNoRecv;
317 nHandshakeNoSend = nBtfHandshakeNoSend;
318 nHandshakeSilent = nBtfHandshakeSilent;
319 strLastDialFail = strBtfLastDialFail;
320 strLastHandshakeTimeout = strBtfLastHandshakeTimeout;
321 }
322 str += "\n .btf churn\n";
323 str += strprintf(" resolves %lld attempts, %lld ok, %lld no descriptor\n",
324 (long long)nResolveAttempts, (long long)nResolveOk,
325 (long long)nResolveMiss);
326 str += strprintf(" outbound dials %lld attempts, %lld ok, %lld failed\n",
327 (long long)nDialAttempts, (long long)nDialOk,
328 (long long)nDialFailed);
329 str += strprintf(" rendezvous local register ok/fail %lld/%lld, pair ok/drop %lld/%lld\n",
330 (long long)nRegisterOk, (long long)nRegisterFailed,
331 (long long)nPairOk, (long long)nPairFailed);
332 str += strprintf(" handshake grace silent %lld, no recv %lld, no send %lld\n",
333 (long long)nHandshakeSilent, (long long)nHandshakeNoRecv,
334 (long long)nHandshakeNoSend);
335 if (!strLastDialFail.empty())
336 str += strprintf(" last dial failure %s\n", strLastDialFail.c_str());
337 if (!strLastHandshakeTimeout.empty())
338 str += strprintf(" last handshake %s\n", strLastHandshakeTimeout.c_str());
339
340 str += "\n peer dir height last recv last send unsent via\n";
341 foreach(CNode* pnode, vCopy)
342 {
343 int nSendSize = 0;
344 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
345 nSendSize = (int)pnode->vSend.size();
346 string strVia;
347 if (!pnode->strBtfMeeting.empty())
348 strVia = pnode->strBtfMeeting;
349 str += strprintf(" %-28s %-4s %6d %10s %10s %7d %s\n",
350 pnode->addr.ToString().substr(0, 28).c_str(),
351 pnode->fInbound ? "in" : "out",
352 pnode->nStartingHeight,
353 FormatAge(pnode->nLastRecv ? nNow - pnode->nLastRecv : -1).c_str(),
354 FormatAge(pnode->nLastSend ? nNow - pnode->nLastSend : -1).c_str(),
355 nSendSize,
356 strVia.substr(0, 28).c_str());
357 }
358 return str;
359}
360
361
362bool GetMyExternalIP(unsigned int& ipRet)
363{
364 // Try several plain-text IP echo services in order.
365 // Each returns just the IPv4 address as the first line of the HTTP body.
366 struct { const char* host; const char* path; } services[] = {
367 { "api4.ipify.org", "/" },
368 { "icanhazip.com", "/" },
369 { "ipecho.net", "/plain" },
370 { "checkip.amazonaws.com", "/" },
371 };
372
373 for (auto& svc : services)
374 {
375 struct addrinfo hints, *res = NULL;
376 memset(&hints, 0, sizeof(hints));
377 hints.ai_family = AF_INET;
378 hints.ai_socktype = SOCK_STREAM;
379 if (getaddrinfo(svc.host, "80", &hints, &res) != 0 || !res)
380 continue;
381
382 SOCKET hSocket = BtfSocketTag(socket(res->ai_family, res->ai_socktype, res->ai_protocol), SOCK_EXTIP);
383 if (hSocket == INVALID_SOCKET) { freeaddrinfo(res); continue; }
384
385 // 5-second timeout so a dead service doesn't stall startup
386#ifdef _WIN32
387 DWORD tv = 5000;
388 setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof(tv));
389 setsockopt(hSocket, SOL_SOCKET, SO_SNDTIMEO, (const char*)&tv, sizeof(tv));
390#else
391 struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0;
392 setsockopt(hSocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
393 setsockopt(hSocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
394#endif
395
396 if (connect(hSocket, res->ai_addr, (int)res->ai_addrlen) != 0)
397 {
398 freeaddrinfo(res); BtfCloseSocket(hSocket); continue;
399 }
400 freeaddrinfo(res);
401
402 string req = string("GET ") + svc.path + " HTTP/1.0\r\nHost: " + svc.host + "\r\nConnection: close\r\n\r\n";
403 send(hSocket, req.c_str(), (int)req.size(), 0);
404
405 // Read response, skip HTTP headers, grab first line of body
406 string response;
407 char buf[256];
408 int n;
409 while ((n = recv(hSocket, buf, sizeof(buf)-1, 0)) > 0)
410 {
411 buf[n] = 0;
412 response += buf;
413 if (response.size() > 4096) break;
414 }
415 BtfCloseSocket(hSocket);
416
417 // Find blank line separating headers from body
418 size_t bodyPos = response.find("\r\n\r\n");
419 if (bodyPos == string::npos) bodyPos = response.find("\n\n");
420 if (bodyPos == string::npos) continue;
421 string body = response.substr(bodyPos + (response[bodyPos+2]=='\r' ? 4 : 2));
422
423 // Trim whitespace
424 while (!body.empty() && (body.back() == '\n' || body.back() == '\r' || body.back() == ' '))
425 body.pop_back();
426
427 // Parse as IP
428 CAddress addr(body.c_str());
429 if (addr.ip == 0) continue;
430
431 printf("GetMyExternalIP() via %s: %s\n", svc.host, body.c_str());
432 ipRet = addr.ip;
433 return true;
434 }
435
436 return error("GetMyExternalIP() : all services failed\n");
437}
438
439
440
441
442
443
444
445
446
447void AbandonRequests(void (*fn)(void*, CDataStream&), void* param1)
448{
449 // If the dialog might get closed before the reply comes back,
450 // call this in the destructor so it doesn't get called after it's deleted.
451 CRITICAL_BLOCK(cs_vNodes)
452 {
453 foreach(CNode* pnode, vNodes)
454 {
455 CRITICAL_BLOCK(pnode->cs_mapRequests)
456 {
457 for (map<uint256, CRequestTracker>::iterator mi = pnode->mapRequests.begin(); mi != pnode->mapRequests.end();)
458 {
459 CRequestTracker& tracker = (*mi).second;
460 if (tracker.fn == fn && tracker.param1 == param1)
461 pnode->mapRequests.erase(mi++);
462 else
463 mi++;
464 }
465 }
466 }
467 }
468}
469
470
471
472
473
474
475
476//
477// Subscription methods for the broadcast and subscription system.
478// Channel numbers are message numbers, i.e. MSG_TABLE and MSG_PRODUCT.
479//
480// The subscription system uses a meet-in-the-middle strategy.
481// With 100,000 nodes, if senders broadcast to 1000 random nodes and receivers
482// subscribe to 1000 random nodes, 99.995% (1 - 0.99^1000) of messages will get through.
483//
484
485bool AnySubscribed(unsigned int nChannel)
486{
487 if (pnodeLocalHost->IsSubscribed(nChannel))
488 return true;
489 CRITICAL_BLOCK(cs_vNodes)
490 foreach(CNode* pnode, vNodes)
491 if (pnode->IsSubscribed(nChannel))
492 return true;
493 return false;
494}
495
496void CNode::PushGetBlocks(CBlockIndex* pindexBegin, uint256 hashEnd)
497{
498 // Filter out duplicate requests.
499 if (pindexBegin == pindexLastGetBlocksBegin && hashEnd == hashLastGetBlocksEnd)
500 return;
501 pindexLastGetBlocksBegin = pindexBegin;
502 hashLastGetBlocksEnd = hashEnd;
503
504 PushMessage("getblocks", CBlockLocator(pindexBegin), hashEnd);
505}
506
507bool CNode::IsSubscribed(unsigned int nChannel)
508{
509 if (nChannel >= vfSubscribe.size())
510 return false;
511 return vfSubscribe[nChannel];
512}
513
514void CNode::Subscribe(unsigned int nChannel, unsigned int nHops)
515{
516 if (nChannel >= vfSubscribe.size())
517 return;
518
519 if (!AnySubscribed(nChannel))
520 {
521 // Relay subscribe
522 CRITICAL_BLOCK(cs_vNodes)
523 foreach(CNode* pnode, vNodes)
524 if (pnode != this)
525 pnode->PushMessage("subscribe", nChannel, nHops);
526 }
527
528 vfSubscribe[nChannel] = true;
529}
530
531void CNode::CancelSubscribe(unsigned int nChannel)
532{
533 if (nChannel >= vfSubscribe.size())
534 return;
535
536 // Prevent from relaying cancel if wasn't subscribed
537 if (!vfSubscribe[nChannel])
538 return;
539 vfSubscribe[nChannel] = false;
540
541 if (!AnySubscribed(nChannel))
542 {
543 // Relay subscription cancel
544 CRITICAL_BLOCK(cs_vNodes)
545 foreach(CNode* pnode, vNodes)
546 if (pnode != this)
547 pnode->PushMessage("sub-cancel", nChannel);
548
549 // Clear memory, no longer subscribed
550 if (nChannel == MSG_PRODUCT)
551 CRITICAL_BLOCK(cs_mapProducts)
552 mapProducts.clear();
553 }
554}
555
556
557
558
559
560
561
562
563
564CNode* FindNode(unsigned int ip)
565{
566 CRITICAL_BLOCK(cs_vNodes)
567 {
568 foreach(CNode* pnode, vNodes)
569 if (pnode->addr.ip == ip)
570 return (pnode);
571 }
572 return NULL;
573}
574
575// Synthetic marker address for a tunneled `.btf` peer. The real endpoint is
576// unknown by design (the tunnel hides it), so tag the CNode with a non-routable
577// 10.x.x.x address (fails IsRoutable, so it is never gossiped as a real peer)
578// that is stable per identity, keeping FindNode and the duplicate check working.
579static CAddress BtfMarkerAddr(const unsigned char b5[5])
580{
581 unsigned int ip;
582 unsigned char b[4] = { 10, b5[0], b5[1], b5[2] };
583 memcpy(&ip, b, 4);
584 unsigned short port = htons((unsigned short)((b5[3] << 8) | b5[4]));
585 return CAddress(ip, port, nLocalServices);
586}
587
588// Shared tail: given a peer's pubkey and already-resolved rendezvous
589// coordinates, open the tunnel and register the CNode. Used by both
590// ConnectNodeBtf (which resolves the descriptor itself) and
591// ConnectNodeBtfResolved (which takes an already-resolved descriptor, so it
592// makes no Nostr relay calls at all -- see nostr.cpp's BtfResolveMany for why
593// that matters when dialing many candidates in parallel).
594//
595// Peers we have actually reached, remembered across restarts.
596//
597// Discovery is otherwise entirely dependent on the Nostr relays: a node that
598// has been running for hours and knows exactly which peers answer throws all
599// of it away on exit, and the next start walks the same ~96%-dead descriptor
600// list again. Reconnecting from this file skips the relays completely --
601// address, meeting node and encryption key are all we need.
602//
603static const size_t MAX_CACHED_BTF_PEERS = 50;
604static const int64 CACHED_BTF_PEER_TTL = 7 * 24 * 60 * 60; // a week
605
606struct CachedBtfPeer
607{
608 string btfAddr;
609 string meeting;
610 string encHex;
611 int64 lastSeen;
612 // The peer's own signed descriptor, as it announced itself. Kept verbatim
613 // because that signature is what lets us hand this peer on to somebody
614 // else: the receiver checks it against the key the address decodes to and
615 // never has to take our word for anything. Empty for entries learned
616 // before peer exchange existed, or resolved through Nostr -- those are
617 // still dialable, just not relayable.
618 string desc;
619};
620
621static string BtfPeerCachePath() { return GetAppDir() + "/btfpeers.json"; }
622
623static string BytesToHex(const unsigned char* p, size_t n)
624{
625 static const char* h = "0123456789abcdef";
626 string s;
627 s.reserve(n * 2);
628 for (size_t i = 0; i < n; i++) { s += h[p[i] >> 4]; s += h[p[i] & 0xf]; }
629 return s;
630}
631
632static bool HexToBytes(const string& s, unsigned char* out, size_t n)
633{
634 if (s.size() != n * 2) return false;
635 for (size_t i = 0; i < n; i++)
636 {
637 unsigned int b;
638 if (sscanf(s.c_str() + i * 2, "%2x", &b) != 1) return false;
639 out[i] = (unsigned char)b;
640 }
641 return true;
642}
643
644void LoadCachedBtfPeers(vector<CachedBtfPeer>& out)
645{
646 out.clear();
647 FILE* f = fopen(BtfPeerCachePath().c_str(), "r");
648 if (!f) return;
649 string body;
650 char buf[4096];
651 size_t r;
652 while ((r = fread(buf, 1, sizeof(buf), f)) > 0) body.append(buf, r);
653 fclose(f);
654 try
655 {
656 nlohmann::json arr = nlohmann::json::parse(body);
657 if (!arr.is_array()) return;
658 int64 nNow = GetTime();
659 for (const auto& o : arr)
660 {
661 if (!o.is_object()) continue;
662 if (!o.contains("btf") || !o["btf"].is_string()) continue;
663 if (!o.contains("meeting") || !o["meeting"].is_string()) continue;
664 if (!o.contains("enc") || !o["enc"].is_string()) continue;
665 CachedBtfPeer p;
666 p.btfAddr = o["btf"].get<string>();
667 p.meeting = o["meeting"].get<string>();
668 p.encHex = o["enc"].get<string>();
669 p.lastSeen = o.value("seen", (int64)0);
670 if (o.contains("desc") && o["desc"].is_string())
671 p.desc = o["desc"].get<string>();
672 if (nNow - p.lastSeen > CACHED_BTF_PEER_TTL) continue; // long gone
673 out.push_back(p);
674 }
675 }
676 catch (...)
677 {
678 LogPrint("net", "btfpeers: cache unreadable, starting empty\n");
679 out.clear();
680 }
681}
682
683static CCriticalSection cs_btfPeerCache;
684
685// strDesc is the peer's own signed descriptor when we have it (it announced
686// itself over peer exchange), "" when we only resolved it through Nostr. An
687// empty one never clears a descriptor already on file: dialing a peer we first
688// learned about by exchange must not cost us the ability to pass it on.
689static void RememberBtfPeer(const string& strBtfAddr, const string& strMeeting,
690 const unsigned char enc_pub[32],
691 const string& strDesc = string())
692{
693 CRITICAL_BLOCK(cs_btfPeerCache)
694 {
695 vector<CachedBtfPeer> peers;
696 LoadCachedBtfPeers(peers);
697
698 string strKeepDesc = strDesc;
699 for (size_t i = 0; i < peers.size(); i++)
700 if (peers[i].btfAddr == strBtfAddr)
701 {
702 if (strKeepDesc.empty())
703 strKeepDesc = peers[i].desc;
704 peers.erase(peers.begin() + i);
705 break;
706 }
707
708 CachedBtfPeer p;
709 p.btfAddr = strBtfAddr;
710 p.meeting = strMeeting;
711 p.encHex = BytesToHex(enc_pub, 32);
712 p.lastSeen = GetTime();
713 p.desc = strKeepDesc;
714 peers.insert(peers.begin(), p); // most recent first
715
716 if (peers.size() > MAX_CACHED_BTF_PEERS)
717 peers.resize(MAX_CACHED_BTF_PEERS);
718
719 nlohmann::json arr = nlohmann::json::array();
720 foreach(const CachedBtfPeer& q, peers)
721 {
722 nlohmann::json o;
723 o["btf"] = q.btfAddr;
724 o["meeting"] = q.meeting;
725 o["enc"] = q.encHex;
726 o["seen"] = q.lastSeen;
727 if (!q.desc.empty())
728 o["desc"] = q.desc;
729 arr.push_back(o);
730 }
731 FILE* f = fopen(BtfPeerCachePath().c_str(), "w");
732 if (f)
733 {
734 string s = arr.dump(2);
735 fwrite(s.c_str(), 1, s.size(), f);
736 fclose(f);
737 }
738 }
739}
740
741//
742// Compiled-in bootstrap seeds.
743//
744// A node with no cache has nothing but the Nostr relays, and if those are down,
745// blocked or simply slow, a first run has no way into the network at all. Seeds
746// are the floor under that: a handful of long-lived peers baked into the binary.
747//
748// A seed entry is deliberately just an address and an encryption key -- no
749// meeting node. The rendezvous relay pairs on the service's public key, and a
750// `.btf` address *is* that key, so a client can find a seed by trying the known
751// relays in turn. Recording which relay a seed was on would rot the moment it
752// failed over, which is the exact failure this project spent a long time
753// chasing: advertising a rendezvous somebody is not registered at.
754//
755// Seeds are ordinary nodes with no special authority. They hand out signed,
756// self-certifying descriptors like any peer, so a hostile seed can stall a
757// bootstrap but cannot forge a peer or feed a false chain.
758//
759struct BtfSeed
760{
761 const char* btfAddr;
762 const char* encHex; // 64 hex chars, the peer's x25519 public key
763};
764
765static const BtfSeed pszBtfSeeds[] =
766{
767 // Dedicated bootstrap node, Almaty. Runs beside a rendezvous relay on the
768 // same host, holds no wallet balance and does not mine -- it exists only to
769 // answer a first dial. It is trusted for nothing: it serves the same signed
770 // descriptors any peer does.
771 { "ygffz37jczlmrkzicxok6chobauyratdexc7hfgwzjdabzvb2nkngqy.btf",
772 "de8284b9d4effa2132e7981b566c1a297c39c1857d9c128e8ae093ef511d3200" },
773};
774static const size_t nBtfSeeds = ARRAYLEN(pszBtfSeeds);
775
776// Extra seeds from the command line (/btfseed=ADDRESS:ENCHEX, repeatable).
777vector<pair<string, string> > vBtfExtraSeeds;
778
779static int TryBtfSeeds()
780{
781 vector<pair<string, string> > seeds;
782 for (size_t i = 0; i < nBtfSeeds; i++)
783 seeds.push_back(make_pair(string(pszBtfSeeds[i].btfAddr),
784 string(pszBtfSeeds[i].encHex)));
785 foreach(const PAIRTYPE(string, string)& s, vBtfExtraSeeds)
786 seeds.push_back(s);
787
788 if (seeds.empty())
789 return 0;
790
791 vector<string> relays = BtfAllRelays();
792 if (relays.empty())
793 return 0;
794
795 LogPrint("net", "btfseed: trying %zu seed(s) across %zu relay(s)\n",
796 seeds.size(), relays.size());
797
798 int nConnected = 0;
799 foreach(const PAIRTYPE(string, string)& s, seeds)
800 {
801 if (fShutdown) return nConnected;
802 unsigned char enc[32];
803 if (!HexToBytes(s.second, enc, 32))
804 {
805 LogPrint("net", "btfseed: %s has a malformed encryption key, skipped\n",
806 s.first.c_str());
807 continue;
808 }
809 // We do not know which relay this seed is registered at, so walk them.
810 foreach(const string& strRelay, relays)
811 {
812 if (fShutdown) return nConnected;
813 if (ConnectNodeBtfResolved(s.first, strRelay, enc))
814 {
815 LogPrint("net", "btfseed: reached %s via %s\n",
816 s.first.c_str(), strRelay.c_str());
817 nConnected++;
818 break; // found it; no need to try this seed's other relays
819 }
820 }
821 if (nConnected >= 4)
822 break; // enough of a foothold; the rest comes from discovery
823 }
824 LogPrint("net", "btfseed: %d seed(s) answered\n", nConnected);
825 return nConnected;
826}
827
828// Dial everything we reached last time, before the relays have said anything.
829void ThreadReconnectCachedBtfPeers(void* parg)
830{
831 vector<CachedBtfPeer> peers;
832 LoadCachedBtfPeers(peers);
833 if (peers.empty())
834 {
835 // First run, or the cache aged out. Seeds are the only way in that does
836 // not depend on a relay answering.
837 LogPrint("net", "btfpeers: no cache yet, falling back to seeds\n");
838 if (TryBtfSeeds() == 0)
839 LogPrint("net", "btfpeers: no seed answered, waiting on relay discovery\n");
840 return;
841 }
842 LogPrint("net", "btfpeers: trying %zu remembered peer(s) before discovery\n",
843 peers.size());
844
845 int nConnected = 0;
846 foreach(const CachedBtfPeer& p, peers)
847 {
848 if (fShutdown) return;
849 unsigned char enc[32];
850 if (!HexToBytes(p.encHex, enc, 32)) continue;
851 if (ConnectNodeBtfResolved(p.btfAddr, p.meeting, enc))
852 {
853 nConnected++;
854 if (nConnected >= 8) break; // enough to bootstrap; the rest can wait
855 }
856 }
857 LogPrint("net", "btfpeers: %d of %zu remembered peer(s) answered\n",
858 nConnected, peers.size());
859}
860
861//
862// .btf peer exchange
863//
864// Until now discovery depended entirely on the Nostr relays: two connected
865// nodes never told each other who else existed, so a relay outage left a
866// running network unable to grow, and a node that found one stale peer had no
867// way to learn there was anything better.
868//
869// What travels here is each peer's own signed descriptor. The receiver checks
870// the Schnorr signature against the key the `.btf` address decodes to, so the
871// sender is trusted for nothing -- forging an entry would need somebody else's
872// secret key. That leaves flooding: valid descriptors for keys the sender
873// generated itself. The caps below bound one message, and the cache prefers
874// peers that actually answered, so a flood costs a Sybil more than it costs us.
875//
876
877void BtfPexCollect(vector<string>& vDescOut)
878{
879 vDescOut.clear();
880
881 // Ours first -- the node on the other end may know nobody but us.
882 string strMine = BtfLocalDescriptor();
883 if (!strMine.empty())
884 vDescOut.push_back(strMine);
885
886 vector<CachedBtfPeer> peers;
887 CRITICAL_BLOCK(cs_btfPeerCache)
888 LoadCachedBtfPeers(peers);
889
890 // Most recently seen first: these answered us, they are not names copied
891 // off a relay listing.
892 foreach(const CachedBtfPeer& p, peers)
893 {
894 if (vDescOut.size() >= MAX_PEX_DESCRIPTORS) break;
895 if (p.desc.empty()) continue; // nothing provable to pass on
896 if (p.desc.size() > MAX_PEX_DESCRIPTOR_BYTES) continue;
897 vDescOut.push_back(p.desc);
898 }
899}
900
901int BtfPexAccept(const vector<string>& vDesc)
902{
903 void* ctx = BtfSecpContext();
904 if (!ctx)
905 return 0;
906
907 string strSelf = BtfLocalAddress();
908 int nKept = 0;
909 unsigned int nSeen = 0;
910
911 foreach(const string& strDesc, vDesc)
912 {
913 if (++nSeen > MAX_PEX_DESCRIPTORS) break;
914 if (strDesc.empty() || strDesc.size() > MAX_PEX_DESCRIPTOR_BYTES) continue;
915
916 // The descriptor names the key it belongs to, and taking that key from
917 // the blob is safe precisely because the signature must verify under
918 // it: nobody can produce a valid descriptor for a key they don't hold.
919 unsigned char pubkey[32];
920 try
921 {
922 nlohmann::json v = nlohmann::json::parse(strDesc);
923 if (!v.is_object() || !v.contains("pubkey") || !v["pubkey"].is_string())
924 continue;
925 if (!HexToBytes(v["pubkey"].get<string>(), pubkey, 32))
926 continue;
927 }
928 catch (...) { continue; } // malformed JSON from an untrusted peer
929
930 btf::Descriptor d;
931 if (!btf::VerifyDescriptor(ctx, strDesc, pubkey, d))
932 continue;
933
934 string strAddr = btf::Address(pubkey);
935 if (strAddr.empty() || strAddr == strSelf)
936 continue; // ourselves, nothing to learn
937
938 unsigned char enc[32];
939 if (!HexToBytes(d.enc, enc, 32))
940 continue;
941
942 RememberBtfPeer(strAddr, d.meeting_node, enc, strDesc);
943 nKept++;
944 }
945 return nKept;
946}
947
948static CNode* ConnectNodeBtfTail(const string& strBtfAddr, const unsigned char pk[32],
949 const string& strMeeting, const unsigned char enc_pub[32])
950{
951 CAddress addr = BtfMarkerAddr(pk);
952 CNode* pnode = FindNode(addr.ip);
953 if (pnode)
954 {
955 pnode->AddRef();
956 return pnode;
957 }
958
959 BtfChurnNoteDialAttempt(strBtfAddr, strMeeting);
960 size_t colon = strMeeting.rfind(':');
961 if (colon == string::npos)
962 {
963 BtfChurnNoteDialResult(strBtfAddr, strMeeting, false);
964 return NULL;
965 }
966 string strHost = strMeeting.substr(0, colon);
967 int nPort = atoi(strMeeting.substr(colon + 1).c_str());
968 if (nPort <= 0 || nPort > 65535)
969 {
970 BtfChurnNoteDialResult(strBtfAddr, strMeeting, false);
971 return NULL;
972 }
973
974 btf_socket_t hSocket = btf::BtfClientTunnel(strHost.c_str(), (unsigned short)nPort, pk, enc_pub);
975 if (hSocket == INVALID_SOCKET)
976 {
977 if (fDebug)
978 LogPrint("net", "ConnectNodeBtf: tunnel to %s via %s failed\n", strBtfAddr.c_str(), strMeeting.c_str());
979 BtfChurnNoteDialResult(strBtfAddr, strMeeting, false);
980 return NULL;
981 }
982
983 if (fDebug)
984 LogPrint("net", "connected %s via rendezvous %s\n", strBtfAddr.c_str(), strMeeting.c_str());
985 BtfChurnNoteDialResult(strBtfAddr, strMeeting, true);
986
987 // This one answered -- worth trying first next time we start.
988 RememberBtfPeer(strBtfAddr, strMeeting, enc_pub);
989
990 // Add node
991 pnode = new CNode(hSocket, addr, false);
992 pnode->strBtfAddr = strBtfAddr;
993 pnode->strBtfMeeting = strMeeting;
994 pnode->AddRef();
995 CRITICAL_BLOCK(cs_vNodes)
996 vNodes.push_back(pnode);
997 return pnode;
998}
999
1000// Connect to a peer by its `.btf` address: resolve the self-certified
1001// descriptor over Nostr, then tunnel through its meeting node with the
1002// end-to-end channel. Neither side ever learns the other's IP.
1003CNode* ConnectNodeBtf(const string& strBtfAddr)
1004{
1005 unsigned char pk[32];
1006 if (!btf::ParseAddress(strBtfAddr, pk))
1007 {
1008 LogPrint("net", "ConnectNodeBtf: invalid address %s\n", strBtfAddr.c_str());
1009 return NULL;
1010 }
1011 if (BtfLocalAddress() == strBtfAddr)
1012 return NULL; // ourselves
1013
1014 if (fDebug)
1015 LogPrint("net", "trying %s\n", strBtfAddr.c_str());
1016
1017 string strMeeting;
1018 unsigned char enc_pub[32];
1019 BtfChurnNoteResolveAttempt();
1020 if (!BtfResolve(strBtfAddr, strMeeting, enc_pub))
1021 {
1022 BtfChurnNoteResolveResult(false);
1023 if (fDebug)
1024 LogPrint("net", "ConnectNodeBtf: could not resolve a descriptor for %s\n", strBtfAddr.c_str());
1025 return NULL;
1026 }
1027 BtfChurnNoteResolveResult(true);
1028 return ConnectNodeBtfTail(strBtfAddr, pk, strMeeting, enc_pub);
1029}
1030
1031// Same as ConnectNodeBtf, but skips the Nostr resolve step because the caller
1032// already resolved the descriptor (e.g. via BtfResolveMany, batching many
1033// addresses into one relay round-trip instead of one relay round-trip per
1034// address). Makes zero relay connections -- only talks to the peer's
1035// rendezvous meeting node.
1036CNode* ConnectNodeBtfResolved(const string& strBtfAddr, const string& strMeeting,
1037 const unsigned char enc_pub[32])
1038{
1039 unsigned char pk[32];
1040 if (!btf::ParseAddress(strBtfAddr, pk))
1041 {
1042 LogPrint("net", "ConnectNodeBtf: invalid address %s\n", strBtfAddr.c_str());
1043 return NULL;
1044 }
1045 if (BtfLocalAddress() == strBtfAddr)
1046 return NULL; // ourselves
1047 return ConnectNodeBtfTail(strBtfAddr, pk, strMeeting, enc_pub);
1048}
1049
1050// Anonymous inbound listener (this node's `.btf` hidden service). Registers at
1051// the meeting relay and blocks until a client dials our address; each pairing
1052// becomes a normal inbound CNode riding the end-to-end channel, then we
1053// register again for the next caller.
1054void ThreadBtfAccept(void* parg)
1055{
1056 printf("ThreadBtfAccept started\n");
1057 unsigned char pk[32];
1058 unsigned char sk[32];
1059 while (!BtfGetIdentity(pk, sk))
1060 {
1061 if (fShutdown)
1062 return;
1063 Sleep(5000);
1064 }
1065 size_t iRelay = 0;
1066 bool fPicked = false;
1067 loop
1068 {
1069 if (fShutdown)
1070 return;
1071 // Curated seeds + relays discovered from Nostr announcements.
1072 vector<string> relays = BtfAllRelays();
1073 if (relays.empty())
1074 {
1075 Sleep(10000); // no meeting relay configured
1076 continue;
1077 }
1078 // Random start spreads nodes across all relays (incl. volunteer ones).
1079 if (!fPicked)
1080 {
1081 iRelay = (size_t)GetRand(relays.size());
1082 fPicked = true;
1083 }
1084 // Stick to the current relay while it works; on failure, fail over to
1085 // the next one so a DDoS'd/blocked relay IP can't keep us offline.
1086 string strMeeting = relays[iRelay % relays.size()];
1087 size_t colon = strMeeting.rfind(':');
1088 if (colon == string::npos)
1089 {
1090 iRelay++;
1091 Sleep(2000);
1092 continue;
1093 }
1094 string strHost = strMeeting.substr(0, colon);
1095 int nPort = atoi(strMeeting.substr(colon + 1).c_str());
1096
1097 // Returns as soon as the relay has us listed -- it does not wait for a
1098 // dial. That distinction is the whole point: we have to be advertised
1099 // before anyone can dial us, so registering and waiting cannot be the
1100 // same call.
1101 btf::RvSocket rv = btf::RvServiceRegister(strHost.c_str(), (unsigned short)nPort, pk);
1102 if (fShutdown)
1103 {
1104 if (rv != btf::RV_INVALID)
1105 btf::RvClose(rv);
1106 return;
1107 }
1108 if (rv == btf::RV_INVALID)
1109 {
1110 BtfChurnNoteRegisterResult(strMeeting, false);
1111 LogPrint("net", "rendezvous: could not register at %s, trying another\n",
1112 strMeeting.c_str());
1113 iRelay++; // this relay is down/attacked -> try the next one
1114 Sleep(3000);
1115 continue;
1116 }
1117 BtfChurnNoteRegisterResult(strMeeting, true);
1118
1119 // Registered. Advertise THIS relay now, while we are listed and before
1120 // anybody dials -- a descriptor naming it is what makes a dial possible
1121 // at all. Keep using it (iRelay unchanged) until it fails.
1122 BtfSetActiveRelay(strMeeting);
1123 LogPrint("net", "rendezvous: registered at %s, waiting for a dial\n",
1124 strMeeting.c_str());
1125
1126 // Now wait for someone to arrive -- but not forever. This used to have
1127 // no bound, and a registration whose path died quietly left the thread
1128 // parked in recv() with nothing to wake it: the loop never came back
1129 // here, the node stopped being reachable, and nothing in the log said
1130 // so. Re-registering every few minutes when nobody has dialled costs
1131 // one reconnect and removes the whole failure mode.
1132 bool fPaired = btf::RvServiceWaitPaired(rv, BTF_RENDEZVOUS_WAIT_SECS);
1133 BtfChurnNotePairResult(strMeeting, fPaired);
1134 if (!fPaired)
1135 {
1136 btf::RvClose(rv);
1137 LogPrint("net", "rendezvous: no dial at %s within %ds (or it dropped us), "
1138 "re-registering\n", strMeeting.c_str(), BTF_RENDEZVOUS_WAIT_SECS);
1139 continue;
1140 }
1141
1142 btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk);
1143 if (hSocket == INVALID_SOCKET)
1144 {
1145 LogPrint("net", "rendezvous: paired at %s but channel setup failed\n",
1146 strMeeting.c_str());
1147 continue;
1148 }
1149
1150 // The dialer is anonymous (its pubkey never reaches us), so tag the
1151 // connection with a random marker address.
1152 unsigned char rnd[5];
1153 RAND_bytes(rnd, sizeof(rnd));
1154 CAddress addr = BtfMarkerAddr(rnd);
1155
1156 LogPrint("net", "accepted .btf connection via rendezvous %s\n", strMeeting.c_str());
1157 CNode* pnode = new CNode(hSocket, addr, true);
1158 pnode->strBtfAddr = "inbound";
1159 pnode->strBtfMeeting = strMeeting;
1160 pnode->AddRef();
1161 CRITICAL_BLOCK(cs_vNodes)
1162 vNodes.push_back(pnode);
1163 }
1164}
1165
1166// Keep an outbound connection to a specific `.btf` peer (from /connectbtf) --
1167// the rendezvous analogue of addnode. Retries until connected, reconnects if
1168// the tunnel drops.
1169void ThreadBtfConnect(void* parg)
1170{
1171 printf("ThreadBtfConnect started\n");
1172 string strAddr = *(string*)parg;
1173 delete (string*)parg;
1174 loop
1175 {
1176 if (fShutdown)
1177 return;
1178 try
1179 {
1180 CNode* pnode = ConnectNodeBtf(strAddr);
1181 if (pnode)
1182 {
1183 if (!pnode->fNetworkNode)
1184 pnode->fNetworkNode = true; // keep the ref from ConnectNodeBtf
1185 else
1186 pnode->Release(); // already pinned; drop the extra ref
1187 }
1188 }
1189 CATCH_PRINT_EXCEPTION("ThreadBtfConnect")
1190 for (int i = 0; i < 30 && !fShutdown; i++)
1191 Sleep(1000);
1192 }
1193}
1194
1195void CNode::Disconnect()
1196{
1197 LogPrint("net", "disconnecting node %s\n", addr.ToString().c_str());
1198
1199 // Invalidate before anything else can look at it. This used to close the
1200 // socket and leave the handle number sitting in the object, so ~CNode
1201 // closed it a second time and the select loop kept arming it in the
1202 // meantime. See the note on ~CNode in net.h.
1203 BtfCloseSocket(hSocket);
1204 hSocket = INVALID_SOCKET;
1205
1206 // All of a nodes broadcasts and subscriptions are automatically torn down
1207 // when it goes down, so a node has to stay up to keep its broadcast going.
1208
1209 CRITICAL_BLOCK(cs_mapProducts)
1210 for (map<uint256, CProduct>::iterator mi = mapProducts.begin(); mi != mapProducts.end();)
1211 AdvertRemoveSource(this, MSG_PRODUCT, 0, (*(mi++)).second);
1212
1213 // Cancel subscriptions
1214 for (unsigned int nChannel = 0; nChannel < vfSubscribe.size(); nChannel++)
1215 if (vfSubscribe[nChannel])
1216 CancelSubscribe(nChannel);
1217}
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231void ThreadSocketHandler(void* parg)
1232{
1233 IMPLEMENT_RANDOMIZE_STACK(ThreadSocketHandler(parg));
1234
1235 loop
1236 {
1237 vfThreadRunning[0] = true;
1238 CheckForShutdown(0);
1239 try
1240 {
1241 ThreadSocketHandler2(parg);
1242 }
1243 CATCH_PRINT_EXCEPTION("ThreadSocketHandler()")
1244 vfThreadRunning[0] = false;
1245 Sleep(5000);
1246 }
1247}
1248
1249void ThreadSocketHandler2(void* parg)
1250{
1251 printf("ThreadSocketHandler started\n");
1252 SOCKET hListenSocket = *(SOCKET*)parg;
1253 list<CNode*> vNodesDisconnected;
1254 int nPrevNodeCount = 0;
1255
1256 loop
1257 {
1258 //
1259 // Disconnect nodes
1260 //
1261 CRITICAL_BLOCK(cs_vNodes)
1262 {
1263 // Disconnect duplicate connections
1264 map<unsigned int, CNode*> mapFirst;
1265 foreach(CNode* pnode, vNodes)
1266 {
1267 if (pnode->fDisconnect)
1268 continue;
1269 unsigned int ip = pnode->addr.ip;
1270 if (mapFirst.count(ip) && addrLocalHost.ip < ip)
1271 {
1272 // In case two nodes connect to each other at once,
1273 // the lower ip disconnects its outbound connection
1274 CNode* pnodeExtra = mapFirst[ip];
1275
1276 if (pnodeExtra->GetRefCount() > (pnodeExtra->fNetworkNode ? 1 : 0))
1277 swap(pnodeExtra, pnode);
1278
1279 if (pnodeExtra->GetRefCount() <= (pnodeExtra->fNetworkNode ? 1 : 0))
1280 {
1281 LogPrint("net", "(%d nodes) disconnecting duplicate: %s\n", (int)vNodes.size(), pnodeExtra->addr.ToString().c_str());
1282 if (pnodeExtra->fNetworkNode && !pnode->fNetworkNode)
1283 {
1284 pnode->AddRef();
1285 swap(pnodeExtra->fNetworkNode, pnode->fNetworkNode);
1286 pnodeExtra->Release();
1287 }
1288 pnodeExtra->fDisconnect = true;
1289 }
1290 }
1291 mapFirst[ip] = pnode;
1292 }
1293
1294 // Disconnect unused nodes
1295 vector<CNode*> vNodesCopy = vNodes;
1296 foreach(CNode* pnode, vNodesCopy)
1297 {
1298 // Wait for the buffers to drain before letting a node go, so a
1299 // last message still gets out -- but not forever. vSend never
1300 // drains through a socket whose far end is gone, and a node
1301 // stuck that way stayed in vNodes for the life of the process,
1302 // holding its socket and counting as a peer.
1303 if (!pnode->ReadyToDisconnect())
1304 pnode->nDisconnectSince = 0;
1305 else if (pnode->nDisconnectSince == 0)
1306 pnode->nDisconnectSince = GetTime();
1307
1308 bool fDrained = pnode->vRecv.empty() && pnode->vSend.empty();
1309 bool fStuck = pnode->nDisconnectSince != 0 &&
1310 GetTime() - pnode->nDisconnectSince > DISCONNECT_DRAIN_SECS;
1311
1312 if (pnode->ReadyToDisconnect() && (fDrained || fStuck))
1313 {
1314 if (!fDrained)
1315 printf("dropping stuck node %s after %d s with %d bytes unsent\n",
1316 pnode->addr.ToString().c_str(),
1317 (int)(GetTime() - pnode->nDisconnectSince),
1318 (int)pnode->vSend.size());
1319 // remove from vNodes
1320 vNodes.erase(remove(vNodes.begin(), vNodes.end(), pnode), vNodes.end());
1321 pnode->Disconnect();
1322
1323 // hold in disconnected pool until all refs are released
1324 pnode->nReleaseTime = max(pnode->nReleaseTime, GetTime() + 5 * 60);
1325 if (pnode->fNetworkNode)
1326 pnode->Release();
1327 vNodesDisconnected.push_back(pnode);
1328 }
1329 }
1330
1331 // Delete disconnected nodes
1332 list<CNode*> vNodesDisconnectedCopy = vNodesDisconnected;
1333 foreach(CNode* pnode, vNodesDisconnectedCopy)
1334 {
1335 // wait until threads are done using it
1336 if (pnode->GetRefCount() <= 0)
1337 {
1338 bool fDelete = false;
1339 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1340 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1341 TRY_CRITICAL_BLOCK(pnode->cs_mapRequests)
1342 TRY_CRITICAL_BLOCK(pnode->cs_inventory)
1343 fDelete = true;
1344 if (fDelete)
1345 {
1346 vNodesDisconnected.remove(pnode);
1347 delete pnode;
1348 }
1349 }
1350 }
1351 }
1352 if (vNodes.size() != nPrevNodeCount)
1353 {
1354 nPrevNodeCount = vNodes.size();
1355 MainFrameRepaint();
1356 }
1357
1358
1359 //
1360 // Find which sockets have data to receive
1361 //
1362 struct timeval timeout;
1363 timeout.tv_sec = 0;
1364 timeout.tv_usec = 50000; // frequency to poll pnode->vSend
1365
1366 fd_set fdsetRecv;
1367 fd_set fdsetSend;
1368 FD_ZERO(&fdsetRecv);
1369 FD_ZERO(&fdsetSend);
1370 SOCKET hSocketMax = 0;
1371 FD_SET(hListenSocket, &fdsetRecv);
1372 hSocketMax = max(hSocketMax, hListenSocket);
1373 // FD_SET drops silently once the set is full, so count what goes in
1374 // and say so. A peer that never makes it into the set is never read,
1375 // and that is indistinguishable from a peer with nothing to say --
1376 // the failure this whole path used to hide.
1377 unsigned int nWatched = 1; // the listen socket
1378 CRITICAL_BLOCK(cs_vNodes)
1379 {
1380 foreach(CNode* pnode, vNodes)
1381 {
1382 if (nWatched >= FD_SETSIZE)
1383 break;
1384 // A disconnected node stays in vNodes until its references go.
1385 // Arming its closed handle asks select() to watch a number the
1386 // operating system may already have given to somebody else.
1387 if (pnode->hSocket == INVALID_SOCKET)
1388 continue;
1389 FD_SET(pnode->hSocket, &fdsetRecv);
1390 nWatched++;
1391 hSocketMax = max(hSocketMax, pnode->hSocket);
1392 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1393 if (!pnode->vSend.empty())
1394 FD_SET(pnode->hSocket, &fdsetSend);
1395 }
1396 if (vNodes.size() + 1 > (size_t)FD_SETSIZE)
1397 {
1398 static int64 nLastWarned = 0;
1399 if (GetTime() - nLastWarned > 60)
1400 {
1401 nLastWarned = GetTime();
1402 printf("WARNING: %d peers but select() can only watch %d -- %d are not being read\n",
1403 (int)vNodes.size(), (int)FD_SETSIZE - 1,
1404 (int)vNodes.size() - (int)FD_SETSIZE + 1);
1405 }
1406 }
1407 nPeersWatched = (int)nWatched - 1; // less the listen socket
1408 }
1409
1410 // Say the state of the node out loud now and then, so a log pulled off
1411 // a machine three weeks later still answers "was it hearing anybody".
1412 {
1413 static int64 nLastReport = 0;
1414 // Wound forward on the first pass so the first report lands about a
1415 // minute in, once peers have had time to connect. A report written
1416 // at second zero says nothing, and waiting ten minutes for the
1417 // first one is ten minutes of a log that cannot answer anything.
1418 if (nLastReport == 0)
1419 nLastReport = GetTime() - 9 * 60;
1420 if (GetTime() - nLastReport > 10 * 60)
1421 {
1422 nLastReport = GetTime();
1423 printf("%s\n", GetDiagnosticsText().c_str());
1424 }
1425 }
1426
1427 vfThreadRunning[0] = false;
1428 int nSelect = select(hSocketMax + 1, &fdsetRecv, &fdsetSend, NULL, &timeout);
1429 vfThreadRunning[0] = true;
1430 CheckForShutdown(0);
1431 if (nSelect == SOCKET_ERROR)
1432 {
1433 // This used to answer a failed select() by marking every
1434 // descriptor from 0 to hSocketMax ready, which is code written for
1435 // POSIX, where a descriptor is a small integer. A Windows SOCKET is
1436 // a kernel handle in the thousands, so the loop iterated over
1437 // numbers that are not sockets and told the rest of the function
1438 // that every peer had data. One bad handle in the set makes
1439 // select() fail on every pass, so a single closed socket put the
1440 // whole thread into that state permanently.
1441 //
1442 // Find the bad handle instead and let it be dropped.
1443 int nErr = WSAGetLastError();
1444 LogPrint("net", "select failed: %d\n", nErr);
1445 FD_ZERO(&fdsetRecv);
1446 FD_ZERO(&fdsetSend);
1447 CRITICAL_BLOCK(cs_vNodes)
1448 {
1449 foreach(CNode* pnode, vNodes)
1450 {
1451 // Already disconnected: its handle is gone on purpose, and
1452 // reporting it here would name the wrong node for a select()
1453 // failure it did not cause.
1454 if (pnode->hSocket == INVALID_SOCKET)
1455 continue;
1456 int nType = 0;
1457#ifdef _WIN32
1458 int nTypeLen = sizeof(nType);
1459#else
1460 socklen_t nTypeLen = sizeof(nType);
1461#endif
1462 if (getsockopt(pnode->hSocket, SOL_SOCKET, SO_TYPE, (char*)&nType, &nTypeLen) != 0)
1463 {
1464 printf("dropping node %s: its socket is no longer valid\n",
1465 pnode->addr.ToString().c_str());
1466 pnode->fDisconnect = true;
1467 }
1468 }
1469 }
1470 Sleep(timeout.tv_usec/1000);
1471 }
1472 RandAddSeed();
1473
1474 //// debug print
1475 //foreach(CNode* pnode, vNodes)
1476 //{
1477 // printf("vRecv = %-5d ", pnode->vRecv.size());
1478 // printf("vSend = %-5d ", pnode->vSend.size());
1479 //}
1480 //printf("\n");
1481
1482
1483 //
1484 // Accept new connections
1485 //
1486 if (FD_ISSET(hListenSocket, &fdsetRecv))
1487 {
1488 struct sockaddr_in sockaddr;
1489#ifdef _WIN32
1490 int len = sizeof(sockaddr);
1491#else
1492 socklen_t len = sizeof(sockaddr);
1493#endif
1494 SOCKET hSocket = BtfSocketTag(accept(hListenSocket, (struct sockaddr*)&sockaddr, &len), SOCK_ACCEPT);
1495 CAddress addr(sockaddr);
1496 if (hSocket == INVALID_SOCKET)
1497 {
1498 if (WSAGetLastError() != WSAEWOULDBLOCK)
1499 printf("ERROR ThreadSocketHandler accept failed: %d\n", WSAGetLastError());
1500 }
1501 else
1502 {
1503 // Refuse rather than accept a connection this node cannot
1504 // watch. Without this the listen socket kept taking peers --
1505 // it is always in the select set -- while everything past the
1506 // limit sat open and unread, which fed on itself: the deafer
1507 // the node got, the more connections it collected.
1508 unsigned int nNodes = 0;
1509 CRITICAL_BLOCK(cs_vNodes)
1510 nNodes = (unsigned int)vNodes.size();
1511 if (nNodes >= MAX_CONNECTIONS)
1512 {
1513 LogPrint("net", "refusing connection from %s, already at %u\n",
1514 addr.ToString().c_str(), nNodes);
1515 BtfCloseSocket(hSocket);
1516 }
1517 else
1518 {
1519 LogPrint("net", "accepted connection from %s\n", addr.ToString().c_str());
1520 CNode* pnode = new CNode(hSocket, addr, true);
1521 pnode->AddRef();
1522 CRITICAL_BLOCK(cs_vNodes)
1523 vNodes.push_back(pnode);
1524 }
1525 }
1526 }
1527
1528
1529 //
1530 // Service each socket
1531 //
1532 vector<CNode*> vNodesCopy;
1533 CRITICAL_BLOCK(cs_vNodes)
1534 vNodesCopy = vNodes;
1535 foreach(CNode* pnode, vNodesCopy)
1536 {
1537 CheckForShutdown(0);
1538 SOCKET hSocket = pnode->hSocket;
1539
1540 //
1541 // Receive
1542 //
1543 if (FD_ISSET(hSocket, &fdsetRecv))
1544 {
1545 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1546 {
1547 CDataStream& vRecv = pnode->vRecv;
1548 unsigned int nPos = vRecv.size();
1549
1550 // typical socket buffer is 8K-64K
1551 const unsigned int nBufSize = 0x10000;
1552 vRecv.resize(nPos + nBufSize);
1553 int nBytes = recv(hSocket, &vRecv[nPos], nBufSize, 0);
1554 vRecv.resize(nPos + max(nBytes, 0));
1555 if (nBytes > 0)
1556 {
1557 pnode->nLastRecv = GetTime();
1558 }
1559 else if (nBytes == 0)
1560 {
1561 // socket closed gracefully
1562 if (!pnode->fDisconnect)
1563 LogPrint("net", "recv: socket closed\n");
1564 pnode->fDisconnect = true;
1565 }
1566 else if (nBytes < 0)
1567 {
1568 // socket error
1569 int nErr = WSAGetLastError();
1570 if (nErr != WSAEWOULDBLOCK && nErr != WSAEMSGSIZE && nErr != WSAEINTR && nErr != WSAEINPROGRESS)
1571 {
1572 if (!pnode->fDisconnect)
1573 LogPrint("net", "recv failed: %d\n", nErr);
1574 pnode->fDisconnect = true;
1575 }
1576 }
1577 }
1578 }
1579
1580 //
1581 // Send
1582 //
1583 if (FD_ISSET(hSocket, &fdsetSend))
1584 {
1585 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1586 {
1587 CDataStream& vSend = pnode->vSend;
1588 if (!vSend.empty())
1589 {
1590 int nBytes = send(hSocket, &vSend[0], vSend.size(), 0);
1591 if (nBytes > 0)
1592 {
1593 vSend.erase(vSend.begin(), vSend.begin() + nBytes);
1594 pnode->nLastSend = GetTime();
1595 }
1596 else if (nBytes == 0)
1597 {
1598 if (pnode->ReadyToDisconnect())
1599 pnode->vSend.clear();
1600 }
1601 else
1602 {
1603 LogPrint("net", "send error %d\n", nBytes);
1604 if (pnode->ReadyToDisconnect())
1605 pnode->vSend.clear();
1606 }
1607 }
1608 if (vSend.empty())
1609 pnode->nLastSendEmpty = GetTime();
1610 }
1611 }
1612
1613 //
1614 // Inactivity
1615 //
1616 // Dropping the connection is the whole cure: everything above this
1617 // layer already knows how to reconnect, and a peer we cannot hear
1618 // is worth exactly as much as no peer at all. Give a new
1619 // connection a grace period first, or we would cut off peers that
1620 // are still completing the rendezvous handshake.
1621 //
1622 if (GetTime() - pnode->nTimeConnected > BTF_HANDSHAKE_GRACE_SECS)
1623 {
1624 if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
1625 {
1626 if (!pnode->strBtfMeeting.empty())
1627 BtfChurnNoteHandshakeTimeout(pnode->strBtfAddr, pnode->strBtfMeeting,
1628 pnode->nLastRecv != 0, pnode->nLastSend != 0);
1629 LogPrint("net", "socket no message in first %d seconds, recv=%d send=%d\n",
1630 BTF_HANDSHAKE_GRACE_SECS, pnode->nLastRecv != 0, pnode->nLastSend != 0);
1631 pnode->fDisconnect = true;
1632 }
1633 else if (GetTime() - pnode->nLastSend > BTF_SEND_STALL_SECS &&
1634 GetTime() - pnode->nLastSendEmpty > BTF_SEND_STALL_SECS)
1635 {
1636 // We have had something queued to send for this long and
1637 // none of it has gone out: the socket accepts no more.
1638 LogPrint("net", "socket not sending\n");
1639 pnode->fDisconnect = true;
1640 }
1641 else if (GetTime() - pnode->nLastRecv > BTF_RECV_TIMEOUT_SECS)
1642 {
1643 // The deaf case. Nothing has arrived for many block
1644 // intervals while the socket still looks perfectly fine.
1645 LogPrint("net", "socket inactivity timeout\n");
1646 pnode->fDisconnect = true;
1647 }
1648 }
1649 }
1650
1651
1652 Sleep(10);
1653 }
1654}
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673void ThreadMessageHandler(void* parg)
1674{
1675 IMPLEMENT_RANDOMIZE_STACK(ThreadMessageHandler(parg));
1676
1677 loop
1678 {
1679 vfThreadRunning[2] = true;
1680 CheckForShutdown(2);
1681 try
1682 {
1683 ThreadMessageHandler2(parg);
1684 }
1685 CATCH_PRINT_EXCEPTION("ThreadMessageHandler()")
1686 vfThreadRunning[2] = false;
1687 Sleep(5000);
1688 }
1689}
1690
1691int GetPeerMedianHeight()
1692{
1693 vector<int> vHeights;
1694 CRITICAL_BLOCK(cs_vNodes)
1695 foreach(CNode* pnode, vNodes)
1696 if (pnode->nStartingHeight >= 0)
1697 vHeights.push_back(pnode->nStartingHeight);
1698
1699 if (vHeights.empty())
1700 return -1;
1701
1702 sort(vHeights.begin(), vHeights.end());
1703 return vHeights[vHeights.size() / 2];
1704}
1705
1706
1707// Say out loud when we are behind the network.
1708//
1709// This is the whole reason the height is in the handshake. Every serious bug
1710// this node has had looked identical from the outside: running, threads alive,
1711// nothing in the log, and no blocks arriving. A node that knows where everyone
1712// else is can say so, and "8 blocks behind for 27 minutes" is a sentence a
1713// user can act on. Deliberately not behind a debug category -- an operator who
1714// already suspects trouble is not the one who needs telling.
1715static void WarnIfBehind()
1716{
1717 static int64 nLastWarned;
1718 static int64 nBehindSince;
1719
1720 int nPeers = GetPeerMedianHeight();
1721 if (nPeers < 0 || nBestHeight < 0)
1722 return;
1723
1724 // One block of slack: somebody is always mid-relay.
1725 if (nBestHeight >= nPeers - 1)
1726 {
1727 nBehindSince = 0;
1728 return;
1729 }
1730
1731 int64 nNow = GetTime();
1732 if (nBehindSince == 0)
1733 {
1734 nBehindSince = nNow;
1735 return;
1736 }
1737
1738 // Falling briefly behind is ordinary. Staying behind is not.
1739 if (nNow - nBehindSince < BTF_BEHIND_GRACE_SECS)
1740 return;
1741 if (nNow - nLastWarned < BTF_BEHIND_WARN_INTERVAL_SECS)
1742 return;
1743
1744 nLastWarned = nNow;
1745 printf("WARNING: %d blocks behind the network (height %d, peers report %d) for %d minutes\n",
1746 nPeers - nBestHeight, nBestHeight, nPeers, (int)((nNow - nBehindSince) / 60));
1747}
1748
1749
1750void ThreadMessageHandler2(void* parg)
1751{
1752 printf("ThreadMessageHandler started\n");
1753 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
1754 loop
1755 {
1756 // Poll the connected nodes for messages
1757 vector<CNode*> vNodesCopy;
1758 CRITICAL_BLOCK(cs_vNodes)
1759 vNodesCopy = vNodes;
1760 foreach(CNode* pnode, vNodesCopy)
1761 {
1762 pnode->AddRef();
1763
1764 // Receive messages
1765 TRY_CRITICAL_BLOCK(pnode->cs_vRecv)
1766 ProcessMessages(pnode);
1767
1768 // Send messages
1769 TRY_CRITICAL_BLOCK(pnode->cs_vSend)
1770 SendMessages(pnode);
1771
1772 pnode->Release();
1773 }
1774
1775 WarnIfBehind();
1776
1777 // Wait and allow messages to bunch up
1778 vfThreadRunning[2] = false;
1779 Sleep(100);
1780 vfThreadRunning[2] = true;
1781 CheckForShutdown(2);
1782 }
1783}
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793// Satoshi's "todo: start one thread per processor" stood here since 2009 and is
1794// what MinerThreadCount() and StartMinerThreads() below finally do -- by way of
1795// std::thread::hardware_concurrency rather than NUMBER_OF_PROCESSORS, which only
1796// ever existed on Windows.
1797//
1798// Miners share slot 3 of vfThreadRunning, and StopNode waits for every slot to
1799// go false before the node tears the database down. With one miner that was the
1800// same thing as "the miner finished"; with several, the first one out would
1801// announce that everybody had finished while the rest were still hashing and
1802// still calling ProcessBlock. So count them, and let only the last one leaving
1803// clear the flag.
1804static CCriticalSection cs_nMinersRunning;
1805static int nMinersRunning = 0;
1806
1807static int MinersRunningCount()
1808{
1809 int n = 0;
1810 CRITICAL_BLOCK(cs_nMinersRunning)
1811 n = nMinersRunning;
1812 return n;
1813}
1814
1815void ThreadBitcoinMiner(void* parg)
1816{
1817 int nThreadId = (int)(intptr_t)parg;
1818 CRITICAL_BLOCK(cs_nMinersRunning)
1819 {
1820 nMinersRunning++;
1821 vfThreadRunning[3] = true;
1822 }
1823 try
1824 {
1825 bool fRet = BitcoinMiner(nThreadId);
1826 printf("BitcoinMiner thread %d returned %s\n", nThreadId, fRet ? "true" : "false");
1827 }
1828 CATCH_PRINT_EXCEPTION("BitcoinMiner()")
1829 CRITICAL_BLOCK(cs_nMinersRunning)
1830 {
1831 if (--nMinersRunning <= 0)
1832 {
1833 nMinersRunning = 0;
1834 vfThreadRunning[3] = false;
1835 }
1836 }
1837}
1838
1839// Start the miners. Returns how many actually got off the ground.
1840int StartMinerThreads()
1841{
1842 int nThreads = MinerThreadCount();
1843 int nStarted = 0;
1844 for (int i = 0; i < nThreads; i++)
1845 {
1846 if (_beginthread(ThreadBitcoinMiner, 0, (void*)(intptr_t)(i + 1)) == (uintptr_t)-1)
1847 printf("Error: _beginthread(ThreadBitcoinMiner) failed on thread %d\n", i + 1);
1848 else
1849 nStarted++;
1850 }
1851 // The dataset is one allocation shared by all of them; only the 2 MB
1852 // scratchpads multiply. Printed because "why is it using 2 GB" is the first
1853 // question anyone asks.
1854 printf("Mining with %d thread(s) of %u core(s) -- about %d MB "
1855 "(~2080 MB shared RandomX dataset + ~2 MB per thread)\n",
1856 nStarted, std::thread::hardware_concurrency(), 2080 + 2 * nStarted);
1857 return nStarted;
1858}
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870bool StartNode(string& strError)
1871{
1872 strError = "";
1873 nNodeStartTime = GetTime();
1874
1875 // Sockets startup
1876 WSADATA wsadata;
1877 int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
1878 if (ret != NO_ERROR)
1879 {
1880 strError = strprintf("Error: TCP/IP socket library failed to start (WSAStartup returned error %d)", ret);
1881 printf("%s\n", strError.c_str());
1882 return false;
1883 }
1884
1885 // Get local host ip
1886 char pszHostName[255];
1887 if (gethostname(pszHostName, 255) == SOCKET_ERROR)
1888 {
1889 strError = strprintf("Error: Unable to get IP address of this computer (gethostname returned error %d)", WSAGetLastError());
1890 printf("%s\n", strError.c_str());
1891 return false;
1892 }
1893 struct hostent* pHostEnt = gethostbyname(pszHostName);
1894 if (!pHostEnt)
1895 {
1896 strError = strprintf("Error: Unable to get IP address of this computer (gethostbyname returned error %d)", WSAGetLastError());
1897 printf("%s\n", strError.c_str());
1898 return false;
1899 }
1900 addrLocalHost = CAddress(*(long*)(pHostEnt->h_addr_list[0]),
1901 nListenPort,
1902 nLocalServices);
1903 printf("addrLocalHost = %s\n", addrLocalHost.ToString().c_str());
1904
1905 // Create socket for listening for incoming connections
1906 SOCKET hListenSocket = BtfSocketTag(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP), SOCK_LISTEN);
1907 if (hListenSocket == INVALID_SOCKET)
1908 {
1909 strError = strprintf("Error: Couldn't open socket for incoming connections (socket returned error %d)", WSAGetLastError());
1910 printf("%s\n", strError.c_str());
1911 return false;
1912 }
1913
1914 // Set to nonblocking, incoming connections will also inherit this
1915 u_long nOne = 1;
1916 if (ioctlsocket(hListenSocket, FIONBIO, &nOne) == SOCKET_ERROR)
1917 {
1918 strError = strprintf("Error: Couldn't set properties on socket for incoming connections (ioctlsocket returned error %d)", WSAGetLastError());
1919 printf("%s\n", strError.c_str());
1920 return false;
1921 }
1922
1923 // The sockaddr_in structure specifies the address family,
1924 // IP address, and port for the socket that is being bound
1925 int nRetryLimit = 15;
1926 struct sockaddr_in sockaddr = addrLocalHost.GetSockAddr();
1927 if (bind(hListenSocket, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR)
1928 {
1929 int nErr = WSAGetLastError();
1930 if (nErr == WSAEADDRINUSE)
1931 strError = strprintf("Error: Unable to bind to port %s on this computer. The program is probably already running.", addrLocalHost.ToString().c_str());
1932 else
1933 strError = strprintf("Error: Unable to bind to port %s on this computer (bind returned error %d)", addrLocalHost.ToString().c_str(), nErr);
1934 printf("%s\n", strError.c_str());
1935 return false;
1936 }
1937 printf("bound to addrLocalHost = %s\n\n", addrLocalHost.ToString().c_str());
1938
1939 // Listen for incoming connections
1940 if (listen(hListenSocket, SOMAXCONN) == SOCKET_ERROR)
1941 {
1942 strError = strprintf("Error: Listening for incoming connections failed (listen returned error %d)", WSAGetLastError());
1943 printf("%s\n", strError.c_str());
1944 return false;
1945 }
1946
1947 // Get our external IP in a background thread -- up to 4 HTTP requests with
1948 // 5s timeouts each could otherwise delay startup by 20s on first run.
1949 // addrIncoming from a previous session is used immediately as a fallback.
1950 if (addrIncoming.ip)
1951 addrLocalHost.ip = addrIncoming.ip;
1952
1953 _beginthread([](void*) {
1954 unsigned int ip = addrLocalHost.ip;
1955 if (GetMyExternalIP(ip)) {
1956 addrLocalHost.ip = ip;
1957 addrIncoming = addrLocalHost;
1958 CWalletDB().WriteSetting("addrIncoming", addrIncoming);
1959 printf("External IP updated: %s\n", addrLocalHost.ToStringIP().c_str());
1960 }
1961 }, 0, NULL);
1962
1963 // Peers that answered last time, dialled straight away. The relays are the
1964 // only way to find anyone otherwise, and reaching them plus walking their
1965 // descriptor list is what makes a restart take minutes.
1966 if (_beginthread(ThreadReconnectCachedBtfPeers, 0, NULL) == -1)
1967 printf("Error: _beginthread(ThreadReconnectCachedBtfPeers) failed\n");
1968
1969 // Peer discovery over Nostr relays (replaces the old IRC seed)
1970 if (_beginthread(ThreadNostrSeed, 0, NULL) == -1)
1971 printf("Error: _beginthread(ThreadNostrSeed) failed\n");
1972
1973 // Anonymous inbound: this node's .btf hidden service, reachable through the
1974 // meeting relay without exposing our IP or needing a public port.
1975 //
1976 // Several of these, not one. Each holds its own registration at a
1977 // rendezvous, and a registration is consumed the moment a caller is paired
1978 // with it -- so with a single thread the node is unreachable for the whole
1979 // gap between being paired and registering again. Measured from a node's
1980 // own counters: half of all outbound dials failed for exactly that reason,
1981 // 15 of 30 in eleven minutes, while descriptors resolved 53 times out of
1982 // 54. Spares parked at the relay close that gap.
1983 //
1984 // Needs a relay that keeps more than one registration per node; against an
1985 // older relay the extra threads are harmless, because it drops the previous
1986 // registration on each new one and the node ends up where it started.
1987 if (!vBtfMeetingRelays.empty())
1988 for (int i = 0; i < BTF_ACCEPT_THREADS; i++)
1989 if (_beginthread(ThreadBtfAccept, 0, NULL) == -1)
1990 printf("Error: _beginthread(ThreadBtfAccept) failed\n");
1991
1992 // Anonymous outbound: keep a connection to a specific .btf peer, if asked.
1993 if (!strBtfConnect.empty())
1994 if (_beginthread(ThreadBtfConnect, 0, new string(strBtfConnect)) == -1)
1995 printf("Error: _beginthread(ThreadBtfConnect) failed\n");
1996
1997 //
1998 // Start threads
1999 //
2000 if (_beginthread(ThreadSocketHandler, 0, new SOCKET(hListenSocket)) == -1)
2001 {
2002 strError = "Error: _beginthread(ThreadSocketHandler) failed";
2003 printf("%s\n", strError.c_str());
2004 return false;
2005 }
2006
2007 if (_beginthread(ThreadMessageHandler, 0, NULL) == -1)
2008 {
2009 strError = "Error: _beginthread(ThreadMessageHandler) failed";
2010 printf("%s\n", strError.c_str());
2011 return false;
2012 }
2013
2014 return true;
2015}
2016
2017bool StopNode()
2018{
2019 printf("StopNode()\n");
2020 fShutdown = true;
2021 nTransactionsUpdated++;
2022 while (count(vfThreadRunning.begin(), vfThreadRunning.end(), true))
2023 Sleep(10);
2024 Sleep(50);
2025
2026 // Sockets shutdown
2027 WSACleanup();
2028 return true;
2029}
2030
2031void CheckForShutdown(int n)
2032{
2033 if (fShutdown)
2034 {
2035 if (n != -1)
2036 vfThreadRunning[n] = false;
2037 _endthread();
2038 }
2039}