librats 1.0.2 → 2.1.4

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.
Files changed (313) hide show
  1. package/README.md +137 -332
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +271 -696
  4. package/lib/index.js +383 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +396 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +731 -0
  10. package/native-src/src/librats/bindings/rats.h +352 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +42 -0
  73. package/native-src/src/librats/core/types.h +93 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/config.h +110 -0
  144. package/native-src/src/librats/node/dial_service.h +54 -0
  145. package/native-src/src/librats/node/dialer.cpp +264 -0
  146. package/native-src/src/librats/node/dialer.h +188 -0
  147. package/native-src/src/librats/node/host_events.h +26 -0
  148. package/native-src/src/librats/node/identify.cpp +130 -0
  149. package/native-src/src/librats/node/identify.h +71 -0
  150. package/native-src/src/librats/node/nat_status.cpp +103 -0
  151. package/native-src/src/librats/node/nat_status.h +118 -0
  152. package/native-src/src/librats/node/node.cpp +826 -0
  153. package/native-src/src/librats/node/node.h +333 -0
  154. package/native-src/src/librats/node/node_context.h +33 -0
  155. package/native-src/src/librats/node/peer_network.h +91 -0
  156. package/native-src/src/librats/peer/peer.h +49 -0
  157. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  158. package/native-src/src/librats/peer/peer_book.h +88 -0
  159. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  160. package/native-src/src/librats/peer/peer_id.h +62 -0
  161. package/native-src/src/librats/peer/peer_info.h +37 -0
  162. package/native-src/src/librats/peer/peer_table.cpp +137 -0
  163. package/native-src/src/librats/peer/peer_table.h +148 -0
  164. package/native-src/src/librats/security/handshaker.h +66 -0
  165. package/native-src/src/librats/security/identity.h +43 -0
  166. package/native-src/src/librats/security/noise_security.cpp +122 -0
  167. package/native-src/src/librats/security/noise_security.h +37 -0
  168. package/native-src/src/librats/security/plaintext_security.h +106 -0
  169. package/native-src/src/librats/security/session.h +37 -0
  170. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  171. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  172. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  173. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  174. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  176. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  177. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  178. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  179. package/native-src/src/librats/subsystems/hole_punch.cpp +532 -0
  180. package/native-src/src/librats/subsystems/hole_punch.h +266 -0
  181. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  182. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  184. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  185. package/native-src/src/librats/subsystems/message_json.h +88 -0
  186. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  188. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  189. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  190. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  192. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  193. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  194. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  195. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  196. package/native-src/src/librats/transport/connection.cpp +343 -0
  197. package/native-src/src/librats/transport/connection.h +283 -0
  198. package/native-src/src/librats/transport/link.h +96 -0
  199. package/native-src/src/librats/transport/reactor.cpp +540 -0
  200. package/native-src/src/librats/transport/reactor.h +224 -0
  201. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  202. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  203. package/native-src/src/librats/transport/tcp_link.h +43 -0
  204. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  205. package/native-src/src/librats/transport/udp_mux.h +363 -0
  206. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  207. package/native-src/src/librats/transport/udp_packet.h +190 -0
  208. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  209. package/native-src/src/librats/transport/udp_stream.h +614 -0
  210. package/native-src/src/librats/util/features.h.in +51 -0
  211. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  212. package/native-src/src/librats/util/fs.h +136 -0
  213. package/native-src/src/librats/util/json.cpp +1002 -0
  214. package/native-src/src/librats/util/json.h +444 -0
  215. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  216. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  217. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  218. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  219. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  220. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  221. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  222. package/native-src/src/librats/util/rats_export.h +69 -0
  223. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  224. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  225. package/native-src/src/librats/wire/frame.cpp +76 -0
  226. package/native-src/src/librats/wire/frame.h +110 -0
  227. package/native-src/src/librats/wire/message_router.cpp +45 -0
  228. package/native-src/src/librats/wire/message_router.h +47 -0
  229. package/package.json +5 -4
  230. package/scripts/build-librats.js +1 -0
  231. package/scripts/postinstall.js +3 -3
  232. package/scripts/prepare-package.js +4 -4
  233. package/scripts/verify-installation.js +63 -105
  234. package/src/librats_node.cpp +1042 -1324
  235. package/native-src/src/bencode.cpp +0 -485
  236. package/native-src/src/bencode.h +0 -145
  237. package/native-src/src/bittorrent.cpp +0 -14
  238. package/native-src/src/bittorrent.h +0 -74
  239. package/native-src/src/bt_bitfield.cpp +0 -372
  240. package/native-src/src/bt_bitfield.h +0 -316
  241. package/native-src/src/bt_choker.cpp +0 -228
  242. package/native-src/src/bt_choker.h +0 -147
  243. package/native-src/src/bt_client.cpp +0 -1047
  244. package/native-src/src/bt_client.h +0 -445
  245. package/native-src/src/bt_create_torrent.cpp +0 -677
  246. package/native-src/src/bt_create_torrent.h +0 -473
  247. package/native-src/src/bt_extension.cpp +0 -469
  248. package/native-src/src/bt_extension.h +0 -309
  249. package/native-src/src/bt_file_storage.cpp +0 -261
  250. package/native-src/src/bt_file_storage.h +0 -298
  251. package/native-src/src/bt_handshake.cpp +0 -134
  252. package/native-src/src/bt_handshake.h +0 -157
  253. package/native-src/src/bt_messages.cpp +0 -364
  254. package/native-src/src/bt_messages.h +0 -324
  255. package/native-src/src/bt_network.cpp +0 -1007
  256. package/native-src/src/bt_network.h +0 -417
  257. package/native-src/src/bt_peer_connection.cpp +0 -742
  258. package/native-src/src/bt_peer_connection.h +0 -592
  259. package/native-src/src/bt_piece_picker.cpp +0 -786
  260. package/native-src/src/bt_piece_picker.h +0 -473
  261. package/native-src/src/bt_resume_data.cpp +0 -410
  262. package/native-src/src/bt_resume_data.h +0 -249
  263. package/native-src/src/bt_torrent.cpp +0 -2120
  264. package/native-src/src/bt_torrent.h +0 -641
  265. package/native-src/src/bt_torrent_info.cpp +0 -659
  266. package/native-src/src/bt_torrent_info.h +0 -418
  267. package/native-src/src/bt_types.h +0 -621
  268. package/native-src/src/chained_send_buffer.cpp +0 -75
  269. package/native-src/src/chained_send_buffer.h +0 -137
  270. package/native-src/src/crypto/hkdf.c +0 -266
  271. package/native-src/src/crypto/poly1305.h +0 -36
  272. package/native-src/src/dht.cpp +0 -3311
  273. package/native-src/src/dht.h +0 -717
  274. package/native-src/src/disk_io.cpp +0 -632
  275. package/native-src/src/disk_io.h +0 -315
  276. package/native-src/src/file_transfer.cpp +0 -1415
  277. package/native-src/src/file_transfer.h +0 -286
  278. package/native-src/src/fs.h +0 -108
  279. package/native-src/src/gossipsub.cpp +0 -1139
  280. package/native-src/src/gossipsub.h +0 -403
  281. package/native-src/src/ice.cpp +0 -893
  282. package/native-src/src/ice.h +0 -559
  283. package/native-src/src/json.hpp +0 -25526
  284. package/native-src/src/librats.cpp +0 -2378
  285. package/native-src/src/librats.h +0 -2324
  286. package/native-src/src/librats_bittorrent.cpp +0 -601
  287. package/native-src/src/librats_c.cpp +0 -1557
  288. package/native-src/src/librats_c.h +0 -323
  289. package/native-src/src/librats_discovery.cpp +0 -402
  290. package/native-src/src/librats_encryption.cpp +0 -275
  291. package/native-src/src/librats_file_transfer.cpp +0 -144
  292. package/native-src/src/librats_gossipsub.cpp +0 -289
  293. package/native-src/src/librats_ice.cpp +0 -213
  294. package/native-src/src/librats_log_macros.h +0 -36
  295. package/native-src/src/librats_logging.cpp +0 -173
  296. package/native-src/src/librats_mdns.cpp +0 -166
  297. package/native-src/src/librats_persistence.cpp +0 -796
  298. package/native-src/src/librats_portmap.cpp +0 -419
  299. package/native-src/src/librats_reconnection.cpp +0 -218
  300. package/native-src/src/librats_statistic.cpp +0 -105
  301. package/native-src/src/librats_storage.cpp +0 -189
  302. package/native-src/src/rats_export.h +0 -17
  303. package/native-src/src/receive_buffer.cpp +0 -82
  304. package/native-src/src/receive_buffer.h +0 -127
  305. package/native-src/src/socket.h +0 -228
  306. package/native-src/src/threadmanager.cpp +0 -105
  307. package/native-src/src/threadmanager.h +0 -53
  308. package/native-src/src/tracker.cpp +0 -1264
  309. package/native-src/src/tracker.h +0 -319
  310. package/native-src/src/turn.cpp +0 -762
  311. package/native-src/src/turn.h +0 -460
  312. package/native-src/src/wakeup_pipe.h +0 -60
  313. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,473 +0,0 @@
