Back to Site
Loading...
Searching...
No Matches
dht_discovery.h
Go to the documentation of this file.
1#pragma once
2
23#include "node/peer_network.h"
24#include "subsystems/dht_service.h"
25#include "dht/dht.h"
26
27#include <atomic>
28#include <chrono>
29#include <condition_variable>
30#include <cstdint>
31#include <memory>
32#include <mutex>
33#include <string>
34#include <thread>
35#include <unordered_set>
36#include <vector>
37
38namespace librats {
39
40class DhtDiscovery final : public Subsystem, public DhtService {
41public:
42 struct Config {
43 uint16_t dht_port = 0;
44 std::string bind_address = "";
45 std::string data_dir = "";
46 bool enable_ipv4 = true;
47 bool enable_ipv6 = true;
48 std::string discovery_key = "librats";
49 std::vector<Address> bootstrap_nodes;
50 std::chrono::milliseconds search_interval{5000};
51 std::chrono::milliseconds announce_interval{30000};
52
57 std::vector<Address> stun_servers;
58 std::chrono::milliseconds stun_timeout{3000};
59 };
60
61 explicit DhtDiscovery(Config config);
62 ~DhtDiscovery() override;
63
64 void attach(NodeContext& ctx) override;
65 void start() override;
66 void stop() override;
67
68 bool is_running() const;
69
73 DhtClient* dht_client() override { return dht_ ? dht_.get() : dht6_.get(); }
74
75 uint16_t dht_port() const;
76 uint16_t dht_port_v6() const;
77 InfoHash discovery_hash() const { return hash_; }
78
81 std::string external_address() const;
82
84 static InfoHash hash_for_key(const std::string& key);
85
86private:
87 void loop();
88 void probe_external_ip();
89 void on_peers(const std::vector<Address>& peers, const InfoHash& info_hash);
90
93 std::unique_ptr<DhtClient> make_client(AddressFamily family);
94
96 template <typename Fn>
97 void for_each_client(Fn fn) {
98 if (dht_) fn(*dht_);
99 if (dht6_) fn(*dht6_);
100 }
101
102 Config config_;
103 InfoHash hash_;
104 PeerNetwork* network_ = nullptr;
105 std::unique_ptr<DhtClient> dht_;
106 std::unique_ptr<DhtClient> dht6_;
107
108 std::thread thread_;
109 std::atomic<bool> running_{false};
110 std::atomic<bool> recover_pending_{false};
111 std::mutex wait_mutex_;
112 std::condition_variable wake_;
113
114 std::mutex dialed_mutex_;
115 std::unordered_set<std::string> dialed_;
116};
117
118} // namespace librats
~DhtDiscovery() override
InfoHash discovery_hash() const
uint16_t dht_port_v6() const
IPv6 DHT UDP port (0 if not running)
std::string external_address() const
Our external (public) IP currently used to derive the DHT node id, learned via STUN at startup or in-...
void stop() override
DhtDiscovery(Config config)
static InfoHash hash_for_key(const std::string &key)
Map an application key to a stable 20-byte discovery hash (SHA-1).
uint16_t dht_port() const
IPv4 DHT UDP port (0 if not running)
DhtClient * dht_client() override
DhtService: hand out the live Kademlia node so siblings (e.g.
void start() override
void attach(NodeContext &ctx) override
bool is_running() const
A pluggable network subsystem.
Definition node.h:65
The narrow contract a subsystem needs from the node — and nothing more.
std::string data_dir
routing-table persistence dir (empty = cwd). Set to the node's data_dir to co-locate state.
bool enable_ipv4
run the IPv4 Kademlia network
uint16_t dht_port
0 = ephemeral
std::chrono::milliseconds announce_interval
std::chrono::milliseconds search_interval
bool enable_ipv6
run the IPv6 Kademlia network (BEP 32)
std::vector< Address > stun_servers
empty → built-in public defaults
bool discover_external_ip
Probe a STUN server once at startup to learn our public IP and seed the DHT node id per BEP 42.
std::vector< Address > bootstrap_nodes
empty → default internet nodes
std::string discovery_key
app namespace
std::chrono::milliseconds stun_timeout