diff options
| author | Bitflash-sh <btf01@proton.me> | 2026-07-24 12:13:30 -0300 |
|---|---|---|
| committer | Bitflash-sh <btf01@proton.me> | 2026-07-24 12:13:30 -0300 |
| commit | 3efd9a089cc6b924d9bc917d3d8145f7c01265ad (patch) | |
| tree | 5c4d1bc9a487e54fb0ec5b386dbd4360b6779f42 /src/net.cpp | |
| parent | 51d617e70f90a972185917ea0096c1ecef2bfa8b (diff) | |
Multi-relay rendezvous with failover + relay rate-limiting
Seed list of 3 geographically-spread relays (Sao Paulo, New Jersey, Almaty);
nodes register at the first reachable one and fail over if it is attacked or
goes down, so no single relay IP is a point of failure. Relay installer now
applies iptables connection rate-limits to soak up single-source floods.
Diffstat (limited to 'src/net.cpp')
| -rw-r--r-- | src/net.cpp | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/net.cpp b/src/net.cpp index 8ab9ccc..659de05 100644 --- a/src/net.cpp +++ b/src/net.cpp | |||
| @@ -441,15 +441,24 @@ void ThreadBtfAccept(void* parg) | |||
| 441 | return; | 441 | return; |
| 442 | Sleep(5000); | 442 | Sleep(5000); |
| 443 | } | 443 | } |
| 444 | size_t iRelay = 0; | ||
| 444 | loop | 445 | loop |
| 445 | { | 446 | { |
| 446 | if (fShutdown) | 447 | if (fShutdown) |
| 447 | return; | 448 | return; |
| 448 | string strMeeting = strBtfMeetingRelay; | 449 | if (vBtfMeetingRelays.empty()) |
| 450 | { | ||
| 451 | Sleep(10000); // no meeting relay configured | ||
| 452 | continue; | ||
| 453 | } | ||
| 454 | // Stick to the current relay while it works; on failure, fail over to | ||
| 455 | // the next seed so a DDoS'd/blocked relay IP can't keep us offline. | ||
| 456 | string strMeeting = vBtfMeetingRelays[iRelay % vBtfMeetingRelays.size()]; | ||
| 449 | size_t colon = strMeeting.rfind(':'); | 457 | size_t colon = strMeeting.rfind(':'); |
| 450 | if (colon == string::npos) | 458 | if (colon == string::npos) |
| 451 | { | 459 | { |
| 452 | Sleep(10000); // no meeting relay configured | 460 | iRelay++; |
| 461 | Sleep(2000); | ||
| 453 | continue; | 462 | continue; |
| 454 | } | 463 | } |
| 455 | string strHost = strMeeting.substr(0, colon); | 464 | string strHost = strMeeting.substr(0, colon); |
| @@ -465,9 +474,13 @@ void ThreadBtfAccept(void* parg) | |||
| 465 | } | 474 | } |
| 466 | if (rv == btf::RV_INVALID) | 475 | if (rv == btf::RV_INVALID) |
| 467 | { | 476 | { |
| 468 | Sleep(10000); // relay unreachable; retry | 477 | iRelay++; // this relay is down/attacked -> try the next one |
| 478 | Sleep(3000); | ||
| 469 | continue; | 479 | continue; |
| 470 | } | 480 | } |
| 481 | // Registered OK: advertise THIS relay in our descriptor so clients dial | ||
| 482 | // us here, and keep using it (iRelay unchanged) until it fails. | ||
| 483 | BtfSetActiveRelay(strMeeting); | ||
| 471 | btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk); | 484 | btf_socket_t hSocket = btf::BtfServiceWrap(rv, sk); |
| 472 | if (hSocket == INVALID_SOCKET) | 485 | if (hSocket == INVALID_SOCKET) |
| 473 | continue; | 486 | continue; |
| @@ -1146,7 +1159,7 @@ bool StartNode(string& strError) | |||
| 1146 | 1159 | ||
| 1147 | // Anonymous inbound: this node's .btf hidden service, reachable through the | 1160 | // Anonymous inbound: this node's .btf hidden service, reachable through the |
| 1148 | // meeting relay without exposing our IP or needing a public port. | 1161 | // meeting relay without exposing our IP or needing a public port. |
| 1149 | if (!strBtfMeetingRelay.empty()) | 1162 | if (!vBtfMeetingRelays.empty()) |
| 1150 | if (_beginthread(ThreadBtfAccept, 0, NULL) == -1) | 1163 | if (_beginthread(ThreadBtfAccept, 0, NULL) == -1) |
| 1151 | printf("Error: _beginthread(ThreadBtfAccept) failed\n"); | 1164 | printf("Error: _beginthread(ThreadBtfAccept) failed\n"); |
| 1152 | 1165 | ||