librats 0.7.2 → 0.9.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.
- package/README.md +9 -4
- package/lib/index.d.ts +9 -22
- package/native-src/CMakeLists.txt +132 -50
- package/native-src/cmake/ratsConfig.cmake.in +8 -0
- package/native-src/src/bt_network.cpp +296 -183
- package/native-src/src/bt_network.h +25 -5
- package/native-src/src/crypto/sha256.c +1 -1
- package/native-src/src/dht.cpp +297 -47
- package/native-src/src/dht.h +70 -6
- package/native-src/src/file_transfer.cpp +1185 -1578
- package/native-src/src/file_transfer.h +240 -521
- package/native-src/src/io_poller.cpp +917 -0
- package/native-src/src/io_poller.h +138 -0
- package/native-src/src/krpc.cpp +161 -96
- package/native-src/src/krpc.h +18 -4
- package/native-src/src/librats.cpp +812 -1236
- package/native-src/src/librats.h +207 -208
- package/native-src/src/librats_bittorrent.cpp +1 -5
- package/native-src/src/librats_c.cpp +22 -39
- package/native-src/src/librats_discovery.cpp +377 -0
- package/native-src/src/librats_encryption.cpp +130 -283
- package/native-src/src/librats_file_transfer.cpp +27 -109
- package/native-src/src/librats_gossipsub.cpp +1 -5
- package/native-src/src/librats_ice.cpp +5 -1
- package/native-src/src/librats_log_macros.h +36 -0
- package/native-src/src/librats_logging.cpp +1 -7
- package/native-src/src/librats_mdns.cpp +1 -11
- package/native-src/src/librats_persistence.cpp +1 -11
- package/native-src/src/librats_reconnection.cpp +2 -13
- package/native-src/src/librats_statistic.cpp +105 -0
- package/native-src/src/socket.cpp +15 -3
- package/package.json +1 -1
- package/scripts/build-librats.js +3 -0
- package/scripts/prepare-package.js +10 -0
- package/src/librats_node.cpp +53 -64
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
#include "librats.h"
|
|
2
|
-
|
|
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)
|
|
2
|
+
#include "librats_log_macros.h"
|
|
7
3
|
|
|
8
4
|
namespace librats {
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
// File
|
|
12
|
-
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// File transfer API - thin forwarding layer over FileTransferManager
|
|
8
|
+
// =============================================================================
|
|
13
9
|
|
|
14
10
|
FileTransferManager& RatsClient::get_file_transfer_manager() {
|
|
15
11
|
if (!file_transfer_manager_) {
|
|
@@ -22,24 +18,22 @@ bool RatsClient::is_file_transfer_available() const {
|
|
|
22
18
|
return file_transfer_manager_ != nullptr;
|
|
23
19
|
}
|
|
24
20
|
|
|
25
|
-
std::string RatsClient::send_file(const std::string& peer_id, const std::string& file_path,
|
|
26
|
-
|
|
21
|
+
std::string RatsClient::send_file(const std::string& peer_id, const std::string& file_path,
|
|
22
|
+
const std::string& remote_filename) {
|
|
27
23
|
if (!is_file_transfer_available()) {
|
|
28
24
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
29
25
|
return "";
|
|
30
26
|
}
|
|
31
|
-
|
|
32
27
|
return file_transfer_manager_->send_file(peer_id, file_path, remote_filename);
|
|
33
28
|
}
|
|
34
29
|
|
|
35
30
|
std::string RatsClient::send_directory(const std::string& peer_id, const std::string& directory_path,
|
|
36
|
-
|
|
31
|
+
const std::string& remote_name) {
|
|
37
32
|
if (!is_file_transfer_available()) {
|
|
38
33
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
39
34
|
return "";
|
|
40
35
|
}
|
|
41
|
-
|
|
42
|
-
return file_transfer_manager_->send_directory(peer_id, directory_path, remote_directory_name, recursive);
|
|
36
|
+
return file_transfer_manager_->send_directory(peer_id, directory_path, remote_name);
|
|
43
37
|
}
|
|
44
38
|
|
|
45
39
|
bool RatsClient::accept_file_transfer(const std::string& transfer_id, const std::string& local_path) {
|
|
@@ -47,8 +41,7 @@ bool RatsClient::accept_file_transfer(const std::string& transfer_id, const std:
|
|
|
47
41
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
48
42
|
return false;
|
|
49
43
|
}
|
|
50
|
-
|
|
51
|
-
return file_transfer_manager_->accept_file_transfer(transfer_id, local_path);
|
|
44
|
+
return file_transfer_manager_->accept(transfer_id, local_path);
|
|
52
45
|
}
|
|
53
46
|
|
|
54
47
|
bool RatsClient::reject_file_transfer(const std::string& transfer_id, const std::string& reason) {
|
|
@@ -56,26 +49,7 @@ bool RatsClient::reject_file_transfer(const std::string& transfer_id, const std:
|
|
|
56
49
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
57
50
|
return false;
|
|
58
51
|
}
|
|
59
|
-
|
|
60
|
-
return file_transfer_manager_->reject_file_transfer(transfer_id, reason);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
bool RatsClient::accept_directory_transfer(const std::string& transfer_id, const std::string& local_path) {
|
|
64
|
-
if (!is_file_transfer_available()) {
|
|
65
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return file_transfer_manager_->accept_directory_transfer(transfer_id, local_path);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
bool RatsClient::reject_directory_transfer(const std::string& transfer_id, const std::string& reason) {
|
|
73
|
-
if (!is_file_transfer_available()) {
|
|
74
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return file_transfer_manager_->reject_directory_transfer(transfer_id, reason);
|
|
52
|
+
return file_transfer_manager_->reject(transfer_id, reason);
|
|
79
53
|
}
|
|
80
54
|
|
|
81
55
|
bool RatsClient::pause_file_transfer(const std::string& transfer_id) {
|
|
@@ -83,8 +57,7 @@ bool RatsClient::pause_file_transfer(const std::string& transfer_id) {
|
|
|
83
57
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
84
58
|
return false;
|
|
85
59
|
}
|
|
86
|
-
|
|
87
|
-
return file_transfer_manager_->pause_transfer(transfer_id);
|
|
60
|
+
return file_transfer_manager_->pause(transfer_id);
|
|
88
61
|
}
|
|
89
62
|
|
|
90
63
|
bool RatsClient::resume_file_transfer(const std::string& transfer_id) {
|
|
@@ -92,8 +65,7 @@ bool RatsClient::resume_file_transfer(const std::string& transfer_id) {
|
|
|
92
65
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
93
66
|
return false;
|
|
94
67
|
}
|
|
95
|
-
|
|
96
|
-
return file_transfer_manager_->resume_transfer(transfer_id);
|
|
68
|
+
return file_transfer_manager_->resume(transfer_id);
|
|
97
69
|
}
|
|
98
70
|
|
|
99
71
|
bool RatsClient::cancel_file_transfer(const std::string& transfer_id) {
|
|
@@ -101,25 +73,24 @@ bool RatsClient::cancel_file_transfer(const std::string& transfer_id) {
|
|
|
101
73
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
102
74
|
return false;
|
|
103
75
|
}
|
|
104
|
-
|
|
105
|
-
return file_transfer_manager_->cancel_transfer(transfer_id);
|
|
76
|
+
return file_transfer_manager_->cancel(transfer_id);
|
|
106
77
|
}
|
|
107
78
|
|
|
108
|
-
std::shared_ptr<FileTransferProgress>
|
|
79
|
+
std::shared_ptr<FileTransferProgress>
|
|
80
|
+
RatsClient::get_file_transfer_progress(const std::string& transfer_id) const {
|
|
109
81
|
if (!is_file_transfer_available()) {
|
|
110
82
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
111
83
|
return nullptr;
|
|
112
84
|
}
|
|
113
|
-
|
|
114
|
-
return file_transfer_manager_->get_transfer_progress(transfer_id);
|
|
85
|
+
return file_transfer_manager_->get_progress(transfer_id);
|
|
115
86
|
}
|
|
116
87
|
|
|
117
|
-
std::vector<std::shared_ptr<FileTransferProgress>>
|
|
88
|
+
std::vector<std::shared_ptr<FileTransferProgress>>
|
|
89
|
+
RatsClient::get_active_file_transfers() const {
|
|
118
90
|
if (!is_file_transfer_available()) {
|
|
119
91
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
120
92
|
return {};
|
|
121
93
|
}
|
|
122
|
-
|
|
123
94
|
return file_transfer_manager_->get_active_transfers();
|
|
124
95
|
}
|
|
125
96
|
|
|
@@ -128,8 +99,7 @@ nlohmann::json RatsClient::get_file_transfer_statistics() const {
|
|
|
128
99
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
129
100
|
return nlohmann::json::object();
|
|
130
101
|
}
|
|
131
|
-
|
|
132
|
-
return file_transfer_manager_->get_transfer_statistics();
|
|
102
|
+
return file_transfer_manager_->get_statistics();
|
|
133
103
|
}
|
|
134
104
|
|
|
135
105
|
void RatsClient::set_file_transfer_config(const FileTransferConfig& config) {
|
|
@@ -137,90 +107,38 @@ void RatsClient::set_file_transfer_config(const FileTransferConfig& config) {
|
|
|
137
107
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
138
108
|
return;
|
|
139
109
|
}
|
|
140
|
-
|
|
141
110
|
file_transfer_manager_->set_config(config);
|
|
142
111
|
}
|
|
143
112
|
|
|
144
|
-
|
|
113
|
+
FileTransferConfig RatsClient::get_file_transfer_config() const {
|
|
145
114
|
if (!is_file_transfer_available()) {
|
|
146
115
|
throw std::runtime_error("File transfer manager not available");
|
|
147
116
|
}
|
|
148
|
-
|
|
149
117
|
return file_transfer_manager_->get_config();
|
|
150
118
|
}
|
|
151
119
|
|
|
152
|
-
void RatsClient::on_file_transfer_progress(
|
|
153
|
-
if (!is_file_transfer_available()) {
|
|
154
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
file_transfer_manager_->set_progress_callback(callback);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
void RatsClient::on_file_transfer_completed(FileTransferCompletedCallback callback) {
|
|
162
|
-
if (!is_file_transfer_available()) {
|
|
163
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
file_transfer_manager_->set_completion_callback(callback);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
void RatsClient::on_file_transfer_request(FileTransferRequestCallback callback) {
|
|
120
|
+
void RatsClient::on_file_transfer_progress(TransferProgressCallback callback) {
|
|
171
121
|
if (!is_file_transfer_available()) {
|
|
172
122
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
173
123
|
return;
|
|
174
124
|
}
|
|
175
|
-
|
|
176
|
-
file_transfer_manager_->set_request_callback(callback);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
void RatsClient::on_directory_transfer_progress(DirectoryTransferProgressCallback callback) {
|
|
180
|
-
if (!is_file_transfer_available()) {
|
|
181
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
file_transfer_manager_->set_directory_progress_callback(callback);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
std::string RatsClient::request_file(const std::string& peer_id, const std::string& remote_file_path,
|
|
189
|
-
const std::string& local_path) {
|
|
190
|
-
if (!is_file_transfer_available()) {
|
|
191
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
192
|
-
return "";
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return file_transfer_manager_->request_file(peer_id, remote_file_path, local_path);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
std::string RatsClient::request_directory(const std::string& peer_id, const std::string& remote_directory_path,
|
|
199
|
-
const std::string& local_directory_path, bool recursive) {
|
|
200
|
-
if (!is_file_transfer_available()) {
|
|
201
|
-
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
202
|
-
return "";
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return file_transfer_manager_->request_directory(peer_id, remote_directory_path, local_directory_path, recursive);
|
|
125
|
+
file_transfer_manager_->set_progress_callback(std::move(callback));
|
|
206
126
|
}
|
|
207
127
|
|
|
208
|
-
void RatsClient::
|
|
128
|
+
void RatsClient::on_file_transfer_completed(TransferCompletedCallback callback) {
|
|
209
129
|
if (!is_file_transfer_available()) {
|
|
210
130
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
211
131
|
return;
|
|
212
132
|
}
|
|
213
|
-
|
|
214
|
-
file_transfer_manager_->set_file_request_callback(callback);
|
|
133
|
+
file_transfer_manager_->set_completed_callback(std::move(callback));
|
|
215
134
|
}
|
|
216
135
|
|
|
217
|
-
void RatsClient::
|
|
136
|
+
void RatsClient::on_file_transfer_request(TransferOfferCallback callback) {
|
|
218
137
|
if (!is_file_transfer_available()) {
|
|
219
138
|
LOG_CLIENT_ERROR("File transfer manager not available");
|
|
220
139
|
return;
|
|
221
140
|
}
|
|
222
|
-
|
|
223
|
-
file_transfer_manager_->set_directory_request_callback(callback);
|
|
141
|
+
file_transfer_manager_->set_offer_callback(std::move(callback));
|
|
224
142
|
}
|
|
225
143
|
|
|
226
|
-
}
|
|
144
|
+
} // namespace librats
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
#include "librats.h"
|
|
2
|
-
|
|
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)
|
|
2
|
+
#include "librats_log_macros.h"
|
|
7
3
|
|
|
8
4
|
namespace librats {
|
|
9
5
|
|
|
@@ -91,6 +91,10 @@ std::optional<StunMappedAddress> RatsClient::discover_public_address(
|
|
|
91
91
|
|
|
92
92
|
if (result.success && result.mapped_address) {
|
|
93
93
|
LOG_INFO("ice", "Discovered public address: " << result.mapped_address->to_string());
|
|
94
|
+
|
|
95
|
+
// Add public IP to our own addresses list to prevent self-connections
|
|
96
|
+
add_ignored_address(result.mapped_address->address);
|
|
97
|
+
|
|
94
98
|
return result.mapped_address;
|
|
95
99
|
}
|
|
96
100
|
|
|
@@ -183,7 +187,7 @@ void RatsClient::set_ice_config(const IceConfig& config) {
|
|
|
183
187
|
get_ice_manager().set_config(config);
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
|
|
190
|
+
IceConfig RatsClient::get_ice_config() const {
|
|
187
191
|
// Need to cast away const to get mutable reference for lazy initialization
|
|
188
192
|
return const_cast<RatsClient*>(this)->get_ice_manager().config();
|
|
189
193
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file librats_log_macros.h
|
|
3
|
+
* @brief Shared logging macros for all librats_*.cpp files.
|
|
4
|
+
*
|
|
5
|
+
* In TESTING builds the macros embed the `this` pointer so that
|
|
6
|
+
* log lines from different RatsClient instances can be distinguished.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#ifndef LIBRATS_LOG_MACROS_H
|
|
10
|
+
#define LIBRATS_LOG_MACROS_H
|
|
11
|
+
|
|
12
|
+
#include "logger.h"
|
|
13
|
+
|
|
14
|
+
#ifdef TESTING
|
|
15
|
+
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", "[pointer: " << this << "] " << message)
|
|
16
|
+
#define LOG_CLIENT_INFO(message) LOG_INFO("client", "[pointer: " << this << "] " << message)
|
|
17
|
+
#define LOG_CLIENT_WARN(message) LOG_WARN("client", "[pointer: " << this << "] " << message)
|
|
18
|
+
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", "[pointer: " << this << "] " << message)
|
|
19
|
+
|
|
20
|
+
#define LOG_SERVER_DEBUG(message) LOG_DEBUG("server", "[pointer: " << this << "] " << message)
|
|
21
|
+
#define LOG_SERVER_INFO(message) LOG_INFO("server", "[pointer: " << this << "] " << message)
|
|
22
|
+
#define LOG_SERVER_WARN(message) LOG_WARN("server", "[pointer: " << this << "] " << message)
|
|
23
|
+
#define LOG_SERVER_ERROR(message) LOG_ERROR("server", "[pointer: " << this << "] " << message)
|
|
24
|
+
#else
|
|
25
|
+
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
26
|
+
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
27
|
+
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
28
|
+
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
29
|
+
|
|
30
|
+
#define LOG_SERVER_DEBUG(message) LOG_DEBUG("server", message)
|
|
31
|
+
#define LOG_SERVER_INFO(message) LOG_INFO("server", message)
|
|
32
|
+
#define LOG_SERVER_WARN(message) LOG_WARN("server", message)
|
|
33
|
+
#define LOG_SERVER_ERROR(message) LOG_ERROR("server", message)
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#endif // LIBRATS_LOG_MACROS_H
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
#include "librats.h"
|
|
2
|
-
#include "
|
|
2
|
+
#include "librats_log_macros.h"
|
|
3
3
|
#include <algorithm>
|
|
4
4
|
|
|
5
|
-
// Logging macros for RatsClient
|
|
6
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
7
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
8
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
9
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
10
|
-
|
|
11
5
|
namespace librats {
|
|
12
6
|
|
|
13
7
|
//=============================================================================
|
|
@@ -6,17 +6,7 @@
|
|
|
6
6
|
#include <memory>
|
|
7
7
|
#include <stdexcept>
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", "[pointer: " << this << "] " << message)
|
|
11
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", "[pointer: " << this << "] " << message)
|
|
12
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", "[pointer: " << this << "] " << message)
|
|
13
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", "[pointer: " << this << "] " << message)
|
|
14
|
-
#else
|
|
15
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
16
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
17
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
18
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
19
|
-
#endif
|
|
9
|
+
#include "librats_log_macros.h"
|
|
20
10
|
|
|
21
11
|
namespace librats {
|
|
22
12
|
|
|
@@ -12,17 +12,7 @@
|
|
|
12
12
|
#include <iomanip>
|
|
13
13
|
#include <stdexcept>
|
|
14
14
|
|
|
15
|
-
#
|
|
16
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", "[pointer: " << this << "] " << message)
|
|
17
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", "[pointer: " << this << "] " << message)
|
|
18
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", "[pointer: " << this << "] " << message)
|
|
19
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", "[pointer: " << this << "] " << message)
|
|
20
|
-
#else
|
|
21
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
22
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
23
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
24
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
25
|
-
#endif
|
|
15
|
+
#include "librats_log_macros.h"
|
|
26
16
|
|
|
27
17
|
namespace librats {
|
|
28
18
|
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
#include "librats.h"
|
|
2
|
-
|
|
3
|
-
#ifdef TESTING
|
|
4
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", "[pointer: " << this << "] " << message)
|
|
5
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", "[pointer: " << this << "] " << message)
|
|
6
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", "[pointer: " << this << "] " << message)
|
|
7
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", "[pointer: " << this << "] " << message)
|
|
8
|
-
#else
|
|
9
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
10
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
11
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
12
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
13
|
-
#endif
|
|
2
|
+
#include "librats_log_macros.h"
|
|
14
3
|
|
|
15
4
|
namespace librats {
|
|
16
5
|
|
|
@@ -37,7 +26,7 @@ void RatsClient::set_reconnect_config(const ReconnectConfig& config) {
|
|
|
37
26
|
<< ", stable_threshold=" << config.stable_connection_threshold_seconds << "s");
|
|
38
27
|
}
|
|
39
28
|
|
|
40
|
-
|
|
29
|
+
ReconnectConfig RatsClient::get_reconnect_config() const {
|
|
41
30
|
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
42
31
|
return reconnect_config_;
|
|
43
32
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
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 (IPv4 + IPv6 combined)
|
|
28
|
+
if (is_dht_running()) {
|
|
29
|
+
stats["dht_running"] = true;
|
|
30
|
+
stats["dht_routing_table_size"] = get_dht_routing_table_size();
|
|
31
|
+
stats["dht_ipv4_running"] = (dht_client_ && dht_client_->is_running());
|
|
32
|
+
stats["dht_ipv6_running"] = (dht_client_v6_ && dht_client_v6_->is_running());
|
|
33
|
+
if (dht_client_ && dht_client_->is_running()) {
|
|
34
|
+
stats["dht_ipv4_routing_table_size"] = dht_client_->get_routing_table_size();
|
|
35
|
+
}
|
|
36
|
+
if (dht_client_v6_ && dht_client_v6_->is_running()) {
|
|
37
|
+
stats["dht_ipv6_routing_table_size"] = dht_client_v6_->get_routing_table_size();
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
stats["dht_running"] = false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// mDNS statistics
|
|
44
|
+
stats["mdns_running"] = is_mdns_running();
|
|
45
|
+
|
|
46
|
+
// Reconnection statistics
|
|
47
|
+
{
|
|
48
|
+
std::lock_guard<std::mutex> lock(reconnect_mutex_);
|
|
49
|
+
stats["reconnect_enabled"] = reconnect_config_.enabled;
|
|
50
|
+
stats["reconnect_queue_size"] = reconnect_queue_.size();
|
|
51
|
+
stats["reconnect_max_attempts"] = reconnect_config_.max_attempts;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return stats;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Cached formatting helpers - computed once on first use
|
|
58
|
+
static const std::string& get_box_separator() {
|
|
59
|
+
static const std::string separator = supports_unicode() ?
|
|
60
|
+
"════════════════════════════════════════════════════════════════════" :
|
|
61
|
+
"=====================================================================";
|
|
62
|
+
return separator;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static const std::string& get_box_vertical() {
|
|
66
|
+
static const std::string vertical = supports_unicode() ? "│" : "|";
|
|
67
|
+
return vertical;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static const std::string& get_checkmark() {
|
|
71
|
+
static const std::string checkmark = supports_unicode() ? "✓" : "[*]";
|
|
72
|
+
return checkmark;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void RatsClient::log_handshake_completion_unlocked(const RatsPeer& peer) {
|
|
76
|
+
// Calculate connection duration
|
|
77
|
+
auto now = std::chrono::steady_clock::now();
|
|
78
|
+
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now - peer.connected_at);
|
|
79
|
+
|
|
80
|
+
// Get current peer count (assumes peers_mutex_ is already locked)
|
|
81
|
+
int current_peer_count = get_peer_count_unlocked();
|
|
82
|
+
|
|
83
|
+
// Create visually appealing log output
|
|
84
|
+
std::string connection_type = peer.is_outgoing ? "OUTGOING" : "INCOMING";
|
|
85
|
+
const std::string& separator = get_box_separator();
|
|
86
|
+
const std::string& vertical = get_box_vertical();
|
|
87
|
+
const std::string& checkmark = get_checkmark();
|
|
88
|
+
|
|
89
|
+
LOG_CLIENT_INFO("");
|
|
90
|
+
LOG_CLIENT_INFO(separator);
|
|
91
|
+
LOG_CLIENT_INFO(checkmark << " HANDSHAKE COMPLETED - NEW PEER CONNECTED");
|
|
92
|
+
LOG_CLIENT_INFO(separator);
|
|
93
|
+
LOG_CLIENT_INFO(vertical << " Peer ID : " << peer.peer_id);
|
|
94
|
+
LOG_CLIENT_INFO(vertical << " Address : " << peer.ip << ":" << peer.port);
|
|
95
|
+
LOG_CLIENT_INFO(vertical << " Connection : " << connection_type);
|
|
96
|
+
LOG_CLIENT_INFO(vertical << " Protocol Ver. : " << peer.version);
|
|
97
|
+
LOG_CLIENT_INFO(vertical << " Socket : " << peer.socket);
|
|
98
|
+
LOG_CLIENT_INFO(vertical << " Duration : " << duration.count() << "ms");
|
|
99
|
+
LOG_CLIENT_INFO(vertical << " Network Peers : " << current_peer_count << "/" << max_peers_);
|
|
100
|
+
|
|
101
|
+
LOG_CLIENT_INFO(separator);
|
|
102
|
+
LOG_CLIENT_INFO("");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
}
|
|
@@ -760,13 +760,25 @@ static bool build_udp_dest_addr(const std::string& host, int port, AddressFamily
|
|
|
760
760
|
sockaddr_storage& addr, socklen_t& addr_len) {
|
|
761
761
|
memset(&addr, 0, sizeof(addr));
|
|
762
762
|
|
|
763
|
-
// Native IPv6 address
|
|
763
|
+
// Native IPv6 address, or hostname that must resolve to IPv6 (pure IPv6 socket).
|
|
764
|
+
// A pure IPv6 socket (V6ONLY) cannot send to IPv4-mapped addresses, so hostnames
|
|
765
|
+
// are resolved via AAAA records here.
|
|
766
|
+
std::string ipv6_host;
|
|
764
767
|
if (network_utils::is_valid_ipv6(host)) {
|
|
768
|
+
ipv6_host = host;
|
|
769
|
+
} else if (af == AddressFamily::IPv6) {
|
|
770
|
+
ipv6_host = network_utils::resolve_hostname_v6(host);
|
|
771
|
+
if (ipv6_host.empty()) {
|
|
772
|
+
LOG_SOCKET_DEBUG("Failed to resolve hostname to IPv6: " << host);
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (!ipv6_host.empty()) {
|
|
765
777
|
auto* a6 = reinterpret_cast<sockaddr_in6*>(&addr);
|
|
766
778
|
a6->sin6_family = AF_INET6;
|
|
767
779
|
a6->sin6_port = htons(port);
|
|
768
|
-
if (inet_pton(AF_INET6,
|
|
769
|
-
LOG_SOCKET_ERROR("Invalid IPv6 address: " <<
|
|
780
|
+
if (inet_pton(AF_INET6, ipv6_host.c_str(), &a6->sin6_addr) <= 0) {
|
|
781
|
+
LOG_SOCKET_ERROR("Invalid IPv6 address: " << ipv6_host);
|
|
770
782
|
return false;
|
|
771
783
|
}
|
|
772
784
|
addr_len = sizeof(sockaddr_in6);
|
package/package.json
CHANGED
package/scripts/build-librats.js
CHANGED
|
@@ -136,6 +136,9 @@ try {
|
|
|
136
136
|
'-DRATS_BUILD_EXAMPLES=OFF',
|
|
137
137
|
'-DRATS_STATIC_LIBRARY=ON',
|
|
138
138
|
'-DRATS_BINDINGS=ON',
|
|
139
|
+
// The bindings only need the static archive; install/package-config rules
|
|
140
|
+
// (find_package support) are unnecessary here and pull in cmake/ratsConfig.cmake.in.
|
|
141
|
+
'-DRATS_INSTALL=OFF',
|
|
139
142
|
'-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreadedDLL'
|
|
140
143
|
];
|
|
141
144
|
|
|
@@ -108,6 +108,16 @@ copyDir(
|
|
|
108
108
|
srcFilter
|
|
109
109
|
);
|
|
110
110
|
|
|
111
|
+
// Copy cmake/ directory (package-config templates referenced by CMakeLists.txt
|
|
112
|
+
// when RATS_INSTALL is enabled, e.g. cmake/ratsConfig.cmake.in)
|
|
113
|
+
if (fs.existsSync(path.join(projectRoot, 'cmake'))) {
|
|
114
|
+
console.log(' Copying cmake/ directory...');
|
|
115
|
+
copyDir(
|
|
116
|
+
path.join(projectRoot, 'cmake'),
|
|
117
|
+
path.join(nativeSrcDir, 'cmake')
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
111
121
|
// Copy 3rdparty/ directory
|
|
112
122
|
if (fs.existsSync(path.join(projectRoot, '3rdparty'))) {
|
|
113
123
|
console.log(' Copying 3rdparty/ directory...');
|