librats 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +1 -1
  2. package/binding.gyp +1 -0
  3. package/lib/index.d.ts +2 -1
  4. package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
  5. package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
  6. package/native-src/CMakeLists.txt +360 -0
  7. package/native-src/LICENSE +21 -0
  8. package/native-src/src/bencode.cpp +485 -0
  9. package/native-src/src/bencode.h +145 -0
  10. package/native-src/src/bittorrent.cpp +3682 -0
  11. package/native-src/src/bittorrent.h +731 -0
  12. package/native-src/src/dht.cpp +2460 -0
  13. package/native-src/src/dht.h +508 -0
  14. package/native-src/src/encrypted_socket.cpp +817 -0
  15. package/native-src/src/encrypted_socket.h +239 -0
  16. package/native-src/src/file_transfer.cpp +1808 -0
  17. package/native-src/src/file_transfer.h +567 -0
  18. package/native-src/src/fs.cpp +639 -0
  19. package/native-src/src/fs.h +108 -0
  20. package/native-src/src/gossipsub.cpp +1137 -0
  21. package/native-src/src/gossipsub.h +403 -0
  22. package/native-src/src/ice.cpp +1386 -0
  23. package/native-src/src/ice.h +328 -0
  24. package/native-src/src/json.hpp +25526 -0
  25. package/native-src/src/krpc.cpp +558 -0
  26. package/native-src/src/krpc.h +145 -0
  27. package/native-src/src/librats.cpp +2735 -0
  28. package/native-src/src/librats.h +1732 -0
  29. package/native-src/src/librats_bittorrent.cpp +167 -0
  30. package/native-src/src/librats_c.cpp +1333 -0
  31. package/native-src/src/librats_c.h +239 -0
  32. package/native-src/src/librats_encryption.cpp +123 -0
  33. package/native-src/src/librats_file_transfer.cpp +226 -0
  34. package/native-src/src/librats_gossipsub.cpp +293 -0
  35. package/native-src/src/librats_ice.cpp +515 -0
  36. package/native-src/src/librats_logging.cpp +158 -0
  37. package/native-src/src/librats_mdns.cpp +171 -0
  38. package/native-src/src/librats_nat.cpp +571 -0
  39. package/native-src/src/librats_persistence.cpp +815 -0
  40. package/native-src/src/logger.h +412 -0
  41. package/native-src/src/mdns.cpp +1178 -0
  42. package/native-src/src/mdns.h +253 -0
  43. package/native-src/src/network_utils.cpp +598 -0
  44. package/native-src/src/network_utils.h +162 -0
  45. package/native-src/src/noise.cpp +981 -0
  46. package/native-src/src/noise.h +227 -0
  47. package/native-src/src/os.cpp +371 -0
  48. package/native-src/src/os.h +40 -0
  49. package/native-src/src/rats_export.h +17 -0
  50. package/native-src/src/sha1.cpp +163 -0
  51. package/native-src/src/sha1.h +42 -0
  52. package/native-src/src/socket.cpp +1376 -0
  53. package/native-src/src/socket.h +309 -0
  54. package/native-src/src/stun.cpp +484 -0
  55. package/native-src/src/stun.h +349 -0
  56. package/native-src/src/threadmanager.cpp +105 -0
  57. package/native-src/src/threadmanager.h +53 -0
  58. package/native-src/src/tracker.cpp +1110 -0
  59. package/native-src/src/tracker.h +268 -0
  60. package/native-src/src/version.cpp +24 -0
  61. package/native-src/src/version.h.in +45 -0
  62. package/native-src/version.rc.in +31 -0
  63. package/package.json +2 -8
  64. package/scripts/build-librats.js +59 -12
  65. package/scripts/prepare-package.js +133 -37
  66. package/src/librats_node.cpp +46 -1
