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
|
@@ -1,469 +0,0 @@
|
|
|
1
|
-
#include "bt_extension.h"
|
|
2
|
-
#include "bt_peer_connection.h"
|
|
3
|
-
|
|
4
|
-
#include <algorithm>
|
|
5
|
-
#include <cstring>
|
|
6
|
-
|
|
7
|
-
namespace librats {
|
|
8
|
-
|
|
9
|
-
//=============================================================================
|
|
10
|
-
// ExtensionManager
|
|
11
|
-
//=============================================================================
|
|
12
|
-
|
|
13
|
-
ExtensionManager::ExtensionManager(BtPeerConnection* conn)
|
|
14
|
-
: conn_(conn) {
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
void ExtensionManager::register_extension(std::shared_ptr<BtExtension> extension,
|
|
18
|
-
uint8_t local_id) {
|
|
19
|
-
extensions_[extension->name()] = extension;
|
|
20
|
-
local_id_map_[local_id] = extension;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
std::shared_ptr<BtExtension> ExtensionManager::get_extension(const std::string& name) {
|
|
24
|
-
auto it = extensions_.find(name);
|
|
25
|
-
if (it != extensions_.end()) {
|
|
26
|
-
return it->second;
|
|
27
|
-
}
|
|
28
|
-
return nullptr;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
std::vector<uint8_t> ExtensionManager::create_handshake() {
|
|
32
|
-
BencodeValue handshake = BencodeValue::create_dict();
|
|
33
|
-
|
|
34
|
-
// Build 'm' dictionary with extension name -> our local ID
|
|
35
|
-
BencodeValue m = BencodeValue::create_dict();
|
|
36
|
-
for (const auto& [local_id, ext] : local_id_map_) {
|
|
37
|
-
m[ext->name()] = BencodeValue(static_cast<int64_t>(local_id));
|
|
38
|
-
}
|
|
39
|
-
handshake["m"] = m;
|
|
40
|
-
|
|
41
|
-
// Let each extension add its data
|
|
42
|
-
for (const auto& [name, ext] : extensions_) {
|
|
43
|
-
ext->add_handshake_data(handshake.as_dict());
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Add client ID
|
|
47
|
-
handshake["v"] = BencodeValue("librats");
|
|
48
|
-
|
|
49
|
-
return handshake.encode();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
void ExtensionManager::process_handshake(const std::vector<uint8_t>& payload) {
|
|
53
|
-
// Decode bencoded handshake
|
|
54
|
-
BencodeValue decoded;
|
|
55
|
-
try {
|
|
56
|
-
decoded = BencodeDecoder::decode(payload);
|
|
57
|
-
} catch (...) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (!decoded.is_dict()) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const auto& dict = decoded.as_dict();
|
|
66
|
-
|
|
67
|
-
// Extract metadata_size if present
|
|
68
|
-
auto metadata_size_it = dict.find("metadata_size");
|
|
69
|
-
if (metadata_size_it != dict.end() && metadata_size_it->second.is_integer()) {
|
|
70
|
-
metadata_size_ = static_cast<size_t>(metadata_size_it->second.as_integer());
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Parse 'm' dictionary for extension IDs
|
|
74
|
-
auto m_it = dict.find("m");
|
|
75
|
-
if (m_it != dict.end() && m_it->second.is_dict()) {
|
|
76
|
-
const auto& m = m_it->second.as_dict();
|
|
77
|
-
|
|
78
|
-
for (const auto& [name, ext] : extensions_) {
|
|
79
|
-
auto ext_it = m.find(name);
|
|
80
|
-
if (ext_it != m.end() && ext_it->second.is_integer()) {
|
|
81
|
-
uint8_t peer_id = static_cast<uint8_t>(ext_it->second.as_integer());
|
|
82
|
-
ext->set_peer_msg_id(peer_id);
|
|
83
|
-
if (peer_id != 0) {
|
|
84
|
-
peer_id_map_[peer_id] = ext;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Notify all extensions of handshake
|
|
91
|
-
for (const auto& [name, ext] : extensions_) {
|
|
92
|
-
ext->on_handshake(dict);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
bool ExtensionManager::handle_message(uint8_t extension_id,
|
|
97
|
-
const std::vector<uint8_t>& payload) {
|
|
98
|
-
// Extension ID 0 is handshake
|
|
99
|
-
if (extension_id == 0) {
|
|
100
|
-
process_handshake(payload);
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Find extension by our local ID
|
|
105
|
-
auto it = local_id_map_.find(extension_id);
|
|
106
|
-
if (it != local_id_map_.end()) {
|
|
107
|
-
return it->second->on_message(extension_id, payload);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
void ExtensionManager::send_message(const std::string& extension_name,
|
|
114
|
-
const std::vector<uint8_t>& payload) {
|
|
115
|
-
auto ext = get_extension(extension_name);
|
|
116
|
-
if (!ext || !ext->peer_supports()) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Send using peer's message ID
|
|
121
|
-
if (conn_) {
|
|
122
|
-
conn_->send_extended(ext->peer_msg_id(), payload);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
//=============================================================================
|
|
127
|
-
// UtMetadataExtension
|
|
128
|
-
//=============================================================================
|
|
129
|
-
|
|
130
|
-
UtMetadataExtension::UtMetadataExtension(size_t metadata_size,
|
|
131
|
-
const std::vector<uint8_t>* our_metadata)
|
|
132
|
-
: metadata_size_(metadata_size)
|
|
133
|
-
, our_metadata_(our_metadata)
|
|
134
|
-
, metadata_complete_(false) {
|
|
135
|
-
|
|
136
|
-
if (metadata_size_ > 0) {
|
|
137
|
-
uint32_t pieces = num_pieces();
|
|
138
|
-
pieces_received_.resize(pieces, false);
|
|
139
|
-
pieces_requested_.resize(pieces, false);
|
|
140
|
-
received_metadata_.resize(metadata_size_);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
void UtMetadataExtension::on_handshake(const BencodeDict& handshake) {
|
|
145
|
-
auto it = handshake.find("metadata_size");
|
|
146
|
-
if (it != handshake.end() && it->second.is_integer()) {
|
|
147
|
-
size_t new_size = static_cast<size_t>(it->second.as_integer());
|
|
148
|
-
|
|
149
|
-
if (metadata_size_ == 0 && new_size > 0) {
|
|
150
|
-
metadata_size_ = new_size;
|
|
151
|
-
uint32_t pieces = num_pieces();
|
|
152
|
-
pieces_received_.resize(pieces, false);
|
|
153
|
-
pieces_requested_.resize(pieces, false);
|
|
154
|
-
received_metadata_.resize(metadata_size_);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
bool UtMetadataExtension::on_message(uint8_t /*msg_id*/,
|
|
160
|
-
const std::vector<uint8_t>& payload) {
|
|
161
|
-
// Decode the message
|
|
162
|
-
BencodeValue decoded;
|
|
163
|
-
try {
|
|
164
|
-
decoded = BencodeDecoder::decode(payload);
|
|
165
|
-
} catch (...) {
|
|
166
|
-
return false;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (!decoded.is_dict()) {
|
|
170
|
-
return false;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const auto& dict = decoded.as_dict();
|
|
174
|
-
|
|
175
|
-
auto msg_type_it = dict.find("msg_type");
|
|
176
|
-
if (msg_type_it == dict.end() || !msg_type_it->second.is_integer()) {
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
uint8_t msg_type = static_cast<uint8_t>(msg_type_it->second.as_integer());
|
|
181
|
-
|
|
182
|
-
switch (static_cast<UtMetadataMessageType>(msg_type)) {
|
|
183
|
-
case UtMetadataMessageType::Request:
|
|
184
|
-
handle_request(dict);
|
|
185
|
-
break;
|
|
186
|
-
case UtMetadataMessageType::Data:
|
|
187
|
-
handle_data(dict, payload);
|
|
188
|
-
break;
|
|
189
|
-
case UtMetadataMessageType::Reject:
|
|
190
|
-
handle_reject(dict);
|
|
191
|
-
break;
|
|
192
|
-
default:
|
|
193
|
-
return false;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
void UtMetadataExtension::add_handshake_data(BencodeDict& handshake) {
|
|
200
|
-
if (our_metadata_ && !our_metadata_->empty()) {
|
|
201
|
-
handshake["metadata_size"] = BencodeValue(static_cast<int64_t>(our_metadata_->size()));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
std::vector<uint8_t> UtMetadataExtension::create_request(uint32_t piece) {
|
|
206
|
-
BencodeValue msg = BencodeValue::create_dict();
|
|
207
|
-
msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Request));
|
|
208
|
-
msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
|
|
209
|
-
|
|
210
|
-
if (piece < pieces_requested_.size()) {
|
|
211
|
-
pieces_requested_[piece] = true;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return msg.encode();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
std::vector<uint8_t> UtMetadataExtension::create_data(uint32_t piece,
|
|
218
|
-
const std::vector<uint8_t>& data) {
|
|
219
|
-
BencodeValue msg = BencodeValue::create_dict();
|
|
220
|
-
msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Data));
|
|
221
|
-
msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
|
|
222
|
-
msg["total_size"] = BencodeValue(static_cast<int64_t>(metadata_size_));
|
|
223
|
-
|
|
224
|
-
std::vector<uint8_t> result = msg.encode();
|
|
225
|
-
|
|
226
|
-
// Append raw data after bencoded dict
|
|
227
|
-
result.insert(result.end(), data.begin(), data.end());
|
|
228
|
-
|
|
229
|
-
return result;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
std::vector<uint8_t> UtMetadataExtension::create_reject(uint32_t piece) {
|
|
233
|
-
BencodeValue msg = BencodeValue::create_dict();
|
|
234
|
-
msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Reject));
|
|
235
|
-
msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
|
|
236
|
-
return msg.encode();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
uint32_t UtMetadataExtension::num_pieces() const {
|
|
240
|
-
if (metadata_size_ == 0) return 0;
|
|
241
|
-
return static_cast<uint32_t>((metadata_size_ + BT_METADATA_PIECE_SIZE - 1) / BT_METADATA_PIECE_SIZE);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
void UtMetadataExtension::handle_request(const BencodeDict& msg) {
|
|
245
|
-
auto piece_it = msg.find("piece");
|
|
246
|
-
if (piece_it == msg.end() || !piece_it->second.is_integer()) {
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
|
|
251
|
-
|
|
252
|
-
// If we have metadata, we could respond here
|
|
253
|
-
// This would require access to the connection to send
|
|
254
|
-
(void)piece;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
void UtMetadataExtension::handle_data(const BencodeDict& msg,
|
|
258
|
-
const std::vector<uint8_t>& payload) {
|
|
259
|
-
auto piece_it = msg.find("piece");
|
|
260
|
-
if (piece_it == msg.end() || !piece_it->second.is_integer()) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
|
|
265
|
-
|
|
266
|
-
if (piece >= num_pieces()) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Find where the data starts (after the bencoded dict)
|
|
271
|
-
// The dict ends with 'e', so we need to find the end of the dict
|
|
272
|
-
size_t dict_end = 0;
|
|
273
|
-
int depth = 0;
|
|
274
|
-
for (size_t i = 0; i < payload.size(); ++i) {
|
|
275
|
-
if (payload[i] == 'd' || payload[i] == 'l') {
|
|
276
|
-
++depth;
|
|
277
|
-
} else if (payload[i] == 'e') {
|
|
278
|
-
--depth;
|
|
279
|
-
if (depth == 0) {
|
|
280
|
-
dict_end = i + 1;
|
|
281
|
-
break;
|
|
282
|
-
}
|
|
283
|
-
} else if (std::isdigit(payload[i])) {
|
|
284
|
-
// Skip string
|
|
285
|
-
size_t len = 0;
|
|
286
|
-
while (i < payload.size() && std::isdigit(payload[i])) {
|
|
287
|
-
len = len * 10 + (payload[i] - '0');
|
|
288
|
-
++i;
|
|
289
|
-
}
|
|
290
|
-
if (i < payload.size() && payload[i] == ':') {
|
|
291
|
-
i += len; // Skip the string content
|
|
292
|
-
}
|
|
293
|
-
} else if (payload[i] == 'i') {
|
|
294
|
-
// Skip integer
|
|
295
|
-
while (i < payload.size() && payload[i] != 'e') {
|
|
296
|
-
++i;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (dict_end >= payload.size()) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// Copy data to correct position
|
|
306
|
-
size_t offset = static_cast<size_t>(piece) * BT_METADATA_PIECE_SIZE;
|
|
307
|
-
size_t data_size = payload.size() - dict_end;
|
|
308
|
-
size_t to_copy = (std::min)(data_size, metadata_size_ - offset);
|
|
309
|
-
|
|
310
|
-
if (offset + to_copy <= received_metadata_.size()) {
|
|
311
|
-
std::memcpy(received_metadata_.data() + offset, payload.data() + dict_end, to_copy);
|
|
312
|
-
pieces_received_[piece] = true;
|
|
313
|
-
|
|
314
|
-
check_complete();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
void UtMetadataExtension::handle_reject(const BencodeDict& msg) {
|
|
319
|
-
auto piece_it = msg.find("piece");
|
|
320
|
-
if (piece_it == msg.end() || !piece_it->second.is_integer()) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
|
|
325
|
-
|
|
326
|
-
if (piece < pieces_requested_.size()) {
|
|
327
|
-
pieces_requested_[piece] = false; // Can retry later
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
void UtMetadataExtension::check_complete() {
|
|
332
|
-
for (bool received : pieces_received_) {
|
|
333
|
-
if (!received) return;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
metadata_complete_ = true;
|
|
337
|
-
|
|
338
|
-
if (on_metadata_complete_) {
|
|
339
|
-
on_metadata_complete_(received_metadata_);
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
uint32_t UtMetadataExtension::next_piece_to_request() const {
|
|
344
|
-
for (uint32_t i = 0; i < num_pieces(); ++i) {
|
|
345
|
-
if (!pieces_received_[i] && !pieces_requested_[i]) {
|
|
346
|
-
return i;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
return num_pieces();
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
//=============================================================================
|
|
353
|
-
// UtPexExtension
|
|
354
|
-
//=============================================================================
|
|
355
|
-
|
|
356
|
-
UtPexExtension::UtPexExtension() {
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
void UtPexExtension::on_handshake(const BencodeDict& /*handshake*/) {
|
|
360
|
-
// Nothing to do
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
bool UtPexExtension::on_message(uint8_t /*msg_id*/,
|
|
364
|
-
const std::vector<uint8_t>& payload) {
|
|
365
|
-
BencodeValue decoded;
|
|
366
|
-
try {
|
|
367
|
-
decoded = BencodeDecoder::decode(payload);
|
|
368
|
-
} catch (...) {
|
|
369
|
-
return false;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (!decoded.is_dict()) {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const auto& dict = decoded.as_dict();
|
|
377
|
-
|
|
378
|
-
std::vector<PexPeer> added, dropped;
|
|
379
|
-
|
|
380
|
-
// Parse added peers (IPv4)
|
|
381
|
-
auto added_it = dict.find("added");
|
|
382
|
-
if (added_it != dict.end() && added_it->second.is_string()) {
|
|
383
|
-
added = parse_peers(added_it->second.as_string());
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
// Parse dropped peers
|
|
387
|
-
auto dropped_it = dict.find("dropped");
|
|
388
|
-
if (dropped_it != dict.end() && dropped_it->second.is_string()) {
|
|
389
|
-
dropped = parse_peers(dropped_it->second.as_string());
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
if (on_peers_) {
|
|
393
|
-
on_peers_(added, dropped);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
return true;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
void UtPexExtension::add_handshake_data(BencodeDict& /*handshake*/) {
|
|
400
|
-
// Nothing to add
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
std::vector<uint8_t> UtPexExtension::create_message(const std::vector<PexPeer>& added,
|
|
404
|
-
const std::vector<PexPeer>& dropped) {
|
|
405
|
-
BencodeValue msg = BencodeValue::create_dict();
|
|
406
|
-
|
|
407
|
-
// Encode added peers in compact format (6 bytes each: 4 IP + 2 port)
|
|
408
|
-
std::string added_compact;
|
|
409
|
-
for (const auto& peer : added) {
|
|
410
|
-
// Parse IP
|
|
411
|
-
uint32_t ip_parts[4];
|
|
412
|
-
if (sscanf(peer.ip.c_str(), "%u.%u.%u.%u",
|
|
413
|
-
&ip_parts[0], &ip_parts[1], &ip_parts[2], &ip_parts[3]) == 4) {
|
|
414
|
-
added_compact += static_cast<char>(ip_parts[0]);
|
|
415
|
-
added_compact += static_cast<char>(ip_parts[1]);
|
|
416
|
-
added_compact += static_cast<char>(ip_parts[2]);
|
|
417
|
-
added_compact += static_cast<char>(ip_parts[3]);
|
|
418
|
-
added_compact += static_cast<char>((peer.port >> 8) & 0xFF);
|
|
419
|
-
added_compact += static_cast<char>(peer.port & 0xFF);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
msg["added"] = BencodeValue(added_compact);
|
|
423
|
-
|
|
424
|
-
// Encode dropped peers
|
|
425
|
-
std::string dropped_compact;
|
|
426
|
-
for (const auto& peer : dropped) {
|
|
427
|
-
uint32_t ip_parts[4];
|
|
428
|
-
if (sscanf(peer.ip.c_str(), "%u.%u.%u.%u",
|
|
429
|
-
&ip_parts[0], &ip_parts[1], &ip_parts[2], &ip_parts[3]) == 4) {
|
|
430
|
-
dropped_compact += static_cast<char>(ip_parts[0]);
|
|
431
|
-
dropped_compact += static_cast<char>(ip_parts[1]);
|
|
432
|
-
dropped_compact += static_cast<char>(ip_parts[2]);
|
|
433
|
-
dropped_compact += static_cast<char>(ip_parts[3]);
|
|
434
|
-
dropped_compact += static_cast<char>((peer.port >> 8) & 0xFF);
|
|
435
|
-
dropped_compact += static_cast<char>(peer.port & 0xFF);
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
msg["dropped"] = BencodeValue(dropped_compact);
|
|
439
|
-
|
|
440
|
-
return msg.encode();
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
std::vector<PexPeer> UtPexExtension::parse_peers(const std::string& compact_peers) {
|
|
444
|
-
std::vector<PexPeer> peers;
|
|
445
|
-
|
|
446
|
-
// Each peer is 6 bytes: 4 for IP, 2 for port
|
|
447
|
-
for (size_t i = 0; i + 6 <= compact_peers.size(); i += 6) {
|
|
448
|
-
PexPeer peer;
|
|
449
|
-
|
|
450
|
-
// Parse IP
|
|
451
|
-
char ip_str[16];
|
|
452
|
-
snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
|
|
453
|
-
static_cast<unsigned char>(compact_peers[i]),
|
|
454
|
-
static_cast<unsigned char>(compact_peers[i + 1]),
|
|
455
|
-
static_cast<unsigned char>(compact_peers[i + 2]),
|
|
456
|
-
static_cast<unsigned char>(compact_peers[i + 3]));
|
|
457
|
-
peer.ip = ip_str;
|
|
458
|
-
|
|
459
|
-
// Parse port (big-endian)
|
|
460
|
-
peer.port = (static_cast<uint16_t>(static_cast<unsigned char>(compact_peers[i + 4])) << 8) |
|
|
461
|
-
static_cast<uint16_t>(static_cast<unsigned char>(compact_peers[i + 5]));
|
|
462
|
-
|
|
463
|
-
peers.push_back(peer);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
return peers;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
} // namespace librats
|