librats 0.7.1 → 0.8.0

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 (42) hide show
  1. package/native-src/CMakeLists.txt +15 -2
  2. package/native-src/src/bt_client.cpp +18 -5
  3. package/native-src/src/bt_client.h +3 -1
  4. package/native-src/src/bt_network.cpp +297 -184
  5. package/native-src/src/bt_network.h +25 -5
  6. package/native-src/src/bt_peer_connection.cpp +11 -0
  7. package/native-src/src/bt_peer_connection.h +6 -0
  8. package/native-src/src/bt_torrent.cpp +17 -6
  9. package/native-src/src/bt_torrent.h +1 -0
  10. package/native-src/src/bt_types.h +287 -20
  11. package/native-src/src/dht.cpp +26 -8
  12. package/native-src/src/dht.h +1 -1
  13. package/native-src/src/ice.cpp +1 -1
  14. package/native-src/src/io_poller.cpp +910 -0
  15. package/native-src/src/io_poller.h +138 -0
  16. package/native-src/src/krpc.cpp +8 -1
  17. package/native-src/src/krpc.h +3 -2
  18. package/native-src/src/librats.cpp +824 -1213
  19. package/native-src/src/librats.h +167 -54
  20. package/native-src/src/librats_bittorrent.cpp +4 -7
  21. package/native-src/src/librats_c.cpp +13 -1
  22. package/native-src/src/librats_c.h +2 -0
  23. package/native-src/src/librats_discovery.cpp +309 -0
  24. package/native-src/src/librats_encryption.cpp +130 -283
  25. package/native-src/src/librats_file_transfer.cpp +2 -6
  26. package/native-src/src/librats_gossipsub.cpp +1 -5
  27. package/native-src/src/librats_ice.cpp +1 -1
  28. package/native-src/src/librats_log_macros.h +36 -0
  29. package/native-src/src/librats_logging.cpp +10 -7
  30. package/native-src/src/librats_mdns.cpp +1 -11
  31. package/native-src/src/librats_persistence.cpp +1 -11
  32. package/native-src/src/librats_reconnection.cpp +2 -13
  33. package/native-src/src/librats_statistic.cpp +97 -0
  34. package/native-src/src/logger.h +40 -4
  35. package/native-src/src/network_utils.cpp +175 -373
  36. package/native-src/src/network_utils.h +2 -113
  37. package/native-src/src/socket.cpp +485 -883
  38. package/native-src/src/socket.h +36 -130
  39. package/native-src/src/stun.cpp +3 -5
  40. package/native-src/src/tracker.cpp +3 -2
  41. package/native-src/src/turn.cpp +4 -6
  42. package/package.json +1 -1
@@ -0,0 +1,97 @@
1
+ #include "librats.h"
2
+ #include "librats_log_macros.h"
3
+ #include "os.h"
4
+
5
+ namespace librats {
6
+
7
+
8
+ // =========================================================================
9
+ // Statistics and Information
10
+ // =========================================================================
11
+
12
+ nlohmann::json RatsClient::get_connection_statistics() const {
13
+ nlohmann::json stats;
14
+
15
+ {
16
+ std::lock_guard<std::mutex> lock(peers_mutex_);
17
+ stats["total_peers"] = peers_.size();
18
+ stats["validated_peers"] = get_peer_count_unlocked();
19
+ stats["max_peers"] = max_peers_;
20
+ }
21
+
22
+ stats["running"] = is_running();
23
+ stats["listen_port"] = listen_port_;
24
+ stats["our_peer_id"] = get_our_peer_id();
25
+ stats["encryption_enabled"] = is_encryption_enabled();
26
+
27
+ // DHT statistics
28
+ if (dht_client_ && dht_client_->is_running()) {
29
+ stats["dht_running"] = true;
30
+ stats["dht_routing_table_size"] = get_dht_routing_table_size();
31
+ } else {
32
+ stats["dht_running"] = false;
33
+ }
34
+
35
+ // mDNS statistics
36
+ stats["mdns_running"] = is_mdns_running();
37
+
38
+ // Reconnection statistics
39
+ {
40
+ std::lock_guard<std::mutex> lock(reconnect_mutex_);
41
+ stats["reconnect_enabled"] = reconnect_config_.enabled;
42
+ stats["reconnect_queue_size"] = reconnect_queue_.size();
43
+ stats["reconnect_max_attempts"] = reconnect_config_.max_attempts;
44
+ }
45
+
46
+ return stats;
47
+ }
48
+
49
+ // Cached formatting helpers - computed once on first use
50
+ static const std::string& get_box_separator() {
51
+ static const std::string separator = supports_unicode() ?
52
+ "════════════════════════════════════════════════════════════════════" :
53
+ "=====================================================================";
54
+ return separator;
55
+ }
56
+
57
+ static const std::string& get_box_vertical() {
58
+ static const std::string vertical = supports_unicode() ? "│" : "|";
59
+ return vertical;
60
+ }
61
+
62
+ static const std::string& get_checkmark() {
63
+ static const std::string checkmark = supports_unicode() ? "✓" : "[*]";
64
+ return checkmark;
65
+ }
66
+
67
+ void RatsClient::log_handshake_completion_unlocked(const RatsPeer& peer) {
68
+ // Calculate connection duration
69
+ auto now = std::chrono::steady_clock::now();
70
+ auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - peer.connected_at);
71
+
72
+ // Get current peer count (assumes peers_mutex_ is already locked)
73
+ int current_peer_count = get_peer_count_unlocked();
74
+
75
+ // Create visually appealing log output
76
+ std::string connection_type = peer.is_outgoing ? "OUTGOING" : "INCOMING";
77
+ const std::string& separator = get_box_separator();
78
+ const std::string& vertical = get_box_vertical();
79
+ const std::string& checkmark = get_checkmark();
80
+
81
+ LOG_CLIENT_INFO("");
82
+ LOG_CLIENT_INFO(separator);
83
+ LOG_CLIENT_INFO(checkmark << " HANDSHAKE COMPLETED - NEW PEER CONNECTED");
84
+ LOG_CLIENT_INFO(separator);
85
+ LOG_CLIENT_INFO(vertical << " Peer ID : " << peer.peer_id);
86
+ LOG_CLIENT_INFO(vertical << " Address : " << peer.ip << ":" << peer.port);
87
+ LOG_CLIENT_INFO(vertical << " Connection : " << connection_type);
88
+ LOG_CLIENT_INFO(vertical << " Protocol Ver. : " << peer.version);
89
+ LOG_CLIENT_INFO(vertical << " Socket : " << peer.socket);
90
+ LOG_CLIENT_INFO(vertical << " Duration : " << duration.count() << "ms");
91
+ LOG_CLIENT_INFO(vertical << " Network Peers : " << current_peer_count << "/" << max_peers_);
92
+
93
+ LOG_CLIENT_INFO(separator);
94
+ LOG_CLIENT_INFO("");
95
+ }
96
+
97
+ }
@@ -100,6 +100,17 @@ public:
100
100
  max_log_files_ = count;
