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,316 +0,0 @@
1
- #pragma once
2
-
3
- /**
4
- * @file bt_bitfield.h
5
- * @brief Efficient bitfield implementation for piece tracking
6
- *
7
- * Provides a memory-efficient bitfield class for tracking which pieces
8
- * have been downloaded or are available from peers.
9
- */
10
-
11
- #include <vector>
12
- #include <cstdint>
13
- #include <cstddef>
14
- #include <string>
15
-
16
- namespace librats {
17
-
18
- /**
19
- * @brief Efficient bit array for tracking pieces
20
- *
21
- * Uses packed uint32_t words for efficient memory usage and fast operations.
22
- * Bits are stored in big-endian order within each byte to match BitTorrent
23
- * protocol wire format.
24
- */
25
- class Bitfield {
26
- public:
27
- /**
28
- * @brief Default constructor - creates empty bitfield
29
- */
30
- Bitfield() noexcept;
31
-
32
- /**
33
- * @brief Create bitfield with specified number of bits
34
- * @param num_bits Number of bits in the bitfield
35
- * @param initial_value Initial value for all bits (default: false)
36
- */
37
- explicit Bitfield(size_t num_bits, bool initial_value = false);
38
-
39
- /**
40
- * @brief Copy constructor
41
- */
42
- Bitfield(const Bitfield& other);
43
-
44
- /**
45
- * @brief Move constructor
46
- */
47
- Bitfield(Bitfield&& other) noexcept;
48
-
49
- /**
50
- * @brief Copy assignment
51
- */
52
- Bitfield& operator=(const Bitfield& other);
53
-
54
- /**
55
- * @brief Move assignment
56
- */
57
- Bitfield& operator=(Bitfield&& other) noexcept;
58
-
59
- /**
60
- * @brief Destructor
61
- */
62
- ~Bitfield() = default;
63
-
64
- //=========================================================================
65
- // Bit Operations
66
- //=========================================================================
67
-
68
- /**
69
- * @brief Set a bit to 1
70
- * @param index Bit index (0-based)
71
- */
72
- void set_bit(size_t index);
73
-
74
- /**
75
- * @brief Clear a bit to 0
76
- * @param index Bit index (0-based)
77
- */
78
- void clear_bit(size_t index);
79
-
80
- /**
81
- * @brief Get the value of a bit
82
- * @param index Bit index (0-based)
83
- * @return true if bit is set, false otherwise
84
- */
85
- bool get_bit(size_t index) const;
86
-
87
- /**
88
- * @brief Operator[] for read access
89
- * @param index Bit index
90
- * @return true if bit is set
91
- */
92
- bool operator[](size_t index) const { return get_bit(index); }
93
-
94
- /**
95
- * @brief Set all bits to 1
96
- */
97
- void set_all();
98
-
99
- /**
100
- * @brief Clear all bits to 0
101
- */
102
- void clear_all();
103
-
104
- //=========================================================================
105
- // Query Operations
106
- //=========================================================================
107
-
108
- /**
109
- * @brief Check if all bits are set
110
- * @return true if all bits are 1
111
- */
112
- bool all_set() const;
113
-
114
- /**
115
- * @brief Check if no bits are set
116
- * @return true if all bits are 0
117
- */
118
- bool none_set() const;
119
-
120
- /**
121
- * @brief Count the number of set bits
122
- * @return Number of bits that are 1
123
- */
124
- size_t count() const;
125
-
126
- /**
127
- * @brief Get the total number of bits
128
- * @return Size of the bitfield in bits
129
- */
130
- size_t size() const noexcept { return num_bits_; }
131
-
132
- /**
133
- * @brief Check if bitfield is empty (size 0)
134
- * @return true if no bits
135
- */
136
- bool empty() const noexcept { return num_bits_ == 0; }
137
-
138
- /**
139
- * @brief Get number of bytes needed to store all bits
140
- * @return Number of bytes
141
- */
142
- size_t num_bytes() const noexcept { return (num_bits_ + 7) / 8; }
143
-
144
- /**
145
- * @brief Get number of 32-bit words used
146
- * @return Number of uint32_t words
147
- */
148
- size_t num_words() const noexcept { return data_.size(); }
149
-
150
- //=========================================================================
151
- // Bitwise Operations
152
- //=========================================================================
153
-
154
- /**
155
- * @brief Bitwise AND with another bitfield
156
- * @param other Other bitfield (must be same size)
157
- * @return Reference to this bitfield
158
- */
159
- Bitfield& operator&=(const Bitfield& other);
160
-
161
- /**
162
- * @brief Bitwise OR with another bitfield
163
- * @param other Other bitfield (must be same size)
164
- * @return Reference to this bitfield
165
- */
166
- Bitfield& operator|=(const Bitfield& other);
167
-
168
- /**
169
- * @brief Bitwise XOR with another bitfield
170
- * @param other Other bitfield (must be same size)
171
- * @return Reference to this bitfield
172
- */
173
- Bitfield& operator^=(const Bitfield& other);
174
-
175
- /**
176
- * @brief Bitwise NOT (complement)
177
- * @return New bitfield with all bits flipped
178
- */
179
- Bitfield operator~() const;
180
-
181
- /**
182
- * @brief Check if this bitfield has any bits that other doesn't have
183
- * @param other Other bitfield
184
- * @return true if (this & ~other) is non-zero
185
- */
186
- bool has_bits_not_in(const Bitfield& other) const;
187
-
188
- //=========================================================================
189
- // Serialization (Wire Format)
190
- //=========================================================================
191
-
192
- /**
193
- * @brief Convert to bytes for wire protocol
194
- *
195
- * Returns bytes in big-endian bit order as per BitTorrent spec.
196
- * Trailing bits in last byte are set to 0.
197
- *
198
- * @return Vector of bytes
199
- */
200
- std::vector<uint8_t> to_bytes() const;
201
-
202
- /**
203
- * @brief Create bitfield from bytes
204
- *
205
- * @param data Pointer to byte data
206
- * @param data_len Length of data in bytes
207
- * @param num_bits Number of bits (may be less than data_len * 8)
208
- * @return New Bitfield
209
- */
210
- static Bitfield from_bytes(const uint8_t* data, size_t data_len, size_t num_bits);
211
-
212
- /**
213
- * @brief Create bitfield from byte vector
214
- *
215
- * @param data Byte vector
216
- * @param num_bits Number of bits
217
- * @return New Bitfield
218
- */
219
- static Bitfield from_bytes(const std::vector<uint8_t>& data, size_t num_bits);
220
-
221
- //=========================================================================
222
- // Resize
223
- //=========================================================================
224
-
225
- /**
226
- * @brief Resize the bitfield
227
- *
228
- * @param new_size New number of bits
229
- * @param value Value for new bits if growing
230
- */
231
- void resize(size_t new_size, bool value = false);
232
-
233
- //=========================================================================
234
- // Iteration Helpers
235
- //=========================================================================
236
-
237
- /**
238
- * @brief Find the first set bit
239
- * @return Index of first set bit, or size() if none
240
- */
241
- size_t find_first_set() const;
242
-
243
- /**
244
- * @brief Find the first clear bit
245
- * @return Index of first clear bit, or size() if none
246
- */
247
- size_t find_first_clear() const;
248
-
249
- /**
250
- * @brief Find the next set bit after given index
251
- * @param start Starting index (exclusive)
252
- * @return Index of next set bit, or size() if none
253
- */
254
- size_t find_next_set(size_t start) const;
255
-
256
- /**
257
- * @brief Find the next clear bit after given index
258
- * @param start Starting index (exclusive)
259
- * @return Index of next clear bit, or size() if none
260
- */
261
- size_t find_next_clear(size_t start) const;
262
-
263
- //=========================================================================
264
- // Comparison
265
- //=========================================================================
266
-
267
- bool operator==(const Bitfield& other) const;
268
- bool operator!=(const Bitfield& other) const { return !(*this == other); }
269
-
270
- //=========================================================================
271
- // Debug
272
- //=========================================================================
273
-
274
- /**
275
- * @brief Convert to string representation for debugging
276
- * @return String of '0' and '1' characters
277
- */
278
- std::string to_string() const;
279
-
280
- private:
281
- std::vector<uint32_t> data_; ///< Packed bit storage
282
- size_t num_bits_; ///< Total number of bits
283
-
284
- /**
285
- * @brief Clear trailing bits that are beyond num_bits_
286
- *
287
- * Called after operations that might set bits beyond the valid range
288
- */
289
- void clear_trailing_bits();
290
-
291
- /**
292
- * @brief Count set bits in a 32-bit word (popcount)
293
- */
294
- static size_t popcount32(uint32_t x);
295
- };
296
-
297
- //=============================================================================
298
- // Free Functions
299
- //=============================================================================
300
-
301
- /**
302
- * @brief Bitwise AND of two bitfields
303
- */
304
- Bitfield operator&(const Bitfield& a, const Bitfield& b);
305
-
306
- /**
307
- * @brief Bitwise OR of two bitfields
308
- */
309
- Bitfield operator|(const Bitfield& a, const Bitfield& b);
310
-
311
- /**
312
- * @brief Bitwise XOR of two bitfields
313
- */
314
- Bitfield operator^(const Bitfield& a, const Bitfield& b);
315
-
316
- } // namespace librats
@@ -1,228 +0,0 @@
1
- #include "bt_choker.h"
2
- #include "bt_peer_connection.h"
3
-
4
- #include <algorithm>
5
- #include <random>
6
-
7
- namespace librats {
8
-
9
- //=============================================================================
10
- // Constructor
11
- //=============================================================================
12
-
13
- Choker::Choker()
14
- : optimistic_peer_(nullptr)
15
- , optimistic_rotation_index_(0) {
16
- last_rechoke_ = std::chrono::steady_clock::now();
17
- last_optimistic_rotation_ = std::chrono::steady_clock::now();
18
- }
19
-
20
- Choker::Choker(const ChokerConfig& config)
21
- : config_(config)
22
- , optimistic_peer_(nullptr)
23
- , optimistic_rotation_index_(0) {
24
- last_rechoke_ = std::chrono::steady_clock::now();
25
- last_optimistic_rotation_ = std::chrono::steady_clock::now();
26
- }
27
-
28
- void Choker::set_config(const ChokerConfig& config) {
29
- config_ = config;
30
- }
31
-
32
- bool Choker::should_rechoke() const {
33
- auto now = std::chrono::steady_clock::now();
34
- return (now - last_rechoke_) >= config_.rechoke_interval;
35
- }
36
-
37
- //=============================================================================
38
- // Main Choking Algorithm
39
- //=============================================================================
40
-
41
- ChokeResult Choker::run(std::vector<ChokePeerInfo>& peers) {
42
- last_rechoke_ = std::chrono::steady_clock::now();
43
-
44
- if (config_.seed_mode) {
45
- return run_seed_mode(peers);
46
- } else {
47
- return run_download_mode(peers);
48
- }
49
- }
50
-
51
- ChokeResult Choker::run_download_mode(std::vector<ChokePeerInfo>& peers) {
52
- ChokeResult result;
53
-
54
- if (peers.empty()) {
55
- return result;
56
- }
57
-
58
- // Check if we should rotate optimistic unchoke
59
- auto now = std::chrono::steady_clock::now();
60
- if ((now - last_optimistic_rotation_) >= config_.optimistic_interval) {
61
- rotate_optimistic(peers);
62
- }
63
-
64
- // Sort peers by download rate (best first)
65
- // Only consider peers that are interested in us
66
- std::vector<ChokePeerInfo*> interested_peers;
67
- for (auto& peer : peers) {
68
- if (peer.peer_interested && peer.connection != nullptr) {
69
- interested_peers.push_back(&peer);
70
- }
71
- }
72
-
73
- std::sort(interested_peers.begin(), interested_peers.end(),
74
- [](const ChokePeerInfo* a, const ChokePeerInfo* b) {
75
- // Prefer peers with higher download rate to us
76
- return a->download_rate > b->download_rate;
77
- });
78
-
79
- // Determine how many slots we have (excluding optimistic)
80
- size_t regular_slots = config_.max_uploads;
81
- if (optimistic_peer_ != nullptr) {
82
- regular_slots = config_.max_uploads > 0 ? config_.max_uploads - 1 : 0;
83
- }
84
-
85
- // Unchoke the top peers
86
- size_t unchoked = 0;
87
- for (auto* peer : interested_peers) {
88
- if (peer->connection == optimistic_peer_) {
89
- // Already counted as optimistic
90
- if (peer->am_choking) {
91
- result.to_unchoke.push_back(peer->connection);
92
- peer->am_choking = false;
93
- peer->last_unchoke = now;
94
- }
95
- continue;
96
- }
97
-
98
- if (unchoked < regular_slots) {
99
- if (peer->am_choking) {
100
- result.to_unchoke.push_back(peer->connection);
101
- peer->am_choking = false;
102
- peer->last_unchoke = now;
103
- }
104
- ++unchoked;
105
- } else {
106
- if (!peer->am_choking) {
107
- result.to_choke.push_back(peer->connection);
108
- peer->am_choking = true;
109
- }
110
- }
111
- }
112
-
113
- // Choke peers who are no longer interested
114
- for (auto& peer : peers) {
115
- if (!peer.peer_interested && !peer.am_choking && peer.connection != nullptr) {
116
- // Could optionally keep them unchoked for a bit
117
- // For now, choke them
118
- result.to_choke.push_back(peer.connection);
119
- peer.am_choking = true;
120
- }
121
- }
122
-
123
- return result;
124
- }
125
-
126
- ChokeResult Choker::run_seed_mode(std::vector<ChokePeerInfo>& peers) {
127
- ChokeResult result;
128
-
129
- if (peers.empty()) {
130
- return result;
131
- }
132
-
133
- auto now = std::chrono::steady_clock::now();
134
-
135
- // In seed mode, we prioritize upload rate and round-robin fairness
136
- // Sort by upload rate, but give some randomness
137
- std::vector<ChokePeerInfo*> interested_peers;
138
- for (auto& peer : peers) {
139
- if (peer.peer_interested && peer.connection != nullptr) {
140
- interested_peers.push_back(&peer);
141
- }
142
- }
143
-
144
- // Sort by upload rate (how fast we're uploading to them)
145
- // and time since last unchoke for fairness
146
- std::sort(interested_peers.begin(), interested_peers.end(),
147
- [now](const ChokePeerInfo* a, const ChokePeerInfo* b) {
148
- // Prioritize peers we haven't unchoked recently
149
- auto a_time = std::chrono::duration_cast<std::chrono::seconds>(
150
- now - a->last_unchoke).count();
151
- auto b_time = std::chrono::duration_cast<std::chrono::seconds>(
152
- now - b->last_unchoke).count();
153
-
154
- // Mix of upload speed and fairness
155
- double a_score = a->upload_rate + (a_time * 10.0);
156
- double b_score = b->upload_rate + (b_time * 10.0);
157
-
158
- return a_score > b_score;
159
- });
160
-
161
- // Unchoke top N
162
- size_t unchoked = 0;
163
- for (auto* peer : interested_peers) {
164
- if (unchoked < config_.max_uploads) {
165
- if (peer->am_choking) {
166
- result.to_unchoke.push_back(peer->connection);
167
- peer->am_choking = false;
168
- peer->last_unchoke = now;
169
- }
170
- ++unchoked;
171
- } else {
172
- if (!peer->am_choking) {
173
- result.to_choke.push_back(peer->connection);
174
- peer->am_choking = true;
175
- }
176
- }
177
- }
178
-
179
- return result;
180
- }
181
-
182
- void Choker::rotate_optimistic(std::vector<ChokePeerInfo>& peers) {
183
- last_optimistic_rotation_ = std::chrono::steady_clock::now();
184
-
185
- // Find peers that are currently choked and interested
186
- std::vector<ChokePeerInfo*> candidates;
187
- for (auto& peer : peers) {
188
- if (peer.am_choking && peer.peer_interested && peer.connection != nullptr) {
189
- candidates.push_back(&peer);
190
- }
191
- }
192
-
193
- if (candidates.empty()) {
194
- optimistic_peer_ = nullptr;
195
- return;
196
- }
197
-
198
- // Prefer peers that have been connected for a short time (new peers)
199
- // to give them a chance to prove themselves
200
- std::sort(candidates.begin(), candidates.end(),
201
- [](const ChokePeerInfo* a, const ChokePeerInfo* b) {
202
- return a->connected_at > b->connected_at; // Newer first
203
- });
204
-
205
- // Pick with some randomness weighted towards newer peers
206
- size_t index = 0;
207
- if (candidates.size() > 1) {
208
- // Prefer first 1/4 of candidates (newer)
209
- size_t range = (std::max)(candidates.size() / 4, size_t(1));
210
-
211
- static thread_local std::mt19937 gen(std::random_device{}());
212
- std::uniform_int_distribution<size_t> dis(0, range - 1);
213
- index = dis(gen);
214
- }
215
-
216
- ChokePeerInfo* selected = candidates[index];
217
- selected->is_optimistic = true;
218
- optimistic_peer_ = selected->connection;
219
-
220
- // Clear optimistic flag from previous peer
221
- for (auto& peer : peers) {
222
- if (peer.connection != optimistic_peer_) {
223
- peer.is_optimistic = false;
224
- }
225
- }
226
- }
227
-
228
- } // namespace librats
@@ -1,147 +0,0 @@
1
- #pragma once
2
-
3
- /**
4
- * @file bt_choker.h
5
- * @brief BitTorrent choking algorithm
6
- *
7
- * Implements the tit-for-tat choking algorithm for fair bandwidth distribution.
8
- * Includes optimistic unchoking for discovering faster peers.
9
- */
10
-
11
- #include <vector>
12
- #include <chrono>
13
- #include <cstdint>
14
- #include <functional>
15
-
16
- namespace librats {
17
-
18
- // Forward declaration
19
- class BtPeerConnection;
20
-
21
- /**
22
- * @brief Configuration for the choking algorithm
23
- */
24
- struct ChokerConfig {
25
- size_t max_uploads; ///< Maximum unchoked peers (default: 4)
26
- std::chrono::seconds rechoke_interval; ///< How often to re-evaluate (default: 10s)
27
- std::chrono::seconds optimistic_interval;///< Optimistic unchoke rotation (default: 30s)
28
- bool seed_mode; ///< Use seed choking algorithm
29
-
30
- ChokerConfig()
31
- : max_uploads(4)
32
- , rechoke_interval(10)
33
- , optimistic_interval(30)
34
- , seed_mode(false) {}
35
- };
36
-
37
- /**
38
- * @brief Peer info for choking decisions
39
- */
40
- struct ChokePeerInfo {
41
- BtPeerConnection* connection;
42
- double download_rate; ///< Bytes/sec we're downloading from peer
43
- double upload_rate; ///< Bytes/sec we're uploading to peer
44
- bool am_choking; ///< Are we choking this peer?
45
- bool am_interested; ///< Are we interested in this peer?
46
- bool peer_interested; ///< Is peer interested in us?
47
- bool is_optimistic; ///< Is this the optimistic unchoke slot?
48
- bool is_snubbed; ///< Has peer not sent data recently?
49
-
50
- std::chrono::steady_clock::time_point last_unchoke;
51
- std::chrono::steady_clock::time_point connected_at;
52
-
53
- ChokePeerInfo()
54
- : connection(nullptr)
55
- , download_rate(0), upload_rate(0)
56
- , am_choking(true), am_interested(false), peer_interested(false)
57
- , is_optimistic(false), is_snubbed(false) {}
58
- };
59
-
60
- /**
61
- * @brief Result of a choking decision
62
- */
63
- struct ChokeResult {
64
- std::vector<BtPeerConnection*> to_choke; ///< Peers to choke
65
- std::vector<BtPeerConnection*> to_unchoke; ///< Peers to unchoke
66
- };
67
-
68
- /**
69
- * @brief Manages choking decisions for BitTorrent peers
70
- *
71
- * The choking algorithm ensures fair bandwidth distribution:
72
- * - Unchoke top N peers based on download rate (reciprocation)
73
- * - One optimistic unchoke slot rotates to discover new fast peers
74
- * - Special handling for seed mode (upload-only)
75
- *
76
- * Thread-safe: Call run_choker() from a single thread.
77
- */
78
- class Choker {
79
- public:
80
- /**
81
- * @brief Create a choker with default config
82
- */
83
- Choker();
84
-
85
- /**
86
- * @brief Create a choker with custom config
87
- */
88
- explicit Choker(const ChokerConfig& config);
89
-
90
- /**
91
- * @brief Set configuration
92
- */
93
- void set_config(const ChokerConfig& config);
94
-
95
- /**
96
- * @brief Get current configuration
97
- */
98
- const ChokerConfig& config() const { return config_; }
99
-
100
- /**
101
- * @brief Set whether we're in seed mode
102
- */
103
- void set_seed_mode(bool seed) { config_.seed_mode = seed; }
104
-
105
- /**
106
- * @brief Run the choking algorithm
107
- *
108
- * @param peers Current peer information
109
- * @return Choking decisions
110
- */
111
- ChokeResult run(std::vector<ChokePeerInfo>& peers);
112
-
113
- /**
114
- * @brief Check if it's time to rechoke
115
- */
116
- bool should_rechoke() const;
117
-
118
- /**
119
- * @brief Get the optimistically unchoked peer
120
- */
121
- BtPeerConnection* optimistic_peer() const { return optimistic_peer_; }
122
-
123
- private:
124
- /**
125
- * @brief Run download mode choking (we're leeching)
126
- */
127
- ChokeResult run_download_mode(std::vector<ChokePeerInfo>& peers);
128
-
129
- /**
130
- * @brief Run seed mode choking (we're seeding)
131
- */
132
- ChokeResult run_seed_mode(std::vector<ChokePeerInfo>& peers);
133
-
134
- /**
135
- * @brief Select new optimistic unchoke peer
136
- */
137
- void rotate_optimistic(std::vector<ChokePeerInfo>& peers);
138
-
139
- ChokerConfig config_;
140
- BtPeerConnection* optimistic_peer_;
141
-
142
- std::chrono::steady_clock::time_point last_rechoke_;
143
- std::chrono::steady_clock::time_point last_optimistic_rotation_;
144
- size_t optimistic_rotation_index_;
145
- };
146
-
147
- } // namespace librats