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.
- package/native-src/CMakeLists.txt +15 -2
- package/native-src/src/bt_client.cpp +18 -5
- package/native-src/src/bt_client.h +3 -1
- package/native-src/src/bt_network.cpp +297 -184
- package/native-src/src/bt_network.h +25 -5
- package/native-src/src/bt_peer_connection.cpp +11 -0
- package/native-src/src/bt_peer_connection.h +6 -0
- package/native-src/src/bt_torrent.cpp +17 -6
- package/native-src/src/bt_torrent.h +1 -0
- package/native-src/src/bt_types.h +287 -20
- package/native-src/src/dht.cpp +26 -8
- package/native-src/src/dht.h +1 -1
- package/native-src/src/ice.cpp +1 -1
- package/native-src/src/io_poller.cpp +910 -0
- package/native-src/src/io_poller.h +138 -0
- package/native-src/src/krpc.cpp +8 -1
- package/native-src/src/krpc.h +3 -2
- package/native-src/src/librats.cpp +824 -1213
- package/native-src/src/librats.h +167 -54
- package/native-src/src/librats_bittorrent.cpp +4 -7
- package/native-src/src/librats_c.cpp +13 -1
- package/native-src/src/librats_c.h +2 -0
- 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 +10 -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/native-src/src/logger.h +40 -4
- package/native-src/src/network_utils.cpp +175 -373
- package/native-src/src/network_utils.h +2 -113
- package/native-src/src/socket.cpp +485 -883
- package/native-src/src/socket.h +36 -130
- package/native-src/src/stun.cpp +3 -5
- package/native-src/src/tracker.cpp +3 -2
- package/native-src/src/turn.cpp +4 -6
- package/package.json +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file io_poller.h
|
|
5
|
+
* @brief Platform-optimal I/O multiplexing abstraction
|
|
6
|
+
*
|
|
7
|
+
* Provides a unified interface over platform-specific I/O multiplexers:
|
|
8
|
+
* - Linux: epoll (O(1) per event, scales to millions of fds)
|
|
9
|
+
* - macOS/BSD: kqueue (O(1) per event, scales to millions of fds)
|
|
10
|
+
* - Windows: IOCP (true async completion ports, O(1) per event)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* auto poller = IOPoller::create();
|
|
14
|
+
* poller->add(fd, PollIn);
|
|
15
|
+
*
|
|
16
|
+
* PollResult results[64];
|
|
17
|
+
* int n = poller->wait(results, 64, 100); // 100ms timeout
|
|
18
|
+
* for (int i = 0; i < n; i++) {
|
|
19
|
+
* if (results[i].events & PollIn) handle_read(results[i].fd);
|
|
20
|
+
* if (results[i].events & PollOut) handle_write(results[i].fd);
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
#include "socket.h"
|
|
25
|
+
|
|
26
|
+
#include <memory>
|
|
27
|
+
#include <cstdint>
|
|
28
|
+
|
|
29
|
+
namespace librats {
|
|
30
|
+
|
|
31
|
+
//=============================================================================
|
|
32
|
+
// Poll Event Flags
|
|
33
|
+
//=============================================================================
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @brief I/O event flags for polling
|
|
37
|
+
*/
|
|
38
|
+
enum PollFlags : uint32_t {
|
|
39
|
+
PollNone = 0,
|
|
40
|
+
PollIn = 1 << 0, ///< Socket is readable (data available or connection accepted)
|
|
41
|
+
PollOut = 1 << 1, ///< Socket is writable (can send or connect completed)
|
|
42
|
+
PollErr = 1 << 2, ///< Error condition on socket
|
|
43
|
+
PollHup = 1 << 3, ///< Hang up / peer disconnected
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
inline uint32_t operator|(PollFlags a, PollFlags b) {
|
|
47
|
+
return static_cast<uint32_t>(a) | static_cast<uint32_t>(b);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//=============================================================================
|
|
51
|
+
// Poll Result
|
|
52
|
+
//=============================================================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @brief Result entry from a poll wait
|
|
56
|
+
*/
|
|
57
|
+
struct PollResult {
|
|
58
|
+
socket_t fd; ///< The socket that has events
|
|
59
|
+
uint32_t events; ///< Bitmask of PollFlags that occurred
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
//=============================================================================
|
|
63
|
+
// IOPoller Abstract Interface
|
|
64
|
+
//=============================================================================
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @brief Abstract I/O multiplexer
|
|
68
|
+
*
|
|
69
|
+
* Thread-safety:
|
|
70
|
+
* - add/modify/remove: Safe to call from any thread (epoll_ctl is thread-safe,
|
|
71
|
+
* kqueue changes are atomic, WSAPoll rebuilds on wait).
|
|
72
|
+
* - wait: Should be called from a single I/O thread.
|
|
73
|
+
* - add/modify/remove can be called concurrently with wait().
|
|
74
|
+
*/
|
|
75
|
+
class IOPoller {
|
|
76
|
+
public:
|
|
77
|
+
virtual ~IOPoller() = default;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @brief Create the platform-optimal poller instance
|
|
81
|
+
*
|
|
82
|
+
* Returns:
|
|
83
|
+
* - EpollPoller on Linux
|
|
84
|
+
* - KqueuePoller on macOS/FreeBSD
|
|
85
|
+
* - IocpPoller on Windows (I/O Completion Ports)
|
|
86
|
+
*/
|
|
87
|
+
static std::unique_ptr<IOPoller> create();
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @brief Add a socket to the poll set
|
|
91
|
+
*
|
|
92
|
+
* @param fd Socket to monitor
|
|
93
|
+
* @param events Bitmask of PollFlags to watch for
|
|
94
|
+
* @return true on success
|
|
95
|
+
*/
|
|
96
|
+
virtual bool add(socket_t fd, uint32_t events) = 0;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @brief Modify the event mask for a monitored socket
|
|
100
|
+
*
|
|
101
|
+
* @param fd Socket already in the poll set
|
|
102
|
+
* @param events New bitmask of PollFlags
|
|
103
|
+
* @return true on success
|
|
104
|
+
*/
|
|
105
|
+
virtual bool modify(socket_t fd, uint32_t events) = 0;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @brief Remove a socket from the poll set
|
|
109
|
+
*
|
|
110
|
+
* @param fd Socket to remove
|
|
111
|
+
* @return true on success (false if fd was not registered)
|
|
112
|
+
*/
|
|
113
|
+
virtual bool remove(socket_t fd) = 0;
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @brief Wait for I/O events
|
|
117
|
+
*
|
|
118
|
+
* Blocks until events occur or timeout expires.
|
|
119
|
+
*
|
|
120
|
+
* @param results Array to fill with ready socket events
|
|
121
|
+
* @param max_results Maximum entries in results array
|
|
122
|
+
* @param timeout_ms Timeout in milliseconds (-1 = block forever, 0 = non-blocking)
|
|
123
|
+
* @return Number of ready descriptors (0 on timeout, -1 on error)
|
|
124
|
+
*/
|
|
125
|
+
virtual int wait(PollResult* results, int max_results, int timeout_ms) = 0;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @brief Get the backend name (for logging/diagnostics)
|
|
129
|
+
*/
|
|
130
|
+
virtual const char* name() const = 0;
|
|
131
|
+
|
|
132
|
+
// Non-copyable
|
|
133
|
+
IOPoller() = default;
|
|
134
|
+
IOPoller(const IOPoller&) = delete;
|
|
135
|
+
IOPoller& operator=(const IOPoller&) = delete;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
} // namespace librats
|
package/native-src/src/krpc.cpp
CHANGED
|
@@ -60,7 +60,7 @@ KrpcMessage KrpcProtocol::create_get_peers_query(const std::string& transaction_
|
|
|
60
60
|
return message;
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
KrpcMessage KrpcProtocol::create_announce_peer_query(const std::string& transaction_id, const NodeId& sender_id, const InfoHash& info_hash, uint16_t port, const std::string& token) {
|
|
63
|
+
KrpcMessage KrpcProtocol::create_announce_peer_query(const std::string& transaction_id, const NodeId& sender_id, const InfoHash& info_hash, uint16_t port, const std::string& token, bool implied_port) {
|
|
64
64
|
KrpcMessage message;
|
|
65
65
|
message.type = KrpcMessageType::Query;
|
|
66
66
|
message.transaction_id = transaction_id;
|
|
@@ -68,6 +68,7 @@ KrpcMessage KrpcProtocol::create_announce_peer_query(const std::string& transact
|
|
|
68
68
|
message.sender_id = sender_id;
|
|
69
69
|
message.info_hash = info_hash;
|
|
70
70
|
message.port = port;
|
|
71
|
+
message.implied_port = implied_port;
|
|
71
72
|
message.token = token;
|
|
72
73
|
return message;
|
|
73
74
|
}
|
|
@@ -176,6 +177,9 @@ BencodeValue KrpcProtocol::encode_query(const KrpcMessage& message) {
|
|
|
176
177
|
args["info_hash"] = BencodeValue(node_id_to_string(message.info_hash));
|
|
177
178
|
args["port"] = BencodeValue(static_cast<int64_t>(message.port));
|
|
178
179
|
args["token"] = BencodeValue(message.token);
|
|
180
|
+
if (message.implied_port) {
|
|
181
|
+
args["implied_port"] = BencodeValue(static_cast<int64_t>(1));
|
|
182
|
+
}
|
|
179
183
|
break;
|
|
180
184
|
}
|
|
181
185
|
|
|
@@ -316,6 +320,9 @@ std::unique_ptr<KrpcMessage> KrpcProtocol::decode_query(const BencodeValue& data
|
|
|
316
320
|
if (args.has_key("token")) {
|
|
317
321
|
message->token = args["token"].as_string();
|
|
318
322
|
}
|
|
323
|
+
if (args.has_key("implied_port")) {
|
|
324
|
+
message->implied_port = (args["implied_port"].as_integer() != 0);
|
|
325
|
+
}
|
|
319
326
|
break;
|
|
320
327
|
}
|
|
321
328
|
|
package/native-src/src/krpc.h
CHANGED
|
@@ -68,6 +68,7 @@ struct KrpcMessage {
|
|
|
68
68
|
NodeId target_id;
|
|
69
69
|
InfoHash info_hash;
|
|
70
70
|
uint16_t port;
|
|
71
|
+
bool implied_port; // BEP 5: if true, use UDP source port instead of 'port' field
|
|
71
72
|
std::string token;
|
|
72
73
|
|
|
73
74
|
// For responses
|
|
@@ -79,7 +80,7 @@ struct KrpcMessage {
|
|
|
79
80
|
KrpcErrorCode error_code;
|
|
80
81
|
std::string error_message;
|
|
81
82
|
|
|
82
|
-
KrpcMessage() : type(KrpcMessageType::Query), query_type(KrpcQueryType::Ping), sender_id(), target_id(), info_hash(), port(0), response_id(), error_code(KrpcErrorCode::GenericError) {}
|
|
83
|
+
KrpcMessage() : type(KrpcMessageType::Query), query_type(KrpcQueryType::Ping), sender_id(), target_id(), info_hash(), port(0), implied_port(false), response_id(), error_code(KrpcErrorCode::GenericError) {}
|
|
83
84
|
};
|
|
84
85
|
|
|
85
86
|
/**
|
|
@@ -96,7 +97,7 @@ public:
|
|
|
96
97
|
static KrpcMessage create_ping_query(const std::string& transaction_id, const NodeId& sender_id);
|
|
97
98
|
static KrpcMessage create_find_node_query(const std::string& transaction_id, const NodeId& sender_id, const NodeId& target_id);
|
|
98
99
|
static KrpcMessage create_get_peers_query(const std::string& transaction_id, const NodeId& sender_id, const InfoHash& info_hash);
|
|
99
|
-
static KrpcMessage create_announce_peer_query(const std::string& transaction_id, const NodeId& sender_id, const InfoHash& info_hash, uint16_t port, const std::string& token);
|
|
100
|
+
static KrpcMessage create_announce_peer_query(const std::string& transaction_id, const NodeId& sender_id, const InfoHash& info_hash, uint16_t port, const std::string& token, bool implied_port = false);
|
|
100
101
|
|
|
101
102
|
static KrpcMessage create_ping_response(const std::string& transaction_id, const NodeId& response_id);
|
|
102
103
|
static KrpcMessage create_find_node_response(const std::string& transaction_id, const NodeId& response_id, const std::vector<KrpcNode>& nodes);
|