Back to Site
Loading...
Searching...
No Matches
dht_discovery.h
Go to the documentation of this file.
1#pragma once
2
23#include "util/rats_export.h"
24#include "node/peer_network.h"
25#include "subsystems/dht_service.h"
26#include "dht/dht.h"
27
28#include <atomic>
29#include <chrono>
30#include <condition_variable>
31#include <cstdint>
32#include <memory>
33#include <mutex>
34#include <string>
35#include <thread>
36#include <unordered_set>
37#include <vector>
38
39namespace librats {
40
41class RATS_API DhtDiscovery final : public Subsystem, public DhtService {
42public:
43 struct Config {
44 uint16_t dht_port = 0;
45 std::string bind_address = "";
46 std::string data_dir = "";
47 bool enable_ipv4 = true;
48 bool enable_ipv6 = true;
49 std::string discovery_key = "";
50 std::vector<HostEndpoint> bootstrap_nodes;
51 std::chrono::milliseconds search_interval{30000};
56 std::chrono::milliseconds announce_interval{600000}; // 10 min
57
61 bool discover_external_ip = true;
62 std::vector<HostEndpoint> stun_servers;
63 std::chrono::milliseconds stun_timeout{3000};
64 };
65
66 explicit DhtDiscovery(Config config);
67 ~DhtDiscovery() override;
68
69 void attach(NodeContext& ctx) override;
70 void start() override;
71 void stop() override;
72
73 bool is_running() const;
74
78 DhtClient* dht_client() override { return dht_ ? dht_.get() : dht6_.get(); }
79
80 uint16_t dht_port() const;
81 uint16_t dht_port_v6() const;
82 InfoHash discovery_hash() const { return hash_; }
83
86 std::string external_address() const;
87
89 static InfoHash hash_for_key(const std::string& key);
90
91private:
92 void loop();
93 void probe_external_ip();
94 void on_peers(const std::vector<Address>& peers, const InfoHash& info_hash);
95
98 std::unique_ptr<DhtClient> make_client(AddressFamily family);
99
101 template <typename Fn>
102 void for_each_client(Fn fn) {
103 if (dht_) fn(*dht_);
104 if (dht6_) fn(*dht6_);
105 }
106
107 Config config_;
108 InfoHash hash_;
109 PeerNetwork* network_ = nullptr;
110 std::unique_ptr<DhtClient> dht_;
111 std::unique_ptr<DhtClient> dht6_;
112
113 std::thread thread_;
114 std::atomic<bool> running_{false};
115 std::atomic<bool> recover_pending_{false};
116 std::mutex wait_mutex_;
117 std::condition_variable wake_;
118
119 std::mutex dialed_mutex_;
120 std::unordered_set<Address> dialed_;
121};
122
123} // 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:66
The narrow contract a subsystem needs from the node — and nothing more.
std::vector< HostEndpoint > bootstrap_nodes
empty → default internet nodes
std::vector< HostEndpoint > stun_servers
empty → built-in public defaults