librats 0.3.1 → 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.
- package/README.md +405 -405
- package/binding.gyp +96 -95
- package/lib/index.d.ts +522 -522
- package/lib/index.js +82 -82
- package/native-src/3rdparty/android/ifaddrs-android.c +600 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +54 -0
- package/native-src/CMakeLists.txt +360 -0
- package/native-src/LICENSE +21 -0
- package/native-src/src/bencode.cpp +485 -0
- package/native-src/src/bencode.h +145 -0
- package/native-src/src/bittorrent.cpp +3682 -0
- package/native-src/src/bittorrent.h +731 -0
- package/native-src/src/dht.cpp +2342 -0
- package/native-src/src/dht.h +501 -0
- package/native-src/src/encrypted_socket.cpp +817 -0
- package/native-src/src/encrypted_socket.h +239 -0
- package/native-src/src/file_transfer.cpp +1808 -0
- package/native-src/src/file_transfer.h +567 -0
- package/native-src/src/fs.cpp +639 -0
- package/native-src/src/fs.h +108 -0
- package/native-src/src/gossipsub.cpp +1137 -0
- package/native-src/src/gossipsub.h +403 -0
- package/native-src/src/ice.cpp +1386 -0
- package/native-src/src/ice.h +328 -0
- package/native-src/src/json.hpp +25526 -0
- package/native-src/src/krpc.cpp +558 -0
- package/native-src/src/krpc.h +145 -0
- package/native-src/src/librats.cpp +2715 -0
- package/native-src/src/librats.h +1729 -0
- package/native-src/src/librats_bittorrent.cpp +167 -0
- package/native-src/src/librats_c.cpp +1317 -0
- package/native-src/src/librats_c.h +237 -0
- package/native-src/src/librats_encryption.cpp +123 -0
- package/native-src/src/librats_file_transfer.cpp +226 -0
- package/native-src/src/librats_gossipsub.cpp +293 -0
- package/native-src/src/librats_ice.cpp +515 -0
- package/native-src/src/librats_logging.cpp +158 -0
- package/native-src/src/librats_mdns.cpp +171 -0
- package/native-src/src/librats_nat.cpp +571 -0
- package/native-src/src/librats_persistence.cpp +815 -0
- package/native-src/src/logger.h +412 -0
- package/native-src/src/mdns.cpp +1178 -0
- package/native-src/src/mdns.h +253 -0
- package/native-src/src/network_utils.cpp +598 -0
- package/native-src/src/network_utils.h +162 -0
- package/native-src/src/noise.cpp +981 -0
- package/native-src/src/noise.h +227 -0
- package/native-src/src/os.cpp +371 -0
- package/native-src/src/os.h +40 -0
- package/native-src/src/rats_export.h +17 -0
- package/native-src/src/sha1.cpp +163 -0
- package/native-src/src/sha1.h +42 -0
- package/native-src/src/socket.cpp +1376 -0
- package/native-src/src/socket.h +309 -0
- package/native-src/src/stun.cpp +484 -0
- package/native-src/src/stun.h +349 -0
- package/native-src/src/threadmanager.cpp +105 -0
- package/native-src/src/threadmanager.h +53 -0
- package/native-src/src/tracker.cpp +1110 -0
- package/native-src/src/tracker.h +268 -0
- package/native-src/src/version.cpp +24 -0
- package/native-src/src/version.h.in +45 -0
- package/native-src/version.rc.in +31 -0
- package/package.json +62 -68
- package/scripts/build-librats.js +241 -194
- package/scripts/postinstall.js +52 -52
- package/scripts/prepare-package.js +187 -91
- package/scripts/verify-installation.js +119 -119
- package/src/librats_node.cpp +1174 -1174
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "socket.h"
|
|
4
|
+
#include "json.hpp"
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <functional>
|
|
8
|
+
#include <memory>
|
|
9
|
+
#include <mutex>
|
|
10
|
+
#include <unordered_map>
|
|
11
|
+
#include <atomic>
|
|
12
|
+
#include <chrono>
|
|
13
|
+
#include <thread>
|
|
14
|
+
#include <queue>
|
|
15
|
+
#include <condition_variable>
|
|
16
|
+
|
|
17
|
+
namespace librats {
|
|
18
|
+
|
|
19
|
+
// Forward declaration
|
|
20
|
+
class RatsClient;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* File transfer status codes
|
|
24
|
+
*/
|
|
25
|
+
enum class FileTransferStatus {
|
|
26
|
+
PENDING, // Transfer queued but not started
|
|
27
|
+
STARTING, // Transfer initialization in progress
|
|
28
|
+
IN_PROGRESS, // Transfer actively sending/receiving chunks
|
|
29
|
+
PAUSED, // Transfer temporarily paused
|
|
30
|
+
COMPLETED, // Transfer completed successfully
|
|
31
|
+
FAILED, // Transfer failed due to error
|
|
32
|
+
CANCELLED, // Transfer cancelled by user
|
|
33
|
+
RESUMING // Transfer resuming from interruption
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* File transfer direction
|
|
38
|
+
*/
|
|
39
|
+
enum class FileTransferDirection {
|
|
40
|
+
SENDING, // We are sending the file
|
|
41
|
+
RECEIVING // We are receiving the file
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Note: Compression removed as requested - only binary chunks needed
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* File transfer chunk information
|
|
48
|
+
*/
|
|
49
|
+
struct FileChunk {
|
|
50
|
+
std::string transfer_id; // Unique transfer identifier
|
|
51
|
+
uint64_t chunk_index; // Sequential chunk number (0-based)
|
|
52
|
+
uint64_t total_chunks; // Total number of chunks in transfer
|
|
53
|
+
uint64_t chunk_size; // Size of this specific chunk
|
|
54
|
+
uint64_t file_offset; // Offset in the original file
|
|
55
|
+
std::vector<uint8_t> data; // Chunk data payload
|
|
56
|
+
std::string checksum; // SHA256 checksum of chunk data
|
|
57
|
+
|
|
58
|
+
FileChunk() : chunk_index(0), total_chunks(0), chunk_size(0),
|
|
59
|
+
file_offset(0) {}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* File metadata for transfers
|
|
64
|
+
*/
|
|
65
|
+
struct FileMetadata {
|
|
66
|
+
std::string filename; // Original filename
|
|
67
|
+
std::string relative_path; // Relative path within directory structure
|
|
68
|
+
uint64_t file_size; // Total file size in bytes
|
|
69
|
+
uint64_t last_modified; // Last modification timestamp
|
|
70
|
+
std::string mime_type; // MIME type of the file
|
|
71
|
+
std::string checksum; // Full file checksum
|
|
72
|
+
|
|
73
|
+
FileMetadata() : file_size(0), last_modified(0) {}
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Directory transfer metadata
|
|
78
|
+
*/
|
|
79
|
+
struct DirectoryMetadata {
|
|
80
|
+
std::string directory_name; // Directory name
|
|
81
|
+
std::string relative_path; // Relative path
|
|
82
|
+
std::vector<FileMetadata> files; // Files in this directory level
|
|
83
|
+
std::vector<DirectoryMetadata> subdirectories; // Nested directories
|
|
84
|
+
|
|
85
|
+
// Calculate total transfer size
|
|
86
|
+
uint64_t get_total_size() const;
|
|
87
|
+
|
|
88
|
+
// Get total file count
|
|
89
|
+
size_t get_total_file_count() const;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* File transfer progress information
|
|
94
|
+
*/
|
|
95
|
+
struct FileTransferProgress {
|
|
96
|
+
std::string transfer_id; // Transfer identifier
|
|
97
|
+
std::string peer_id; // Peer we're transferring with
|
|
98
|
+
FileTransferDirection direction; // Send or receive
|
|
99
|
+
FileTransferStatus status; // Current status
|
|
100
|
+
|
|
101
|
+
// File information
|
|
102
|
+
std::string filename; // File being transferred
|
|
103
|
+
std::string local_path; // Local file path
|
|
104
|
+
uint64_t file_size; // Total file size
|
|
105
|
+
|
|
106
|
+
// Progress tracking
|
|
107
|
+
uint64_t bytes_transferred; // Bytes completed
|
|
108
|
+
uint64_t total_bytes; // Total bytes to transfer
|
|
109
|
+
uint32_t chunks_completed; // Chunks successfully transferred
|
|
110
|
+
uint32_t total_chunks; // Total chunks in transfer
|
|
111
|
+
|
|
112
|
+
// Performance metrics
|
|
113
|
+
std::chrono::steady_clock::time_point start_time; // Transfer start time
|
|
114
|
+
std::chrono::steady_clock::time_point last_update; // Last progress update
|
|
115
|
+
double transfer_rate_bps; // Current transfer rate (bytes/second)
|
|
116
|
+
double average_rate_bps; // Average transfer rate since start
|
|
117
|
+
std::chrono::milliseconds estimated_time_remaining; // ETA
|
|
118
|
+
|
|
119
|
+
// Error information
|
|
120
|
+
std::string error_message; // Error details if failed
|
|
121
|
+
uint32_t retry_count; // Number of retries attempted
|
|
122
|
+
|
|
123
|
+
FileTransferProgress() : direction(FileTransferDirection::SENDING),
|
|
124
|
+
status(FileTransferStatus::PENDING),
|
|
125
|
+
file_size(0), bytes_transferred(0), total_bytes(0),
|
|
126
|
+
chunks_completed(0), total_chunks(0),
|
|
127
|
+
transfer_rate_bps(0.0), average_rate_bps(0.0),
|
|
128
|
+
retry_count(0) {
|
|
129
|
+
start_time = std::chrono::steady_clock::now();
|
|
130
|
+
last_update = start_time;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Calculate completion percentage (0.0 to 100.0)
|
|
134
|
+
double get_completion_percentage() const {
|
|
135
|
+
if (total_bytes == 0) return 0.0;
|
|
136
|
+
return (static_cast<double>(bytes_transferred) / total_bytes) * 100.0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Calculate elapsed time
|
|
140
|
+
std::chrono::milliseconds get_elapsed_time() const {
|
|
141
|
+
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
142
|
+
std::chrono::steady_clock::now() - start_time);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Update transfer rate calculations
|
|
146
|
+
void update_transfer_rates(uint64_t new_bytes_transferred);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* File transfer configuration
|
|
151
|
+
*/
|
|
152
|
+
struct FileTransferConfig {
|
|
153
|
+
uint32_t chunk_size; // Size of each chunk (default: 64KB)
|
|
154
|
+
uint32_t max_concurrent_chunks; // Max chunks in flight (default: 4)
|
|
155
|
+
uint32_t max_retries; // Max retry attempts per chunk (default: 3)
|
|
156
|
+
uint32_t timeout_seconds; // Timeout per chunk (default: 30)
|
|
157
|
+
bool verify_checksums; // Verify chunk checksums (default: true)
|
|
158
|
+
bool allow_resume; // Allow resuming interrupted transfers (default: true)
|
|
159
|
+
std::string temp_directory; // Temporary directory for incomplete files
|
|
160
|
+
|
|
161
|
+
FileTransferConfig()
|
|
162
|
+
: chunk_size(65536), // 64KB chunks
|
|
163
|
+
max_concurrent_chunks(4),
|
|
164
|
+
max_retries(3),
|
|
165
|
+
timeout_seconds(30),
|
|
166
|
+
verify_checksums(true),
|
|
167
|
+
allow_resume(true),
|
|
168
|
+
temp_directory("./temp_transfers") {}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Callback function types for file transfer events
|
|
173
|
+
*/
|
|
174
|
+
using FileTransferProgressCallback = std::function<void(const FileTransferProgress&)>;
|
|
175
|
+
using FileTransferCompletedCallback = std::function<void(const std::string& transfer_id, bool success, const std::string& error_message)>;
|
|
176
|
+
using FileTransferRequestCallback = std::function<bool(const std::string& peer_id, const FileMetadata& metadata, const std::string& transfer_id)>;
|
|
177
|
+
using DirectoryTransferProgressCallback = std::function<void(const std::string& transfer_id, const std::string& current_file, uint64_t files_completed, uint64_t total_files, uint64_t bytes_completed, uint64_t total_bytes)>;
|
|
178
|
+
using FileRequestCallback = std::function<bool(const std::string& peer_id, const std::string& file_path, const std::string& transfer_id)>;
|
|
179
|
+
using DirectoryRequestCallback = std::function<bool(const std::string& peer_id, const std::string& directory_path, bool recursive, const std::string& transfer_id)>;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* File transfer manager class
|
|
183
|
+
* Handles efficient chunked file transfers with resume capability
|
|
184
|
+
*/
|
|
185
|
+
class FileTransferManager {
|
|
186
|
+
public:
|
|
187
|
+
/**
|
|
188
|
+
* Constructor
|
|
189
|
+
* @param client Reference to RatsClient for communication
|
|
190
|
+
* @param config Transfer configuration settings
|
|
191
|
+
*/
|
|
192
|
+
FileTransferManager(RatsClient& client, const FileTransferConfig& config = FileTransferConfig());
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Destructor
|
|
196
|
+
*/
|
|
197
|
+
~FileTransferManager();
|
|
198
|
+
|
|
199
|
+
// Configuration
|
|
200
|
+
/**
|
|
201
|
+
* Update transfer configuration
|
|
202
|
+
* @param config New configuration settings
|
|
203
|
+
*/
|
|
204
|
+
void set_config(const FileTransferConfig& config);
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Get current configuration
|
|
208
|
+
* @return Current configuration settings
|
|
209
|
+
*/
|
|
210
|
+
const FileTransferConfig& get_config() const;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Handle binary data that might be file transfer chunks
|
|
214
|
+
* @param peer_id Source peer ID
|
|
215
|
+
* @param binary_data Binary data received
|
|
216
|
+
* @return true if this was a file transfer chunk, false otherwise
|
|
217
|
+
*/
|
|
218
|
+
bool handle_binary_data(const std::string& peer_id, const std::vector<uint8_t>& binary_data);
|
|
219
|
+
|
|
220
|
+
// Callback registration
|
|
221
|
+
/**
|
|
222
|
+
* Set progress callback for transfer updates
|
|
223
|
+
* @param callback Function to call with progress updates
|
|
224
|
+
*/
|
|
225
|
+
void set_progress_callback(FileTransferProgressCallback callback);
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Set completion callback for transfer completion
|
|
229
|
+
* @param callback Function to call when transfers complete
|
|
230
|
+
*/
|
|
231
|
+
void set_completion_callback(FileTransferCompletedCallback callback);
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Set incoming transfer request callback
|
|
235
|
+
* @param callback Function to call when receiving transfer requests
|
|
236
|
+
*/
|
|
237
|
+
void set_request_callback(FileTransferRequestCallback callback);
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Set directory transfer progress callback
|
|
241
|
+
* @param callback Function to call with directory transfer progress
|
|
242
|
+
*/
|
|
243
|
+
void set_directory_progress_callback(DirectoryTransferProgressCallback callback);
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Set file request callback (called when receiving file requests)
|
|
247
|
+
* @param callback Function to call when receiving file requests
|
|
248
|
+
*/
|
|
249
|
+
void set_file_request_callback(FileRequestCallback callback);
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Set directory request callback (called when receiving directory requests)
|
|
253
|
+
* @param callback Function to call when receiving directory requests
|
|
254
|
+
*/
|
|
255
|
+
void set_directory_request_callback(DirectoryRequestCallback callback);
|
|
256
|
+
|
|
257
|
+
// File transfer operations
|
|
258
|
+
/**
|
|
259
|
+
* Send a file to a peer
|
|
260
|
+
* @param peer_id Target peer ID
|
|
261
|
+
* @param file_path Local file path to send
|
|
262
|
+
* @param remote_filename Optional remote filename (default: use local name)
|
|
263
|
+
* @return Transfer ID if successful, empty string if failed
|
|
264
|
+
*/
|
|
265
|
+
std::string send_file(const std::string& peer_id, const std::string& file_path,
|
|
266
|
+
const std::string& remote_filename = "");
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Send a file with custom metadata
|
|
270
|
+
* @param peer_id Target peer ID
|
|
271
|
+
* @param file_path Local file path to send
|
|
272
|
+
* @param metadata Custom file metadata
|
|
273
|
+
* @return Transfer ID if successful, empty string if failed
|
|
274
|
+
*/
|
|
275
|
+
std::string send_file_with_metadata(const std::string& peer_id, const std::string& file_path,
|
|
276
|
+
const FileMetadata& metadata);
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Send an entire directory to a peer
|
|
280
|
+
* @param peer_id Target peer ID
|
|
281
|
+
* @param directory_path Local directory path to send
|
|
282
|
+
* @param remote_directory_name Optional remote directory name
|
|
283
|
+
* @param recursive Whether to include subdirectories (default: true)
|
|
284
|
+
* @return Transfer ID if successful, empty string if failed
|
|
285
|
+
*/
|
|
286
|
+
std::string send_directory(const std::string& peer_id, const std::string& directory_path,
|
|
287
|
+
const std::string& remote_directory_name = "", bool recursive = true);
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Request a file from a remote peer
|
|
291
|
+
* @param peer_id Target peer ID
|
|
292
|
+
* @param remote_file_path Path to file on remote peer
|
|
293
|
+
* @param local_path Local path where file should be saved
|
|
294
|
+
* @return Transfer ID if successful, empty string if failed
|
|
295
|
+
*/
|
|
296
|
+
std::string request_file(const std::string& peer_id, const std::string& remote_file_path,
|
|
297
|
+
const std::string& local_path);
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Request a directory from a remote peer
|
|
301
|
+
* @param peer_id Target peer ID
|
|
302
|
+
* @param remote_directory_path Path to directory on remote peer
|
|
303
|
+
* @param local_directory_path Local path where directory should be saved
|
|
304
|
+
* @param recursive Whether to include subdirectories (default: true)
|
|
305
|
+
* @return Transfer ID if successful, empty string if failed
|
|
306
|
+
*/
|
|
307
|
+
std::string request_directory(const std::string& peer_id, const std::string& remote_directory_path,
|
|
308
|
+
const std::string& local_directory_path, bool recursive = true);
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Accept an incoming file transfer
|
|
312
|
+
* @param transfer_id Transfer identifier from request
|
|
313
|
+
* @param local_path Local path where file should be saved
|
|
314
|
+
* @return true if accepted successfully
|
|
315
|
+
*/
|
|
316
|
+
bool accept_file_transfer(const std::string& transfer_id, const std::string& local_path);
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Reject an incoming file transfer
|
|
320
|
+
* @param transfer_id Transfer identifier from request
|
|
321
|
+
* @param reason Optional reason for rejection
|
|
322
|
+
* @return true if rejected successfully
|
|
323
|
+
*/
|
|
324
|
+
bool reject_file_transfer(const std::string& transfer_id, const std::string& reason = "");
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Accept an incoming directory transfer
|
|
328
|
+
* @param transfer_id Transfer identifier from request
|
|
329
|
+
* @param local_path Local path where directory should be saved
|
|
330
|
+
* @return true if accepted successfully
|
|
331
|
+
*/
|
|
332
|
+
bool accept_directory_transfer(const std::string& transfer_id, const std::string& local_path);
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Reject an incoming directory transfer
|
|
336
|
+
* @param transfer_id Transfer identifier from request
|
|
337
|
+
* @param reason Optional reason for rejection
|
|
338
|
+
* @return true if rejected successfully
|
|
339
|
+
*/
|
|
340
|
+
bool reject_directory_transfer(const std::string& transfer_id, const std::string& reason = "");
|
|
341
|
+
|
|
342
|
+
// Transfer control
|
|
343
|
+
/**
|
|
344
|
+
* Pause an active transfer
|
|
345
|
+
* @param transfer_id Transfer to pause
|
|
346
|
+
* @return true if paused successfully
|
|
347
|
+
*/
|
|
348
|
+
bool pause_transfer(const std::string& transfer_id);
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Resume a paused transfer
|
|
352
|
+
* @param transfer_id Transfer to resume
|
|
353
|
+
* @return true if resumed successfully
|
|
354
|
+
*/
|
|
355
|
+
bool resume_transfer(const std::string& transfer_id);
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Cancel an active or paused transfer
|
|
359
|
+
* @param transfer_id Transfer to cancel
|
|
360
|
+
* @return true if cancelled successfully
|
|
361
|
+
*/
|
|
362
|
+
bool cancel_transfer(const std::string& transfer_id);
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Retry a failed transfer
|
|
366
|
+
* @param transfer_id Transfer to retry
|
|
367
|
+
* @return true if retry initiated successfully
|
|
368
|
+
*/
|
|
369
|
+
bool retry_transfer(const std::string& transfer_id);
|
|
370
|
+
|
|
371
|
+
// Information and monitoring
|
|
372
|
+
/**
|
|
373
|
+
* Get progress information for a transfer
|
|
374
|
+
* @param transfer_id Transfer to query
|
|
375
|
+
* @return Progress information or nullptr if not found
|
|
376
|
+
*/
|
|
377
|
+
std::shared_ptr<FileTransferProgress> get_transfer_progress(const std::string& transfer_id) const;
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get all active transfers
|
|
381
|
+
* @return Vector of transfer progress objects
|
|
382
|
+
*/
|
|
383
|
+
std::vector<std::shared_ptr<FileTransferProgress>> get_active_transfers() const;
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Get transfer history
|
|
387
|
+
* @param limit Maximum number of entries to return (0 for all)
|
|
388
|
+
* @return Vector of completed transfer progress objects
|
|
389
|
+
*/
|
|
390
|
+
std::vector<std::shared_ptr<FileTransferProgress>> get_transfer_history(size_t limit = 0) const;
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Clear transfer history
|
|
394
|
+
*/
|
|
395
|
+
void clear_transfer_history();
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Get statistics about transfers
|
|
399
|
+
* @return JSON object with transfer statistics
|
|
400
|
+
*/
|
|
401
|
+
nlohmann::json get_transfer_statistics() const;
|
|
402
|
+
|
|
403
|
+
// Utility functions
|
|
404
|
+
/**
|
|
405
|
+
* Calculate file checksum
|
|
406
|
+
* @param file_path Path to file
|
|
407
|
+
* @param algorithm Hash algorithm ("md5", "sha256")
|
|
408
|
+
* @return Checksum string or empty if failed
|
|
409
|
+
*/
|
|
410
|
+
static std::string calculate_file_checksum(const std::string& file_path, const std::string& algorithm = "sha256");
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Get file metadata
|
|
414
|
+
* @param file_path Path to file
|
|
415
|
+
* @return File metadata structure
|
|
416
|
+
*/
|
|
417
|
+
static FileMetadata get_file_metadata(const std::string& file_path);
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Get directory metadata
|
|
421
|
+
* @param directory_path Path to directory
|
|
422
|
+
* @param recursive Whether to scan recursively
|
|
423
|
+
* @return Directory metadata structure
|
|
424
|
+
*/
|
|
425
|
+
static DirectoryMetadata get_directory_metadata(const std::string& directory_path, bool recursive = true);
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Validate file path and permissions
|
|
429
|
+
* @param file_path Path to validate
|
|
430
|
+
* @param check_write Whether to check write permissions
|
|
431
|
+
* @return true if valid and accessible
|
|
432
|
+
*/
|
|
433
|
+
static bool validate_file_path(const std::string& file_path, bool check_write = false);
|
|
434
|
+
|
|
435
|
+
private:
|
|
436
|
+
RatsClient& client_;
|
|
437
|
+
FileTransferConfig config_;
|
|
438
|
+
|
|
439
|
+
// Transfer tracking
|
|
440
|
+
mutable std::mutex transfers_mutex_;
|
|
441
|
+
std::unordered_map<std::string, std::shared_ptr<FileTransferProgress>> active_transfers_;
|
|
442
|
+
std::unordered_map<std::string, std::shared_ptr<FileTransferProgress>> completed_transfers_;
|
|
443
|
+
|
|
444
|
+
// Pending transfers (not yet accepted/rejected)
|
|
445
|
+
mutable std::mutex pending_mutex_;
|
|
446
|
+
struct PendingFileTransfer {
|
|
447
|
+
FileMetadata metadata;
|
|
448
|
+
std::string peer_id;
|
|
449
|
+
};
|
|
450
|
+
struct PendingDirectoryTransfer {
|
|
451
|
+
DirectoryMetadata metadata;
|
|
452
|
+
std::string peer_id;
|
|
453
|
+
};
|
|
454
|
+
std::unordered_map<std::string, PendingFileTransfer> pending_transfers_;
|
|
455
|
+
std::unordered_map<std::string, PendingDirectoryTransfer> pending_directory_transfers_;
|
|
456
|
+
|
|
457
|
+
// Active directory transfers
|
|
458
|
+
mutable std::mutex directory_transfers_mutex_;
|
|
459
|
+
std::unordered_map<std::string, DirectoryMetadata> active_directory_transfers_;
|
|
460
|
+
|
|
461
|
+
// Chunk management
|
|
462
|
+
mutable std::mutex chunks_mutex_;
|
|
463
|
+
std::unordered_map<std::string, std::queue<FileChunk>> outgoing_chunks_;
|
|
464
|
+
std::unordered_map<std::string, std::unordered_map<uint64_t, FileChunk>> received_chunks_;
|
|
465
|
+
|
|
466
|
+
// Active chunk transfers waiting for binary data
|
|
467
|
+
struct PendingChunk {
|
|
468
|
+
std::string transfer_id;
|
|
469
|
+
uint64_t chunk_index;
|
|
470
|
+
uint64_t total_chunks;
|
|
471
|
+
uint64_t chunk_size;
|
|
472
|
+
uint64_t file_offset;
|
|
473
|
+
std::string checksum;
|
|
474
|
+
std::chrono::steady_clock::time_point created_at;
|
|
475
|
+
};
|
|
476
|
+
std::unordered_map<std::string, PendingChunk> pending_chunks_; // key: peer_id
|
|
477
|
+
|
|
478
|
+
// Worker threads
|
|
479
|
+
std::vector<std::thread> worker_threads_;
|
|
480
|
+
std::atomic<bool> running_;
|
|
481
|
+
std::condition_variable work_condition_;
|
|
482
|
+
std::mutex work_mutex_;
|
|
483
|
+
std::queue<std::string> work_queue_; // Transfer IDs that need processing
|
|
484
|
+
|
|
485
|
+
// Cleanup thread synchronization
|
|
486
|
+
std::condition_variable cleanup_condition_;
|
|
487
|
+
std::mutex cleanup_mutex_;
|
|
488
|
+
|
|
489
|
+
// Throttling synchronization
|
|
490
|
+
std::condition_variable throttle_condition_;
|
|
491
|
+
std::mutex throttle_mutex_;
|
|
492
|
+
|
|
493
|
+
// Callbacks
|
|
494
|
+
FileTransferProgressCallback progress_callback_;
|
|
495
|
+
FileTransferCompletedCallback completion_callback_;
|
|
496
|
+
FileTransferRequestCallback request_callback_;
|
|
497
|
+
DirectoryTransferProgressCallback directory_progress_callback_;
|
|
498
|
+
FileRequestCallback file_request_callback_;
|
|
499
|
+
DirectoryRequestCallback directory_request_callback_;
|
|
500
|
+
|
|
501
|
+
// Statistics
|
|
502
|
+
mutable std::mutex stats_mutex_;
|
|
503
|
+
uint64_t total_bytes_sent_;
|
|
504
|
+
uint64_t total_bytes_received_;
|
|
505
|
+
uint64_t total_files_sent_;
|
|
506
|
+
uint64_t total_files_received_;
|
|
507
|
+
std::chrono::steady_clock::time_point start_time_;
|
|
508
|
+
|
|
509
|
+
// Private methods
|
|
510
|
+
void initialize();
|
|
511
|
+
void shutdown();
|
|
512
|
+
void worker_thread_loop();
|
|
513
|
+
void cleanup_thread_loop();
|
|
514
|
+
void process_transfer(const std::string& transfer_id);
|
|
515
|
+
|
|
516
|
+
// Transfer management
|
|
517
|
+
std::string generate_transfer_id() const;
|
|
518
|
+
void start_file_send(const std::string& transfer_id);
|
|
519
|
+
void start_file_receive(const std::string& transfer_id);
|
|
520
|
+
void start_directory_send(const std::string& transfer_id);
|
|
521
|
+
void start_directory_receive(const std::string& transfer_id);
|
|
522
|
+
void handle_chunk_received(const FileChunk& chunk);
|
|
523
|
+
void handle_chunk_ack(const std::string& transfer_id, uint64_t chunk_index, bool success);
|
|
524
|
+
|
|
525
|
+
// File operations
|
|
526
|
+
bool create_temp_file(const std::string& transfer_id, uint64_t file_size);
|
|
527
|
+
bool finalize_received_file(const std::string& transfer_id, const std::string& final_path);
|
|
528
|
+
|
|
529
|
+
// Checksum validation
|
|
530
|
+
bool verify_chunk_checksum(const FileChunk& chunk);
|
|
531
|
+
std::string calculate_chunk_checksum(const std::vector<uint8_t>& data);
|
|
532
|
+
|
|
533
|
+
// Network message handling
|
|
534
|
+
void handle_transfer_request(const std::string& peer_id, const nlohmann::json& message);
|
|
535
|
+
void handle_transfer_response(const std::string& peer_id, const nlohmann::json& message);
|
|
536
|
+
void handle_chunk_metadata_message(const std::string& peer_id, const nlohmann::json& message);
|
|
537
|
+
void handle_chunk_binary_message(const std::string& peer_id, const std::vector<uint8_t>& binary_data);
|
|
538
|
+
void handle_chunk_ack_message(const std::string& peer_id, const nlohmann::json& message);
|
|
539
|
+
void handle_transfer_control(const std::string& peer_id, const nlohmann::json& message);
|
|
540
|
+
void handle_file_request(const std::string& peer_id, const nlohmann::json& message);
|
|
541
|
+
void handle_directory_request(const std::string& peer_id, const nlohmann::json& message);
|
|
542
|
+
|
|
543
|
+
// Message creation
|
|
544
|
+
nlohmann::json create_transfer_request_message(const FileMetadata& metadata, const std::string& transfer_id);
|
|
545
|
+
nlohmann::json create_transfer_response_message(const std::string& transfer_id, bool accepted, const std::string& reason = "");
|
|
546
|
+
std::vector<uint8_t> create_chunk_binary_message(const FileChunk& chunk);
|
|
547
|
+
nlohmann::json create_chunk_metadata_message(const FileChunk& chunk);
|
|
548
|
+
nlohmann::json create_chunk_ack_message(const std::string& transfer_id, uint64_t chunk_index, bool success, const std::string& error = "");
|
|
549
|
+
nlohmann::json create_control_message(const std::string& transfer_id, const std::string& action, const nlohmann::json& data = nlohmann::json::object());
|
|
550
|
+
|
|
551
|
+
// Progress tracking
|
|
552
|
+
void update_transfer_progress(const std::string& transfer_id, uint64_t bytes_delta = 0);
|
|
553
|
+
void complete_transfer(const std::string& transfer_id, bool success, const std::string& error_message = "");
|
|
554
|
+
void move_to_completed(const std::string& transfer_id);
|
|
555
|
+
|
|
556
|
+
// File system utilities
|
|
557
|
+
static bool ensure_directory_exists(const std::string& directory_path);
|
|
558
|
+
static std::string get_temp_file_path(const std::string& transfer_id, const std::string& temp_dir);
|
|
559
|
+
static std::string extract_filename(const std::string& file_path);
|
|
560
|
+
static std::string get_mime_type(const std::string& file_path);
|
|
561
|
+
|
|
562
|
+
// Binary chunk transmission helper
|
|
563
|
+
bool parse_chunk_binary_header(const std::vector<uint8_t>& binary_data, FileChunk& chunk);
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
} // namespace librats
|
|
567
|
+
|