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
@@ -0,0 +1,97 @@
1
+ #include "librats/bittorrent/bitfield.h"
2
+
3
+ #include <algorithm>
4
+ #include <array>
5
+
6
+ namespace librats::bittorrent {
7
+
8
+ namespace {
9
+
10
+ /// 256-entry popcount table, built once. Reading a table beats per-bit work and
11
+ /// keeps count() branch-free and portable across compilers (no C++20 std::popcount).
12
+ const std::array<std::uint8_t, 256>& popcount_table() {
13
+ static const std::array<std::uint8_t, 256> table = [] {
14
+ std::array<std::uint8_t, 256> t{};
15
+ for (int i = 0; i < 256; ++i) {
16
+ std::uint8_t bits = 0;
17
+ for (int b = i; b; b >>= 1) bits += b & 1;
18
+ t[std::size_t(i)] = bits;
19
+ }
20
+ return t;
21
+ }();
22
+ return table;
23
+ }
24
+
25
+ } // namespace
26
+
27
+ void Bitfield::resize(std::size_t bits, bool value) {
28
+ const std::size_t old_bits = bits_;
29
+ const std::size_t new_bytes = (bits + 7) / 8;
30
+
31
+ // resize() fills only the *newly appended* bytes with the fill value.
32
+ bytes_.resize(new_bytes, value ? 0xFFu : 0x00u);
33
+ bits_ = bits;
34
+
35
+ // When growing with value=true, the spare bits left over in the old (partial)
36
+ // last byte were trailing zeros and weren't touched by resize() — set them.
37
+ if (value && bits > old_bits) {
38
+ const std::size_t old_byte_end = (old_bits + 7) / 8 * 8; // bit just past old last byte
39
+ for (std::size_t i = old_bits; i < (std::min)(bits, old_byte_end); ++i) set(i);
40
+ }
41
+ clear_trailing_bits();
42
+ }
43
+
44
+ void Bitfield::assign(const std::uint8_t* data, std::size_t bytes, std::size_t bits) {
45
+ bytes_.assign(data, data + bytes);
46
+ bytes_.resize((bits + 7) / 8, 0x00u); // tolerate a short/long wire buffer
47
+ bits_ = bits;
48
+ clear_trailing_bits();
49
+ }
50
+
51
+ void Bitfield::clear_trailing_bits() noexcept {
52
+ const std::size_t rem = bits_ & 7;
53
+ if (rem != 0 && !bytes_.empty()) {
54
+ bytes_.back() &= std::uint8_t(0xFFu << (8 - rem)); // keep the top `rem` bits
55
+ }
56
+ }
57
+
58
+ std::size_t Bitfield::count() const noexcept {
59
+ // Spare bits are always zero, so whole-byte popcount is exact.
60
+ const auto& tbl = popcount_table();
61
+ std::size_t n = 0;
62
+ for (std::uint8_t b : bytes_) n += tbl[b];
63
+ return n;
64
+ }
65
+
66
+ bool Bitfield::all_set() const noexcept {
67
+ return find_first_unset() == bits_;
68
+ }
69
+
70
+ bool Bitfield::none_set() const noexcept {
71
+ for (std::uint8_t b : bytes_) if (b != 0) return false;
72
+ return true;
73
+ }
74
+
75
+ void Bitfield::set_all() noexcept {
76
+ std::fill(bytes_.begin(), bytes_.end(), 0xFFu);
77
+ clear_trailing_bits();
78
+ }
79
+
80
+ void Bitfield::clear_all() noexcept {
81
+ std::fill(bytes_.begin(), bytes_.end(), 0x00u);
82
+ }
83
+
84
+ std::size_t Bitfield::find_first_unset() const noexcept {
85
+ for (std::size_t bi = 0; bi < bytes_.size(); ++bi) {
86
+ if (bytes_[bi] == 0xFFu) continue; // fully set byte — skip fast
87
+ const std::size_t base = bi * 8;
88
+ for (std::size_t k = 0; k < 8; ++k) {
89
+ const std::size_t idx = base + k;
90
+ if (idx >= bits_) return bits_;
91
+ if (!get(idx)) return idx;
92
+ }
93
+ }
94
+ return bits_;
95
+ }
96
+
97
+ } // namespace librats::bittorrent
@@ -0,0 +1,76 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file bitfield.h
5
+ * @brief A compact, wire-compatible bit set — the BitTorrent "bitfield".
6
+ *
7
+ * Bits are packed MSB-first within each byte (bit @c i lives in byte @c i/8 at
8
+ * mask @c 0x80>>(i%8)), which is exactly the on-wire layout of the BEP 3
9
+ * `bitfield` message. So data()/data_size() can be sent verbatim and assign()
10
+ * ingests a received message with no conversion. Spare bits in the final byte
11
+ * are always kept zero, which lets count()/none_set() scan whole bytes safely.
12
+ *
13
+ * Owned by a single torrent on the network thread — deliberately not thread-safe.
14
+ */
15
+
16
+ #include "librats/util/rats_export.h"
17
+
18
+ #include <cstddef>
19
+ #include <cstdint>
20
+ #include <vector>
21
+
22
+ namespace librats::bittorrent {
23
+
24
+ class RATS_API Bitfield {
25
+ public:
26
+ Bitfield() = default;
27
+ explicit Bitfield(std::size_t bits, bool value = false) { resize(bits, value); }
28
+
29
+ /// Resize to @p bits bits; any newly added bits take @p value. Existing bits preserved.
30
+ void resize(std::size_t bits, bool value = false);
31
+
32
+ /// Ingest a received wire bitfield: @p bytes raw bytes interpreted as @p bits bits.
33
+ /// Spare bits beyond @p bits are cleared so the invariant holds.
34
+ void assign(const std::uint8_t* data, std::size_t bytes, std::size_t bits);
35
+
36
+ void clear() noexcept { bytes_.clear(); bits_ = 0; }
37
+
38
+ std::size_t size() const noexcept { return bits_; }
39
+ std::size_t num_bytes() const noexcept { return bytes_.size(); }
40
+ bool empty() const noexcept { return bits_ == 0; }
41
+
42
+ bool get(std::size_t i) const noexcept {
43
+ return (bytes_[i >> 3] & (0x80u >> (i & 7))) != 0;
44
+ }
45
+ bool operator[](std::size_t i) const noexcept { return get(i); }
46
+
47
+ void set(std::size_t i) noexcept { bytes_[i >> 3] |= std::uint8_t(0x80u >> (i & 7)); }
48
+ void reset(std::size_t i) noexcept { bytes_[i >> 3] &= std::uint8_t(~(0x80u >> (i & 7))); }
49
+ void set(std::size_t i, bool v) noexcept { if (v) set(i); else reset(i); }
50
+
51
+ std::size_t count() const noexcept; ///< number of set bits
52
+ bool all_set() const noexcept;
53
+ bool none_set() const noexcept;
54
+ void set_all() noexcept;
55
+ void clear_all() noexcept;
56
+
57
+ /// First index whose bit is 0, or size() if all bits are set. Answers
58
+ /// "what is the first piece I still need?".
59
+ std::size_t find_first_unset() const noexcept;
60
+
61
+ const std::uint8_t* data() const noexcept { return bytes_.data(); }
62
+ std::size_t data_size() const noexcept { return bytes_.size(); }
63
+
64
+ bool operator==(const Bitfield& o) const noexcept {
65
+ return bits_ == o.bits_ && bytes_ == o.bytes_;
66
+ }
67
+ bool operator!=(const Bitfield& o) const noexcept { return !(*this == o); }
68
+
69
+ private:
70
+ void clear_trailing_bits() noexcept; ///< keep the spare bits of the last byte zero
71
+
72
+ std::vector<std::uint8_t> bytes_;
73
+ std::size_t bits_ = 0;
74
+ };
75
+
76
+ } // namespace librats::bittorrent
@@ -0,0 +1,58 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file byte_io.h
5
+ * @brief Big-endian (network order) integer read/write helpers for the BitTorrent wire.
6
+ *
7
+ * The BitTorrent peer protocol, the BEP 15 UDP tracker protocol and extension
8
+ * messages are all big-endian. These tiny inline helpers keep (de)serialisation
9
+ * obvious and endianness-correct, without sprinkling htonl/ntohl or manual shifts
10
+ * across the codebase.
11
+ */
12
+
13
+ #include "librats/core/bytes.h"
14
+
15
+ #include <cstddef>
16
+ #include <cstdint>
17
+
18
+ namespace librats::bittorrent {
19
+
20
+ inline std::uint16_t read_u16_be(const std::uint8_t* p) noexcept {
21
+ return std::uint16_t(std::uint16_t(p[0]) << 8 | std::uint16_t(p[1]));
22
+ }
23
+ inline std::uint32_t read_u32_be(const std::uint8_t* p) noexcept {
24
+ return std::uint32_t(p[0]) << 24 | std::uint32_t(p[1]) << 16
25
+ | std::uint32_t(p[2]) << 8 | std::uint32_t(p[3]);
26
+ }
27
+ inline std::uint64_t read_u64_be(const std::uint8_t* p) noexcept {
28
+ return std::uint64_t(read_u32_be(p)) << 32 | read_u32_be(p + 4);
29
+ }
30
+
31
+ inline void write_u16_be(std::uint8_t* p, std::uint16_t v) noexcept {
32
+ p[0] = std::uint8_t(v >> 8);
33
+ p[1] = std::uint8_t(v);
34
+ }
35
+ inline void write_u32_be(std::uint8_t* p, std::uint32_t v) noexcept {
36
+ p[0] = std::uint8_t(v >> 24);
37
+ p[1] = std::uint8_t(v >> 16);
38
+ p[2] = std::uint8_t(v >> 8);
39
+ p[3] = std::uint8_t(v);
40
+ }
41
+ inline void write_u64_be(std::uint8_t* p, std::uint64_t v) noexcept {
42
+ write_u32_be(p, std::uint32_t(v >> 32));
43
+ write_u32_be(p + 4, std::uint32_t(v));
44
+ }
45
+
46
+ // Append helpers — grow a Bytes buffer with one big-endian value.
47
+ inline void append_u8(Bytes& b, std::uint8_t v) { b.push_back(v); }
48
+ inline void append_u16_be(Bytes& b, std::uint16_t v) {
49
+ std::uint8_t t[2]; write_u16_be(t, v); b.insert(b.end(), t, t + 2);
50
+ }
51
+ inline void append_u32_be(Bytes& b, std::uint32_t v) {
52
+ std::uint8_t t[4]; write_u32_be(t, v); b.insert(b.end(), t, t + 4);
53
+ }
54
+ inline void append_u64_be(Bytes& b, std::uint64_t v) {
55
+ std::uint8_t t[8]; write_u64_be(t, v); b.insert(b.end(), t, t + 8);
56
+ }
57
+
58
+ } // namespace librats::bittorrent
@@ -0,0 +1,25 @@
1
+ #include "librats/bittorrent/choker.h"
2
+
3
+ #include <algorithm>
4
+
5
+ namespace librats::bittorrent {
6
+
7
+ std::vector<const void*> Choker::select(std::vector<Candidate> candidates,
8
+ const void* optimistic) const {
9
+ // Highest score first; stable so equal-score peers keep a deterministic order.
10
+ std::stable_sort(candidates.begin(), candidates.end(),
11
+ [](const Candidate& a, const Candidate& b) { return a.score > b.score; });
12
+
13
+ std::vector<const void*> chosen;
14
+ const std::size_t take = (std::min)(slots_, candidates.size());
15
+ chosen.reserve(take + 1);
16
+ for (std::size_t i = 0; i < take; ++i) chosen.push_back(candidates[i].peer);
17
+
18
+ if (optimistic &&
19
+ std::find(chosen.begin(), chosen.end(), optimistic) == chosen.end()) {
20
+ chosen.push_back(optimistic);
21
+ }
22
+ return chosen;
23
+ }
24
+
25
+ } // namespace librats::bittorrent
@@ -0,0 +1,46 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file choker.h
5
+ * @brief The unchoke decision — who we upload to.
6
+ *
7
+ * BitTorrent reciprocates: a leecher unchokes the peers that feed it fastest
8
+ * (tit-for-tat), a seed spreads its slots by upload rate. The Choker is a pure
9
+ * policy over a list of *interested* candidates scored by the caller (recent
10
+ * bytes received from them, or served to them when seeding): it returns the
11
+ * subset to unchoke — the top `slots` by score, plus an optional optimistic
12
+ * unchoke that gets a chance regardless of score so newcomers can bootstrap.
13
+ *
14
+ * Stateless and side-effect-free, so the Torrent can recompute it each round and
15
+ * apply the diff against current choke state.
16
+ */
17
+
18
+ #include <cstddef>
19
+ #include <cstdint>
20
+ #include <vector>
21
+
22
+ namespace librats::bittorrent {
23
+
24
+ class Choker {
25
+ public:
26
+ explicit Choker(std::size_t upload_slots = 4) : slots_(upload_slots) {}
27
+
28
+ void set_slots(std::size_t slots) noexcept { slots_ = slots; }
29
+ std::size_t slots() const noexcept { return slots_; }
30
+
31
+ struct Candidate {
32
+ const void* peer = nullptr; ///< opaque peer identity
33
+ std::uint64_t score = 0; ///< higher = more deserving of a slot
34
+ };
35
+
36
+ /// Choose who to unchoke. Pass only *interested* peers. The result holds the
37
+ /// top `slots` by score; if @p optimistic is non-null it is always included
38
+ /// (an extra slot if it didn't already make the cut).
39
+ std::vector<const void*> select(std::vector<Candidate> candidates,
40
+ const void* optimistic = nullptr) const;
41
+
42
+ private:
43
+ std::size_t slots_;
44
+ };
45
+
46
+ } // namespace librats::bittorrent