librats 0.5.0 → 0.5.1

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 (63) hide show
  1. package/binding.gyp +1 -0
  2. package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
  3. package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
  4. package/native-src/CMakeLists.txt +360 -0
  5. package/native-src/LICENSE +21 -0
  6. package/native-src/src/bencode.cpp +485 -0
  7. package/native-src/src/bencode.h +145 -0
  8. package/native-src/src/bittorrent.cpp +3682 -0
  9. package/native-src/src/bittorrent.h +731 -0
  10. package/native-src/src/dht.cpp +2342 -0
  11. package/native-src/src/dht.h +501 -0
  12. package/native-src/src/encrypted_socket.cpp +817 -0
  13. package/native-src/src/encrypted_socket.h +239 -0
  14. package/native-src/src/file_transfer.cpp +1808 -0
  15. package/native-src/src/file_transfer.h +567 -0
  16. package/native-src/src/fs.cpp +639 -0
  17. package/native-src/src/fs.h +108 -0
  18. package/native-src/src/gossipsub.cpp +1137 -0
  19. package/native-src/src/gossipsub.h +403 -0
  20. package/native-src/src/ice.cpp +1386 -0
  21. package/native-src/src/ice.h +328 -0
  22. package/native-src/src/json.hpp +25526 -0
  23. package/native-src/src/krpc.cpp +558 -0
  24. package/native-src/src/krpc.h +145 -0
  25. package/native-src/src/librats.cpp +2715 -0
  26. package/native-src/src/librats.h +1729 -0
  27. package/native-src/src/librats_bittorrent.cpp +167 -0
  28. package/native-src/src/librats_c.cpp +1317 -0
  29. package/native-src/src/librats_c.h +237 -0
  30. package/native-src/src/librats_encryption.cpp +123 -0
  31. package/native-src/src/librats_file_transfer.cpp +226 -0
  32. package/native-src/src/librats_gossipsub.cpp +293 -0
  33. package/native-src/src/librats_ice.cpp +515 -0
  34. package/native-src/src/librats_logging.cpp +158 -0
  35. package/native-src/src/librats_mdns.cpp +171 -0
  36. package/native-src/src/librats_nat.cpp +571 -0
  37. package/native-src/src/librats_persistence.cpp +815 -0
  38. package/native-src/src/logger.h +412 -0
  39. package/native-src/src/mdns.cpp +1178 -0
  40. package/native-src/src/mdns.h +253 -0
  41. package/native-src/src/network_utils.cpp +598 -0
  42. package/native-src/src/network_utils.h +162 -0
  43. package/native-src/src/noise.cpp +981 -0
  44. package/native-src/src/noise.h +227 -0
  45. package/native-src/src/os.cpp +371 -0
  46. package/native-src/src/os.h +40 -0
  47. package/native-src/src/rats_export.h +17 -0
  48. package/native-src/src/sha1.cpp +163 -0
  49. package/native-src/src/sha1.h +42 -0
  50. package/native-src/src/socket.cpp +1376 -0
  51. package/native-src/src/socket.h +309 -0
  52. package/native-src/src/stun.cpp +484 -0
  53. package/native-src/src/stun.h +349 -0
  54. package/native-src/src/threadmanager.cpp +105 -0
  55. package/native-src/src/threadmanager.h +53 -0
  56. package/native-src/src/tracker.cpp +1110 -0
  57. package/native-src/src/tracker.h +268 -0
  58. package/native-src/src/version.cpp +24 -0
  59. package/native-src/src/version.h.in +45 -0
  60. package/native-src/version.rc.in +31 -0
  61. package/package.json +2 -8
  62. package/scripts/build-librats.js +59 -12
  63. package/scripts/prepare-package.js +133 -37
