Back to Site
Loading...
Searching...
No Matches
peer_exchange.h
Go to the documentation of this file.
1#pragma once
2
59
60#include "librats/util/rats_export.h"
62#include "librats/peer/peer.h"
65
66#include <atomic>
67#include <chrono>
68#include <cstdint>
69#include <mutex>
70#include <string>
71#include <unordered_map>
72#include <unordered_set>
73#include <vector>
74
75namespace librats {
76
77class ServiceRegistry;
78struct HolePunchService;
79
80class RATS_API PeerExchange final : public Subsystem {
81public:
82 struct Config {
84 size_t request_max = 32;
85 bool request_on_connect = true;
86 bool public_only = false;
87 std::chrono::milliseconds dial_cooldown{std::chrono::minutes(5)};
88 size_t max_recent_dials = 4096;
89
96 size_t peer_target = 0;
97
103 std::chrono::milliseconds punch_window{std::chrono::seconds(30)};
105 size_t max_pending_dials = 512;
106
112 };
113
115 explicit PeerExchange(Config config);
116 ~PeerExchange() override;
117
118 void attach(NodeContext& ctx) override;
119 void start() override;
120 void stop() override;
121
122private:
123 void on_connected(const Peer& peer);
124 void handle(const Peer& peer, ByteView payload);
125 void handle_request(const Peer& requester, uint16_t max);
128 void introduce(const PeerId& peer, const std::vector<PeerInfo>& peers,
129 const std::vector<PeerId>& listed);
130 void handle_response(ByteView body);
132 void on_dial_failed(const Address& address);
133
134 const Address* pick_shareable(const std::vector<Address>& addrs) const;
135 bool should_dial(const Address& addr);
138 void remember_dial(const Address& addr, const PeerId& id);
139
140 Config config_;
141 PeerNetwork* network_ = nullptr;
142 ServiceRegistry* services_ = nullptr;
145 std::atomic<HolePunchService*> punch_{nullptr};
146 std::atomic<bool> running_{false};
147
148 struct PendingDial {
149 PeerId id;
150 std::chrono::steady_clock::time_point started;
151 };
152
153 std::mutex mutex_;
154 std::unordered_map<Address, std::chrono::steady_clock::time_point> recent_dials_;
155 std::unordered_map<Address, PendingDial> pending_dials_;
156 std::unordered_set<PeerId, PeerId::Hash> introduced_;
157};
158
159} // namespace librats
A dialable transport endpoint: a numeric IP + port.
Non-owning view over a contiguous run of bytes.
Definition bytes.h:27
void stop() override
PeerExchange(Config config)
~PeerExchange() override
void attach(NodeContext &ctx) override
void start() override
A pluggable network subsystem.
Definition node.h:75
A lightweight handle to a connected peer.
Self-certifying peer identity.
The narrow contract a subsystem needs from the node — and nothing more.
size_t request_max
how many peers we ask for on connect
size_t max_pending_dials
Bound on dials awaiting their verdict — one entry is an address and an id.
std::chrono::milliseconds dial_cooldown
re-dial suppression
bool public_only
only share globally-routable addresses
bool introduce_requesters
Tell the peers an answer left out about the peer that asked, so that a small mesh whose members join ...
size_t peer_target
Stop dialing discovered peers once this many are connected.
size_t max_addresses_per_response
cap entries we send / act on per response
size_t max_recent_dials
bound the cooldown set
bool punch_on_dial_failure
Ask HolePunch to reach a discovered peer whose address would not dial.
std::chrono::milliseconds punch_window
How long a dial started here stays eligible for that fallback.