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.
Files changed (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -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 +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -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 +43 -0
  73. package/native-src/src/librats/core/types.h +103 -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/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /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