@@ -0,0 +1,328 @@
1
+ #ifndef LIBRATS_ICE_H
2
+ #define LIBRATS_ICE_H
3
+
4
+ #include "socket.h"
5
+ #include "stun.h"
6
+ #include "json.hpp"
7
+ #include <string>
8
+ #include <vector>
9
+ #include <memory>
10
+ #include <functional>
11
+ #include <chrono>
12
+ #include <atomic>
13
+ #include <thread>
14
+ #include <mutex>
15
+ #include <unordered_map>
16
+ #include <condition_variable>
17
+
18
+ namespace librats {
19
+
20
+ // ICE Candidate Types
21
+ enum class IceCandidateType {
22
+ HOST, // Local interface address
23
+ SERVER_REFLEXIVE, // Public address discovered via STUN
24
+ PEER_REFLEXIVE, // Address discovered during connectivity checks
25
+ RELAY // Address allocated on TURN server
26
+ };
27
+
28
+ // ICE Candidate Transport Protocol
29
+ enum class IceTransport {
30
+ UDP,
31
+ TCP
32
+ };
33
+
34
+ // ICE Candidate Structure
35
+ struct IceCandidate {
36
+ std::string foundation; // Foundation for grouping candidates
37
+ uint32_t component_id; // Component identifier (1 for RTP, 2 for RTCP, etc.)
38
+ IceTransport transport; // Transport protocol
39
+ uint32_t priority; // Candidate priority
40
+ std::string ip; // IP address
41
+ uint16_t port; // Port number
42
+ IceCandidateType type; // Candidate type
43
+ std::string related_ip; // Related address (for reflexive/relay candidates)
44
+ uint16_t related_port; // Related port
45
+ std::string ufrag; // Username fragment
46
+ std::string pwd; // Password
47
+
48
+ // Optional TURN server info (for relay candidates)
49
+ std::string turn_server;
50
+ uint16_t turn_port;
51
+
52
+ IceCandidate();
53
+ std::string to_sdp() const;
54
+ static IceCandidate from_sdp(const std::string& sdp_line);
55
+ nlohmann::json to_json() const;
56
+ static IceCandidate from_json(const nlohmann::json& json);
57
+ };
58
+
59
+ // ICE Candidate Pair for connectivity checks
60
+ struct IceCandidatePair {
61
+ IceCandidate local;
62
+ IceCandidate remote;
63
+ uint64_t priority;
64
+ bool nominated;
65
+ std::chrono::steady_clock::time_point last_check_time;
66
+ int check_count;
67
+ bool succeeded;
68
+
69
+ IceCandidatePair(const IceCandidate& local, const IceCandidate& remote);
70
+ uint64_t calculate_priority() const;
71
+ };
72
+
73
+ // ICE Connection State
74
+ enum class IceConnectionState {
75
+ NEW,
76
+ GATHERING,
77
+ CHECKING,
78
+ CONNECTED,
79
+ COMPLETED,
80
+ FAILED,
81
+ DISCONNECTED,
82
+ CLOSED
83
+ };
84
+
85
+ // ICE Role
86
+ enum class IceRole {
87
+ CONTROLLING,
88
+ CONTROLLED
89
+ };
90
+
91
+ // NAT Type Detection Results
92
+ enum class NatType {
93
+ UNKNOWN,
94
+ OPEN_INTERNET, // No NAT
95
+ FULL_CONE, // Full cone NAT
96
+ RESTRICTED_CONE, // Restricted cone NAT
97
+ PORT_RESTRICTED, // Port restricted cone NAT
98
+ SYMMETRIC, // Symmetric NAT
99
+ BLOCKED // UDP blocked
100
+ };
101
+
102
+ // ICE Configuration
103
+ struct IceConfig {
104
+ std::vector<std::string> stun_servers;
105
+ std::vector<std::string> turn_servers;
106
+ std::vector<std::string> turn_usernames;
107
+ std::vector<std::string> turn_passwords;
108
+ bool enable_host_candidates;
109
+ bool enable_server_reflexive_candidates;
110
+ bool enable_relay_candidates;
111
+ bool enable_tcp_candidates;
112
+ int stun_timeout_ms;
113
+ int turn_timeout_ms;
114
+ int connectivity_check_timeout_ms;
115
+ int max_connectivity_checks;
116
+
117
+ IceConfig();
118
+ };
119
+
120
+ // ICE Events
121
+ class IceAgent;
122
+ using IceCandidateCallback = std::function<void(const IceCandidate&)>;
123
+ using IceStateChangeCallback = std::function<void(IceConnectionState)>;
124
+ using IceConnectedCallback = std::function<void(const std::string& local_addr, const std::string& remote_addr)>;
125
+ using IceDataCallback = std::function<void(const std::vector<uint8_t>&, const std::string& from_addr)>;
126
+
127
+ // TURN Client for relay candidates
128
+ class TurnClient {
129
+ public:
130
+ TurnClient(const std::string& server, uint16_t port,
131
+ const std::string& username, const std::string& password);
132
+ ~TurnClient();
133
+
134
+ bool allocate_relay(std::string& allocated_ip, uint16_t& allocated_port);
135
+ bool create_permission(const std::string& peer_ip);
136
+ bool send_data(const std::vector<uint8_t>& data, const std::string& peer_ip, uint16_t peer_port);
137
+ std::vector<uint8_t> receive_data(std::string& from_ip, uint16_t& from_port, int timeout_ms = 1000);
138
+ void refresh_allocation();
139
+ void deallocate();
140
+
141
+ bool is_allocated() const { return allocated_; }
142
+ std::string get_allocated_ip() const { return allocated_ip_; }
143
+ uint16_t get_allocated_port() const { return allocated_port_; }
144
+
145
+ private:
146
+ std::string server_;
147
+ uint16_t port_;
148
+ std::string username_;
149
+ std::string password_;
150
+ socket_t socket_;
151
+ bool allocated_;
152
+ std::string allocated_ip_;
153
+ uint16_t allocated_port_;
154
+ std::string realm_;
155
+ std::string nonce_;
156
+ std::chrono::steady_clock::time_point last_refresh_;
157
+
158
+ bool send_allocate_request();
159
+ bool send_refresh_request();
160
+ bool handle_allocate_response(const std::vector<uint8_t>& response);
161
+ bool authenticate_with_server();
162
+ };
163
+
164
+ // NAT Type Detector
165
+ class NatTypeDetector {
166
+ public:
167
+ NatTypeDetector();
168
+ ~NatTypeDetector();
169
+
170
+ NatType detect_nat_type(const std::vector<std::string>& stun_servers, int timeout_ms = 5000);
171
+ std::string nat_type_to_string(NatType type) const;
172
+
173
+ private:
174
+ bool test_udp_blocked(const std::string& stun_server, int timeout_ms);
175
+ bool test_open_internet(const std::string& stun_server, int timeout_ms);
176
+ bool test_full_cone(const std::string& stun_server1, const std::string& stun_server2, int timeout_ms);
177
+ bool test_symmetric_nat(const std::string& stun_server1, const std::string& stun_server2, int timeout_ms);
178
+
179
+ StunAddress get_mapped_address(const std::string& stun_server, int timeout_ms);
180
+ StunAddress get_mapped_address_different_port(const std::string& stun_server, int timeout_ms);
181
+ };
182
+
183
+ // Main ICE Agent
184
+ class IceAgent {
185
+ public:
186
+ IceAgent(IceRole role, const IceConfig& config = IceConfig());
187
+ ~IceAgent();
188
+
189
+ // Lifecycle
190
+ bool start();
191
+ void stop();
192
+ void shutdown_immediate();
193
+ bool is_running() const { return running_.load(); }
194
+
195
+ // Configuration
196
+ void set_config(const IceConfig& config) { config_ = config; }
197
+ IceConfig get_config() const { return config_; }
198
+ void set_role(IceRole role) { role_ = role; }
199
+ IceRole get_role() const { return role_; }
200
+
201
+ // Credentials
202
+ void set_local_credentials(const std::string& ufrag, const std::string& pwd);
203
+ void set_remote_credentials(const std::string& ufrag, const std::string& pwd);
204
+ std::pair<std::string, std::string> get_local_credentials() const;
205
+
206
+ // Candidate gathering
207
+ void gather_candidates();
208
+ std::vector<IceCandidate> get_local_candidates() const;
209
+ void add_remote_candidate(const IceCandidate& candidate);
210
+ void add_remote_candidates(const std::vector<IceCandidate>& candidates);
211
+
212
+ // Connectivity establishment
213
+ void start_connectivity_checks();
214
+ void restart_ice();
215
+
216
+ // Data transmission
217
+ bool send_data(const std::vector<uint8_t>& data);
218
+ bool send_data_to(const std::vector<uint8_t>& data, const std::string& addr);
219
+
220
+ // State
221
+ IceConnectionState get_connection_state() const { return state_.load(); }
222
+ bool is_connected() const { return state_.load() == IceConnectionState::CONNECTED ||
223
+ state_.load() == IceConnectionState::COMPLETED; }
224
+
225
+ // NAT traversal utilities
226
+ NatType detect_nat_type();
227
+ bool perform_hole_punching(const std::string& peer_ip, uint16_t peer_port);
228
+ bool coordinate_connection(const nlohmann::json& signaling_data);
229
+
230
+ // Callbacks
231
+ void set_candidate_callback(IceCandidateCallback callback) { candidate_callback_ = callback; }
232
+ void set_state_change_callback(IceStateChangeCallback callback) { state_change_callback_ = callback; }
233
+ void set_connected_callback(IceConnectedCallback callback) { connected_callback_ = callback; }
234
+ void set_data_callback(IceDataCallback callback) { data_callback_ = callback; }
235
+
236
+ // Signaling support
237
+ nlohmann::json get_local_description() const;
238
+ bool set_remote_description(const nlohmann::json& remote_desc);
239
+ nlohmann::json create_connection_offer() const;
240
+ nlohmann::json create_connection_answer(const nlohmann::json& offer) const;
241
+
242
+ // Statistics and debugging
243
+ std::vector<IceCandidatePair> get_candidate_pairs() const;
244
+ IceCandidatePair get_selected_pair() const;
245
+ nlohmann::json get_statistics() const;
246
+
247
+ private:
248
+ IceRole role_;
249
+ IceConfig config_;
250
+ std::atomic<bool> running_;
251
+ std::atomic<IceConnectionState> state_;
252
+
253
+ // Credentials
254
+ std::string local_ufrag_;
255
+ std::string local_pwd_;
256
+ std::string remote_ufrag_;
257
+ std::string remote_pwd_;
258
+
259
+ // Candidates
260
+ std::vector<IceCandidate> local_candidates_;
261
+ std::vector<IceCandidate> remote_candidates_;
262
+ mutable std::mutex candidates_mutex_;
263
+
264
+ // Candidate pairs and connectivity checks
265
+ std::vector<IceCandidatePair> candidate_pairs_;
266
+ IceCandidatePair selected_pair_;
267
+ mutable std::mutex pairs_mutex_;
268
+
269
+ // Networking
270
+ socket_t udp_socket_;
271
+ socket_t tcp_socket_;
272
+ std::unique_ptr<TurnClient> turn_client_;
273
+ std::unique_ptr<NatTypeDetector> nat_detector_;
274
+
275
+ // Threading
276
+ std::thread gather_thread_;
277
+ std::thread check_thread_;
278
+ std::thread receive_thread_;
279
+
280
+ // Conditional variables for immediate shutdown
281
+ std::condition_variable shutdown_cv_;
282
+ std::mutex shutdown_mutex_;
283
+
284
+ // Callbacks
285
+ IceCandidateCallback candidate_callback_;
286
+ IceStateChangeCallback state_change_callback_;
287
+ IceConnectedCallback connected_callback_;
288
+ IceDataCallback data_callback_;
289
+
290
+ // Internal methods
291
+ void set_state(IceConnectionState new_state);
292
+ void gather_host_candidates();
293
+ void gather_server_reflexive_candidates();
294
+ void gather_relay_candidates();
295
+ void gather_tcp_candidates();
296
+
297
+ void connectivity_check_loop();
298
+ bool perform_connectivity_check(IceCandidatePair& pair);
299
+ void form_candidate_pairs();
300
+ void prioritize_candidate_pairs();
301
+ void nominate_pair(IceCandidatePair& pair);
302
+
303
+ void receive_loop();
304
+ void handle_incoming_data(const std::vector<uint8_t>& data, const std::string& from_addr);
305
+ bool is_stun_message(const std::vector<uint8_t>& data);
306
+ void handle_stun_message(const std::vector<uint8_t>& data, const std::string& from_addr);
307
+
308
+ uint32_t calculate_candidate_priority(IceCandidateType type, uint16_t local_pref, uint16_t component_id);
309
+ std::string generate_foundation(const IceCandidate& candidate);
310
+ std::string generate_ufrag();
311
+ std::string generate_password();
312
+
313
+ // Hole punching helpers
314
+ bool udp_hole_punch(const std::string& peer_ip, uint16_t peer_port);
315
+ bool tcp_hole_punch(const std::string& peer_ip, uint16_t peer_port);
316
+ bool coordinate_hole_punch(const nlohmann::json& punch_data);
317
+ };
318
+
319
+ // Utility functions
320
+ std::string ice_candidate_type_to_string(IceCandidateType type);
321
+ IceCandidateType string_to_ice_candidate_type(const std::string& type_str);
322
+ std::string ice_transport_to_string(IceTransport transport);
323
+ IceTransport string_to_ice_transport(const std::string& transport_str);
324
+ std::string ice_connection_state_to_string(IceConnectionState state);
325
+
326
+ } // namespace librats
327
+
328
+ #endif // LIBRATS_ICE_H