librats 1.0.2 → 2.2.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 +145 -331
- package/binding.gyp +16 -3
- package/lib/index.d.ts +288 -696
- package/lib/index.js +407 -44
- package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
- package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
- package/native-src/CMakeLists.txt +404 -179
- package/native-src/LICENSE +1 -1
- package/native-src/src/librats/bindings/rats.cpp +762 -0
- package/native-src/src/librats/bindings/rats.h +380 -0
- package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
- package/native-src/src/librats/bittorrent/bencode.h +176 -0
- package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
- package/native-src/src/librats/bittorrent/bitfield.h +76 -0
- package/native-src/src/librats/bittorrent/byte_io.h +58 -0
- package/native-src/src/librats/bittorrent/choker.cpp +25 -0
- package/native-src/src/librats/bittorrent/choker.h +46 -0
- package/native-src/src/librats/bittorrent/client.cpp +413 -0
- package/native-src/src/librats/bittorrent/client.h +227 -0
- package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
- package/native-src/src/librats/bittorrent/disk_io.h +150 -0
- package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
- package/native-src/src/librats/bittorrent/extensions.h +94 -0
- package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
- package/native-src/src/librats/bittorrent/file_storage.h +79 -0
- package/native-src/src/librats/bittorrent/log.h +42 -0
- package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
- package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
- package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
- package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
- package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
- package/native-src/src/librats/bittorrent/peer_list.h +75 -0
- package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
- package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
- package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
- package/native-src/src/librats/bittorrent/reactor.h +89 -0
- package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
- package/native-src/src/librats/bittorrent/resume_data.h +41 -0
- package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
- package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
- package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
- package/native-src/src/librats/bittorrent/torrent.h +260 -0
- package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
- package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
- package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
- package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
- package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
- package/native-src/src/librats/bittorrent/tracker.h +108 -0
- package/native-src/src/librats/bittorrent/types.cpp +206 -0
- package/native-src/src/librats/bittorrent/types.h +86 -0
- package/native-src/src/librats/core/address.cpp +35 -0
- package/native-src/src/librats/core/address.h +78 -0
- package/native-src/src/librats/core/bytes.h +69 -0
- package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
- package/native-src/src/librats/core/chained_send_buffer.h +183 -0
- package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
- package/native-src/src/librats/core/endpoint_parse.h +31 -0
- package/native-src/src/librats/core/event_bus.h +70 -0
- package/native-src/src/librats/core/host_endpoint.h +56 -0
- package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
- package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
- package/native-src/src/librats/core/ip_address.cpp +120 -0
- package/native-src/src/librats/core/ip_address.h +109 -0
- package/native-src/src/librats/core/mpsc_queue.h +47 -0
- package/native-src/src/librats/core/notifier.h +74 -0
- package/native-src/src/librats/core/receive_buffer.cpp +219 -0
- package/native-src/src/librats/core/receive_buffer.h +171 -0
- package/native-src/src/librats/core/service_registry.h +58 -0
- package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
- package/native-src/src/librats/core/socket.h +496 -0
- package/native-src/src/librats/core/timer_queue.h +105 -0
- package/native-src/src/librats/core/types.cpp +43 -0
- package/native-src/src/librats/core/types.h +103 -0
- package/native-src/src/librats/core/wakeup_pipe.h +83 -0
- package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
- package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
- package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
- package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
- package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
- package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
- package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
- package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
- package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
- package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
- package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
- package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
- package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
- package/native-src/src/librats/crypto/hkdf.c +266 -0
- package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
- package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
- package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
- package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
- package/native-src/src/librats/crypto/poly1305.h +37 -0
- package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
- package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
- package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
- package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
- package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
- package/native-src/src/librats/dht/announce.cpp +37 -0
- package/native-src/src/librats/dht/announce.h +41 -0
- package/native-src/src/librats/dht/bep42.cpp +109 -0
- package/native-src/src/librats/dht/bep42.h +48 -0
- package/native-src/src/librats/dht/dht.cpp +501 -0
- package/native-src/src/librats/dht/dht.h +119 -0
- package/native-src/src/librats/dht/dht_runner.cpp +103 -0
- package/native-src/src/librats/dht/dht_runner.h +71 -0
- package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
- package/native-src/src/librats/dht/dos_blocker.h +47 -0
- package/native-src/src/librats/dht/find_peers.cpp +52 -0
- package/native-src/src/librats/dht/find_peers.h +73 -0
- package/native-src/src/librats/dht/id.h +167 -0
- package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
- package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
- package/native-src/src/librats/dht/log.h +38 -0
- package/native-src/src/librats/dht/node.cpp +473 -0
- package/native-src/src/librats/dht/node.h +164 -0
- package/native-src/src/librats/dht/node_entry.h +81 -0
- package/native-src/src/librats/dht/observer.h +72 -0
- package/native-src/src/librats/dht/persistence.cpp +90 -0
- package/native-src/src/librats/dht/persistence.h +32 -0
- package/native-src/src/librats/dht/routing_table.cpp +559 -0
- package/native-src/src/librats/dht/routing_table.h +185 -0
- package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
- package/native-src/src/librats/dht/rpc_manager.h +77 -0
- package/native-src/src/librats/dht/storage.cpp +92 -0
- package/native-src/src/librats/dht/storage.h +74 -0
- package/native-src/src/librats/dht/transport.h +27 -0
- package/native-src/src/librats/dht/traversal.cpp +326 -0
- package/native-src/src/librats/dht/traversal.h +120 -0
- package/native-src/src/librats/dht/udp_transport.cpp +49 -0
- package/native-src/src/librats/dht/udp_transport.h +51 -0
- package/native-src/src/librats/mdns/log.h +22 -0
- package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
- package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
- package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
- package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
- package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
- package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
- package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
- package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
- package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
- package/native-src/src/librats/node/circuit_service.h +84 -0
- package/native-src/src/librats/node/config.h +110 -0
- package/native-src/src/librats/node/dial_service.h +54 -0
- package/native-src/src/librats/node/dialer.cpp +264 -0
- package/native-src/src/librats/node/dialer.h +188 -0
- package/native-src/src/librats/node/host_events.h +26 -0
- package/native-src/src/librats/node/identify.cpp +130 -0
- package/native-src/src/librats/node/identify.h +71 -0
- package/native-src/src/librats/node/nat_status.cpp +103 -0
- package/native-src/src/librats/node/nat_status.h +118 -0
- package/native-src/src/librats/node/node.cpp +865 -0
- package/native-src/src/librats/node/node.h +344 -0
- package/native-src/src/librats/node/node_context.h +33 -0
- package/native-src/src/librats/node/peer_network.h +91 -0
- package/native-src/src/librats/peer/peer.h +49 -0
- package/native-src/src/librats/peer/peer_book.cpp +181 -0
- package/native-src/src/librats/peer/peer_book.h +88 -0
- package/native-src/src/librats/peer/peer_id.cpp +72 -0
- package/native-src/src/librats/peer/peer_id.h +62 -0
- package/native-src/src/librats/peer/peer_info.h +37 -0
- package/native-src/src/librats/peer/peer_table.cpp +170 -0
- package/native-src/src/librats/peer/peer_table.h +148 -0
- package/native-src/src/librats/security/handshaker.h +66 -0
- package/native-src/src/librats/security/identity.h +43 -0
- package/native-src/src/librats/security/noise_security.cpp +122 -0
- package/native-src/src/librats/security/noise_security.h +37 -0
- package/native-src/src/librats/security/plaintext_security.h +106 -0
- package/native-src/src/librats/security/session.h +37 -0
- package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
- package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
- package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
- package/native-src/src/librats/subsystems/bittorrent.h +136 -0
- package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
- package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
- package/native-src/src/librats/subsystems/dht_service.h +36 -0
- package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
- package/native-src/src/librats/subsystems/file_transfer.h +367 -0
- package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
- package/native-src/src/librats/subsystems/hole_punch.h +290 -0
- package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
- package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
- package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
- package/native-src/src/librats/subsystems/message_json.cpp +112 -0
- package/native-src/src/librats/subsystems/message_json.h +88 -0
- package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
- package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
- package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
- package/native-src/src/librats/subsystems/ping_service.h +66 -0
- package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
- package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
- package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
- package/native-src/src/librats/subsystems/pubsub.h +175 -0
- package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
- package/native-src/src/librats/subsystems/reconnection.h +126 -0
- package/native-src/src/librats/subsystems/relay.cpp +1142 -0
- package/native-src/src/librats/subsystems/relay.h +211 -0
- package/native-src/src/librats/subsystems/relay_service.h +46 -0
- package/native-src/src/librats/transport/connection.cpp +343 -0
- package/native-src/src/librats/transport/connection.h +283 -0
- package/native-src/src/librats/transport/link.h +96 -0
- package/native-src/src/librats/transport/reactor.cpp +588 -0
- package/native-src/src/librats/transport/reactor.h +262 -0
- package/native-src/src/librats/transport/reactor_pool.h +81 -0
- package/native-src/src/librats/transport/relay_link.cpp +208 -0
- package/native-src/src/librats/transport/relay_link.h +303 -0
- package/native-src/src/librats/transport/tcp_link.cpp +49 -0
- package/native-src/src/librats/transport/tcp_link.h +43 -0
- package/native-src/src/librats/transport/udp_mux.cpp +617 -0
- package/native-src/src/librats/transport/udp_mux.h +363 -0
- package/native-src/src/librats/transport/udp_packet.cpp +121 -0
- package/native-src/src/librats/transport/udp_packet.h +190 -0
- package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
- package/native-src/src/librats/transport/udp_stream.h +614 -0
- package/native-src/src/librats/util/features.h.in +51 -0
- package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
- package/native-src/src/librats/util/fs.h +136 -0
- package/native-src/src/librats/util/json.cpp +1002 -0
- package/native-src/src/librats/util/json.h +444 -0
- package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
- package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
- package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
- package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
- package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
- package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
- package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
- package/native-src/src/librats/util/rats_export.h +69 -0
- package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
- package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
- package/native-src/src/librats/wire/frame.cpp +76 -0
- package/native-src/src/librats/wire/frame.h +111 -0
- package/native-src/src/librats/wire/message_router.cpp +45 -0
- package/native-src/src/librats/wire/message_router.h +47 -0
- package/package.json +5 -4
- package/scripts/build-librats.js +1 -0
- package/scripts/postinstall.js +3 -3
- package/scripts/prepare-package.js +4 -4
- package/scripts/verify-installation.js +63 -105
- package/src/librats_node.cpp +1067 -1323
- package/native-src/src/bencode.cpp +0 -485
- package/native-src/src/bencode.h +0 -145
- package/native-src/src/bittorrent.cpp +0 -14
- package/native-src/src/bittorrent.h +0 -74
- package/native-src/src/bt_bitfield.cpp +0 -372
- package/native-src/src/bt_bitfield.h +0 -316
- package/native-src/src/bt_choker.cpp +0 -228
- package/native-src/src/bt_choker.h +0 -147
- package/native-src/src/bt_client.cpp +0 -1047
- package/native-src/src/bt_client.h +0 -445
- package/native-src/src/bt_create_torrent.cpp +0 -677
- package/native-src/src/bt_create_torrent.h +0 -473
- package/native-src/src/bt_extension.cpp +0 -469
- package/native-src/src/bt_extension.h +0 -309
- package/native-src/src/bt_file_storage.cpp +0 -261
- package/native-src/src/bt_file_storage.h +0 -298
- package/native-src/src/bt_handshake.cpp +0 -134
- package/native-src/src/bt_handshake.h +0 -157
- package/native-src/src/bt_messages.cpp +0 -364
- package/native-src/src/bt_messages.h +0 -324
- package/native-src/src/bt_network.cpp +0 -1007
- package/native-src/src/bt_network.h +0 -417
- package/native-src/src/bt_peer_connection.cpp +0 -742
- package/native-src/src/bt_peer_connection.h +0 -592
- package/native-src/src/bt_piece_picker.cpp +0 -786
- package/native-src/src/bt_piece_picker.h +0 -473
- package/native-src/src/bt_resume_data.cpp +0 -410
- package/native-src/src/bt_resume_data.h +0 -249
- package/native-src/src/bt_torrent.cpp +0 -2120
- package/native-src/src/bt_torrent.h +0 -641
- package/native-src/src/bt_torrent_info.cpp +0 -659
- package/native-src/src/bt_torrent_info.h +0 -418
- package/native-src/src/bt_types.h +0 -621
- package/native-src/src/chained_send_buffer.cpp +0 -75
- package/native-src/src/chained_send_buffer.h +0 -137
- package/native-src/src/crypto/hkdf.c +0 -266
- package/native-src/src/crypto/poly1305.h +0 -36
- package/native-src/src/dht.cpp +0 -3311
- package/native-src/src/dht.h +0 -717
- package/native-src/src/disk_io.cpp +0 -632
- package/native-src/src/disk_io.h +0 -315
- package/native-src/src/file_transfer.cpp +0 -1415
- package/native-src/src/file_transfer.h +0 -286
- package/native-src/src/fs.h +0 -108
- package/native-src/src/gossipsub.cpp +0 -1139
- package/native-src/src/gossipsub.h +0 -403
- package/native-src/src/ice.cpp +0 -893
- package/native-src/src/ice.h +0 -559
- package/native-src/src/json.hpp +0 -25526
- package/native-src/src/librats.cpp +0 -2378
- package/native-src/src/librats.h +0 -2324
- package/native-src/src/librats_bittorrent.cpp +0 -601
- package/native-src/src/librats_c.cpp +0 -1557
- package/native-src/src/librats_c.h +0 -323
- package/native-src/src/librats_discovery.cpp +0 -402
- package/native-src/src/librats_encryption.cpp +0 -275
- package/native-src/src/librats_file_transfer.cpp +0 -144
- package/native-src/src/librats_gossipsub.cpp +0 -289
- package/native-src/src/librats_ice.cpp +0 -213
- package/native-src/src/librats_log_macros.h +0 -36
- package/native-src/src/librats_logging.cpp +0 -173
- package/native-src/src/librats_mdns.cpp +0 -166
- package/native-src/src/librats_persistence.cpp +0 -796
- package/native-src/src/librats_portmap.cpp +0 -419
- package/native-src/src/librats_reconnection.cpp +0 -218
- package/native-src/src/librats_statistic.cpp +0 -105
- package/native-src/src/librats_storage.cpp +0 -189
- package/native-src/src/rats_export.h +0 -17
- package/native-src/src/receive_buffer.cpp +0 -82
- package/native-src/src/receive_buffer.h +0 -127
- package/native-src/src/socket.h +0 -228
- package/native-src/src/threadmanager.cpp +0 -105
- package/native-src/src/threadmanager.h +0 -53
- package/native-src/src/tracker.cpp +0 -1264
- package/native-src/src/tracker.h +0 -319
- package/native-src/src/turn.cpp +0 -762
- package/native-src/src/turn.h +0 -460
- package/native-src/src/wakeup_pipe.h +0 -60
- /package/native-src/src/{os.h → librats/util/os.h} +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#include "librats/bittorrent/file_storage.h"
|
|
2
|
+
#include "librats/bittorrent/types.h" // kBlockSize
|
|
3
|
+
|
|
4
|
+
#include <algorithm>
|
|
5
|
+
#include <limits>
|
|
6
|
+
|
|
7
|
+
namespace librats::bittorrent {
|
|
8
|
+
|
|
9
|
+
bool FileStorage::add_file(std::string path, std::int64_t size) {
|
|
10
|
+
// Reject a negative size or a running total that would overflow int64: a
|
|
11
|
+
// hostile .torrent could otherwise trigger signed-overflow UB here and a
|
|
12
|
+
// garbage num_pieces() downstream. Leave the layout untouched so the caller
|
|
13
|
+
// can bail cleanly.
|
|
14
|
+
if (size < 0 || size > std::numeric_limits<std::int64_t>::max() - total_size_)
|
|
15
|
+
return false;
|
|
16
|
+
files_.push_back(FileEntry{std::move(path), size, total_size_});
|
|
17
|
+
total_size_ += size;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
void FileStorage::clear() {
|
|
22
|
+
files_.clear();
|
|
23
|
+
name_.clear();
|
|
24
|
+
piece_length_ = 0;
|
|
25
|
+
total_size_ = 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
std::uint32_t FileStorage::num_pieces() const noexcept {
|
|
29
|
+
if (piece_length_ == 0) return 0;
|
|
30
|
+
return std::uint32_t((total_size_ + piece_length_ - 1) / piece_length_);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
std::uint32_t FileStorage::piece_size(std::uint32_t piece) const noexcept {
|
|
34
|
+
const std::uint32_t n = num_pieces();
|
|
35
|
+
if (piece + 1 < n) return piece_length_;
|
|
36
|
+
// Final piece: the remainder. (Also the only piece for tiny torrents.)
|
|
37
|
+
const std::int64_t tail = total_size_ - std::int64_t(piece) * piece_length_;
|
|
38
|
+
if (tail <= 0) return 0;
|
|
39
|
+
return std::uint32_t(std::min<std::int64_t>(tail, piece_length_));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
std::uint32_t FileStorage::blocks_in_piece(std::uint32_t piece) const noexcept {
|
|
43
|
+
const std::uint32_t ps = piece_size(piece);
|
|
44
|
+
return (ps + kBlockSize - 1) / kBlockSize;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
std::vector<FileSlice> FileStorage::map_block(std::uint32_t piece, std::uint32_t offset,
|
|
48
|
+
std::int64_t size) const {
|
|
49
|
+
std::vector<FileSlice> slices;
|
|
50
|
+
if (size <= 0 || files_.empty()) return slices;
|
|
51
|
+
|
|
52
|
+
std::int64_t abs = std::int64_t(piece) * piece_length_ + offset;
|
|
53
|
+
if (abs >= total_size_) return slices;
|
|
54
|
+
std::int64_t remaining = (std::min)(size, total_size_ - abs); // clamp to payload
|
|
55
|
+
|
|
56
|
+
// Binary search: the file containing `abs` is the last one whose offset <= abs.
|
|
57
|
+
// (Zero-length files share an offset with the following file; picking the last
|
|
58
|
+
// such index lands on the real, non-empty file, and the loop skips empties.)
|
|
59
|
+
std::size_t f = std::size_t(
|
|
60
|
+
std::upper_bound(files_.begin(), files_.end(), abs,
|
|
61
|
+
[](std::int64_t a, const FileEntry& e) { return a < e.offset; })
|
|
62
|
+
- files_.begin());
|
|
63
|
+
if (f > 0) --f;
|
|
64
|
+
|
|
65
|
+
while (remaining > 0 && f < files_.size()) {
|
|
66
|
+
const std::int64_t file_off = abs - files_[f].offset;
|
|
67
|
+
if (file_off >= files_[f].size) { ++f; continue; } // empty / already past this file
|
|
68
|
+
const std::int64_t take = (std::min)(remaining, files_[f].size - file_off);
|
|
69
|
+
slices.push_back(FileSlice{f, file_off, take});
|
|
70
|
+
remaining -= take;
|
|
71
|
+
abs += take;
|
|
72
|
+
++f;
|
|
73
|
+
}
|
|
74
|
+
return slices;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file file_storage.h
|
|
5
|
+
* @brief The file layout of a torrent and the piece <-> file mapping.
|
|
6
|
+
*
|
|
7
|
+
* A torrent's payload is one contiguous byte space: files are laid end-to-end
|
|
8
|
+
* in order, each at a running @c offset. Pieces are fixed-size windows over that
|
|
9
|
+
* space (the final piece is short). FileStorage answers the two questions the
|
|
10
|
+
* disk and wire layers need: "how big is piece i?" and "which file regions does
|
|
11
|
+
* a (piece, offset, length) range touch?". The latter (map_block) is O(log n)
|
|
12
|
+
* via a binary search over the sorted file offsets.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#include "librats/util/rats_export.h"
|
|
16
|
+
|
|
17
|
+
#include <cstddef>
|
|
18
|
+
#include <cstdint>
|
|
19
|
+
#include <string>
|
|
20
|
+
#include <vector>
|
|
21
|
+
|
|
22
|
+
namespace librats::bittorrent {
|
|
23
|
+
|
|
24
|
+
/// One file in the torrent. @c path is the full relative path including the
|
|
25
|
+
/// torrent name as its first component (so the disk layer just joins it onto
|
|
26
|
+
/// the save path). @c offset is the file's start in the torrent byte space.
|
|
27
|
+
struct FileEntry {
|
|
28
|
+
std::string path;
|
|
29
|
+
std::int64_t size = 0;
|
|
30
|
+
std::int64_t offset = 0;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/// A contiguous region of a single file — one fragment of a mapped block.
|
|
34
|
+
struct FileSlice {
|
|
35
|
+
std::size_t file_index = 0;
|
|
36
|
+
std::int64_t offset = 0; ///< byte offset within the file
|
|
37
|
+
std::int64_t size = 0;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
class RATS_API FileStorage {
|
|
41
|
+
public:
|
|
42
|
+
void set_piece_length(std::uint32_t length) noexcept { piece_length_ = length; }
|
|
43
|
+
void set_name(std::string name) { name_ = std::move(name); }
|
|
44
|
+
/// Append a file (its offset is computed from the running total). Returns
|
|
45
|
+
/// false and leaves the layout unchanged if @p size is negative or would
|
|
46
|
+
/// overflow the int64 running total — a hostile .torrent must be rejected
|
|
47
|
+
/// rather than driving signed-overflow UB and a garbage num_pieces().
|
|
48
|
+
bool add_file(std::string path, std::int64_t size);
|
|
49
|
+
void clear();
|
|
50
|
+
|
|
51
|
+
const std::string& name() const noexcept { return name_; }
|
|
52
|
+
std::uint32_t piece_length() const noexcept { return piece_length_; }
|
|
53
|
+
std::int64_t total_size() const noexcept { return total_size_; }
|
|
54
|
+
std::size_t num_files() const noexcept { return files_.size(); }
|
|
55
|
+
const FileEntry& file_at(std::size_t i) const { return files_[i]; }
|
|
56
|
+
const std::vector<FileEntry>& files() const noexcept { return files_; }
|
|
57
|
+
|
|
58
|
+
/// A layout is usable once it has a piece length and at least one file.
|
|
59
|
+
bool is_valid() const noexcept { return piece_length_ > 0 && !files_.empty(); }
|
|
60
|
+
|
|
61
|
+
std::uint32_t num_pieces() const noexcept;
|
|
62
|
+
/// Size of piece @p piece — piece_length except a possibly-short final piece.
|
|
63
|
+
std::uint32_t piece_size(std::uint32_t piece) const noexcept;
|
|
64
|
+
/// Number of 16 KiB blocks in piece @p piece (the last block may be short).
|
|
65
|
+
std::uint32_t blocks_in_piece(std::uint32_t piece) const noexcept;
|
|
66
|
+
|
|
67
|
+
/// Map a byte range within a piece to the file regions it covers. The range
|
|
68
|
+
/// is clamped to the torrent's total size; zero-length files are skipped.
|
|
69
|
+
std::vector<FileSlice> map_block(std::uint32_t piece, std::uint32_t offset,
|
|
70
|
+
std::int64_t size) const;
|
|
71
|
+
|
|
72
|
+
private:
|
|
73
|
+
std::vector<FileEntry> files_;
|
|
74
|
+
std::string name_;
|
|
75
|
+
std::uint32_t piece_length_ = 0;
|
|
76
|
+
std::int64_t total_size_ = 0;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file log.h
|
|
5
|
+
* @brief Small logging helpers shared across the BitTorrent modules.
|
|
6
|
+
*
|
|
7
|
+
* Formatting sugar on top of util/logger.h — nothing more. BitTorrent logs under a
|
|
8
|
+
* set of dot-namespaced tags so each component gets its own stable colour and is
|
|
9
|
+
* easy to grep (mirrors the dht.* scheme):
|
|
10
|
+
*
|
|
11
|
+
* "bt.client" — the session: listener, accept/dial, add/remove torrent
|
|
12
|
+
* "bt.torrent" — one torrent's lifecycle: state transitions, pieces, choking
|
|
13
|
+
* "bt.peer" — a peer link: handshake and disconnect (with reason)
|
|
14
|
+
* "bt.tracker" — per-tracker HTTP/UDP announce results
|
|
15
|
+
* "bt.meta" — magnet metadata fetch (BEP 9)
|
|
16
|
+
* "bt.disk" — disk I/O failures
|
|
17
|
+
* "bt.picker" — piece selection (end-game entry)
|
|
18
|
+
* "bt.node" — the Node subsystem wrapper
|
|
19
|
+
*
|
|
20
|
+
* Conventions: an info-hash renders via short_hash() (8 leading hex, like a git
|
|
21
|
+
* short hash); a peer renders as "ip:port". Direction/outcome use glyphs —
|
|
22
|
+
* → outgoing, ← incoming, ✓ success, ✗ failure — matching the DHT logs.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
#include "librats/bittorrent/types.h"
|
|
26
|
+
#include "librats/util/logger.h"
|
|
27
|
+
|
|
28
|
+
#include <cstddef>
|
|
29
|
+
#include <string>
|
|
30
|
+
|
|
31
|
+
namespace librats::bittorrent {
|
|
32
|
+
|
|
33
|
+
/// Compact, log-friendly rendering of a 20-byte info-hash: its leading `chars`
|
|
34
|
+
/// hex digits (default 8, like a git short hash). The full 40-char id is
|
|
35
|
+
/// unreadable in a log line and its prefix is more than enough to follow one
|
|
36
|
+
/// torrent across lines. Use to_hex(id) only where the complete id matters.
|
|
37
|
+
inline std::string short_hash(const InfoHash& id, std::size_t chars = 8) {
|
|
38
|
+
const std::string full = to_hex(id);
|
|
39
|
+
return chars >= full.size() ? full : full.substr(0, chars);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#include "librats/bittorrent/magnet_uri.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
#include <cctype>
|
|
5
|
+
|
|
6
|
+
namespace librats::bittorrent {
|
|
7
|
+
|
|
8
|
+
namespace {
|
|
9
|
+
|
|
10
|
+
/// Percent-decode a URL component (leaves '+' as a literal, as magnet links do).
|
|
11
|
+
std::string url_decode(const std::string& s) {
|
|
12
|
+
std::string out;
|
|
13
|
+
out.reserve(s.size());
|
|
14
|
+
for (std::size_t i = 0; i < s.size(); ++i) {
|
|
15
|
+
if (s[i] == '%' && i + 2 < s.size()) {
|
|
16
|
+
auto hex = [](char c) -> int {
|
|
17
|
+
if (c >= '0' && c <= '9') return c - '0';
|
|
18
|
+
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
19
|
+
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
20
|
+
return -1;
|
|
21
|
+
};
|
|
22
|
+
const int hi = hex(s[i + 1]), lo = hex(s[i + 2]);
|
|
23
|
+
if (hi >= 0 && lo >= 0) { out.push_back(char(hi << 4 | lo)); i += 2; continue; }
|
|
24
|
+
}
|
|
25
|
+
out.push_back(s[i]);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/// Decode a 32-character RFC 4648 base32 string into a 20-byte info-hash.
|
|
31
|
+
std::optional<InfoHash> base32_to_info_hash(const std::string& in) {
|
|
32
|
+
if (in.size() != 32) return std::nullopt;
|
|
33
|
+
auto value = [](char c) -> int {
|
|
34
|
+
c = char(std::toupper(static_cast<unsigned char>(c)));
|
|
35
|
+
if (c >= 'A' && c <= 'Z') return c - 'A';
|
|
36
|
+
if (c >= '2' && c <= '7') return c - '2' + 26;
|
|
37
|
+
return -1;
|
|
38
|
+
};
|
|
39
|
+
InfoHash out{};
|
|
40
|
+
std::uint32_t bits = 0;
|
|
41
|
+
int bit_count = 0;
|
|
42
|
+
std::size_t byte = 0;
|
|
43
|
+
for (char c : in) {
|
|
44
|
+
const int v = value(c);
|
|
45
|
+
if (v < 0) return std::nullopt;
|
|
46
|
+
bits = bits << 5 | std::uint32_t(v);
|
|
47
|
+
bit_count += 5;
|
|
48
|
+
if (bit_count >= 8) {
|
|
49
|
+
bit_count -= 8;
|
|
50
|
+
out[byte++] = std::uint8_t(bits >> bit_count);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return out; // 32 * 5 = 160 bits = exactly 20 bytes
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
} // namespace
|
|
57
|
+
|
|
58
|
+
std::optional<MagnetUri> MagnetUri::parse(const std::string& uri) {
|
|
59
|
+
constexpr char kPrefix[] = "magnet:?";
|
|
60
|
+
if (uri.rfind(kPrefix, 0) != 0) return std::nullopt;
|
|
61
|
+
|
|
62
|
+
MagnetUri result;
|
|
63
|
+
const std::string query = uri.substr(sizeof(kPrefix) - 1);
|
|
64
|
+
|
|
65
|
+
std::size_t pos = 0;
|
|
66
|
+
while (pos < query.size()) {
|
|
67
|
+
std::size_t amp = query.find('&', pos);
|
|
68
|
+
if (amp == std::string::npos) amp = query.size();
|
|
69
|
+
const std::string token = query.substr(pos, amp - pos);
|
|
70
|
+
pos = amp + 1;
|
|
71
|
+
|
|
72
|
+
const std::size_t eq = token.find('=');
|
|
73
|
+
if (eq == std::string::npos) continue;
|
|
74
|
+
const std::string key = token.substr(0, eq);
|
|
75
|
+
const std::string val = url_decode(token.substr(eq + 1));
|
|
76
|
+
|
|
77
|
+
if (key == "xt") {
|
|
78
|
+
constexpr char kBtih[] = "urn:btih:";
|
|
79
|
+
if (val.rfind(kBtih, 0) == 0) {
|
|
80
|
+
const std::string id = val.substr(sizeof(kBtih) - 1);
|
|
81
|
+
if (auto h = info_hash_from_hex(id)) result.info_hash = *h;
|
|
82
|
+
else if (auto b = base32_to_info_hash(id)) result.info_hash = *b;
|
|
83
|
+
}
|
|
84
|
+
// urn:btmh: (v2) intentionally ignored for now.
|
|
85
|
+
} else if (key == "dn") {
|
|
86
|
+
result.display_name = val;
|
|
87
|
+
} else if (key == "tr") {
|
|
88
|
+
if (!val.empty()) result.trackers.push_back(val);
|
|
89
|
+
} else if (key == "ws") {
|
|
90
|
+
if (!val.empty()) result.web_seeds.push_back(val);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!result.is_valid()) return std::nullopt;
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file magnet_uri.h
|
|
5
|
+
* @brief Parsing of magnet links (BEP 9 / BEP 53 subset).
|
|
6
|
+
*
|
|
7
|
+
* A magnet link carries an info-hash (and optionally a name, trackers and web
|
|
8
|
+
* seeds) but no metadata — the file list and piece hashes must still be fetched
|
|
9
|
+
* from peers via ut_metadata. We accept the v1 `xt=urn:btih:` form with either a
|
|
10
|
+
* 40-char hex or a 32-char base32 SHA-1.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#include "librats/util/rats_export.h"
|
|
14
|
+
#include "librats/bittorrent/types.h"
|
|
15
|
+
|
|
16
|
+
#include <optional>
|
|
17
|
+
#include <string>
|
|
18
|
+
#include <vector>
|
|
19
|
+
|
|
20
|
+
namespace librats::bittorrent {
|
|
21
|
+
|
|
22
|
+
struct RATS_API MagnetUri {
|
|
23
|
+
InfoHash info_hash{};
|
|
24
|
+
std::string display_name; ///< dn
|
|
25
|
+
std::vector<std::string> trackers; ///< tr
|
|
26
|
+
std::vector<std::string> web_seeds; ///< ws
|
|
27
|
+
|
|
28
|
+
bool is_valid() const noexcept { return !is_all_zero(info_hash); }
|
|
29
|
+
|
|
30
|
+
/// Parse a "magnet:?…" URI. nullopt if it is not a magnet link or carries no
|
|
31
|
+
/// valid v1 info-hash.
|
|
32
|
+
static std::optional<MagnetUri> parse(const std::string& uri);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
} // namespace librats::bittorrent
|