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,89 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file reactor.h
|
|
5
|
+
* @brief Single-threaded event loop for the BitTorrent peer transport.
|
|
6
|
+
*
|
|
7
|
+
* BitTorrent peers speak a plaintext wire protocol that is unrelated to the
|
|
8
|
+
* node's Noise mesh, so rather than bend `transport::Reactor` (which is tied to
|
|
9
|
+
* the Noise handshake) we assemble a dedicated loop from the same reusable
|
|
10
|
+
* primitives: an IOPoller, a TimerQueue, an MPSC task queue and a Notifier
|
|
11
|
+
* self-pipe to break the poll wait.
|
|
12
|
+
*
|
|
13
|
+
* One thread owns the loop and therefore all protocol state hung off it — peers,
|
|
14
|
+
* pickers, torrents — so none of that needs locks. Other threads reach in only
|
|
15
|
+
* through post(), which enqueues a task and wakes the loop. Socket registration
|
|
16
|
+
* (add/modify/remove) and timers are reactor-thread-only; call them from a task
|
|
17
|
+
* if you are elsewhere.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
#include "librats/util/rats_export.h"
|
|
21
|
+
#include "librats/core/io_poller.h"
|
|
22
|
+
#include "librats/core/mpsc_queue.h"
|
|
23
|
+
#include "librats/core/notifier.h"
|
|
24
|
+
#include "librats/core/socket.h"
|
|
25
|
+
#include "librats/core/timer_queue.h"
|
|
26
|
+
#include "librats/core/types.h"
|
|
27
|
+
|
|
28
|
+
#include <atomic>
|
|
29
|
+
#include <chrono>
|
|
30
|
+
#include <cstdint>
|
|
31
|
+
#include <functional>
|
|
32
|
+
#include <thread>
|
|
33
|
+
#include <unordered_map>
|
|
34
|
+
|
|
35
|
+
namespace librats::bittorrent {
|
|
36
|
+
|
|
37
|
+
class RATS_API Reactor {
|
|
38
|
+
public:
|
|
39
|
+
using Task = std::function<void()>;
|
|
40
|
+
using IoCallback = std::function<void(std::uint32_t events)>;
|
|
41
|
+
using TimerCallback = std::function<void()>;
|
|
42
|
+
|
|
43
|
+
Reactor();
|
|
44
|
+
~Reactor();
|
|
45
|
+
|
|
46
|
+
Reactor(const Reactor&) = delete;
|
|
47
|
+
Reactor& operator=(const Reactor&) = delete;
|
|
48
|
+
|
|
49
|
+
/// Run the loop on a dedicated thread until stop().
|
|
50
|
+
void start();
|
|
51
|
+
/// Stop the loop and join its thread (if any). Idempotent.
|
|
52
|
+
void stop();
|
|
53
|
+
/// Run the loop on the calling thread until stop().
|
|
54
|
+
void run();
|
|
55
|
+
/// Run a single loop iteration: poll, dispatch I/O, run posted tasks and due
|
|
56
|
+
/// timers. Exposed for tests and for embedding in another loop.
|
|
57
|
+
void run_one(int timeout_ms);
|
|
58
|
+
|
|
59
|
+
bool running() const noexcept { return running_.load(); }
|
|
60
|
+
bool on_reactor_thread() const noexcept { return std::this_thread::get_id() == loop_thread_; }
|
|
61
|
+
|
|
62
|
+
/// Enqueue a task to run on the reactor thread. Thread-safe.
|
|
63
|
+
void post(Task task);
|
|
64
|
+
|
|
65
|
+
// ---- reactor-thread only ----
|
|
66
|
+
bool add(socket_t fd, std::uint32_t events, IoCallback cb);
|
|
67
|
+
bool modify(socket_t fd, std::uint32_t events);
|
|
68
|
+
void remove(socket_t fd);
|
|
69
|
+
|
|
70
|
+
TimerId schedule(std::chrono::milliseconds delay, TimerCallback cb);
|
|
71
|
+
void cancel(TimerId id);
|
|
72
|
+
|
|
73
|
+
private:
|
|
74
|
+
void dispatch_io();
|
|
75
|
+
void run_tasks();
|
|
76
|
+
|
|
77
|
+
std::unique_ptr<IOPoller> poller_;
|
|
78
|
+
TimerQueue timers_;
|
|
79
|
+
MpscQueue<Task> tasks_;
|
|
80
|
+
Notifier notifier_;
|
|
81
|
+
std::unordered_map<socket_t, IoCallback> handlers_;
|
|
82
|
+
std::vector<Task> task_scratch_;
|
|
83
|
+
|
|
84
|
+
std::atomic<bool> running_{false};
|
|
85
|
+
std::thread thread_;
|
|
86
|
+
std::thread::id loop_thread_;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#include "librats/bittorrent/resume_data.h"
|
|
2
|
+
|
|
3
|
+
#include "librats/bittorrent/bencode.h"
|
|
4
|
+
|
|
5
|
+
#include <cstring>
|
|
6
|
+
|
|
7
|
+
namespace librats::bittorrent {
|
|
8
|
+
|
|
9
|
+
namespace {
|
|
10
|
+
constexpr char kFormatTag[] = "librats resume";
|
|
11
|
+
|
|
12
|
+
const librats::BencodeValue* find(const librats::BencodeValue& d, const char* key) {
|
|
13
|
+
return d.find(key);
|
|
14
|
+
}
|
|
15
|
+
} // namespace
|
|
16
|
+
|
|
17
|
+
Bytes ResumeData::encode() const {
|
|
18
|
+
librats::BencodeValue d = librats::BencodeValue::create_dict();
|
|
19
|
+
d["format"] = librats::BencodeValue(std::string(kFormatTag));
|
|
20
|
+
d["version"] = librats::BencodeValue(std::int64_t(1));
|
|
21
|
+
d["info-hash"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(info_hash.data()), info_hash.size()));
|
|
22
|
+
d["name"] = librats::BencodeValue(name);
|
|
23
|
+
d["save-path"] = librats::BencodeValue(save_path);
|
|
24
|
+
d["num-pieces"] = librats::BencodeValue(std::int64_t(have.size()));
|
|
25
|
+
d["pieces"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(have.data()), have.data_size()));
|
|
26
|
+
d["uploaded"] = librats::BencodeValue(std::int64_t(total_uploaded));
|
|
27
|
+
d["downloaded"] = librats::BencodeValue(std::int64_t(total_downloaded));
|
|
28
|
+
if (!info_dict.empty())
|
|
29
|
+
d["info"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(info_dict.data()), info_dict.size()));
|
|
30
|
+
return d.encode();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
std::optional<ResumeData> ResumeData::decode(const Bytes& data) {
|
|
34
|
+
try {
|
|
35
|
+
librats::BencodeValue d = librats::BencodeDecoder::decode(data.data(), data.size());
|
|
36
|
+
if (!d.is_dict()) return std::nullopt;
|
|
37
|
+
const auto* fmt = find(d, "format");
|
|
38
|
+
if (!fmt || !fmt->is_string() || fmt->as_string() != kFormatTag) return std::nullopt;
|
|
39
|
+
|
|
40
|
+
ResumeData rd;
|
|
41
|
+
if (const auto* ih = find(d, "info-hash"); ih && ih->is_string() && ih->as_string().size() == 20)
|
|
42
|
+
std::memcpy(rd.info_hash.data(), ih->as_string().data(), 20);
|
|
43
|
+
if (const auto* n = find(d, "name"); n && n->is_string()) rd.name = n->as_string();
|
|
44
|
+
if (const auto* sp = find(d, "save-path"); sp && sp->is_string()) rd.save_path = sp->as_string();
|
|
45
|
+
if (const auto* up = find(d, "uploaded"); up && up->is_integer()) rd.total_uploaded = std::uint64_t(up->as_integer());
|
|
46
|
+
if (const auto* dn = find(d, "downloaded"); dn && dn->is_integer()) rd.total_downloaded = std::uint64_t(dn->as_integer());
|
|
47
|
+
|
|
48
|
+
std::int64_t num_pieces = 0;
|
|
49
|
+
if (const auto* np = find(d, "num-pieces"); np && np->is_integer() && np->as_integer() >= 0)
|
|
50
|
+
num_pieces = np->as_integer();
|
|
51
|
+
if (const auto* p = find(d, "pieces"); p && p->is_string()) {
|
|
52
|
+
const std::string& bytes = p->as_string();
|
|
53
|
+
// `num-pieces` is attacker-controlled and drives Bitfield::assign's
|
|
54
|
+
// allocation independently of the `pieces` string length. A tiny file
|
|
55
|
+
// claiming billions of pieces would allocate gigabytes (C4). A valid
|
|
56
|
+
// record always has exactly ceil(num_pieces/8) bytes of bitfield, so
|
|
57
|
+
// reject anything that doesn't match rather than trusting the count.
|
|
58
|
+
if (std::uint64_t((num_pieces + 7) / 8) != bytes.size()) return std::nullopt;
|
|
59
|
+
rd.have.assign(reinterpret_cast<const std::uint8_t*>(bytes.data()),
|
|
60
|
+
bytes.size(), std::size_t(num_pieces));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (const auto* info = find(d, "info"); info && info->is_string())
|
|
64
|
+
rd.info_dict.assign(info->as_string().begin(), info->as_string().end());
|
|
65
|
+
|
|
66
|
+
return rd;
|
|
67
|
+
} catch (const std::exception&) {
|
|
68
|
+
return std::nullopt;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file resume_data.h
|
|
5
|
+
* @brief Fast-resume state: what a torrent needs to pick up where it left off
|
|
6
|
+
* without re-hashing every piece on disk.
|
|
7
|
+
*
|
|
8
|
+
* It is a small bencoded record — the have-bitfield, transfer totals, save path
|
|
9
|
+
* and (optionally) the verbatim info dictionary so a magnet-started torrent can
|
|
10
|
+
* resume without re-fetching metadata. On load the engine *trusts* the recorded
|
|
11
|
+
* bitfield (skipping the hash check for those pieces); the verbatim info section,
|
|
12
|
+
* if present, is re-hashed against the info-hash before it is believed.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#include "librats/util/rats_export.h"
|
|
16
|
+
#include "librats/bittorrent/bitfield.h"
|
|
17
|
+
#include "librats/bittorrent/types.h"
|
|
18
|
+
#include "librats/core/bytes.h"
|
|
19
|
+
|
|
20
|
+
#include <cstdint>
|
|
21
|
+
#include <optional>
|
|
22
|
+
#include <string>
|
|
23
|
+
|
|
24
|
+
namespace librats::bittorrent {
|
|
25
|
+
|
|
26
|
+
struct RATS_API ResumeData {
|
|
27
|
+
InfoHash info_hash{};
|
|
28
|
+
std::string name;
|
|
29
|
+
std::string save_path;
|
|
30
|
+
Bitfield have; ///< pieces already on disk
|
|
31
|
+
std::uint64_t total_uploaded = 0;
|
|
32
|
+
std::uint64_t total_downloaded = 0;
|
|
33
|
+
Bytes info_dict; ///< optional verbatim info section
|
|
34
|
+
|
|
35
|
+
/// Serialise to the on-disk bencoded form.
|
|
36
|
+
Bytes encode() const;
|
|
37
|
+
/// Parse it back. nullopt if it isn't a librats resume record.
|
|
38
|
+
static std::optional<ResumeData> decode(const Bytes& data);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#include "librats/bittorrent/store_buffer.h"
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
|
|
5
|
+
namespace librats::bittorrent {
|
|
6
|
+
|
|
7
|
+
void StoreBuffer::insert(std::uint32_t piece, std::uint32_t offset, const Bytes& data) {
|
|
8
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
9
|
+
blocks_[{piece, offset}] = data;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
void StoreBuffer::erase(std::uint32_t piece, std::uint32_t offset) {
|
|
13
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
14
|
+
blocks_.erase({piece, offset});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
void StoreBuffer::overlay(std::uint32_t piece, std::uint32_t offset, Bytes& out) const {
|
|
18
|
+
if (out.empty()) return;
|
|
19
|
+
const std::uint64_t read_begin = offset;
|
|
20
|
+
const std::uint64_t read_end = offset + out.size();
|
|
21
|
+
|
|
22
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
23
|
+
// Walk only this piece's entries: keys in [(piece,0), (piece+1,0)).
|
|
24
|
+
auto it = blocks_.lower_bound({piece, 0});
|
|
25
|
+
auto end = (piece == UINT32_MAX) ? blocks_.end() : blocks_.lower_bound({piece + 1, 0});
|
|
26
|
+
for (; it != end; ++it) {
|
|
27
|
+
const std::uint64_t blk_begin = it->first.second;
|
|
28
|
+
const std::uint64_t blk_end = blk_begin + it->second.size();
|
|
29
|
+
const std::uint64_t from = (std::max)(read_begin, blk_begin);
|
|
30
|
+
const std::uint64_t to = (std::min)(read_end, blk_end);
|
|
31
|
+
if (from >= to) continue; // no intersection
|
|
32
|
+
std::copy(it->second.begin() + std::ptrdiff_t(from - blk_begin),
|
|
33
|
+
it->second.begin() + std::ptrdiff_t(to - blk_begin),
|
|
34
|
+
out.begin() + std::ptrdiff_t(from - read_begin));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
bool StoreBuffer::empty() const {
|
|
39
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
40
|
+
return blocks_.empty();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
std::size_t StoreBuffer::size() const {
|
|
44
|
+
std::lock_guard<std::mutex> lock(mutex_);
|
|
45
|
+
return blocks_.size();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
} // namespace librats::bittorrent
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file store_buffer.h
|
|
5
|
+
* @brief In-RAM cache of blocks whose disk write is still in flight.
|
|
6
|
+
*
|
|
7
|
+
* When a block is handed to the disk for writing it is also parked here, keyed
|
|
8
|
+
* by (piece, offset within piece). A read or hash issued before that write
|
|
9
|
+
* reaches the platter is then satisfied from RAM by overlaying these bytes onto
|
|
10
|
+
* whatever the disk returned — so the engine never reads stale data for a block
|
|
11
|
+
* it has already accepted. The entry is dropped once the write completes.
|
|
12
|
+
*
|
|
13
|
+
* Thread-safe: writers insert/erase from disk-worker threads while readers
|
|
14
|
+
* overlay; all access is guarded by an internal mutex.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#include "librats/core/bytes.h"
|
|
18
|
+
|
|
19
|
+
#include <cstdint>
|
|
20
|
+
#include <map>
|
|
21
|
+
#include <mutex>
|
|
22
|
+
|
|
23
|
+
namespace librats::bittorrent {
|
|
24
|
+
|
|
25
|
+
class StoreBuffer {
|
|
26
|
+
public:
|
|
27
|
+
/// Park a pending block. Replaces any existing entry at the same key.
|
|
28
|
+
void insert(std::uint32_t piece, std::uint32_t offset, const Bytes& data);
|
|
29
|
+
|
|
30
|
+
/// Drop a block once its write has landed on disk.
|
|
31
|
+
void erase(std::uint32_t piece, std::uint32_t offset);
|
|
32
|
+
|
|
33
|
+
/// Overlay any parked bytes for @p piece that intersect
|
|
34
|
+
/// [@p offset, @p offset + out.size()) onto @p out (indexed from @p offset).
|
|
35
|
+
void overlay(std::uint32_t piece, std::uint32_t offset, Bytes& out) const;
|
|
36
|
+
|
|
37
|
+
bool empty() const;
|
|
38
|
+
std::size_t size() const;
|
|
39
|
+
|
|
40
|
+
private:
|
|
41
|
+
using Key = std::pair<std::uint32_t, std::uint32_t>; // (piece, offset)
|
|
42
|
+
|
|
43
|
+
mutable std::mutex mutex_;
|
|
44
|
+
std::map<Key, Bytes> blocks_;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
} // namespace librats::bittorrent
|