90#include "librats/util/rats_export.h"
92#include "librats/core/types.h"
102#include <condition_variable>
106#include <unordered_map>
167 std::chrono::milliseconds
tick{250};
197 uint64_t
relayed() const noexcept {
return relayed_.load(); }
200 enum class Phase : uint8_t {
207 bool initiator =
false;
208 Phase phase = Phase::AwaitingPeerConnect;
210 std::vector<Address> peer_addresses;
211 std::chrono::steady_clock::time_point deadline{};
217 bool have_via =
false;
221 void handle(
const Peer& from, ByteView payload);
222 void handle_relay_request(
const Peer& from,
const PeerId& dst, ByteView inner);
223 void handle_relayed(
const Peer& via,
const PeerId& src, ByteView inner);
226 void handle_connect(
const Peer& via,
const PeerId& src,
bool opening,
227 std::vector<Address> addresses);
228 void handle_sync(
const PeerId& src);
234 size_t relay_to(
const PeerId& dst,
const Bytes& inner,
const PeerId* via);
235 bool send_connect(
const PeerId& target,
bool opening,
const PeerId* via);
236 void send_sync(
const PeerId& target,
const PeerId* via);
239 void fire_punch(
const PeerId& target,
const std::vector<Address>& addresses);
243 void service_sessions();
252 void escalate_to_relay(
const PeerId& target);
256 std::vector<PeerId> directly_connected()
const;
257 std::vector<Address> own_punch_addresses()
const;
258 bool relay_budget_ok(
const PeerId& from);
259 bool in_cooldown(
const PeerId& target)
const;
260 void begin_cooldown(
const PeerId& target);
263 PeerNetwork* network_ =
nullptr;
264 DialService* dialer_ =
nullptr;
265 ExternalAddressService* external_ =
nullptr;
266 ServiceRegistry* services_ =
nullptr;
270 std::atomic<RelayService*> relay_{
nullptr};
272 std::atomic<bool> running_{
false};
273 std::atomic<uint64_t> punches_started_{0};
274 std::atomic<uint64_t> relayed_{0};
276 mutable std::mutex mutex_;
277 std::condition_variable cv_;
279 std::unordered_map<PeerId, Session, PeerId::Hash> sessions_;
280 std::unordered_map<PeerId, std::chrono::steady_clock::time_point, PeerId::Hash> cooldown_;
283 std::chrono::steady_clock::time_point window_started{};
286 std::mutex relay_mutex_;
287 std::unordered_map<PeerId, RelayBudget, PeerId::Hash> relay_budget_;
A dialable transport endpoint: a numeric IP + port.
uint64_t relayed() const noexcept
Messages forwarded on behalf of other peers (diagnostics and tests).
size_t active_sessions() const
Sessions currently in flight (diagnostics and tests).
void attach(NodeContext &ctx) override
bool punch(const PeerId &target) override
Try to reach target by punching.
uint64_t punches_started() const noexcept
Punch bursts this node has fired (diagnostics and tests).
A pluggable network subsystem.
Capability that lets a sibling module ask for a NAT hole punch by PeerId.
What the mesh has told us about our own side of the NAT.
A lightweight handle to a connected peer.
Self-certifying peer identity.
The narrow contract a subsystem needs from the node — and nothing more.
Capability that lets a sibling module ask for a peer to be reached through a third node,...
size_t max_addresses
Endpoints advertised to the target, and therefore dialed by it.
bool enable_relay
Serve as a rendezvous for other peers' punches.
int attempts
Rendezvous rounds before a target is given up on for cooldown.
bool relay_on_failure
When a punch cannot be attempted at all, or has been given up on, hand the target to RelayService — t...
std::chrono::milliseconds cooldown
How long after giving up before the same target may be punched again.
size_t relay_budget
Relay budget: messages one peer may have forwarded per window.
std::chrono::milliseconds round_timeout
How long one round may take from the first Connect to a live connection.
std::chrono::milliseconds relay_window
std::chrono::milliseconds tick
Session bookkeeping cadence — retries, timeouts, cooldown expiry.
size_t max_sessions
Concurrent punch sessions.
size_t max_relays
Peers asked to carry one punch's rendezvous.
DialProfile profile
How hard each punch dial repeats its Initial.
bool skip_when_endpoint_dependent
Refuse to punch when the mesh says our own mapping is per-destination (symmetric NAT): no endpoint we...