librats 1.0.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/README.md +137 -332
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +271 -696
  4. package/lib/index.js +383 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +396 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +731 -0
  10. package/native-src/src/librats/bindings/rats.h +352 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +42 -0
  73. package/native-src/src/librats/core/types.h +93 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/config.h +110 -0
  144. package/native-src/src/librats/node/dial_service.h +54 -0
  145. package/native-src/src/librats/node/dialer.cpp +264 -0
  146. package/native-src/src/librats/node/dialer.h +188 -0
  147. package/native-src/src/librats/node/host_events.h +26 -0
  148. package/native-src/src/librats/node/identify.cpp +130 -0
  149. package/native-src/src/librats/node/identify.h +71 -0
  150. package/native-src/src/librats/node/nat_status.cpp +103 -0
  151. package/native-src/src/librats/node/nat_status.h +118 -0
  152. package/native-src/src/librats/node/node.cpp +826 -0
  153. package/native-src/src/librats/node/node.h +333 -0
  154. package/native-src/src/librats/node/node_context.h +33 -0
  155. package/native-src/src/librats/node/peer_network.h +91 -0
  156. package/native-src/src/librats/peer/peer.h +49 -0
  157. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  158. package/native-src/src/librats/peer/peer_book.h +88 -0
  159. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  160. package/native-src/src/librats/peer/peer_id.h +62 -0
  161. package/native-src/src/librats/peer/peer_info.h +37 -0
  162. package/native-src/src/librats/peer/peer_table.cpp +137 -0
  163. package/native-src/src/librats/peer/peer_table.h +148 -0
  164. package/native-src/src/librats/security/handshaker.h +66 -0
  165. package/native-src/src/librats/security/identity.h +43 -0
  166. package/native-src/src/librats/security/noise_security.cpp +122 -0
  167. package/native-src/src/librats/security/noise_security.h +37 -0
  168. package/native-src/src/librats/security/plaintext_security.h +106 -0
  169. package/native-src/src/librats/security/session.h +37 -0
  170. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  171. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  172. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  173. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  174. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  176. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  177. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  178. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  179. package/native-src/src/librats/subsystems/hole_punch.cpp +532 -0
  180. package/native-src/src/librats/subsystems/hole_punch.h +266 -0
  181. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  182. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  184. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  185. package/native-src/src/librats/subsystems/message_json.h +88 -0
  186. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  188. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  189. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  190. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  192. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  193. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  194. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  195. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  196. package/native-src/src/librats/transport/connection.cpp +343 -0
  197. package/native-src/src/librats/transport/connection.h +283 -0
  198. package/native-src/src/librats/transport/link.h +96 -0
  199. package/native-src/src/librats/transport/reactor.cpp +540 -0
  200. package/native-src/src/librats/transport/reactor.h +224 -0
  201. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  202. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  203. package/native-src/src/librats/transport/tcp_link.h +43 -0
  204. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  205. package/native-src/src/librats/transport/udp_mux.h +363 -0
  206. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  207. package/native-src/src/librats/transport/udp_packet.h +190 -0
  208. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  209. package/native-src/src/librats/transport/udp_stream.h +614 -0
  210. package/native-src/src/librats/util/features.h.in +51 -0
  211. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  212. package/native-src/src/librats/util/fs.h +136 -0
  213. package/native-src/src/librats/util/json.cpp +1002 -0
  214. package/native-src/src/librats/util/json.h +444 -0
  215. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  216. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  217. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  218. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  219. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  220. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  221. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  222. package/native-src/src/librats/util/rats_export.h +69 -0
  223. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  224. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  225. package/native-src/src/librats/wire/frame.cpp +76 -0
  226. package/native-src/src/librats/wire/frame.h +110 -0
  227. package/native-src/src/librats/wire/message_router.cpp +45 -0
  228. package/native-src/src/librats/wire/message_router.h +47 -0
  229. package/package.json +5 -4
  230. package/scripts/build-librats.js +1 -0
  231. package/scripts/postinstall.js +3 -3
  232. package/scripts/prepare-package.js +4 -4
  233. package/scripts/verify-installation.js +63 -105
  234. package/src/librats_node.cpp +1042 -1324
  235. package/native-src/src/bencode.cpp +0 -485
  236. package/native-src/src/bencode.h +0 -145
  237. package/native-src/src/bittorrent.cpp +0 -14
  238. package/native-src/src/bittorrent.h +0 -74
  239. package/native-src/src/bt_bitfield.cpp +0 -372
  240. package/native-src/src/bt_bitfield.h +0 -316
  241. package/native-src/src/bt_choker.cpp +0 -228
  242. package/native-src/src/bt_choker.h +0 -147
  243. package/native-src/src/bt_client.cpp +0 -1047
  244. package/native-src/src/bt_client.h +0 -445
  245. package/native-src/src/bt_create_torrent.cpp +0 -677
  246. package/native-src/src/bt_create_torrent.h +0 -473
  247. package/native-src/src/bt_extension.cpp +0 -469
  248. package/native-src/src/bt_extension.h +0 -309
  249. package/native-src/src/bt_file_storage.cpp +0 -261
  250. package/native-src/src/bt_file_storage.h +0 -298
  251. package/native-src/src/bt_handshake.cpp +0 -134
  252. package/native-src/src/bt_handshake.h +0 -157
  253. package/native-src/src/bt_messages.cpp +0 -364
  254. package/native-src/src/bt_messages.h +0 -324
  255. package/native-src/src/bt_network.cpp +0 -1007
  256. package/native-src/src/bt_network.h +0 -417
  257. package/native-src/src/bt_peer_connection.cpp +0 -742
  258. package/native-src/src/bt_peer_connection.h +0 -592
  259. package/native-src/src/bt_piece_picker.cpp +0 -786
  260. package/native-src/src/bt_piece_picker.h +0 -473
  261. package/native-src/src/bt_resume_data.cpp +0 -410
  262. package/native-src/src/bt_resume_data.h +0 -249
  263. package/native-src/src/bt_torrent.cpp +0 -2120
  264. package/native-src/src/bt_torrent.h +0 -641
  265. package/native-src/src/bt_torrent_info.cpp +0 -659
  266. package/native-src/src/bt_torrent_info.h +0 -418
  267. package/native-src/src/bt_types.h +0 -621
  268. package/native-src/src/chained_send_buffer.cpp +0 -75
  269. package/native-src/src/chained_send_buffer.h +0 -137
  270. package/native-src/src/crypto/hkdf.c +0 -266
  271. package/native-src/src/crypto/poly1305.h +0 -36
  272. package/native-src/src/dht.cpp +0 -3311
  273. package/native-src/src/dht.h +0 -717
  274. package/native-src/src/disk_io.cpp +0 -632
  275. package/native-src/src/disk_io.h +0 -315
  276. package/native-src/src/file_transfer.cpp +0 -1415
  277. package/native-src/src/file_transfer.h +0 -286
  278. package/native-src/src/fs.h +0 -108
  279. package/native-src/src/gossipsub.cpp +0 -1139
  280. package/native-src/src/gossipsub.h +0 -403
  281. package/native-src/src/ice.cpp +0 -893
  282. package/native-src/src/ice.h +0 -559
  283. package/native-src/src/json.hpp +0 -25526
  284. package/native-src/src/librats.cpp +0 -2378
  285. package/native-src/src/librats.h +0 -2324
  286. package/native-src/src/librats_bittorrent.cpp +0 -601
  287. package/native-src/src/librats_c.cpp +0 -1557
  288. package/native-src/src/librats_c.h +0 -323
  289. package/native-src/src/librats_discovery.cpp +0 -402
  290. package/native-src/src/librats_encryption.cpp +0 -275
  291. package/native-src/src/librats_file_transfer.cpp +0 -144
  292. package/native-src/src/librats_gossipsub.cpp +0 -289
  293. package/native-src/src/librats_ice.cpp +0 -213
  294. package/native-src/src/librats_log_macros.h +0 -36
  295. package/native-src/src/librats_logging.cpp +0 -173
  296. package/native-src/src/librats_mdns.cpp +0 -166
  297. package/native-src/src/librats_persistence.cpp +0 -796
  298. package/native-src/src/librats_portmap.cpp +0 -419
  299. package/native-src/src/librats_reconnection.cpp +0 -218
  300. package/native-src/src/librats_statistic.cpp +0 -105
  301. package/native-src/src/librats_storage.cpp +0 -189
  302. package/native-src/src/rats_export.h +0 -17
  303. package/native-src/src/receive_buffer.cpp +0 -82
  304. package/native-src/src/receive_buffer.h +0 -127
  305. package/native-src/src/socket.h +0 -228
  306. package/native-src/src/threadmanager.cpp +0 -105
  307. package/native-src/src/threadmanager.h +0 -53
  308. package/native-src/src/tracker.cpp +0 -1264
  309. package/native-src/src/tracker.h +0 -319
  310. package/native-src/src/turn.cpp +0 -762
  311. package/native-src/src/turn.h +0 -460
  312. package/native-src/src/wakeup_pipe.h +0 -60
  313. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -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