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,89 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file reactor.h
5
+ * @brief Single-threaded event loop for the BitTorrent peer transport.
6
+ *
7
+ * BitTorrent peers speak a plaintext wire protocol that is unrelated to the
8
+ * node's Noise mesh, so rather than bend `transport::Reactor` (which is tied to
9
+ * the Noise handshake) we assemble a dedicated loop from the same reusable
10
+ * primitives: an IOPoller, a TimerQueue, an MPSC task queue and a Notifier
11
+ * self-pipe to break the poll wait.
12
+ *
13
+ * One thread owns the loop and therefore all protocol state hung off it — peers,
14
+ * pickers, torrents — so none of that needs locks. Other threads reach in only
15
+ * through post(), which enqueues a task and wakes the loop. Socket registration
16
+ * (add/modify/remove) and timers are reactor-thread-only; call them from a task
17
+ * if you are elsewhere.
18
+ */
19
+
20
+ #include "librats/util/rats_export.h"
21
+ #include "librats/core/io_poller.h"
22
+ #include "librats/core/mpsc_queue.h"
23
+ #include "librats/core/notifier.h"
24
+ #include "librats/core/socket.h"
25
+ #include "librats/core/timer_queue.h"
26
+ #include "librats/core/types.h"
27
+
28
+ #include <atomic>
29
+ #include <chrono>
30
+ #include <cstdint>
31
+ #include <functional>
32
+ #include <thread>
33
+ #include <unordered_map>
34
+
35
+ namespace librats::bittorrent {
36
+
37
+ class RATS_API Reactor {
38
+ public:
39
+ using Task = std::function<void()>;
40
+ using IoCallback = std::function<void(std::uint32_t events)>;
41
+ using TimerCallback = std::function<void()>;
42
+
43
+ Reactor();
44
+ ~Reactor();
45
+
46
+ Reactor(const Reactor&) = delete;
47
+ Reactor& operator=(const Reactor&) = delete;
48
+
49
+ /// Run the loop on a dedicated thread until stop().
50
+ void start();
51
+ /// Stop the loop and join its thread (if any). Idempotent.
52
+ void stop();
53
+ /// Run the loop on the calling thread until stop().
54
+ void run();
55
+ /// Run a single loop iteration: poll, dispatch I/O, run posted tasks and due
56
+ /// timers. Exposed for tests and for embedding in another loop.
57
+ void run_one(int timeout_ms);
58
+
59
+ bool running() const noexcept { return running_.load(); }
60
+ bool on_reactor_thread() const noexcept { return std::this_thread::get_id() == loop_thread_; }
61
+
62
+ /// Enqueue a task to run on the reactor thread. Thread-safe.
63
+ void post(Task task);
64
+
65
+ // ---- reactor-thread only ----
66
+ bool add(socket_t fd, std::uint32_t events, IoCallback cb);
67
+ bool modify(socket_t fd, std::uint32_t events);
68
+ void remove(socket_t fd);
69
+
70
+ TimerId schedule(std::chrono::milliseconds delay, TimerCallback cb);
71
+ void cancel(TimerId id);
72
+
73
+ private:
74
+ void dispatch_io();
75
+ void run_tasks();
76
+
77
+ std::unique_ptr<IOPoller> poller_;
78
+ TimerQueue timers_;
79
+ MpscQueue<Task> tasks_;
80
+ Notifier notifier_;
81
+ std::unordered_map<socket_t, IoCallback> handlers_;
82
+ std::vector<Task> task_scratch_;
83
+
84
+ std::atomic<bool> running_{false};
85
+ std::thread thread_;
86
+ std::thread::id loop_thread_;
87
+ };
88
+
89
+ } // namespace librats::bittorrent
@@ -0,0 +1,72 @@
1
+ #include "librats/bittorrent/resume_data.h"
2
+
3
+ #include "librats/bittorrent/bencode.h"
4
+
5
+ #include <cstring>
6
+
7
+ namespace librats::bittorrent {
8
+
9
+ namespace {
10
+ constexpr char kFormatTag[] = "librats resume";
11
+
12
+ const librats::BencodeValue* find(const librats::BencodeValue& d, const char* key) {
13
+ return d.find(key);
14
+ }
15
+ } // namespace
16
+
17
+ Bytes ResumeData::encode() const {
18
+ librats::BencodeValue d = librats::BencodeValue::create_dict();
19
+ d["format"] = librats::BencodeValue(std::string(kFormatTag));
20
+ d["version"] = librats::BencodeValue(std::int64_t(1));
21
+ d["info-hash"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(info_hash.data()), info_hash.size()));
22
+ d["name"] = librats::BencodeValue(name);
23
+ d["save-path"] = librats::BencodeValue(save_path);
24
+ d["num-pieces"] = librats::BencodeValue(std::int64_t(have.size()));
25
+ d["pieces"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(have.data()), have.data_size()));
26
+ d["uploaded"] = librats::BencodeValue(std::int64_t(total_uploaded));
27
+ d["downloaded"] = librats::BencodeValue(std::int64_t(total_downloaded));
28
+ if (!info_dict.empty())
29
+ d["info"] = librats::BencodeValue(std::string(reinterpret_cast<const char*>(info_dict.data()), info_dict.size()));
30
+ return d.encode();
31
+ }
32
+
33
+ std::optional<ResumeData> ResumeData::decode(const Bytes& data) {
34
+ try {
35
+ librats::BencodeValue d = librats::BencodeDecoder::decode(data.data(), data.size());
36
+ if (!d.is_dict()) return std::nullopt;
37
+ const auto* fmt = find(d, "format");
38
+ if (!fmt || !fmt->is_string() || fmt->as_string() != kFormatTag) return std::nullopt;
39
+
40
+ ResumeData rd;
41
+ if (const auto* ih = find(d, "info-hash"); ih && ih->is_string() && ih->as_string().size() == 20)
42
+ std::memcpy(rd.info_hash.data(), ih->as_string().data(), 20);
43
+ if (const auto* n = find(d, "name"); n && n->is_string()) rd.name = n->as_string();
44
+ if (const auto* sp = find(d, "save-path"); sp && sp->is_string()) rd.save_path = sp->as_string();
45
+ if (const auto* up = find(d, "uploaded"); up && up->is_integer()) rd.total_uploaded = std::uint64_t(up->as_integer());
46
+ if (const auto* dn = find(d, "downloaded"); dn && dn->is_integer()) rd.total_downloaded = std::uint64_t(dn->as_integer());
47
+
48
+ std::int64_t num_pieces = 0;
49
+ if (const auto* np = find(d, "num-pieces"); np && np->is_integer() && np->as_integer() >= 0)
50
+ num_pieces = np->as_integer();
51
+ if (const auto* p = find(d, "pieces"); p && p->is_string()) {
52
+ const std::string& bytes = p->as_string();
53
+ // `num-pieces` is attacker-controlled and drives Bitfield::assign's
54
+ // allocation independently of the `pieces` string length. A tiny file
55
+ // claiming billions of pieces would allocate gigabytes (C4). A valid
56
+ // record always has exactly ceil(num_pieces/8) bytes of bitfield, so
57
+ // reject anything that doesn't match rather than trusting the count.
58
+ if (std::uint64_t((num_pieces + 7) / 8) != bytes.size()) return std::nullopt;
59
+ rd.have.assign(reinterpret_cast<const std::uint8_t*>(bytes.data()),
60
+ bytes.size(), std::size_t(num_pieces));
61
+ }
62
+
63
+ if (const auto* info = find(d, "info"); info && info->is_string())
64
+ rd.info_dict.assign(info->as_string().begin(), info->as_string().end());
65
+
66
+ return rd;
67
+ } catch (const std::exception&) {
68
+ return std::nullopt;
69
+ }
70
+ }
71
+
72
+ } // namespace librats::bittorrent
@@ -0,0 +1,41 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file resume_data.h
5
+ * @brief Fast-resume state: what a torrent needs to pick up where it left off
6
+ * without re-hashing every piece on disk.
7
+ *
8
+ * It is a small bencoded record — the have-bitfield, transfer totals, save path
9
+ * and (optionally) the verbatim info dictionary so a magnet-started torrent can
10
+ * resume without re-fetching metadata. On load the engine *trusts* the recorded
11
+ * bitfield (skipping the hash check for those pieces); the verbatim info section,
12
+ * if present, is re-hashed against the info-hash before it is believed.
13
+ */
14
+
15
+ #include "librats/util/rats_export.h"
16
+ #include "librats/bittorrent/bitfield.h"
17
+ #include "librats/bittorrent/types.h"
18
+ #include "librats/core/bytes.h"
19
+
20
+ #include <cstdint>
21
+ #include <optional>
22
+ #include <string>
23
+
24
+ namespace librats::bittorrent {
25
+
26
+ struct RATS_API ResumeData {
27
+ InfoHash info_hash{};
28
+ std::string name;
29
+ std::string save_path;
30
+ Bitfield have; ///< pieces already on disk
31
+ std::uint64_t total_uploaded = 0;
32
+ std::uint64_t total_downloaded = 0;
33
+ Bytes info_dict; ///< optional verbatim info section
34
+
35
+ /// Serialise to the on-disk bencoded form.
36
+ Bytes encode() const;
37
+ /// Parse it back. nullopt if it isn't a librats resume record.
38
+ static std::optional<ResumeData> decode(const Bytes& data);
39
+ };
40
+
41
+ } // namespace librats::bittorrent
@@ -0,0 +1,48 @@
1
+ #include "librats/bittorrent/store_buffer.h"
2
+
3
+ #include <algorithm>
4
+
5
+ namespace librats::bittorrent {
6
+
7
+ void StoreBuffer::insert(std::uint32_t piece, std::uint32_t offset, const Bytes& data) {
8
+ std::lock_guard<std::mutex> lock(mutex_);
9
+ blocks_[{piece, offset}] = data;
10
+ }
11
+
12
+ void StoreBuffer::erase(std::uint32_t piece, std::uint32_t offset) {
13
+ std::lock_guard<std::mutex> lock(mutex_);
14
+ blocks_.erase({piece, offset});
15
+ }
16
+
17
+ void StoreBuffer::overlay(std::uint32_t piece, std::uint32_t offset, Bytes& out) const {
18
+ if (out.empty()) return;
19
+ const std::uint64_t read_begin = offset;
20
+ const std::uint64_t read_end = offset + out.size();
21
+
22
+ std::lock_guard<std::mutex> lock(mutex_);
23
+ // Walk only this piece's entries: keys in [(piece,0), (piece+1,0)).
24
+ auto it = blocks_.lower_bound({piece, 0});
25
+ auto end = (piece == UINT32_MAX) ? blocks_.end() : blocks_.lower_bound({piece + 1, 0});
26
+ for (; it != end; ++it) {
27
+ const std::uint64_t blk_begin = it->first.second;
28
+ const std::uint64_t blk_end = blk_begin + it->second.size();
29
+ const std::uint64_t from = (std::max)(read_begin, blk_begin);
30
+ const std::uint64_t to = (std::min)(read_end, blk_end);
31
+ if (from >= to) continue; // no intersection
32
+ std::copy(it->second.begin() + std::ptrdiff_t(from - blk_begin),
33
+ it->second.begin() + std::ptrdiff_t(to - blk_begin),
34
+ out.begin() + std::ptrdiff_t(from - read_begin));
35
+ }
36
+ }
37
+
38
+ bool StoreBuffer::empty() const {
39
+ std::lock_guard<std::mutex> lock(mutex_);
40
+ return blocks_.empty();
41
+ }
42
+
43
+ std::size_t StoreBuffer::size() const {
44
+ std::lock_guard<std::mutex> lock(mutex_);
45
+ return blocks_.size();
46
+ }
47
+
48
+ } // namespace librats::bittorrent
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file store_buffer.h
5
+ * @brief In-RAM cache of blocks whose disk write is still in flight.
6
+ *
7
+ * When a block is handed to the disk for writing it is also parked here, keyed
8
+ * by (piece, offset within piece). A read or hash issued before that write
9
+ * reaches the platter is then satisfied from RAM by overlaying these bytes onto
10
+ * whatever the disk returned — so the engine never reads stale data for a block
11
+ * it has already accepted. The entry is dropped once the write completes.
12
+ *
13
+ * Thread-safe: writers insert/erase from disk-worker threads while readers
14
+ * overlay; all access is guarded by an internal mutex.
15
+ */
16
+
17
+ #include "librats/core/bytes.h"
18
+
19
+ #include <cstdint>
20
+ #include <map>
21
+ #include <mutex>
22
+
23
+ namespace librats::bittorrent {
24
+
25
+ class StoreBuffer {
26
+ public:
27
+ /// Park a pending block. Replaces any existing entry at the same key.
28
+ void insert(std::uint32_t piece, std::uint32_t offset, const Bytes& data);
29
+
30
+ /// Drop a block once its write has landed on disk.
31
+ void erase(std::uint32_t piece, std::uint32_t offset);
32
+
33
+ /// Overlay any parked bytes for @p piece that intersect
34
+ /// [@p offset, @p offset + out.size()) onto @p out (indexed from @p offset).
35
+ void overlay(std::uint32_t piece, std::uint32_t offset, Bytes& out) const;
36
+
37
+ bool empty() const;
38
+ std::size_t size() const;
39
+
40
+ private:
41
+ using Key = std::pair<std::uint32_t, std::uint32_t>; // (piece, offset)
42
+
43
+ mutable std::mutex mutex_;
44
+ std::map<Key, Bytes> blocks_;
45
+ };
46
+
47
+ } // namespace librats::bittorrent