1
- #pragma once
2
-
3
- /**
4
- * @file bt_piece_picker.h
5
- * @brief Intelligent piece selection for BitTorrent downloads
6
- *
7
- * Implements various piece picking strategies:
8
- * - Rarest-first: Download pieces that are least available in the swarm
9
- * - Sequential: Download pieces in order (for streaming)
10
- * - Random: Random selection for initial bootstrapping
11
- * - Endgame: Request same blocks from multiple peers at end of download
12
- */
13
-
14
- #include "bt_types.h"
15
- #include "bt_bitfield.h"
16
-
17
- #include <vector>
18
- #include <set>
19
- #include <unordered_set>
20
- #include <mutex>
21
- #include <optional>
22
- #include <functional>
23
-
24
- namespace librats {
25
-
26
- /**
27
- * @brief Priority level for pieces (0-7)
28
- */
29
- enum class PiecePriority : uint8_t {
30
- Skip = 0, ///< Don't download this piece
31
- Lowest = 1,
32
- Low = 2,
33
- BelowNormal = 3,
34
- Normal = 4, ///< Default priority
35
- AboveNormal = 5,
36
- High = 6,
37
- Highest = 7
38
- };
39
-
40
- /**
41
- * @brief State of a block within a piece
42
- */
43
- enum class BlockState : uint8_t {
44
- None = 0, ///< Not requested
45
- Requested = 1, ///< Request sent to peer
46
- Writing = 2, ///< Data received, being written to disk
47
- Finished = 3 ///< Written to disk
48
- };
49
-
50
- /**
51
- * @brief Information about a block request
52
- */
53
- struct BlockRequest {
54
- BlockInfo block;
55
- void* peer; ///< Opaque peer pointer (for tracking who requested)
56
-
57
- BlockRequest() : peer(nullptr) {}
58
- BlockRequest(const BlockInfo& b, void* p = nullptr) : block(b), peer(p) {}
59
-
60
- bool operator==(const BlockRequest& other) const {
61
- return block == other.block;
62
- }
63
- };
64
-
65
- /**
66
- * @brief Piece selection mode
67
- */
68
- enum class PickerMode : uint8_t {
69
- RarestFirst, ///< Pick rarest pieces first (default)
70
- Sequential, ///< Pick pieces in order
71
- Random ///< Pick random pieces
72
- };
73
-
74
- /**
75
- * @brief Statistics about a piece being downloaded
76
- */
77
- struct DownloadingPiece {
78
- uint32_t piece_index;
79
- uint16_t blocks_total;
80
- uint16_t blocks_requested;
81
- uint16_t blocks_writing;
82
- uint16_t blocks_finished;
83
-
84
- DownloadingPiece()
85
- : piece_index(0), blocks_total(0), blocks_requested(0)
86
- , blocks_writing(0), blocks_finished(0) {}
87
-
88
- explicit DownloadingPiece(uint32_t idx, uint16_t total)
89
- : piece_index(idx), blocks_total(total), blocks_requested(0)
90
- , blocks_writing(0), blocks_finished(0) {}
91
-
92
- bool is_complete() const { return blocks_finished == blocks_total; }
93
- bool is_empty() const { return blocks_requested == 0 && blocks_finished == 0; }
94
- };
95
-
96
- /// Default maximum number of pieces downloading simultaneously
97
- /// This prevents memory bloat and improves piece completion rate
98
- constexpr size_t DEFAULT_MAX_DOWNLOADING_PIECES = 20;
99
-
100
- /**
101
- * @brief Intelligent piece picker for BitTorrent downloads
102
- *
103
- * This class manages:
104
- * - Which pieces to request next based on availability and priority
105
- * - Tracking of in-progress pieces and their blocks
106
- * - Peer piece availability
107
- * - Endgame mode for finishing downloads
108
- *
109
- * Thread-safe: All public methods are protected by a mutex.
110
- */
111
- class PiecePicker {
112
- public:
113
- /**
114
- * @brief Create a piece picker
115
- * @param num_pieces Total number of pieces in the torrent
116
- * @param piece_length Length of each piece in bytes
117
- * @param last_piece_length Length of the last piece (may be smaller)
118
- */
119
- PiecePicker(uint32_t num_pieces, uint32_t piece_length, uint32_t last_piece_length);
120
-
121
- /**
122
- * @brief Destructor
123
- */
124
- ~PiecePicker();
125
-
126
- // Non-copyable
127
- PiecePicker(const PiecePicker&) = delete;
128
- PiecePicker& operator=(const PiecePicker&) = delete;
129
-
130
- // Movable
131
- PiecePicker(PiecePicker&&) noexcept;
132
- PiecePicker& operator=(PiecePicker&&) noexcept;
133
-
134
- //=========================================================================
135
- // Configuration
136
- //=========================================================================
137
-
138
- /**
139
- * @brief Set the picking mode
140
- */
141
- void set_mode(PickerMode mode);
142
-
143
- /**
144
- * @brief Get the current picking mode
145
- */
146
- PickerMode mode() const;
147
-
148
- /**
149
- * @brief Set priority for a specific piece
150
- */
151
- void set_piece_priority(uint32_t piece, PiecePriority priority);
152
-
153
- /**
154
- * @brief Get priority for a specific piece
155
- */
156
- PiecePriority piece_priority(uint32_t piece) const;
157
-
158
- /**
159
- * @brief Set priority for a range of pieces
160
- */
161
- void set_piece_priority_range(uint32_t start, uint32_t end, PiecePriority priority);
162
-
163
- /**
164
- * @brief Set maximum number of pieces to download simultaneously
165
- *
166
- * Limits memory usage and improves piece completion rate by focusing
167
- * on completing partial pieces before starting new ones.
168
- */
169
- void set_max_downloading_pieces(size_t max) { max_downloading_pieces_ = max; }
170
-
171
- /**
172
- * @brief Get maximum number of pieces to download simultaneously
173
- */
174
- size_t max_downloading_pieces() const { return max_downloading_pieces_; }
175
-
176
- //=========================================================================
177
- // Piece State Management
178
- //=========================================================================
179
-
180
- /**
181
- * @brief Mark a piece as having been downloaded and verified
182
- * @param piece Piece index
183
- */
184
- void mark_have(uint32_t piece);
185
-
186
- /**
187
- * @brief Mark ALL pieces as having been downloaded and verified
188
- *
189
- * Used for seed_mode when we assume all files are complete.
190
- * This is more efficient than calling mark_have() for each piece.
191
- */
192
- void mark_have_all();
193
-
194
- /**
195
- * @brief Check if we have a piece
196
- * @param piece Piece index
197
- */
198
- bool have_piece(uint32_t piece) const;
199
-
200
- /**
201
- * @brief Get bitfield of pieces we have
202
- */
203
- Bitfield get_have_bitfield() const;
204
-
205
- /**
206
- * @brief Set the initial have bitfield (for resume)
207
- */
208
- void set_have_bitfield(const Bitfield& have);
209
-
210
- /**
211
- * @brief Get number of pieces we have
212
- */
213
- uint32_t num_have() const;
214
-
215
- /**
216
- * @brief Get number of pieces we still need
217
- */
218
- uint32_t num_want() const;
219
-
220
- /**
221
- * @brief Check if download is complete
222
- */
223
- bool is_complete() const;
224
-
225
- //=========================================================================
226
- // Peer Availability
227
- //=========================================================================
228
-
229
- /**
230
- * @brief Add a peer's piece availability
231
- * @param peer_id Unique identifier for the peer
232
- * @param bitfield Peer's have bitfield
233
- */
234
- void add_peer(void* peer_id, const Bitfield& bitfield);
235
-
236
- /**
237
- * @brief Remove a peer's contribution to availability
238
- * @param peer_id Peer to remove
239
- */
240
- void remove_peer(void* peer_id);
241
-
242
- /**
243
- * @brief Update a peer's availability (received HAVE message)
244
- * @param peer_id Peer identifier
245
- * @param piece Piece the peer now has
246
- */
247
- void peer_has_piece(void* peer_id, uint32_t piece);
248
-
249
- /**
250
- * @brief Get availability count for a piece
251
- * @param piece Piece index
252
- * @return Number of peers that have this piece
253
- */
254
- uint32_t availability(uint32_t piece) const;
255
-
256
- //=========================================================================
257
- // Piece Picking
258
- //=========================================================================
259
-
260
- /**
261
- * @brief Pick pieces to request from a peer
262
- *
263
- * @param peer_bitfield Pieces the peer has
264
- * @param num_blocks Maximum number of blocks to return
265
- * @param peer_id Peer identifier (for tracking)
266
- * @return List of blocks to request
267
- */
268
- std::vector<BlockRequest> pick_pieces(
269
- const Bitfield& peer_bitfield,
270
- size_t num_blocks,
271
- void* peer_id);
272
-
273
- /**
274
- * @brief Pick a single piece to request
275
- *
276
- * @param peer_bitfield Pieces the peer has
277
- * @return Piece index, or nullopt if no suitable piece
278
- */
279
- std::optional<uint32_t> pick_piece(const Bitfield& peer_bitfield);
280
-
281
- /**
282
- * @brief Check if a peer has pieces we're interested in
283
- */
284
- bool is_interesting(const Bitfield& peer_bitfield) const;
285
-
286
- //=========================================================================
287
- // Block Management
288
- //=========================================================================
289
-
290
- /**
291
- * @brief Mark a block as requested
292
- * @param block Block info
293
- * @param peer_id Peer the block was requested from
294
- */
295
- void mark_requested(const BlockInfo& block, void* peer_id);
296
-
297
- /**
298
- * @brief Mark a block as being written to disk
299
- * @param block Block info
300
- */
301
- void mark_writing(const BlockInfo& block);
302
-
303
- /**
304
- * @brief Mark a block as finished (written to disk)
305
- * @param block Block info
306
- * @return true if this completes the piece
307
- */
308
- bool mark_finished(const BlockInfo& block);
309
-
310
- /**
311
- * @brief Cancel a block request
312
- * @param block Block info
313
- * @param peer_id Peer the request was sent to
314
- */
315
- void cancel_request(const BlockInfo& block, void* peer_id);
316
-
317
- /**
318
- * @brief Cancel all requests to a peer
319
- * @param peer_id Peer identifier
320
- */
321
- void cancel_peer_requests(void* peer_id);
322
-
323
- /**
324
- * @brief Abort download of a specific block (e.g., when peer rejects request)
325
- * @param block Block to abort
326
- * @param peer_id Peer that was downloading the block (optional)
327
- *
328
- * Marks the block as available for re-request from another peer.
329
- */
330
- void abort_download(const BlockInfo& block, void* peer_id = nullptr);
331
-
332
- /**
333
- * @brief Get state of a specific block
334
- */
335
- BlockState block_state(const BlockInfo& block) const;
336
-
337
- //=========================================================================
338
- // Endgame Mode
339
- //=========================================================================
340
-
341
- /**
342
- * @brief Check if we're in endgame mode
343
- *
344
- * Endgame mode is activated when we have most pieces and only a few
345
- * blocks remaining. In this mode, we may request the same block from
346
- * multiple peers.
347
- */
348
- bool in_endgame_mode() const;
349
-
350
- /**
351
- * @brief Enable/disable endgame mode
352
- */
353
- void set_endgame_mode(bool enable);
354
-
355
- //=========================================================================
356
- // Statistics
357
- //=========================================================================
358
-
359
- /**
360
- * @brief Get number of pieces currently being downloaded
361
- */
362
- size_t num_downloading() const;
363
-
364
- /**
365
- * @brief Get list of pieces currently being downloaded
366
- */
367
- std::vector<DownloadingPiece> downloading_pieces() const;
368
-
369
- /**
370
- * @brief Get information about a specific downloading piece
371
- */
372
- std::optional<DownloadingPiece> get_downloading_piece(uint32_t piece) const;
373
-
374
- //=========================================================================
375
- // Utility
376
- //=========================================================================
377
-
378
- /**
379
- * @brief Get number of blocks in a piece
380
- */
381
- uint32_t blocks_in_piece(uint32_t piece) const;
382
-
383
- /**
384
- * @brief Get size of a specific block
385
- */
386
- uint32_t block_size(uint32_t piece, uint32_t block_index) const;
387
-
388
- /**
389
- * @brief Get total number of pieces
390
- */
391
- uint32_t num_pieces() const { return num_pieces_; }
392
-
393
- /**
394
- * @brief Get piece length
395
- */
396
- uint32_t piece_length() const { return piece_length_; }
397
-
398
- private:
399
- //=========================================================================
400
- // Internal Types
401
- //=========================================================================
402
-
403
- struct PieceState {
404
- uint32_t availability; // How many peers have this piece
405
- PiecePriority priority;
406
- bool have; // We have this piece
407
- bool downloading; // Currently downloading
408
-
409
- PieceState()
410
- : availability(0), priority(PiecePriority::Normal)
411
- , have(false), downloading(false) {}
412
- };
413
-
414
- struct BlockInfo_Internal {
415
- BlockState state;
416
- void* peer; // Who we requested from
417
-
418
- BlockInfo_Internal() : state(BlockState::None), peer(nullptr) {}
419
- };
420
-
421
- struct DownloadingPieceState {
422
- uint32_t piece_index;
423
- std::vector<BlockInfo_Internal> blocks;
424
-
425
- explicit DownloadingPieceState(uint32_t idx, size_t num_blocks)
426
- : piece_index(idx), blocks(num_blocks) {}
427
- };
428
-
429
- //=========================================================================
430
- // Internal Methods
431
- //=========================================================================
432
-
433
- uint32_t pick_rarest(const Bitfield& peer_bitfield) const;
434
- uint32_t pick_sequential(const Bitfield& peer_bitfield) const;
435
- uint32_t pick_random(const Bitfield& peer_bitfield) const;
436
-
437
- DownloadingPieceState* get_or_create_downloading(uint32_t piece);
438
- DownloadingPieceState* find_downloading(uint32_t piece);
439
- const DownloadingPieceState* find_downloading(uint32_t piece) const;
440
- void remove_downloading(uint32_t piece);
441
-
442
- void check_endgame();
443
-
444
- //=========================================================================
445
- // Data
446
- //=========================================================================
447
-
448
- mutable std::mutex mutex_;
449
-
450
- uint32_t num_pieces_;
451
- uint32_t piece_length_;
452
- uint32_t last_piece_length_;
453
-
454
- PickerMode mode_;
455
- bool endgame_enabled_;
456
- bool in_endgame_;
457
- size_t max_downloading_pieces_;
458
-
459
- std::vector<PieceState> pieces_;
460
- std::vector<DownloadingPieceState> downloading_;
461
-
462
- // Track which pieces each peer has (for accurate availability on disconnect)
463
- std::unordered_map<void*, Bitfield> peer_pieces_;
464
-
465
- // Cached counts
466
- uint32_t num_have_;
467
- uint32_t num_downloading_;
468
-
469
- // Sequential mode cursor
470
- uint32_t sequential_cursor_;
471
- };
472
-
473
- } // namespace librats