Back to Site
Loading...
Searching...
No Matches
librats.h
Go to the documentation of this file.
1#pragma once
2
3#include "socket.h"
4#include "dht.h"
5#include "mdns.h"
6#include "logger.h"
7#include "threadmanager.h"
8#include "gossipsub.h" // For ValidationResult enum and GossipSub types
9#include "file_transfer.h" // File transfer functionality
10#include "noise.h" // Noise Protocol encryption
11#include "ice.h" // ICE-lite NAT traversal
12#ifdef RATS_STORAGE
13#include "storage.h" // Distributed storage functionality
14#endif
15#ifdef RATS_SEARCH_FEATURES
16#include "bittorrent.h" // BitTorrent functionality (optional, requires RATS_SEARCH_FEATURES)
17#endif
18#include "json.hpp" // nlohmann::json
19#include <string>
20#include <functional>
21#include <thread>
22#include <vector>
23#include <mutex>
24#include <atomic>
25#include <unordered_map>
26#include <memory>
27#include <chrono>
28#include <condition_variable>
29#include <unordered_set> // Added for unordered_set
30#include <cstdint>
31#include <cstring>
32#include "rats_export.h"
33
34namespace librats {
35
39struct RatsPeer {
40 std::string peer_id; // Unique hash ID for the peer
41 std::string ip; // IP address
42 uint16_t port; // Port number
43 socket_t socket; // Socket handle
44 std::string normalized_address; // Normalized address for duplicate detection (ip:port)
45 std::chrono::steady_clock::time_point connected_at; // Connection timestamp
46 bool is_outgoing; // True if we initiated the connection, false if incoming
47
48 // Handshake-related fields
49 enum class HandshakeState {
50 PENDING, // Handshake not started
51 SENT, // Handshake sent, waiting for response
52 NOISE_PENDING, // Rats handshake done, Noise handshake in progress
53 COMPLETED, // Handshake completed successfully (including Noise if enabled)
54 FAILED // Handshake failed
55 };
56
57 HandshakeState handshake_state; // Current handshake state
58 std::string version; // Protocol version of remote peer
59 std::chrono::steady_clock::time_point handshake_start_time; // When handshake started
60
61 // Encryption-related fields
62 bool encryption_enabled; // Whether encryption is enabled for this peer
63 bool noise_handshake_completed; // Whether noise handshake is completed
64 std::shared_ptr<rats::NoiseCipherState> send_cipher; // Cipher for sending encrypted data
65 std::shared_ptr<rats::NoiseCipherState> recv_cipher; // Cipher for receiving encrypted data
66 std::vector<uint8_t> remote_static_key; // Remote peer's static public key (for identity verification)
67
69 encryption_enabled(false),
71 connected_at = std::chrono::steady_clock::now();
73 }
74
75 RatsPeer(const std::string& id, const std::string& peer_ip, uint16_t peer_port,
76 socket_t sock, const std::string& norm_addr, bool outgoing)
77 : peer_id(id), ip(peer_ip), port(peer_port), socket(sock),
78 normalized_address(norm_addr), is_outgoing(outgoing),
80 encryption_enabled(false),
82 connected_at = std::chrono::steady_clock::now();
84 }
85
86 // Check if peer has completed Noise handshake and is ready for encrypted communication
90
91 // Helper methods
94};
95
100 int max_attempts = 3; // Maximum number of reconnection attempts
101 std::vector<int> retry_intervals_seconds = {5, 30, 120}; // Intervals between attempts (5s, 30s, 2min)
102 int stable_connection_threshold_seconds = 60; // Connection duration to be considered "stable" (1 minute)
103 int stable_first_retry_seconds = 2; // First retry interval for stable peers (faster)
104 bool enabled = true; // Whether auto-reconnection is enabled
105};
106
111 std::string peer_id; // Peer ID for identification
112 std::string ip; // IP address to reconnect to
113 uint16_t port; // Port number
114 int attempt_count; // Current number of reconnection attempts
115 std::chrono::steady_clock::time_point next_attempt_time; // When to attempt next reconnection
116 std::chrono::milliseconds connection_duration; // How long the peer was connected before disconnect
117 bool is_stable; // Whether this was a "stable" connection
118
120 next_attempt_time = std::chrono::steady_clock::now();
121 }
122
123 ReconnectInfo(const std::string& id, const std::string& peer_ip, uint16_t peer_port,
124 std::chrono::milliseconds duration, bool stable)
125 : peer_id(id), ip(peer_ip), port(peer_port), attempt_count(0),
126 connection_duration(duration), is_stable(stable) {
127 next_attempt_time = std::chrono::steady_clock::now();
128 }
129};
130
134enum class MessageDataType : uint8_t {
135 BINARY = 0x01, // Raw binary data
136 STRING = 0x02, // UTF-8 string data
137 JSON = 0x03 // JSON formatted data
138};
139
148 static constexpr uint32_t MAGIC_NUMBER = 0x52415453; // "RATS" in ASCII
149 static constexpr size_t HEADER_SIZE = 8;
150
151 uint32_t magic; // Magic number for validation
152 MessageDataType type; // Message data type
153 uint8_t reserved[3]; // Reserved bytes for future use
154
156 reserved[0] = reserved[1] = reserved[2] = 0;
157 }
158
162
163 // Serialize header to bytes
164 std::vector<uint8_t> serialize() const {
165 std::vector<uint8_t> data(HEADER_SIZE);
166 uint32_t network_magic = htonl(magic);
167 memcpy(data.data(), &network_magic, 4);
168 data[4] = static_cast<uint8_t>(type);
169 data[5] = reserved[0];
170 data[6] = reserved[1];
171 data[7] = reserved[2];
172 return data;
173 }
174
175 // Deserialize header from bytes
176 static bool deserialize(const std::vector<uint8_t>& data, MessageHeader& header) {
177 if (data.size() < HEADER_SIZE) {
178 return false;
179 }
180
181 uint32_t network_magic;
182 memcpy(&network_magic, data.data(), 4);
183 header.magic = ntohl(network_magic);
184
185 if (header.magic != MAGIC_NUMBER) {
186 return false;
187 }
188
189 header.type = static_cast<MessageDataType>(data[4]);
190 header.reserved[0] = data[5];
191 header.reserved[1] = data[6];
192 header.reserved[2] = data[7];
193
194 return true;
195 }
196
197 // Validate data type
198 bool is_valid_type() const {
199 return type == MessageDataType::BINARY ||
202 }
203};
204
208class RATS_API RatsClient : public ThreadManager {
209public:
210 // =========================================================================
211 // Type Definitions and Callbacks
212 // =========================================================================
213 using ConnectionCallback = std::function<void(socket_t, const std::string&)>;
214 using BinaryDataCallback = std::function<void(socket_t, const std::string&, const std::vector<uint8_t>&)>;
215 using StringDataCallback = std::function<void(socket_t, const std::string&, const std::string&)>;
216 using JsonDataCallback = std::function<void(socket_t, const std::string&, const nlohmann::json&)>;
217 using DisconnectCallback = std::function<void(socket_t, const std::string&)>;
218 using MessageCallback = std::function<void(const std::string&, const nlohmann::json&)>;
219 using SendCallback = std::function<void(bool, const std::string&)>;
220
221 // =========================================================================
222 // Constructor and Destructor
223 // =========================================================================
224
231 RatsClient(int listen_port, int max_peers = 10, const std::string& bind_address = "");
232
237
238 // =========================================================================
239 // Core Lifecycle Management
240 // =========================================================================
241
246 bool start();
247
251 void stop();
252
257
262 bool is_running() const;
263
264
265 // =========================================================================
266 // Utility Methods
267 // =========================================================================
268
269 int get_listen_port() const;
270
275 std::string get_bind_address() const;
276
277 // =========================================================================
278 // Connection Management
279 // =========================================================================
280
287 bool connect_to_peer(const std::string& host, int port);
288
294
299 void disconnect_peer_by_id(const std::string& peer_id);
300
301 // =========================================================================
302 // Data Transmission Methods
303 // =========================================================================
304
305 // Send to specific peer by socket
313 bool send_binary_to_peer(socket_t socket, const std::vector<uint8_t>& data, MessageDataType message_type = MessageDataType::BINARY);
314
321 bool send_string_to_peer(socket_t socket, const std::string& data);
322
329 bool send_json_to_peer(socket_t socket, const nlohmann::json& data);
330
331 // Send to specific peer by ID
339 bool send_binary_to_peer_id(const std::string& peer_id, const std::vector<uint8_t>& data, MessageDataType message_type = MessageDataType::BINARY);
340
347 bool send_string_to_peer_id(const std::string& peer_id, const std::string& data);
348
355 bool send_json_to_peer_id(const std::string& peer_id, const nlohmann::json& data);
356
357 // Broadcast to all peers
364 int broadcast_binary_to_peers(const std::vector<uint8_t>& data, MessageDataType message_type = MessageDataType::BINARY);
365
371 int broadcast_string_to_peers(const std::string& data);
372
378 int broadcast_json_to_peers(const nlohmann::json& data);
379
380 // =========================================================================
381 // Peer Information and Management
382 // =========================================================================
383
388 int get_peer_count() const;
389
390
396 std::string get_peer_id(socket_t socket) const;
397
403 socket_t get_peer_socket_by_id(const std::string& peer_id) const;
404
409 std::string get_our_peer_id() const;
410
415 std::vector<RatsPeer> get_all_peers() const;
416
421 std::vector<RatsPeer> get_validated_peers() const;
422
428 const RatsPeer* get_peer_by_id(const std::string& peer_id) const;
429
436
441 int get_max_peers() const;
442
447 void set_max_peers(int max_peers);
448
454
455 // =========================================================================
456 // Automatic Reconnection
457 // =========================================================================
458
463 void set_reconnect_enabled(bool enabled);
464
470
476
482
488
493
498 std::vector<ReconnectInfo> get_reconnect_queue() const;
499
500 // =========================================================================
501 // Callback Registration
502 // =========================================================================
503
509
515
521
527
533
534 // =========================================================================
535 // Peer Discovery Methods
536 // =========================================================================
537
538 // DHT Discovery
544 bool start_dht_discovery(int dht_port = 6881);
545
550
557 bool find_peers_by_hash(const std::string& content_hash,
558 std::function<void(const std::vector<std::string>&)> callback);
559
568 bool announce_for_hash(const std::string& content_hash, uint16_t port = 0,
569 std::function<void(const std::vector<std::string>&)> callback = nullptr);
570
575 bool is_dht_running() const;
576
582
583 // mDNS Discovery
590 bool start_mdns_discovery(const std::string& service_instance_name = "",
591 const std::map<std::string, std::string>& txt_records = {});
592
597
602 bool is_mdns_running() const;
603
608 void set_mdns_callback(std::function<void(const std::string&, int, const std::string&)> callback);
609
614 std::vector<MdnsService> get_mdns_services() const;
615
621
622 // Automatic Discovery
627
632
638
644 std::chrono::seconds calculate_discovery_interval() const;
645
650 std::string get_discovery_hash() const;
651
656 static std::string get_rats_peer_discovery_hash();
657
662 void add_ignored_address(const std::string& ip_address);
663
664 // =========================================================================
665 // Protocol Configuration
666 // =========================================================================
667
672 void set_protocol_name(const std::string& protocol_name);
673
678 void set_protocol_version(const std::string& protocol_version);
679
684 std::string get_protocol_name() const;
685
690 std::string get_protocol_version() const;
691
692 // =========================================================================
693 // Message Exchange API
694 // =========================================================================
695
701 void on(const std::string& message_type, MessageCallback callback);
702
708 void once(const std::string& message_type, MessageCallback callback);
709
714 void off(const std::string& message_type);
715
722 void send(const std::string& message_type, const nlohmann::json& data, SendCallback callback = nullptr);
723
731 void send(const std::string& peer_id, const std::string& message_type, const nlohmann::json& data, SendCallback callback = nullptr);
732
739 bool parse_json_message(const std::string& message, nlohmann::json& out_json);
740
741 // =========================================================================
742 // Encryption Functionality
743 // =========================================================================
744
750 bool initialize_encryption(bool enable);
751
756 void set_encryption_enabled(bool enabled);
757
763
769 bool is_peer_encrypted(const std::string& peer_id) const;
770
777 bool set_noise_static_keypair(const uint8_t private_key[32]);
778
783 std::vector<uint8_t> get_noise_static_public_key() const;
784
790 std::vector<uint8_t> get_peer_noise_public_key(const std::string& peer_id) const;
791
797 std::vector<uint8_t> get_peer_handshake_hash(const std::string& peer_id) const;
798
799 // =========================================================================
800 // Configuration Persistence
801 // =========================================================================
802
808
814
820 bool set_data_directory(const std::string& directory_path);
821
826 std::string get_data_directory() const;
827
833
839
845
850
855 std::vector<RatsPeer> get_historical_peers() const;
856
857 // =========================================================================
858 // Statistics and Information
859 // =========================================================================
860
865 nlohmann::json get_connection_statistics() const;
866
867 // =========================================================================
868 // GossipSub Functionality
869 // =========================================================================
870
876
882
883 // Topic Management
889 bool subscribe_to_topic(const std::string& topic);
890
896 bool unsubscribe_from_topic(const std::string& topic);
897
903 bool is_subscribed_to_topic(const std::string& topic) const;
904
909 std::vector<std::string> get_subscribed_topics() const;
910
911 // Publishing
918 bool publish_to_topic(const std::string& topic, const std::string& message);
919
926 bool publish_json_to_topic(const std::string& topic, const nlohmann::json& message);
927
928 // Event Handlers (Unified API)
934 void on_topic_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const std::string&)> callback);
935
941 void on_topic_json_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const nlohmann::json&)> callback);
942
948 void on_topic_peer_joined(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback);
949
955 void on_topic_peer_left(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback);
956
962 void set_topic_message_validator(const std::string& topic, std::function<ValidationResult(const std::string&, const std::string&, const std::string&)> validator);
963
968 void off_topic(const std::string& topic);
969
970 // Information
976 std::vector<std::string> get_topic_peers(const std::string& topic) const;
977
983 std::vector<std::string> get_topic_mesh_peers(const std::string& topic) const;
984
989 nlohmann::json get_gossipsub_statistics() const;
990
996
997 // =========================================================================
998 // Logging Control API
999 // =========================================================================
1000
1008
1014
1020 void set_logging_enabled(bool enabled);
1021
1027
1032 void set_log_file_path(const std::string& file_path);
1033
1038 std::string get_log_file_path() const;
1039
1045
1050 void set_log_level(const std::string& level_str);
1051
1057
1062 void set_log_colors_enabled(bool enabled);
1063
1069
1074 void set_log_timestamps_enabled(bool enabled);
1075
1081
1086 void set_log_rotation_size(size_t max_size_bytes);
1087
1093
1100 void set_log_rotate_on_startup(bool enabled);
1101
1107
1112
1113 // =========================================================================
1114 // File Transfer API
1115 // =========================================================================
1116
1122
1128
1129 // Sending and Requesting
1137 std::string send_file(const std::string& peer_id, const std::string& file_path,
1138 const std::string& remote_filename = "");
1139
1148 std::string send_directory(const std::string& peer_id, const std::string& directory_path,
1149 const std::string& remote_directory_name = "", bool recursive = true);
1150
1158 std::string request_file(const std::string& peer_id, const std::string& remote_file_path,
1159 const std::string& local_path);
1160
1169 std::string request_directory(const std::string& peer_id, const std::string& remote_directory_path,
1170 const std::string& local_directory_path, bool recursive = true);
1171
1172 // Accept/Reject Operations
1179 bool accept_file_transfer(const std::string& transfer_id, const std::string& local_path);
1180
1187 bool reject_file_transfer(const std::string& transfer_id, const std::string& reason = "");
1188
1195 bool accept_directory_transfer(const std::string& transfer_id, const std::string& local_path);
1196
1203 bool reject_directory_transfer(const std::string& transfer_id, const std::string& reason = "");
1204
1205 // Transfer Control
1211 bool pause_file_transfer(const std::string& transfer_id);
1212
1218 bool resume_file_transfer(const std::string& transfer_id);
1219
1225 bool cancel_file_transfer(const std::string& transfer_id);
1226
1227 // Information and Monitoring
1233 std::shared_ptr<FileTransferProgress> get_file_transfer_progress(const std::string& transfer_id) const;
1234
1239 std::vector<std::shared_ptr<FileTransferProgress>> get_active_file_transfers() const;
1240
1245 nlohmann::json get_file_transfer_statistics() const;
1246
1252
1258
1259 // Event Handlers
1265
1271
1277
1283
1289
1295
1296 // =========================================================================
1297 // ICE (NAT Traversal) API
1298 // =========================================================================
1299
1305
1310 bool is_ice_available() const;
1311
1312 // Server Configuration
1318 void add_stun_server(const std::string& host, uint16_t port = STUN_DEFAULT_PORT);
1319
1327 void add_turn_server(const std::string& host, uint16_t port,
1328 const std::string& username, const std::string& password);
1329
1334
1335 // Candidate Gathering
1342
1348 std::vector<IceCandidate> get_ice_candidates() const;
1349
1355
1356 // Public Address Discovery
1361 std::optional<std::pair<std::string, uint16_t>> get_public_address() const;
1362
1371 std::optional<StunMappedAddress> discover_public_address(
1372 const std::string& server = "stun.l.google.com",
1373 uint16_t port = 19302,
1374 int timeout_ms = 5000);
1375
1376 // Remote Candidates
1382
1387 void add_remote_ice_candidates_from_sdp(const std::vector<std::string>& sdp_lines);
1388
1393
1394 // Connectivity
1399
1405
1411
1416 bool is_ice_connected() const;
1417
1422 std::optional<IceCandidatePair> get_ice_selected_pair() const;
1423
1424 // ICE Event Callbacks
1430
1436
1442
1448
1454
1455 // ICE Configuration
1460 void set_ice_config(const IceConfig& config);
1461
1467
1468 // ICE Lifecycle
1473
1478
1479#ifdef RATS_STORAGE
1480 // =========================================================================
1481 // Distributed Storage API (requires RATS_STORAGE)
1482 // =========================================================================
1483
1488 StorageManager& get_storage_manager();
1489
1495
1496 // Put Operations
1503 bool storage_put(const std::string& key, const std::string& value);
1504
1511 bool storage_put(const std::string& key, int64_t value);
1512
1519 bool storage_put(const std::string& key, double value);
1520
1527 bool storage_put(const std::string& key, const std::vector<uint8_t>& value);
1528
1535 bool storage_put_json(const std::string& key, const nlohmann::json& value);
1536
1537 // Get Operations
1543 std::optional<std::string> storage_get_string(const std::string& key) const;
1544
1550 std::optional<int64_t> storage_get_int(const std::string& key) const;
1551
1557 std::optional<double> storage_get_double(const std::string& key) const;
1558
1564 std::optional<std::vector<uint8_t>> storage_get_binary(const std::string& key) const;
1565
1571 std::optional<nlohmann::json> storage_get_json(const std::string& key) const;
1572
1573 // Delete and Query Operations
1579 bool storage_delete(const std::string& key);
1580
1586 bool storage_has(const std::string& key) const;
1587
1592 std::vector<std::string> storage_keys() const;
1593
1599 std::vector<std::string> storage_keys_with_prefix(const std::string& prefix) const;
1600
1605 size_t storage_size() const;
1606
1607 // Synchronization
1613
1618 bool is_storage_synced() const;
1619
1620 // Statistics
1625 nlohmann::json get_storage_statistics() const;
1626
1631 void set_storage_config(const StorageConfig& config);
1632
1637 const StorageConfig& get_storage_config() const;
1638
1639 // Event Handlers
1644 void on_storage_change(StorageChangeCallback callback);
1645
1650 void on_storage_sync_complete(StorageSyncCompleteCallback callback);
1651#endif // RATS_STORAGE
1652
1653#ifdef RATS_SEARCH_FEATURES
1654 // =========================================================================
1655 // BitTorrent API (requires RATS_SEARCH_FEATURES)
1656 // =========================================================================
1657
1663 bool enable_bittorrent(int listen_port = 6881);
1664
1671 void set_resume_data_path(const std::string& path);
1672
1677
1683
1690 std::shared_ptr<TorrentDownload> add_torrent(const std::string& torrent_file,
1691 const std::string& download_path);
1692
1699 std::shared_ptr<TorrentDownload> add_torrent(const TorrentInfo& torrent_info,
1700 const std::string& download_path);
1701
1709 std::shared_ptr<TorrentDownload> add_torrent_by_hash(const InfoHash& info_hash,
1710 const std::string& download_path);
1711
1719 std::shared_ptr<TorrentDownload> add_torrent_by_hash(const std::string& info_hash_hex,
1720 const std::string& download_path);
1721
1727 bool remove_torrent(const InfoHash& info_hash);
1728
1734 std::shared_ptr<TorrentDownload> get_torrent(const InfoHash& info_hash);
1735
1740 std::vector<std::shared_ptr<TorrentDownload>> get_all_torrents();
1741
1747
1752 std::pair<uint64_t, uint64_t> get_bittorrent_stats() const;
1753
1760 void get_torrent_metadata(const InfoHash& info_hash,
1761 std::function<void(const TorrentInfo&, bool, const std::string&)> callback);
1762
1769 void get_torrent_metadata(const std::string& info_hash_hex,
1770 std::function<void(const TorrentInfo&, bool, const std::string&)> callback);
1771
1782 const std::string& peer_ip,
1783 uint16_t peer_port,
1784 std::function<void(const TorrentInfo&, bool, const std::string&)> callback);
1785
1794 void get_torrent_metadata_from_peer(const std::string& info_hash_hex,
1795 const std::string& peer_ip,
1796 uint16_t peer_port,
1797 std::function<void(const TorrentInfo&, bool, const std::string&)> callback);
1798
1799 // =========================================================================
1800 // Torrent Creation API (requires RATS_SEARCH_FEATURES)
1801 // =========================================================================
1802
1809 using TorrentCreationProgressCallback = std::function<void(uint32_t current_piece, uint32_t total_pieces)>;
1810
1820 std::optional<TorrentInfo> create_torrent_from_path(
1821 const std::string& path,
1822 const std::vector<std::string>& trackers = {},
1823 const std::string& comment = "",
1824 TorrentCreationProgressCallback progress_callback = nullptr);
1825
1834 std::vector<uint8_t> create_torrent_data(
1835 const std::string& path,
1836 const std::vector<std::string>& trackers = {},
1837 const std::string& comment = "",
1838 TorrentCreationProgressCallback progress_callback = nullptr);
1839
1850 const std::string& path,
1851 const std::string& output_file,
1852 const std::vector<std::string>& trackers = {},
1853 const std::string& comment = "",
1854 TorrentCreationProgressCallback progress_callback = nullptr);
1855
1866 std::shared_ptr<TorrentDownload> create_and_seed_torrent(
1867 const std::string& path,
1868 const std::vector<std::string>& trackers = {},
1869 const std::string& comment = "",
1870 TorrentCreationProgressCallback progress_callback = nullptr);
1871
1872 // =========================================================================
1873 // Spider Mode API (requires RATS_SEARCH_FEATURES)
1874 // =========================================================================
1875
1882 using SpiderAnnounceCallback = std::function<void(const std::string& info_hash, const std::string& peer_address)>;
1883
1891 void set_spider_mode(bool enable);
1892
1897 bool is_spider_mode() const;
1898
1905
1911 void set_spider_ignore(bool ignore);
1912
1918
1925
1930 size_t get_spider_pool_size() const;
1931
1937
1943#endif // RATS_SEARCH_FEATURES
1944
1945private:
1946 int listen_port_;
1947 std::string bind_address_;
1948 int max_peers_;
1949 socket_t server_socket_;
1950 std::atomic<bool> running_;
1951
1952 // =========================================================================
1953 // MUTEX LOCKING ORDER - CRITICAL FOR DEADLOCK PREVENTION
1954 // =========================================================================
1955 // When acquiring multiple mutexes, ALWAYS follow this strict order:
1956 //
1957 // 1. config_mutex_ (Configuration and peer ID)
1958 // 2. protocol_config_mutex_ (Protocol name and version)
1959 // 3. encryption_mutex_ (Encryption settings and keys)
1960 // 4. local_addresses_mutex_ (Local interface addresses)
1961 // 5. peers_mutex_ (Peer management - most frequently locked)
1962 // 6. socket_send_mutexes_mutex_ (Socket send mutex management)
1963 // 7. message_handlers_mutex_ (Message handler registration)
1964 // 8. reconnect_mutex_ (Reconnection queue management)
1965 // =========================================================================
1966
1967 // [1] Configuration persistence (protected by config_mutex_)
1968 mutable std::mutex config_mutex_; // [1] Protects configuration data
1969 std::string our_peer_id_; // Our persistent peer ID
1970 std::string data_directory_; // Directory where data files are stored
1971 static const std::string CONFIG_FILE_NAME; // "config.json"
1972 static const std::string PEERS_FILE_NAME; // "peers.rats"
1973 static const std::string PEERS_EVER_FILE_NAME; // "peers_ever.rats"
1974
1975 // [2] Custom protocol configuration (protected by protocol_config_mutex_)
1976 mutable std::mutex protocol_config_mutex_; // [2] Protects protocol configuration
1977 std::string custom_protocol_name_; // Custom protocol name (default: "rats")
1978 std::string custom_protocol_version_; // Custom protocol version (default: "1.0")
1979
1980 // [3] Encryption state (protected by encryption_mutex_)
1981 mutable std::mutex encryption_mutex_; // [3] Protects encryption state
1982 bool encryption_enabled_; // Whether encryption is enabled
1983 rats::NoiseKeyPair noise_static_keypair_; // Our static Noise keypair
1984 bool noise_keypair_initialized_; // Whether keypair has been initialized
1985
1986 // [4] Local interface address blocking (protected by local_addresses_mutex_)
1987 mutable std::mutex local_addresses_mutex_; // [4] Protects local interface addresses
1988 std::vector<std::string> local_interface_addresses_;
1989
1990 // [5] Organized peer management using RatsPeer struct (protected by peers_mutex_)
1991 mutable std::mutex peers_mutex_; // [5] Protects peer data (most frequently locked)
1992 std::unordered_map<std::string, RatsPeer> peers_; // keyed by peer_id
1993 std::unordered_map<socket_t, std::string> socket_to_peer_id_; // for quick socket->peer_id lookup
1994 std::unordered_map<std::string, std::string> address_to_peer_id_; // for duplicate detection (normalized_address->peer_id)
1995
1996 // [6] Per-socket synchronization for thread-safe message sending (protected by socket_send_mutexes_mutex_)
1997 mutable std::mutex socket_send_mutexes_mutex_; // [6] Protects socket send mutex map
1998 std::unordered_map<socket_t, std::shared_ptr<std::mutex>> socket_send_mutexes_;
1999
2000 // Server and client management
2001 std::thread server_thread_;
2002 std::thread management_thread_;
2003
2004 ConnectionCallback connection_callback_;
2005 BinaryDataCallback binary_data_callback_;
2006 StringDataCallback string_data_callback_;
2007 JsonDataCallback json_data_callback_;
2008 DisconnectCallback disconnect_callback_;
2009
2010 // DHT client for peer discovery
2011 std::unique_ptr<DhtClient> dht_client_;
2012
2013 // mDNS client for local network discovery
2014 std::unique_ptr<MdnsClient> mdns_client_;
2015 std::function<void(const std::string&, int, const std::string&)> mdns_callback_;
2016
2017 // GossipSub for publish-subscribe messaging
2018 std::unique_ptr<GossipSub> gossipsub_;
2019
2020 // File transfer manager
2021 std::unique_ptr<FileTransferManager> file_transfer_manager_;
2022
2023 // ICE manager for NAT traversal
2024 std::unique_ptr<IceManager> ice_manager_;
2025
2026#ifdef RATS_STORAGE
2027 // Distributed storage manager (optional, requires RATS_STORAGE)
2028 std::unique_ptr<StorageManager> storage_manager_;
2029#endif
2030
2031#ifdef RATS_SEARCH_FEATURES
2032 // BitTorrent client (optional, requires RATS_SEARCH_FEATURES)
2033 std::unique_ptr<BitTorrentClient> bittorrent_client_;
2034#endif
2035
2036 void initialize_modules();
2037 void destroy_modules();
2038
2039 void server_loop();
2040 void management_loop();
2041 void handle_client(socket_t client_socket, const std::string& peer_hash_id);
2042 void remove_peer(socket_t socket);
2043 std::string generate_peer_hash_id(socket_t socket, const std::string& connection_info);
2044 void handle_dht_peer_discovery(const std::vector<Peer>& peers, const InfoHash& info_hash);
2045 void handle_mdns_service_discovery(const MdnsService& service, bool is_new);
2046
2047 // Message header helpers
2048 std::vector<uint8_t> create_message_with_header(const std::vector<uint8_t>& payload, MessageDataType type);
2049 bool parse_message_with_header(const std::vector<uint8_t>& message, MessageHeader& header, std::vector<uint8_t>& payload) const;
2050
2051 // Peer management methods using RatsPeer
2052 void add_peer(const RatsPeer& peer);
2053 void add_peer_unlocked(const RatsPeer& peer); // Assumes peers_mutex_ is already locked
2054 void remove_peer_by_id(const std::string& peer_id);
2055 void remove_peer_by_id_unlocked(const std::string& peer_id); // Assumes peers_mutex_ is already locked
2056 bool is_already_connected_to_address(const std::string& normalized_address) const;
2057 std::string normalize_peer_address(const std::string& ip, int port) const;
2058
2059 // Data transmission helper - assumes peers_mutex_ is already locked or peer data is cached
2060 bool send_binary_to_peer_unlocked(socket_t socket, const std::vector<uint8_t>& data,
2061 MessageDataType message_type,
2062 rats::NoiseCipherState* send_cipher,
2063 const std::string& peer_id_for_logging);
2064
2065 // Local interface address blocking helper functions
2066 void initialize_local_addresses();
2067 bool is_blocked_address(const std::string& ip_address) const;
2068 bool should_ignore_peer(const std::string& ip, int port) const;
2069 static bool parse_address_string(const std::string& address_str, std::string& out_ip, int& out_port);
2070
2071 // Helper functions that assume mutex is already locked
2072 int get_peer_count_unlocked() const; // Helper that assumes peers_mutex_ is already locked
2073
2074 // Handshake protocol
2075 static constexpr const char* RATS_PROTOCOL_VERSION = "1.0";
2076 static constexpr int HANDSHAKE_TIMEOUT_SECONDS = 10;
2077
2078 struct HandshakeMessage {
2079 std::string protocol;
2080 std::string version;
2081 std::string peer_id;
2082 std::string message_type;
2083 int64_t timestamp;
2084 bool encryption_enabled; // Whether peer supports/wants encryption
2085 uint16_t listen_port; // Peer's listening port for peer exchange
2086 };
2087
2088 std::string create_handshake_message(const std::string& message_type, const std::string& our_peer_id) const;
2089 bool parse_handshake_message(const std::vector<uint8_t>& data, HandshakeMessage& out_msg) const;
2090 bool validate_handshake_message(const HandshakeMessage& msg) const;
2091 bool is_handshake_message(const std::vector<uint8_t>& data) const;
2092 bool send_handshake(socket_t socket, const std::string& our_peer_id);
2093 bool send_handshake_unlocked(socket_t socket, const std::string& our_peer_id);
2094 bool handle_handshake_message(socket_t socket, const std::string& peer_hash_id, const std::vector<uint8_t>& data);
2095 void check_handshake_timeouts();
2096 void log_handshake_completion_unlocked(const RatsPeer& peer);
2097
2098 // Automatic discovery
2099 std::atomic<bool> auto_discovery_running_;
2100 std::thread auto_discovery_thread_;
2101 void automatic_discovery_loop();
2102 void announce_rats_peer();
2103
2104 // Message handling system
2105 nlohmann::json create_rats_message(const std::string& type, const nlohmann::json& payload, const std::string& sender_peer_id);
2106 void handle_rats_message(socket_t socket, const std::string& peer_hash_id, const nlohmann::json& message);
2107
2108 // Specific message handlers
2109 void handle_peer_exchange_message(socket_t socket, const std::string& peer_hash_id, const nlohmann::json& payload);
2110 void handle_peers_request_message(socket_t socket, const std::string& peer_hash_id, const nlohmann::json& payload);
2111 void handle_peers_response_message(socket_t socket, const std::string& peer_hash_id, const nlohmann::json& payload);
2112
2113 // Message creation and broadcasting
2114 nlohmann::json create_peer_exchange_message(const RatsPeer& peer);
2115 void broadcast_peer_exchange_message(const RatsPeer& new_peer);
2116 nlohmann::json create_peers_request_message(const std::string& sender_peer_id);
2117 nlohmann::json create_peers_response_message(const std::vector<RatsPeer>& peers, const std::string& sender_peer_id);
2118 std::vector<RatsPeer> get_random_peers(int max_count, const std::string& exclude_peer_id = "") const;
2119 void send_peers_request(socket_t socket, const std::string& our_peer_id);
2120
2121 int broadcast_rats_message(const nlohmann::json& message, const std::string& exclude_peer_id = "");
2122 int broadcast_rats_message_to_validated_peers(const nlohmann::json& message, const std::string& exclude_peer_id = "");
2123
2124 // [7] Message exchange API implementation (protected by message_handlers_mutex_)
2125 mutable std::mutex message_handlers_mutex_; // [7] Protects message handlers
2126 struct MessageHandler {
2127 MessageCallback callback;
2128 bool is_once;
2129
2130 MessageHandler(MessageCallback cb, bool once) : callback(cb), is_once(once) {}
2131 };
2132 std::unordered_map<std::string, std::vector<MessageHandler>> message_handlers_;
2133
2134 void call_message_handlers(const std::string& message_type, const std::string& peer_id, const nlohmann::json& data);
2135
2136 // [8] Automatic reconnection system (protected by reconnect_mutex_)
2137 mutable std::mutex reconnect_mutex_; // [8] Protects reconnection queue
2138 std::unordered_map<std::string, ReconnectInfo> reconnect_queue_; // keyed by peer_id
2139 ReconnectConfig reconnect_config_; // Reconnection configuration
2140 std::unordered_set<std::string> manual_disconnect_peers_; // Peers that were manually disconnected (don't reconnect)
2141
2142 // Reconnection helper methods
2143 void schedule_reconnect(const RatsPeer& peer);
2144 void process_reconnect_queue();
2145 void remove_from_reconnect_queue(const std::string& peer_id);
2146 int get_retry_interval_seconds(int attempt, bool is_stable) const;
2147
2148 // Per-socket synchronization helpers
2149 std::shared_ptr<std::mutex> get_socket_send_mutex(socket_t socket);
2150 void cleanup_socket_send_mutex(socket_t socket);
2151
2152 // Configuration persistence helpers
2153 std::string generate_persistent_peer_id() const;
2154 nlohmann::json serialize_peer_for_persistence(const RatsPeer& peer) const;
2155 bool deserialize_peer_from_persistence(const nlohmann::json& json, std::string& ip, int& port, std::string& peer_id) const;
2156 std::string get_config_file_path() const;
2157 std::string get_peers_file_path() const;
2158 std::string get_peers_ever_file_path() const;
2159 bool save_peers_to_file();
2160 bool append_peer_to_historical_file(const RatsPeer& peer);
2161 int load_and_reconnect_historical_peers();
2162
2163 // Noise Protocol encryption helpers
2164 void initialize_noise_keypair();
2165 bool perform_noise_handshake(socket_t socket, const std::string& peer_id, bool is_initiator);
2166 bool send_noise_message(socket_t socket, const uint8_t* data, size_t len);
2167 bool recv_noise_message(socket_t socket, std::vector<uint8_t>& out_data, int timeout_ms = 10000);
2168 bool encrypt_and_send(socket_t socket, const std::string& peer_id, const std::vector<uint8_t>& plaintext);
2169 bool receive_and_decrypt(socket_t socket, const std::string& peer_id, std::vector<uint8_t>& plaintext);
2170};
2171
2172// Utility functions
2173std::unique_ptr<RatsClient> create_rats_client(int listen_port);
2174
2175// Library version query (stable, binding-friendly)
2176RATS_API const char* rats_get_library_version_string();
2177RATS_API void rats_get_library_version(int* major, int* minor, int* patch, int* build);
2178RATS_API const char* rats_get_library_git_describe();
2179RATS_API uint32_t rats_get_library_abi(); // packed as (major<<16)|(minor<<8)|patch
2180
2181} // namespace librats
File transfer manager class Handles efficient chunked file transfers with resume capability.
Main GossipSub implementation class.
Definition gossipsub.h:167
ICE-lite Manager for NAT traversal.
Definition ice.h:321
RatsClient - Core peer-to-peer networking client.
Definition librats.h:208
std::function< void(socket_t, const std::string &, const std::vector< uint8_t > &)> BinaryDataCallback
Definition librats.h:214
std::vector< ReconnectInfo > get_reconnect_queue() const
Get information about peers pending reconnection.
LogLevel get_log_level() const
Get the current log level.
std::vector< MdnsService > get_mdns_services() const
Get recently discovered mDNS services.
void on_ice_gathering_state_changed(IceGatheringStateCallback callback)
Set callback for ICE gathering state changes.
std::vector< RatsPeer > get_all_peers() const
Get all connected peers.
bool reject_directory_transfer(const std::string &transfer_id, const std::string &reason="")
Reject an incoming directory transfer.
void set_encryption_enabled(bool enabled)
Set encryption enabled/disabled.
std::vector< uint8_t > create_torrent_data(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent from a file or directory and return raw torrent data.
bool subscribe_to_topic(const std::string &topic)
Subscribe to a GossipSub topic.
bool save_historical_peers()
Save current peers to a historical file.
void stop_mdns_discovery()
Stop mDNS discovery.
std::optional< StunMappedAddress > discover_public_address(const std::string &server="stun.l.google.com", uint16_t port=19302, int timeout_ms=5000)
Perform a simple STUN binding request to discover public address This is a convenience method that do...
std::function< void(socket_t, const std::string &, const nlohmann::json &)> JsonDataCallback
Definition librats.h:216
std::function< void(bool, const std::string &)> SendCallback
Definition librats.h:219
void set_log_level(const std::string &level_str)
Set the minimum log level using string.
bool cancel_file_transfer(const std::string &transfer_id)
Cancel an active or paused file transfer.
void set_file_transfer_config(const FileTransferConfig &config)
Set file transfer configuration.
bool is_file_transfer_available() const
Check if file transfer is available.
size_t get_spider_pool_size() const
Get the size of the spider node pool.
bool initialize_encryption(bool enable)
Initialize encryption system.
void set_spider_announce_callback(SpiderAnnounceCallback callback)
Set callback for announce_peer requests (spider mode) Called when other peers announce they have a to...
bool is_dht_running() const
Check if DHT is currently running.
void on_file_transfer_progress(FileTransferProgressCallback callback)
Set file transfer progress callback.
std::function< void(socket_t, const std::string &)> DisconnectCallback
Definition librats.h:217
void start_automatic_peer_discovery()
Start automatic peer discovery.
std::string get_log_file_path() const
Get the current log file path.
void set_log_rotation_size(size_t max_size_bytes)
Set log file rotation size.
const StorageConfig & get_storage_config() const
Get current storage configuration.
void set_log_rotate_on_startup(bool enabled)
Enable or disable log rotation on application startup When enabled, the existing log file will be rot...
IceGatheringState get_ice_gathering_state() const
Get ICE gathering state.
void set_string_data_callback(StringDataCallback callback)
Set string data callback (called when string data is received)
int broadcast_binary_to_peers(const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Broadcast binary data to all connected peers (primary method)
const RatsPeer * get_peer_by_socket(socket_t socket) const
Get peer information by socket.
bool set_noise_static_keypair(const uint8_t private_key[32])
Set a custom static keypair for Noise Protocol If not set, a new keypair is generated automatically.
std::vector< std::shared_ptr< TorrentDownload > > get_all_torrents()
Get all active torrents.
size_t storage_size() const
Get the number of entries in storage.
int broadcast_string_to_peers(const std::string &data)
Broadcast string data to all connected peers.
int broadcast_json_to_peers(const nlohmann::json &data)
Broadcast JSON data to all connected peers.
std::function< void(const std::string &info_hash, const std::string &peer_address)> SpiderAnnounceCallback
Spider announce callback type Called when a peer announces they have a torrent (announce_peer request...
Definition librats.h:1882
bool send_binary_to_peer_id(const std::string &peer_id, const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Send binary data to a peer by peer_id (preferred)
std::string request_directory(const std::string &peer_id, const std::string &remote_directory_path, const std::string &local_directory_path, bool recursive=true)
Request a directory from a remote peer.
void on_ice_selected_pair(IceSelectedPairCallback callback)
Set callback for ICE selected pair.
std::optional< std::pair< std::string, uint16_t > > get_public_address() const
Get our public IP address (discovered via STUN)
void clear_spider_state()
Clear spider state (pool and visited nodes) Useful for resetting the spider walk.
void set_spider_mode(bool enable)
Enable spider mode on DHT In spider mode:
std::string get_discovery_hash() const
Get the discovery hash for current protocol configuration.
void set_spider_ignore(bool ignore)
Set spider ignore mode - when true, incoming requests are not processed Useful for rate limiting in s...
bool parse_json_message(const std::string &message, nlohmann::json &out_json)
Parse a JSON message.
bool is_storage_available() const
Check if storage is available.
void add_remote_ice_candidates_from_sdp(const std::vector< std::string > &sdp_lines)
Add remote ICE candidates from SDP attribute lines.
void get_torrent_metadata_from_peer(const InfoHash &info_hash, const std::string &peer_ip, uint16_t peer_port, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata directly from a specific peer (fast path - no DHT search needed) This is more ef...
std::string get_bind_address() const
Get the bind address being used.
bool is_log_timestamps_enabled() const
Check if timestamps are enabled in log output.
void clear_ice_servers()
Clear all ICE (STUN/TURN) servers.
void on_ice_candidates_gathered(IceCandidatesCallback callback)
Set callback for ICE candidates gathered.
std::shared_ptr< TorrentDownload > add_torrent_by_hash(const std::string &info_hash_hex, const std::string &download_path)
Add a torrent by info hash hex string (magnet link style - uses DHT to find peers)
void set_reconnect_enabled(bool enabled)
Enable or disable automatic reconnection to disconnected peers.
bool is_encryption_enabled() const
Check if encryption is enabled.
bool publish_to_topic(const std::string &topic, const std::string &message)
Publish a message to a GossipSub topic.
std::vector< RatsPeer > get_validated_peers() const
Get all peers that have completed handshake.
std::function< void(uint32_t current_piece, uint32_t total_pieces)> TorrentCreationProgressCallback
Torrent creation progress callback type Called during piece hashing to report progress.
Definition librats.h:1809
void add_remote_ice_candidate(const IceCandidate &candidate)
Add a remote ICE candidate (received from peer via signaling)
void close_ice()
Close ICE manager and release resources.
bool send_string_to_peer(socket_t socket, const std::string &data)
Send string data to a specific peer.
std::string get_our_peer_id() const
Get our own peer ID.
void set_ice_config(const IceConfig &config)
Set ICE configuration.
size_t get_active_torrents_count() const
Get the number of active torrents.
bool storage_has(const std::string &key) const
Check if a key exists in storage.
std::optional< std::vector< uint8_t > > storage_get_binary(const std::string &key) const
Get binary data.
bool unsubscribe_from_topic(const std::string &topic)
Unsubscribe from a GossipSub topic.
void off_topic(const std::string &topic)
Remove all event handlers for a GossipSub topic.
void set_log_level(LogLevel level)
Set the minimum log level.
bool save_configuration()
Save configuration to files.
void disable_bittorrent()
Disable BitTorrent functionality.
std::shared_ptr< TorrentDownload > add_torrent(const std::string &torrent_file, const std::string &download_path)
Add a torrent from a file.
void stop_automatic_peer_discovery()
Stop automatic peer discovery.
std::shared_ptr< TorrentDownload > create_and_seed_torrent(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent, add it to the BitTorrent client, and start seeding This combines torrent creation w...
bool storage_delete(const std::string &key)
Delete a key from storage.
bool accept_directory_transfer(const std::string &transfer_id, const std::string &local_path)
Accept an incoming directory transfer.
void on_storage_sync_complete(StorageSyncCompleteCallback callback)
Set storage sync complete callback.
void off(const std::string &message_type)
Remove all handlers for a message type.
bool is_peer_encrypted(const std::string &peer_id) const
Check if a peer connection is encrypted.
void shutdown_all_threads()
Shutdown all background threads.
void disconnect_peer_by_id(const std::string &peer_id)
Disconnect from a peer by peer_id (preferred)
std::vector< std::string > storage_keys_with_prefix(const std::string &prefix) const
Get keys matching a prefix.
void add_turn_server(const std::string &host, uint16_t port, const std::string &username, const std::string &password)
Add a TURN server for relay-based NAT traversal.
void set_topic_message_validator(const std::string &topic, std::function< ValidationResult(const std::string &, const std::string &, const std::string &)> validator)
Set a message validator for a GossipSub topic.
bool storage_put(const std::string &key, const std::string &value)
Store a string value.
StorageManager & get_storage_manager()
Get the storage manager instance.
bool is_console_logging_enabled() const
Check if console logging is currently enabled.
void set_log_file_path(const std::string &file_path)
Set the log file path.
void send(const std::string &message_type, const nlohmann::json &data, SendCallback callback=nullptr)
Send a message to all peers.
bool find_peers_by_hash(const std::string &content_hash, std::function< void(const std::vector< std::string > &)> callback)
Find peers by content hash using DHT.
void on_file_transfer_request(FileTransferRequestCallback callback)
Set incoming file transfer request callback.
bool load_configuration()
Load configuration from files.
std::shared_ptr< FileTransferProgress > get_file_transfer_progress(const std::string &transfer_id) const
Get file transfer progress information.
void clear_log_file()
Clear/reset the current log file.
void set_console_logging_enabled(bool enabled)
Enable or disable console logging When disabled, log messages will not be printed to stdout/stderr Fi...
std::string send_directory(const std::string &peer_id, const std::string &directory_path, const std::string &remote_directory_name="", bool recursive=true)
Send an entire directory to a peer.
bool storage_request_sync()
Request storage sync from connected peers.
std::string request_file(const std::string &peer_id, const std::string &remote_file_path, const std::string &local_path)
Request a file from a remote peer.
bool connect_to_peer(const std::string &host, int port)
Connect to a peer via direct TCP connection.
bool is_ice_connected() const
Check if ICE is connected.
bool publish_json_to_topic(const std::string &topic, const nlohmann::json &message)
Publish a JSON message to a GossipSub topic.
void clear_historical_peers()
Clear all historical peers.
void stop()
Stop the RatsClient and close all connections.
std::pair< uint64_t, uint64_t > get_bittorrent_stats() const
Get BitTorrent statistics (downloaded and uploaded bytes)
std::optional< std::string > storage_get_string(const std::string &key) const
Get a string value.
bool enable_bittorrent(int listen_port=6881)
Enable BitTorrent functionality.
GossipSub & get_gossipsub()
Get GossipSub instance for publish-subscribe messaging.
void on_file_transfer_completed(FileTransferCompletedCallback callback)
Set file transfer completion callback.
void on_topic_message(const std::string &topic, std::function< void(const std::string &, const std::string &, const std::string &)> callback)
Set a message handler for a GossipSub topic using unified event API pattern.
size_t get_spider_visited_count() const
Get the number of visited nodes in spider mode.
bool accept_file_transfer(const std::string &transfer_id, const std::string &local_path)
Accept an incoming file transfer.
bool send_binary_to_peer(socket_t socket, const std::vector< uint8_t > &data, MessageDataType message_type=MessageDataType::BINARY)
Send binary data to a specific peer (primary method)
void get_torrent_metadata(const std::string &info_hash_hex, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata without downloading by hex string (requires DHT to be running)
bool is_spider_mode() const
Check if spider mode is enabled.
std::function< void(socket_t, const std::string &)> ConnectionCallback
Definition librats.h:213
void on(const std::string &message_type, MessageCallback callback)
Register a persistent message handler.
void on_directory_request(DirectoryRequestCallback callback)
Set directory request callback (called when receiving directory requests)
void set_storage_config(const StorageConfig &config)
Set storage configuration.
void add_ignored_address(const std::string &ip_address)
Add an IP address to the ignore list (for blocking connections to self)
void set_connection_callback(ConnectionCallback callback)
Set connection callback (called when a new peer connects)
bool is_peer_limit_reached() const
Check if peer limit has been reached.
void set_log_retention_count(int count)
Set the number of log files to retain during rotation.
std::vector< std::shared_ptr< FileTransferProgress > > get_active_file_transfers() const
Get all active file transfers.
bool query_mdns_services()
Manually query for mDNS services.
const RatsPeer * get_peer_by_id(const std::string &peer_id) const
Get peer information by peer ID.
std::string send_file(const std::string &peer_id, const std::string &file_path, const std::string &remote_filename="")
Send a file to a peer.
std::optional< IceCandidatePair > get_ice_selected_pair() const
Get the selected ICE candidate pair.
void set_mdns_callback(std::function< void(const std::string &, int, const std::string &)> callback)
Set mDNS service discovery callback.
void on_storage_change(StorageChangeCallback callback)
Set storage change callback.
FileTransferManager & get_file_transfer_manager()
Get the file transfer manager instance.
bool start_mdns_discovery(const std::string &service_instance_name="", const std::map< std::string, std::string > &txt_records={})
Start mDNS service discovery and announcement.
bool is_ice_available() const
Check if ICE is available.
bool start_dht_discovery(int dht_port=6881)
Start DHT discovery on specified port.
void set_disconnect_callback(DisconnectCallback callback)
Set disconnect callback (called when a peer disconnects)
std::shared_ptr< TorrentDownload > add_torrent(const TorrentInfo &torrent_info, const std::string &download_path)
Add a torrent from TorrentInfo.
const FileTransferConfig & get_file_transfer_config() const
Get current file transfer configuration.
int load_and_reconnect_peers()
Load saved peers and attempt to reconnect.
void spider_walk()
Trigger a single spider walk iteration Sends find_node to a random node from the spider pool Call thi...
void on_directory_transfer_progress(DirectoryTransferProgressCallback callback)
Set directory transfer progress callback.
nlohmann::json get_storage_statistics() const
Get storage statistics.
IceManager & get_ice_manager()
Get the ICE manager instance.
bool is_reconnect_enabled() const
Check if automatic reconnection is enabled.
void set_protocol_name(const std::string &protocol_name)
Set custom protocol name for handshakes and DHT discovery.
static std::string get_rats_peer_discovery_hash()
Get the well-known RATS peer discovery hash.
void get_torrent_metadata(const InfoHash &info_hash, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata without downloading (requires DHT to be running)
bool is_mdns_running() const
Check if mDNS is currently running.
nlohmann::json get_file_transfer_statistics() const
Get file transfer statistics.
void set_resume_data_path(const std::string &path)
Set the directory for storing resume data files Resume data allows torrents to resume from where they...
bool start()
Start the RatsClient and begin listening for connections.
void on_ice_connection_state_changed(IceConnectionStateCallback callback)
Set callback for ICE connection state changes.
std::vector< uint8_t > get_peer_noise_public_key(const std::string &peer_id) const
Get the remote peer's Noise static public key.
void set_logging_enabled(bool enabled)
Enable or disable file logging When enabled, logs will be written to "rats.log" by default.
bool is_logging_enabled() const
Check if file logging is currently enabled.
std::optional< int64_t > storage_get_int(const std::string &key) const
Get a 64-bit integer value.
void set_binary_data_callback(BinaryDataCallback callback)
Set binary data callback (called when binary data is received)
bool storage_put_json(const std::string &key, const nlohmann::json &value)
Store a JSON document.
bool create_torrent_file(const std::string &path, const std::string &output_file, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent and save it to a file.
void on_topic_peer_joined(const std::string &topic, std::function< void(const std::string &, const std::string &)> callback)
Set a peer joined handler for a GossipSub topic using unified event API pattern.
void stop_dht_discovery()
Stop DHT discovery.
bool remove_torrent(const InfoHash &info_hash)
Remove a torrent by info hash.
int get_peer_count() const
Get the number of currently connected peers.
bool is_automatic_discovery_running() const
Check if automatic discovery is running.
void add_stun_server(const std::string &host, uint16_t port=STUN_DEFAULT_PORT)
Add a STUN server for NAT traversal.
std::vector< std::string > storage_keys() const
Get all keys in storage.
std::optional< nlohmann::json > storage_get_json(const std::string &key) const
Get a JSON document.
bool is_gossipsub_available() const
Check if GossipSub is available.
size_t get_reconnect_queue_size() const
Get the number of peers pending reconnection.
socket_t get_peer_socket_by_id(const std::string &peer_id) const
Get socket for a peer by peer_id (preferred)
nlohmann::json get_gossipsub_statistics() const
Get GossipSub statistics.
std::vector< uint8_t > get_noise_static_public_key() const
Get our Noise Protocol static public key.
void set_reconnect_config(const ReconnectConfig &config)
Set reconnection configuration.
bool load_historical_peers()
Load historical peers from a file.
RatsClient(int listen_port, int max_peers=10, const std::string &bind_address="")
Constructor.
bool pause_file_transfer(const std::string &transfer_id)
Pause an active file transfer.
int get_max_peers() const
Get maximum number of peers.
bool send_string_to_peer_id(const std::string &peer_id, const std::string &data)
Send string data to a peer by peer_id (preferred)
void set_json_data_callback(JsonDataCallback callback)
Set JSON data callback (called when JSON data is received)
std::chrono::seconds calculate_discovery_interval() const
Calculate discovery interval based on current peer count Uses graduated scaling: more aggressive when...
bool storage_put(const std::string &key, double value)
Store a double-precision floating point value.
int get_listen_port() const
bool send_json_to_peer_id(const std::string &peer_id, const nlohmann::json &data)
Send JSON data to a peer by peer_id (preferred)
std::function< void(socket_t, const std::string &, const std::string &)> StringDataCallback
Definition librats.h:215
void end_of_remote_ice_candidates()
Signal end of remote candidates (trickle ICE complete)
std::vector< std::string > get_topic_mesh_peers(const std::string &topic) const
Get mesh peers for a GossipSub topic.
void disconnect_peer(socket_t socket)
Disconnect from a specific peer.
bool is_gossipsub_running() const
Check if GossipSub is running.
bool is_bittorrent_enabled() const
Check if BitTorrent is enabled.
const ReconnectConfig & get_reconnect_config() const
Get current reconnection configuration.
bool is_subscribed_to_topic(const std::string &topic) const
Check if subscribed to a GossipSub topic.
void restart_ice()
Restart ICE (re-gather candidates and restart checks)
std::shared_ptr< TorrentDownload > add_torrent_by_hash(const InfoHash &info_hash, const std::string &download_path)
Add a torrent by info hash (magnet link style - uses DHT to find peers)
bool is_spider_ignoring() const
Check if spider ignore mode is enabled.
bool is_log_rotate_on_startup_enabled() const
Check if log rotation on startup is enabled.
bool reject_file_transfer(const std::string &transfer_id, const std::string &reason="")
Reject an incoming file transfer.
void set_max_peers(int max_peers)
Set maximum number of peers.
IceConnectionState get_ice_connection_state() const
Get current ICE connection state.
std::string get_protocol_version() const
Get current protocol version.
bool announce_for_hash(const std::string &content_hash, uint16_t port=0, std::function< void(const std::vector< std::string > &)> callback=nullptr)
Announce our presence for a content hash with optional peer discovery callback If callback is provide...
std::optional< double > storage_get_double(const std::string &key) const
Get a double-precision floating point value.
std::shared_ptr< TorrentDownload > get_torrent(const InfoHash &info_hash)
Get a torrent by info hash.
void set_protocol_version(const std::string &protocol_version)
Set custom protocol version for handshakes.
bool storage_put(const std::string &key, int64_t value)
Store a 64-bit integer value.
std::string get_protocol_name() const
Get current protocol name.
std::vector< std::string > get_topic_peers(const std::string &topic) const
Get peers subscribed to a GossipSub topic.
void start_ice_checks()
Start ICE connectivity checks.
void on_ice_new_candidate(IceNewCandidateCallback callback)
Set callback for new ICE candidate (trickle ICE)
size_t get_dht_routing_table_size() const
Get the size of the DHT routing table.
std::vector< IceCandidate > get_ice_candidates() const
Get our local ICE candidates Call after gathering is complete.
std::string get_peer_id(socket_t socket) const
Get peer_id for a peer by socket (preferred)
void get_torrent_metadata_from_peer(const std::string &info_hash_hex, const std::string &peer_ip, uint16_t peer_port, std::function< void(const TorrentInfo &, bool, const std::string &)> callback)
Get torrent metadata directly from a specific peer by hex string (fast path)
bool is_running() const
Check if the client is currently running.
const IceConfig & get_ice_config() const
Get current ICE configuration.
bool resume_file_transfer(const std::string &transfer_id)
Resume a paused file transfer.
void clear_reconnect_queue()
Clear all pending reconnection attempts.
void set_log_timestamps_enabled(bool enabled)
Enable or disable timestamps in log output.
std::vector< std::string > get_subscribed_topics() const
Get list of subscribed GossipSub topics.
bool gather_ice_candidates()
Start gathering ICE candidates This discovers our public address and generates connection candidates.
bool send_json_to_peer(socket_t socket, const nlohmann::json &data)
Send JSON data to a specific peer.
std::vector< RatsPeer > get_historical_peers() const
Get all historical peers.
void on_topic_peer_left(const std::string &topic, std::function< void(const std::string &, const std::string &)> callback)
Set a peer left handler for a GossipSub topic using unified event API pattern
~RatsClient()
Destructor.
std::optional< TorrentInfo > create_torrent_from_path(const std::string &path, const std::vector< std::string > &trackers={}, const std::string &comment="", TorrentCreationProgressCallback progress_callback=nullptr)
Create a torrent from a file or directory and return TorrentInfo This is a synchronous operation that...
void send(const std::string &peer_id, const std::string &message_type, const nlohmann::json &data, SendCallback callback=nullptr)
Send a message to a specific peer.
void set_log_colors_enabled(bool enabled)
Enable or disable colored log output.
std::vector< uint8_t > get_peer_handshake_hash(const std::string &peer_id) const
Get the handshake hash for a peer connection (for channel binding)
bool is_ice_gathering_complete() const
Check if ICE candidate gathering is complete.
void on_file_request(FileRequestCallback callback)
Set file request callback (called when receiving file requests)
bool set_data_directory(const std::string &directory_path)
Set directory where data files will be stored.
void once(const std::string &message_type, MessageCallback callback)
Register a one-time message handler.
bool is_storage_synced() const
Check if storage is synchronized.
nlohmann::json get_connection_statistics() const
Get connection statistics.
std::string get_data_directory() const
Get current data directory path.
bool is_log_colors_enabled() const
Check if colored log output is enabled.
void on_topic_json_message(const std::string &topic, std::function< void(const std::string &, const std::string &, const nlohmann::json &)> callback)
Set a JSON message handler for a GossipSub topic using unified event API pattern.
std::function< void(const std::string &, const nlohmann::json &)> MessageCallback
Definition librats.h:218
bool storage_put(const std::string &key, const std::vector< uint8_t > &value)
Store binary data.
ThreadManager - Manages background threads with graceful shutdown.
ICE-lite (Interactive Connectivity Establishment) Implementation.
LogLevel
Definition logger.h:28
IceGatheringState
ICE gathering state.
Definition ice.h:87
std::function< void(IceGatheringState)> IceGatheringStateCallback
Callback when gathering state changes.
Definition ice.h:263
std::function< void(const std::string &topic, const std::string &message, const std::string &sender_peer_id)> MessageHandler
Definition gossipsub.h:160
MessageDataType
Message data types for librats message headers.
Definition librats.h:134
uint32_t rats_get_library_abi()
std::function< void(const std::string &transfer_id, bool success, const std::string &error_message)> FileTransferCompletedCallback
const char * rats_get_library_version_string()
std::function< void(const IceCandidate &)> IceNewCandidateCallback
Callback when a new candidate is discovered (trickle ICE)
Definition ice.h:269
std::function< void(const std::vector< IceCandidate > &)> IceCandidatesCallback
Callback when candidates are gathered.
Definition ice.h:260
std::function< bool(const std::string &peer_id, const std::string &file_path, const std::string &transfer_id)> FileRequestCallback
std::function< bool(const std::string &peer_id, const std::string &directory_path, bool recursive, const std::string &transfer_id)> DirectoryRequestCallback
std::function< void(IceConnectionState)> IceConnectionStateCallback
Callback when connection state changes.
Definition ice.h:266
std::function< void(const FileTransferProgress &)> FileTransferProgressCallback
Callback function types for file transfer events.
std::function< void(const IceCandidatePair &)> IceSelectedPairCallback
Callback when ICE completes with selected pair.
Definition ice.h:272
ValidationResult
Message validation result.
Definition gossipsub.h:150
std::unique_ptr< RatsClient > create_rats_client(int listen_port)
std::array< uint8_t, NODE_ID_SIZE > InfoHash
Definition dht.h:50
void rats_get_library_version(int *major, int *minor, int *patch, int *build)
std::function< void(const std::string &transfer_id, const std::string &current_file, uint64_t files_completed, uint64_t total_files, uint64_t bytes_completed, uint64_t total_bytes)> DirectoryTransferProgressCallback
const char * rats_get_library_git_describe()
IceConnectionState
ICE connection state.
Definition ice.h:73
std::function< bool(const std::string &peer_id, const FileMetadata &metadata, const std::string &transfer_id)> FileTransferRequestCallback
int socket_t
Definition socket.h:22
File transfer configuration.
ICE candidate.
Definition ice.h:96
ICE configuration.
Definition ice.h:226
Message header structure for librats messages Fixed 8-byte header format: [0-3]: Magic number "RATS" ...
Definition librats.h:147
MessageDataType type
Definition librats.h:152
bool is_valid_type() const
Definition librats.h:198
static bool deserialize(const std::vector< uint8_t > &data, MessageHeader &header)
Definition librats.h:176
MessageHeader(MessageDataType data_type)
Definition librats.h:155
static constexpr uint32_t MAGIC_NUMBER
Definition librats.h:148
static constexpr size_t HEADER_SIZE
Definition librats.h:149
uint8_t reserved[3]
Definition librats.h:153
std::vector< uint8_t > serialize() const
Definition librats.h:164
RatsPeer struct - comprehensive information about a connected rats peer.
Definition librats.h:39
std::string ip
Definition librats.h:41
socket_t socket
Definition librats.h:43
bool encryption_enabled
Definition librats.h:62
std::shared_ptr< rats::NoiseCipherState > recv_cipher
Definition librats.h:65
std::vector< uint8_t > remote_static_key
Definition librats.h:66
bool is_noise_encrypted() const
Definition librats.h:87
std::shared_ptr< rats::NoiseCipherState > send_cipher
Definition librats.h:64
bool is_handshake_completed() const
Definition librats.h:92
bool noise_handshake_completed
Definition librats.h:63
std::string peer_id
Definition librats.h:40
HandshakeState handshake_state
Definition librats.h:57
RatsPeer(const std::string &id, const std::string &peer_ip, uint16_t peer_port, socket_t sock, const std::string &norm_addr, bool outgoing)
Definition librats.h:75
bool is_handshake_failed() const
Definition librats.h:93
std::chrono::steady_clock::time_point handshake_start_time
Definition librats.h:59
std::string normalized_address
Definition librats.h:44
uint16_t port
Definition librats.h:42
std::string version
Definition librats.h:58
std::chrono::steady_clock::time_point connected_at
Definition librats.h:45
ReconnectConfig - Configuration for automatic peer reconnection.
Definition librats.h:99
std::vector< int > retry_intervals_seconds
Definition librats.h:101
int stable_connection_threshold_seconds
Definition librats.h:102
ReconnectInfo - Information about a peer pending reconnection.
Definition librats.h:110
ReconnectInfo(const std::string &id, const std::string &peer_ip, uint16_t peer_port, std::chrono::milliseconds duration, bool stable)
Definition librats.h:123
std::chrono::milliseconds connection_duration
Definition librats.h:116
std::string peer_id
Definition librats.h:111
std::chrono::steady_clock::time_point next_attempt_time
Definition librats.h:115