librats 0.7.2 → 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.
- package/native-src/CMakeLists.txt +10 -2
- package/native-src/src/bt_network.cpp +296 -183
- package/native-src/src/bt_network.h +25 -5
- package/native-src/src/io_poller.cpp +910 -0
- package/native-src/src/io_poller.h +138 -0
- package/native-src/src/librats.cpp +809 -1236
- package/native-src/src/librats.h +146 -54
- package/native-src/src/librats_bittorrent.cpp +1 -5
- package/native-src/src/librats_c.cpp +1 -1
- package/native-src/src/librats_discovery.cpp +309 -0
- package/native-src/src/librats_encryption.cpp +130 -283
- package/native-src/src/librats_file_transfer.cpp +2 -6
- package/native-src/src/librats_gossipsub.cpp +1 -5
- package/native-src/src/librats_ice.cpp +1 -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 +97 -0
- package/package.json +1 -1
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
#include "librats.h"
|
|
2
|
-
#include "
|
|
3
|
-
|
|
4
|
-
#define LOG_CLIENT_DEBUG(message) LOG_DEBUG("client", message)
|
|
5
|
-
#define LOG_CLIENT_INFO(message) LOG_INFO("client", message)
|
|
6
|
-
#define LOG_CLIENT_WARN(message) LOG_WARN("client", message)
|
|
7
|
-
#define LOG_CLIENT_ERROR(message) LOG_ERROR("client", message)
|
|
2
|
+
#include "librats_log_macros.h"
|
|
8
3
|
|
|
9
4
|
namespace librats {
|
|
10
5
|
|
|
@@ -102,73 +97,28 @@ std::vector<uint8_t> RatsClient::get_peer_handshake_hash(const std::string& peer
|
|
|
102
97
|
return std::vector<uint8_t>();
|
|
103
98
|
}
|
|
104
99
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
auto socket_mutex = get_socket_send_mutex(socket);
|
|
109
|
-
std::lock_guard<std::mutex> send_lock(*socket_mutex);
|
|
110
|
-
|
|
111
|
-
// Send length-prefixed message for Noise handshake
|
|
112
|
-
uint32_t network_len = htonl(static_cast<uint32_t>(len));
|
|
113
|
-
|
|
114
|
-
// Send length
|
|
115
|
-
int sent = ::send(socket, reinterpret_cast<const char*>(&network_len), 4, 0);
|
|
116
|
-
if (sent != 4) {
|
|
117
|
-
LOG_CLIENT_ERROR("Failed to send Noise message length");
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Send data
|
|
122
|
-
sent = ::send(socket, reinterpret_cast<const char*>(data), static_cast<int>(len), 0);
|
|
123
|
-
if (sent != static_cast<int>(len)) {
|
|
124
|
-
LOG_CLIENT_ERROR("Failed to send Noise message data");
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return true;
|
|
129
|
-
}
|
|
100
|
+
// =========================================================================
|
|
101
|
+
// Async Noise Handshake (non-blocking, driven by io_loop)
|
|
102
|
+
// =========================================================================
|
|
130
103
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// Receive length
|
|
146
|
-
uint32_t network_len;
|
|
147
|
-
int received = recv(socket, reinterpret_cast<char*>(&network_len), 4, MSG_WAITALL);
|
|
148
|
-
if (received != 4) {
|
|
149
|
-
LOG_CLIENT_ERROR("Failed to receive Noise message length");
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
uint32_t len = ntohl(network_len);
|
|
154
|
-
if (len > rats::NOISE_MAX_MESSAGE_SIZE) {
|
|
155
|
-
LOG_CLIENT_ERROR("Noise message too large: " << len);
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Receive data
|
|
160
|
-
out_data.resize(len);
|
|
161
|
-
received = recv(socket, reinterpret_cast<char*>(out_data.data()), static_cast<int>(len), MSG_WAITALL);
|
|
162
|
-
if (received != static_cast<int>(len)) {
|
|
163
|
-
LOG_CLIENT_ERROR("Failed to receive Noise message data");
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return true;
|
|
168
|
-
}
|
|
104
|
+
/*
|
|
105
|
+
* Noise XX pattern (3 messages):
|
|
106
|
+
* Initiator: write msg0 → read msg1 → write msg2 → split
|
|
107
|
+
* Responder: read msg0 → write msg1 → read msg2 → split
|
|
108
|
+
*
|
|
109
|
+
* noise_step tracks where we are in this sequence:
|
|
110
|
+
* Initiator: 0 = need write, 1 = need read, 2 = need write, 3 = done
|
|
111
|
+
* Responder: 0 = need read, 1 = need write, 2 = need read, 3 = done
|
|
112
|
+
*
|
|
113
|
+
* start_noise_handshake_async() initialises noise_hs and writes the first
|
|
114
|
+
* outgoing message (if initiator). Subsequent messages are processed by
|
|
115
|
+
* handle_noise_frame() which is called from handle_readable when
|
|
116
|
+
* handshake_state == NOISE_PENDING.
|
|
117
|
+
*/
|
|
169
118
|
|
|
170
|
-
|
|
171
|
-
LOG_CLIENT_INFO("Starting Noise handshake
|
|
119
|
+
void RatsClient::start_noise_handshake_async(RatsPeer& peer) {
|
|
120
|
+
LOG_CLIENT_INFO("Starting async Noise handshake for " << peer.peer_id
|
|
121
|
+
<< " (initiator: " << peer.is_outgoing << ")");
|
|
172
122
|
|
|
173
123
|
// Get our static keypair
|
|
174
124
|
rats::NoiseKeyPair static_keypair;
|
|
@@ -183,245 +133,142 @@ bool RatsClient::perform_noise_handshake(socket_t socket, const std::string& pee
|
|
|
183
133
|
static_keypair.has_keys = true;
|
|
184
134
|
}
|
|
185
135
|
|
|
186
|
-
//
|
|
187
|
-
rats::NoiseHandshakeState
|
|
188
|
-
|
|
136
|
+
// Allocate handshake state on the peer's IO context
|
|
137
|
+
peer.io_.noise_hs = std::make_unique<rats::NoiseHandshakeState>();
|
|
138
|
+
peer.io_.noise_step = 0;
|
|
139
|
+
|
|
140
|
+
auto err = peer.io_.noise_hs->initialize(peer.is_outgoing, &static_keypair);
|
|
189
141
|
if (err != rats::NoiseError::OK) {
|
|
190
|
-
LOG_CLIENT_ERROR("Failed to
|
|
191
|
-
|
|
142
|
+
LOG_CLIENT_ERROR("Failed to initialise Noise handshake: " << static_cast<int>(err));
|
|
143
|
+
peer.handshake_state = RatsPeer::HandshakeState::FAILED;
|
|
144
|
+
return;
|
|
192
145
|
}
|
|
193
146
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
/*
|
|
201
|
-
* XX Pattern:
|
|
202
|
-
* -> e (message 0, initiator sends)
|
|
203
|
-
* <- e, ee, s, es (message 1, responder sends)
|
|
204
|
-
* -> s, se (message 2, initiator sends)
|
|
205
|
-
*/
|
|
206
|
-
|
|
207
|
-
if (is_initiator) {
|
|
208
|
-
// Message 0: -> e
|
|
209
|
-
message_len = sizeof(message_buf);
|
|
210
|
-
err = handshake.write_message(nullptr, 0, message_buf, &message_len);
|
|
211
|
-
if (err != rats::NoiseError::OK) {
|
|
212
|
-
LOG_CLIENT_ERROR("Failed to write Noise message 0");
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (!send_noise_message(socket, message_buf, message_len)) {
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
LOG_CLIENT_DEBUG("Sent Noise message 0 (e) - " << message_len << " bytes");
|
|
220
|
-
|
|
221
|
-
// Receive message 1: <- e, ee, s, es
|
|
222
|
-
if (!recv_noise_message(socket, received_data)) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
LOG_CLIENT_DEBUG("Received Noise message 1 - " << received_data.size() << " bytes");
|
|
226
|
-
|
|
227
|
-
payload_len = sizeof(payload_buf);
|
|
228
|
-
err = handshake.read_message(received_data.data(), received_data.size(), payload_buf, &payload_len);
|
|
229
|
-
if (err != rats::NoiseError::OK) {
|
|
230
|
-
LOG_CLIENT_ERROR("Failed to read Noise message 1: " << static_cast<int>(err));
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Message 2: -> s, se
|
|
235
|
-
message_len = sizeof(message_buf);
|
|
236
|
-
err = handshake.write_message(nullptr, 0, message_buf, &message_len);
|
|
147
|
+
// Initiator sends message 0 immediately
|
|
148
|
+
if (peer.is_outgoing) {
|
|
149
|
+
uint8_t msg_buf[256];
|
|
150
|
+
size_t msg_len = sizeof(msg_buf);
|
|
151
|
+
err = peer.io_.noise_hs->write_message(nullptr, 0, msg_buf, &msg_len);
|
|
237
152
|
if (err != rats::NoiseError::OK) {
|
|
238
|
-
LOG_CLIENT_ERROR("Failed to write Noise
|
|
239
|
-
|
|
153
|
+
LOG_CLIENT_ERROR("Failed to write Noise msg 0: " << static_cast<int>(err));
|
|
154
|
+
peer.handshake_state = RatsPeer::HandshakeState::FAILED;
|
|
155
|
+
return;
|
|
240
156
|
}
|
|
241
157
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
} else {
|
|
248
|
-
// Responder
|
|
249
|
-
|
|
250
|
-
// Receive message 0: -> e
|
|
251
|
-
if (!recv_noise_message(socket, received_data)) {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
LOG_CLIENT_DEBUG("Received Noise message 0 - " << received_data.size() << " bytes");
|
|
255
|
-
|
|
256
|
-
payload_len = sizeof(payload_buf);
|
|
257
|
-
err = handshake.read_message(received_data.data(), received_data.size(), payload_buf, &payload_len);
|
|
258
|
-
if (err != rats::NoiseError::OK) {
|
|
259
|
-
LOG_CLIENT_ERROR("Failed to read Noise message 0: " << static_cast<int>(err));
|
|
260
|
-
return false;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Message 1: <- e, ee, s, es
|
|
264
|
-
message_len = sizeof(message_buf);
|
|
265
|
-
err = handshake.write_message(nullptr, 0, message_buf, &message_len);
|
|
266
|
-
if (err != rats::NoiseError::OK) {
|
|
267
|
-
LOG_CLIENT_ERROR("Failed to write Noise message 1");
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (!send_noise_message(socket, message_buf, message_len)) {
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
LOG_CLIENT_DEBUG("Sent Noise message 1 (e, ee, s, es) - " << message_len << " bytes");
|
|
275
|
-
|
|
276
|
-
// Receive message 2: -> s, se
|
|
277
|
-
if (!recv_noise_message(socket, received_data)) {
|
|
278
|
-
return false;
|
|
279
|
-
}
|
|
280
|
-
LOG_CLIENT_DEBUG("Received Noise message 2 - " << received_data.size() << " bytes");
|
|
281
|
-
|
|
282
|
-
payload_len = sizeof(payload_buf);
|
|
283
|
-
err = handshake.read_message(received_data.data(), received_data.size(), payload_buf, &payload_len);
|
|
284
|
-
if (err != rats::NoiseError::OK) {
|
|
285
|
-
LOG_CLIENT_ERROR("Failed to read Noise message 2: " << static_cast<int>(err));
|
|
286
|
-
return false;
|
|
287
|
-
}
|
|
158
|
+
// Enqueue as a length-prefixed frame (same framing as data messages)
|
|
159
|
+
std::vector<uint8_t> payload(msg_buf, msg_buf + msg_len);
|
|
160
|
+
enqueue_message_unlocked(peer, payload);
|
|
161
|
+
peer.io_.noise_step = 1; // next: need to read msg 1
|
|
162
|
+
LOG_CLIENT_DEBUG("Sent Noise msg 0 (" << msg_len << " bytes) to " << peer.peer_id);
|
|
288
163
|
}
|
|
164
|
+
// Responder waits for msg 0 from initiator (noise_step stays 0)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
bool RatsClient::handle_noise_frame(RatsPeer& peer) {
|
|
168
|
+
// The caller (handle_readable) has already verified that a complete
|
|
169
|
+
// length-prefixed frame is available in the receive buffer, but hasn't
|
|
170
|
+
// consumed it yet. We read the payload from recv_buf (skip 4-byte length).
|
|
171
|
+
auto& recv_buf = peer.io_.recv_buffer;
|
|
289
172
|
|
|
290
|
-
//
|
|
291
|
-
|
|
292
|
-
|
|
173
|
+
// Read payload length
|
|
174
|
+
uint32_t net_len;
|
|
175
|
+
memcpy(&net_len, recv_buf.data(), 4);
|
|
176
|
+
uint32_t frame_len = ntohl(net_len);
|
|
177
|
+
|
|
178
|
+
const uint8_t* frame_data = recv_buf.data() + 4;
|
|
179
|
+
|
|
180
|
+
if (!peer.io_.noise_hs) {
|
|
181
|
+
LOG_CLIENT_ERROR("Noise frame received but no handshake state for " << peer.peer_id);
|
|
293
182
|
return false;
|
|
294
183
|
}
|
|
295
184
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
185
|
+
auto& hs = *peer.io_.noise_hs;
|
|
186
|
+
bool is_initiator = peer.is_outgoing;
|
|
187
|
+
rats::NoiseError err;
|
|
188
|
+
uint8_t out_buf[256];
|
|
189
|
+
size_t out_len;
|
|
299
190
|
|
|
300
|
-
|
|
191
|
+
/*
|
|
192
|
+
* Step table (noise_step → action):
|
|
193
|
+
* Initiator: 0=write, 1=read, 2=write, 3=done
|
|
194
|
+
* Responder: 0=read, 1=write, 2=read, 3=done
|
|
195
|
+
*
|
|
196
|
+
* This function is only called when we received a frame, so the current
|
|
197
|
+
* step must expect a "read".
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
// ── Read the incoming Noise message ──
|
|
201
|
+
out_len = sizeof(out_buf);
|
|
202
|
+
err = hs.read_message(frame_data, frame_len, out_buf, &out_len);
|
|
301
203
|
if (err != rats::NoiseError::OK) {
|
|
302
|
-
LOG_CLIENT_ERROR("
|
|
204
|
+
LOG_CLIENT_ERROR("Noise read_message failed (step " << peer.io_.noise_step
|
|
205
|
+
<< "): " << static_cast<int>(err));
|
|
303
206
|
return false;
|
|
304
207
|
}
|
|
208
|
+
LOG_CLIENT_DEBUG("Read Noise msg (step " << peer.io_.noise_step
|
|
209
|
+
<< ", " << frame_len << " bytes) from " << peer.peer_id);
|
|
305
210
|
|
|
306
|
-
|
|
307
|
-
{
|
|
308
|
-
std::lock_guard<std::mutex> lock(peers_mutex_);
|
|
309
|
-
auto it = peers_.find(peer_id);
|
|
310
|
-
if (it == peers_.end()) {
|
|
311
|
-
// Try to find by socket
|
|
312
|
-
auto sock_it = socket_to_peer_id_.find(socket);
|
|
313
|
-
if (sock_it != socket_to_peer_id_.end()) {
|
|
314
|
-
it = peers_.find(sock_it->second);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (it != peers_.end()) {
|
|
319
|
-
it->second.send_cipher = std::move(send_cipher);
|
|
320
|
-
it->second.recv_cipher = std::move(recv_cipher);
|
|
321
|
-
it->second.noise_handshake_completed = true;
|
|
322
|
-
|
|
323
|
-
// Store remote static key
|
|
324
|
-
const uint8_t* remote_key = handshake.get_remote_static_public();
|
|
325
|
-
if (handshake.has_remote_static()) {
|
|
326
|
-
it->second.remote_static_key.assign(remote_key, remote_key + 32);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
LOG_CLIENT_INFO("Noise handshake completed with " << it->second.peer_id);
|
|
330
|
-
} else {
|
|
331
|
-
LOG_CLIENT_ERROR("Peer not found after Noise handshake: " << peer_id);
|
|
332
|
-
return false;
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// Reset socket timeout to infinite (0) for normal operation after handshake
|
|
337
|
-
#ifdef _WIN32
|
|
338
|
-
DWORD no_timeout = 0;
|
|
339
|
-
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&no_timeout), sizeof(no_timeout));
|
|
340
|
-
#else
|
|
341
|
-
struct timeval no_timeout;
|
|
342
|
-
no_timeout.tv_sec = 0;
|
|
343
|
-
no_timeout.tv_usec = 0;
|
|
344
|
-
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&no_timeout), sizeof(no_timeout));
|
|
345
|
-
#endif
|
|
211
|
+
peer.io_.noise_step++;
|
|
346
212
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
213
|
+
// ── If there's a reply to write, do it now ──
|
|
214
|
+
bool need_write = false;
|
|
215
|
+
if (is_initiator) {
|
|
216
|
+
// Initiator writes on steps 0 and 2 → after reading (step becomes 2), write
|
|
217
|
+
need_write = (peer.io_.noise_step == 2);
|
|
218
|
+
} else {
|
|
219
|
+
// Responder writes on step 1 → after reading (step becomes 1), write
|
|
220
|
+
need_write = (peer.io_.noise_step == 1);
|
|
221
|
+
}
|
|
352
222
|
|
|
353
|
-
{
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
223
|
+
if (need_write) {
|
|
224
|
+
out_len = sizeof(out_buf);
|
|
225
|
+
err = hs.write_message(nullptr, 0, out_buf, &out_len);
|
|
226
|
+
if (err != rats::NoiseError::OK) {
|
|
227
|
+
LOG_CLIENT_ERROR("Noise write_message failed (step " << peer.io_.noise_step
|
|
228
|
+
<< "): " << static_cast<int>(err));
|
|
229
|
+
return false;
|
|
361
230
|
}
|
|
362
231
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (!cipher) {
|
|
369
|
-
LOG_CLIENT_ERROR("No send cipher for peer: " << peer_id);
|
|
370
|
-
return false;
|
|
232
|
+
std::vector<uint8_t> payload(out_buf, out_buf + out_len);
|
|
233
|
+
enqueue_message_unlocked(peer, payload);
|
|
234
|
+
LOG_CLIENT_DEBUG("Sent Noise msg (step " << peer.io_.noise_step
|
|
235
|
+
<< ", " << out_len << " bytes) to " << peer.peer_id);
|
|
236
|
+
peer.io_.noise_step++;
|
|
371
237
|
}
|
|
372
238
|
|
|
373
|
-
//
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
// Send as framed message
|
|
384
|
-
return send_noise_message(socket, ciphertext.data(), ciphertext.size());
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
bool RatsClient::receive_and_decrypt(socket_t socket, const std::string& peer_id, std::vector<uint8_t>& plaintext) {
|
|
388
|
-
rats::NoiseCipherState* cipher = nullptr;
|
|
389
|
-
|
|
390
|
-
{
|
|
391
|
-
std::lock_guard<std::mutex> lock(peers_mutex_);
|
|
392
|
-
auto it = peers_.find(peer_id);
|
|
393
|
-
if (it == peers_.end()) {
|
|
394
|
-
auto sock_it = socket_to_peer_id_.find(socket);
|
|
395
|
-
if (sock_it != socket_to_peer_id_.end()) {
|
|
396
|
-
it = peers_.find(sock_it->second);
|
|
397
|
-
}
|
|
239
|
+
// ── Check if handshake is complete ──
|
|
240
|
+
if (hs.is_handshake_complete()) {
|
|
241
|
+
auto send_cipher = std::make_shared<rats::NoiseCipherState>();
|
|
242
|
+
auto recv_cipher = std::make_shared<rats::NoiseCipherState>();
|
|
243
|
+
|
|
244
|
+
err = hs.split(*send_cipher, *recv_cipher);
|
|
245
|
+
if (err != rats::NoiseError::OK) {
|
|
246
|
+
LOG_CLIENT_ERROR("Noise split failed: " << static_cast<int>(err));
|
|
247
|
+
return false;
|
|
398
248
|
}
|
|
399
249
|
|
|
400
|
-
|
|
401
|
-
|
|
250
|
+
// Store ciphers and remote static key
|
|
251
|
+
peer.send_cipher = std::move(send_cipher);
|
|
252
|
+
peer.recv_cipher = std::move(recv_cipher);
|
|
253
|
+
peer.noise_handshake_completed = true;
|
|
254
|
+
|
|
255
|
+
if (hs.has_remote_static()) {
|
|
256
|
+
const uint8_t* remote_key = hs.get_remote_static_public();
|
|
257
|
+
peer.remote_static_key.assign(remote_key, remote_key + 32);
|
|
402
258
|
}
|
|
259
|
+
|
|
260
|
+
// Free handshake state (no longer needed)
|
|
261
|
+
peer.io_.noise_hs.reset();
|
|
262
|
+
peer.io_.noise_step = 0;
|
|
263
|
+
|
|
264
|
+
// Mark handshake completed
|
|
265
|
+
peer.handshake_state = RatsPeer::HandshakeState::COMPLETED;
|
|
266
|
+
validated_peer_count_.fetch_add(1, std::memory_order_relaxed);
|
|
267
|
+
log_handshake_completion_unlocked(peer);
|
|
268
|
+
|
|
269
|
+
LOG_CLIENT_INFO("Noise handshake completed with " << peer.peer_id);
|
|
403
270
|
}
|
|
404
271
|
|
|
405
|
-
if (!cipher) {
|
|
406
|
-
LOG_CLIENT_ERROR("No recv cipher for peer: " << peer_id);
|
|
407
|
-
return false;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Receive ciphertext
|
|
411
|
-
std::vector<uint8_t> ciphertext;
|
|
412
|
-
if (!recv_noise_message(socket, ciphertext)) {
|
|
413
|
-
return false;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
// Decrypt
|
|
417
|
-
plaintext.resize(ciphertext.size());
|
|
418
|
-
size_t pt_len = cipher->decrypt_with_ad(nullptr, 0, ciphertext.data(), ciphertext.size(), plaintext.data());
|
|
419
|
-
if (pt_len == 0) {
|
|
420
|
-
LOG_CLIENT_ERROR("Decryption failed for peer: " << peer_id);
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
plaintext.resize(pt_len);
|
|
425
272
|
return true;
|
|
426
273
|
}
|
|
427
274
|
|
|
@@ -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
|
|
|
@@ -141,7 +137,7 @@ void RatsClient::set_file_transfer_config(const FileTransferConfig& config) {
|
|
|
141
137
|
file_transfer_manager_->set_config(config);
|
|
142
138
|
}
|
|
143
139
|
|
|
144
|
-
|
|
140
|
+
FileTransferConfig RatsClient::get_file_transfer_config() const {
|
|
145
141
|
if (!is_file_transfer_available()) {
|
|
146
142
|
throw std::runtime_error("File transfer manager not available");
|
|
147
143
|
}
|
|
@@ -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
|
|
|
@@ -183,7 +183,7 @@ void RatsClient::set_ice_config(const IceConfig& config) {
|
|
|
183
183
|
get_ice_manager().set_config(config);
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
-
|
|
186
|
+
IceConfig RatsClient::get_ice_config() const {
|
|
187
187
|
// Need to cast away const to get mutable reference for lazy initialization
|
|
188
188
|
return const_cast<RatsClient*>(this)->get_ice_manager().config();
|
|
189
189
|
}
|
|
@@ -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
|
}
|