101
101
  }
102
102
 
103
+ // Rotate on startup configuration
104
+ void set_rotate_on_startup(bool enabled) {
105
+ std::lock_guard<std::mutex> lock(mutex_);
106
+ rotate_on_startup_ = enabled;
107
+ }
108
+
109
+ bool is_rotate_on_startup_enabled() const {
110
+ std::lock_guard<std::mutex> lock(mutex_);
111
+ return rotate_on_startup_;
112
+ }
113
+
103
114
  // Get current file logging status
104
115
  bool is_file_logging_enabled() const {
105
116
  std::lock_guard<std::mutex> lock(mutex_);
@@ -178,7 +189,8 @@ public:
178
189
  private:
179
190
  Logger() : min_level_(LogLevel::INFO), colors_enabled_(true), timestamps_enabled_(true),
180
191
  console_logging_enabled_(true), file_logging_enabled_(false),
181
- max_log_file_size_(10 * 1024 * 1024), max_log_files_(5), current_file_size_(0) {
192
+ max_log_file_size_(10 * 1024 * 1024), max_log_files_(5), current_file_size_(0),
193
+ rotate_on_startup_(false), startup_rotation_done_(false) {
182
194
  // Check if we're outputting to a terminal
183
195
  is_terminal_ = isatty(fileno(stdout));
184
196
 
@@ -330,6 +342,19 @@ private:
330
342
  }
331
343
  }
332
344
 
345
+ // Perform rotation on startup if enabled and not yet done this session
346
+ if (rotate_on_startup_ && !startup_rotation_done_) {
347
+ // Check if the log file exists and has content
348
+ if (file_exists(log_file_path_.c_str())) {
349
+ std::ifstream check_file(log_file_path_, std::ios::ate);
350
+ if (check_file.is_open() && check_file.tellg() > 0) {
351
+ check_file.close();
352
+ rotate_log_files_impl();
353
+ }
354
+ }
355
+ startup_rotation_done_ = true;
356
+ }
357
+
333
358
  log_file_.open(log_file_path_, std::ios::app);
334
359
  if (log_file_.is_open()) {
335
360
  // Get current file size
@@ -350,6 +375,16 @@ private:
350
375
  if (log_file_path_.empty() || max_log_files_ <= 0) return;
351
376
 
352
377
  close_log_file();
378
+ rotate_log_files_impl();
379
+
380
+ // Reopen the log file (new empty file)
381
+ open_log_file();
382
+ }
383
+
384
+ // Internal rotation implementation - does not close/open files
385
+ // Called directly when we need to rotate before opening (e.g., on startup)
386
+ void rotate_log_files_impl() {
387
+ if (log_file_path_.empty() || max_log_files_ <= 0) return;
353
388
 
354
389
  // Move existing log files
355
390
  for (int i = max_log_files_ - 1; i >= 1; i--) {
@@ -368,9 +403,6 @@ private:
368
403
  // Move current log file to .1
369
404
  std::string backup_name = log_file_path_ + ".1";
370
405
  std::rename(log_file_path_.c_str(), backup_name.c_str());
371
-
372
- // Reopen the log file (new empty file)
373
- open_log_file();
374
406
  }
375
407
 
376
408
  mutable std::mutex mutex_;
@@ -389,6 +421,10 @@ private:
389
421
  size_t max_log_file_size_;
390
422
  int max_log_files_;
391
423
  size_t current_file_size_;
424
+
425
+ // Rotate on startup members
426
+ bool rotate_on_startup_;
427
+ bool startup_rotation_done_; // Tracks if we've already done startup rotation for this session
392
428
  };
393
429
 
394
430
  } // namespace librats