@@ -0,0 +1,293 @@
1
+ #include "librats.h"
2
+ // Logging macros for RatsClient
3
+ #define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
4
+ #define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
5
+ #define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
6
+ #define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
7
+
8
+ namespace librats {
9
+
10
+ //=============================================================================
11
+ // GossipSub Integration Methods
12
+ //=============================================================================
13
+
14
+ GossipSub& RatsClient::get_gossipsub() {
15
+ if (!gossipsub_) {
16
+ throw std::runtime_error("GossipSub not initialized");
17
+ }
18
+ return *gossipsub_;
19
+ }
20
+
21
+ bool RatsClient::is_gossipsub_available() const {
22
+ return gossipsub_ != nullptr;
23
+ }
24
+
25
+ //=============================================================================
26
+ // GossipSub Convenience Methods - Topic Management
27
+ //=============================================================================
28
+
29
+ bool RatsClient::subscribe_to_topic(const std::string& topic) {
30
+ if (!is_gossipsub_available()) {
31
+ LOG_CLIENT_ERROR("GossipSub not available for topic subscription: " << topic);
32
+ return false;
33
+ }
34
+
35
+ try {
36
+ return gossipsub_->subscribe(topic);
37
+ } catch (const std::exception& e) {
38
+ LOG_CLIENT_ERROR("Failed to subscribe to topic '" << topic << "': " << e.what());
39
+ return false;
40
+ }
41
+ }
42
+
43
+ bool RatsClient::unsubscribe_from_topic(const std::string& topic) {
44
+ if (!is_gossipsub_available()) {
45
+ LOG_CLIENT_ERROR("GossipSub not available for topic unsubscription: " << topic);
46
+ return false;
47
+ }
48
+
49
+ try {
50
+ return gossipsub_->unsubscribe(topic);
51
+ } catch (const std::exception& e) {
52
+ LOG_CLIENT_ERROR("Failed to unsubscribe from topic '" << topic << "': " << e.what());
53
+ return false;
54
+ }
55
+ }
56
+
57
+ bool RatsClient::is_subscribed_to_topic(const std::string& topic) const {
58
+ if (!is_gossipsub_available()) {
59
+ return false;
60
+ }
61
+
62
+ try {
63
+ return gossipsub_->is_subscribed(topic);
64
+ } catch (const std::exception& e) {
65
+ LOG_CLIENT_ERROR("Failed to check subscription for topic '" << topic << "': " << e.what());
66
+ return false;
67
+ }
68
+ }
69
+
70
+ std::vector<std::string> RatsClient::get_subscribed_topics() const {
71
+ if (!is_gossipsub_available()) {
72
+ return {};
73
+ }
74
+
75
+ try {
76
+ return gossipsub_->get_subscribed_topics();
77
+ } catch (const std::exception& e) {
78
+ LOG_CLIENT_ERROR("Failed to get subscribed topics: " << e.what());
79
+ return {};
80
+ }
81
+ }
82
+
83
+ //=============================================================================
84
+ // GossipSub Convenience Methods - Publishing
85
+ //=============================================================================
86
+
87
+ bool RatsClient::publish_to_topic(const std::string& topic, const std::string& message) {
88
+ if (!is_gossipsub_available()) {
89
+ LOG_CLIENT_ERROR("GossipSub not available for publishing to topic: " << topic);
90
+ return false;
91
+ }
92
+
93
+ try {
94
+ return gossipsub_->publish(topic, message);
95
+ } catch (const std::exception& e) {
96
+ LOG_CLIENT_ERROR("Failed to publish to topic '" << topic << "': " << e.what());
97
+ return false;
98
+ }
99
+ }
100
+
101
+ bool RatsClient::publish_json_to_topic(const std::string& topic, const nlohmann::json& message) {
102
+ if (!is_gossipsub_available()) {
103
+ LOG_CLIENT_ERROR("GossipSub not available for publishing JSON to topic: " << topic);
104
+ return false;
105
+ }
106
+
107
+ try {
108
+ return gossipsub_->publish(topic, message);
109
+ } catch (const std::exception& e) {
110
+ LOG_CLIENT_ERROR("Failed to publish JSON to topic '" << topic << "': " << e.what());
111
+ return false;
112
+ }
113
+ }
114
+
115
+ //=============================================================================
116
+ // GossipSub Convenience Methods - Event Handlers (Unified API)
117
+ //=============================================================================
118
+
119
+ void RatsClient::on_topic_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const std::string&)> callback) {
120
+ if (!is_gossipsub_available()) {
121
+ LOG_CLIENT_ERROR("GossipSub not available for setting message handler on topic: " << topic);
122
+ return;
123
+ }
124
+
125
+ try {
126
+ // Convert unified callback signature to GossipSub's MessageHandler signature
127
+ gossipsub_->set_message_handler(topic, [callback](const std::string& topic, const std::string& message, const std::string& sender_peer_id) {
128
+ callback(sender_peer_id, topic, message);
129
+ });
130
+ LOG_CLIENT_INFO("Set message handler for topic: " << topic);
131
+ } catch (const std::exception& e) {
132
+ LOG_CLIENT_ERROR("Failed to set message handler for topic '" << topic << "': " << e.what());
133
+ }
134
+ }
135
+
136
+ void RatsClient::on_topic_json_message(const std::string& topic, std::function<void(const std::string&, const std::string&, const nlohmann::json&)> callback) {
137
+ if (!is_gossipsub_available()) {
138
+ LOG_CLIENT_ERROR("GossipSub not available for setting JSON message handler on topic: " << topic);
139
+ return;
140
+ }
141
+
142
+ try {
143
+ // Convert unified callback signature to GossipSub's MessageHandler signature with JSON parsing
144
+ gossipsub_->set_message_handler(topic, [callback](const std::string& topic, const std::string& message, const std::string& sender_peer_id) {
145
+ try {
146
+ nlohmann::json json_message = nlohmann::json::parse(message);
147
+ callback(sender_peer_id, topic, json_message);
148
+ } catch (const nlohmann::json::exception& e) {
149
+ LOG_WARN("client", "Failed to parse JSON message on topic '" << topic << "': " << e.what());
150
+ // Still call callback with empty JSON object to maintain consistency
151
+ callback(sender_peer_id, topic, nlohmann::json{});
152
+ }
153
+ });
154
+ LOG_CLIENT_INFO("Set JSON message handler for topic: " << topic);
155
+ } catch (const std::exception& e) {
156
+ LOG_CLIENT_ERROR("Failed to set JSON message handler for topic '" << topic << "': " << e.what());
157
+ }
158
+ }
159
+
160
+ void RatsClient::on_topic_peer_joined(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback) {
161
+ if (!is_gossipsub_available()) {
162
+ LOG_CLIENT_ERROR("GossipSub not available for setting peer joined handler on topic: " << topic);
163
+ return;
164
+ }
165
+
166
+ try {
167
+ // Convert unified callback signature to GossipSub's PeerJoinedHandler signature
168
+ gossipsub_->set_peer_joined_handler(topic, [callback](const std::string& topic, const std::string& peer_id) {
169
+ callback(peer_id, topic);
170
+ });
171
+ LOG_CLIENT_INFO("Set peer joined handler for topic: " << topic);
172
+ } catch (const std::exception& e) {
173
+ LOG_CLIENT_ERROR("Failed to set peer joined handler for topic '" << topic << "': " << e.what());
174
+ }
175
+ }
176
+
177
+ void RatsClient::on_topic_peer_left(const std::string& topic, std::function<void(const std::string&, const std::string&)> callback) {
178
+ if (!is_gossipsub_available()) {
179
+ LOG_CLIENT_ERROR("GossipSub not available for setting peer left handler on topic: " << topic);
180
+ return;
181
+ }
182
+
183
+ try {
184
+ // Convert unified callback signature to GossipSub's PeerLeftHandler signature
185
+ gossipsub_->set_peer_left_handler(topic, [callback](const std::string& topic, const std::string& peer_id) {
186
+ callback(peer_id, topic);
187
+ });
188
+ LOG_CLIENT_INFO("Set peer left handler for topic: " << topic);
189
+ } catch (const std::exception& e) {
190
+ LOG_CLIENT_ERROR("Failed to set peer left handler for topic '" << topic << "': " << e.what());
191
+ }
192
+ }
193
+
194
+ void RatsClient::set_topic_message_validator(const std::string& topic, std::function<ValidationResult(const std::string&, const std::string&, const std::string&)> validator) {
195
+ if (!is_gossipsub_available()) {
196
+ LOG_CLIENT_ERROR("GossipSub not available for setting message validator on topic: " << topic);
197
+ return;
198
+ }
199
+
200
+ try {
201
+ // Convert unified callback signature to GossipSub's MessageValidator signature
202
+ gossipsub_->set_message_validator(topic, [validator](const std::string& topic, const std::string& message, const std::string& sender_peer_id) {
203
+ return validator(topic, message, sender_peer_id);
204
+ });
205
+ LOG_CLIENT_INFO("Set message validator for topic: " << topic);
206
+ } catch (const std::exception& e) {
207
+ LOG_CLIENT_ERROR("Failed to set message validator for topic '" << topic << "': " << e.what());
208
+ }
209
+ }
210
+
211
+ void RatsClient::off_topic(const std::string& topic) {
212
+ if (!is_gossipsub_available()) {
213
+ LOG_CLIENT_ERROR("GossipSub not available for removing handlers from topic: " << topic);
214
+ return;
215
+ }
216
+
217
+ try {
218
+ // Remove all handlers by setting them to nullptr
219
+ gossipsub_->set_message_handler(topic, nullptr);
220
+ gossipsub_->set_peer_joined_handler(topic, nullptr);
221
+ gossipsub_->set_peer_left_handler(topic, nullptr);
222
+ gossipsub_->set_message_validator(topic, nullptr);
223
+ LOG_CLIENT_INFO("Removed all handlers for topic: " << topic);
224
+ } catch (const std::exception& e) {
225
+ LOG_CLIENT_ERROR("Failed to remove handlers for topic '" << topic << "': " << e.what());
226
+ }
227
+ }
228
+
229
+ //=============================================================================
230
+ // GossipSub Convenience Methods - Information
231
+ //=============================================================================
232
+
233
+ std::vector<std::string> RatsClient::get_topic_peers(const std::string& topic) const {
234
+ if (!is_gossipsub_available()) {
235
+ return {};
236
+ }
237
+
238
+ try {
239
+ return gossipsub_->get_topic_peers(topic);
240
+ } catch (const std::exception& e) {
241
+ LOG_CLIENT_ERROR("Failed to get topic peers for '" << topic << "': " << e.what());
242
+ return {};
243
+ }
244
+ }
245
+
246
+ std::vector<std::string> RatsClient::get_topic_mesh_peers(const std::string& topic) const {
247
+ if (!is_gossipsub_available()) {
248
+ return {};
249
+ }
250
+
251
+ try {
252
+ return gossipsub_->get_mesh_peers(topic);
253
+ } catch (const std::exception& e) {
254
+ LOG_CLIENT_ERROR("Failed to get mesh peers for topic '" << topic << "': " << e.what());
255
+ return {};
256
+ }
257
+ }
258
+
259
+ nlohmann::json RatsClient::get_gossipsub_statistics() const {
260
+ if (!is_gossipsub_available()) {
261
+ nlohmann::json empty_stats;
262
+ empty_stats["available"] = false;
263
+ empty_stats["error"] = "GossipSub not initialized";
264
+ return empty_stats;
265
+ }
266
+
267
+ try {
268
+ nlohmann::json stats = gossipsub_->get_statistics();
269
+ stats["available"] = true;
270
+ stats["running"] = gossipsub_->is_running();
271
+ return stats;
272
+ } catch (const std::exception& e) {
273
+ nlohmann::json error_stats;
274
+ error_stats["available"] = true;
275
+ error_stats["error"] = e.what();
276
+ return error_stats;
277
+ }
278
+ }
279
+
280
+ bool RatsClient::is_gossipsub_running() const {
281
+ if (!is_gossipsub_available()) {
282
+ return false;
283
+ }
284
+
285
+ try {
286
+ return gossipsub_->is_running();
287
+ } catch (const std::exception& e) {
288
+ LOG_CLIENT_ERROR("Failed to check GossipSub running status: " << e.what());
289
+ return false;
290
+ }
291
+ }
292
+
293
+ }