librats 1.0.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +43 -0
  73. package/native-src/src/librats/core/types.h +103 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,621 +0,0 @@
1
- #pragma once
2
-
3
- /**
4
- * @file bt_types.h
5
- * @brief Core BitTorrent types and constants for librats
6
- *
7
- * This file contains fundamental types used throughout the BitTorrent
8
- * implementation including PeerID, constants, and utility functions.
9
- */
10
-
11
- #include <array>
12
- #include <cstdint>
13
- #include <cstring>
14
- #include <cstdio>
15
- #include <string>
16
- #include <random>
17
- #include <chrono>
18
- #include <sstream>
19
- #include <iomanip>
20
-
21
- namespace librats {
22
-
23
- //=============================================================================
24
- // Constants
25
- //=============================================================================
26
-
27
- /// Size of peer ID in bytes (BEP 20)
28
- constexpr size_t BT_PEER_ID_SIZE = 20;
29
-
30
- /// Size of info hash in bytes (SHA-1)
31
- constexpr size_t BT_INFO_HASH_SIZE = 20;
32
-
33
- /// Standard block size in bytes (16 KB)
34
- constexpr uint32_t BT_BLOCK_SIZE = 16384;
35
-
36
- /// Maximum block size allowed (typically 16 KB, some clients allow 32 KB)
37
- constexpr uint32_t BT_MAX_BLOCK_SIZE = 32768;
38
-
39
- /// Default piece length for created torrents (256 KB)
40
- constexpr uint32_t BT_DEFAULT_PIECE_LENGTH = 262144;
41
-
42
- /// Protocol string for BitTorrent handshake
43
- constexpr char BT_PROTOCOL_STRING[] = "BitTorrent protocol";
44
-
45
- /// Length of protocol string
46
- constexpr size_t BT_PROTOCOL_STRING_LEN = 19;
47
-
48
- /// Total handshake size: 1 + 19 + 8 + 20 + 20 = 68 bytes
49
- constexpr size_t BT_HANDSHAKE_SIZE = 68;
50
-
51
- /// Reserved bytes in handshake (8 bytes)
52
- constexpr size_t BT_RESERVED_SIZE = 8;
53
-
54
- /// Metadata block size for BEP 9 (16 KB)
55
- constexpr uint32_t BT_METADATA_PIECE_SIZE = 16384;
56
-
57
- /// Maximum number of outstanding requests to a single peer
58
- constexpr size_t BT_MAX_PENDING_REQUESTS = 250;
59
-
60
- /// Default request queue size
61
- constexpr size_t BT_DEFAULT_REQUEST_QUEUE_SIZE = 16;
62
-
63
- //=============================================================================
64
- // Extension Protocol Message IDs (BEP 10)
65
- //=============================================================================
66
-
67
- /// Our local ID for ut_metadata extension (BEP 9)
68
- constexpr uint8_t BT_EXT_UT_METADATA_ID = 1;
69
-
70
- /// Our local ID for ut_pex extension (BEP 11)
71
- constexpr uint8_t BT_EXT_UT_PEX_ID = 2;
72
-
73
- //=============================================================================
74
- // Reserved Bytes Bit Positions (for extensions)
75
- //=============================================================================
76
-
77
- namespace ReservedBits {
78
- /// BEP 5: DHT support (reserved[7] bit 0)
79
- constexpr uint8_t DHT = 0x01;
80
-
81
- /// BEP 6: Fast extension (reserved[7] bit 2)
82
- constexpr uint8_t FAST = 0x04;
83
-
84
- /// BEP 10: Extension protocol (reserved[5] bit 4)
85
- constexpr uint8_t EXTENSION_PROTOCOL = 0x10;
86
- }
87
-
88
- //=============================================================================
89
- // Type Definitions
90
- //=============================================================================
91
-
92
- /// 20-byte peer identifier (BEP 20 format)
93
- using PeerID = std::array<uint8_t, BT_PEER_ID_SIZE>;
94
-
95
- /// 20-byte info hash (SHA-1 of info dict)
96
- /// Note: Reuses InfoHash from dht.h when available
97
- using BtInfoHash = std::array<uint8_t, BT_INFO_HASH_SIZE>;
98
-
99
- /**
100
- * @brief Hash function for BtInfoHash in unordered containers
101
- */
102
- struct InfoHashHash {
103
- size_t operator()(const BtInfoHash& hash) const {
104
- // Simple hash - combine first few bytes
105
- size_t result = 0;
106
- for (size_t i = 0; i < (std::min)(sizeof(size_t), hash.size()); ++i) {
107
- result = (result << 8) | hash[i];
108
- }
109
- return result;
110
- }
111
- };
112
-
113
- //=============================================================================
114
- // Peer ID Generation (BEP 20)
115
- //=============================================================================
116
-
117
- /**
118
- * @brief Generate a peer ID in Azureus-style format (BEP 20)
119
- *
120
- * Format: -XX0000-xxxxxxxxxxxx
121
- * Where XX is client ID, 0000 is version, x is random
122
- *
123
- * @param client_id Client identifier (e.g., "-LR0001-" for librats v0.0.0.1)
124
- * @return Generated peer ID
125
- */
126
- inline PeerID generate_peer_id(const std::string& client_id = "-LR0001-") {
127
- PeerID peer_id{};
128
-
129
- // Copy client ID prefix (up to 8 characters)
130
- size_t prefix_len = (std::min)(client_id.size(), static_cast<size_t>(8));
131
- for (size_t i = 0; i < prefix_len; ++i) {
132
- peer_id[i] = static_cast<uint8_t>(client_id[i]);
133
- }
134
-
135
- // Fill remaining 12 bytes with random data
136
- std::random_device rd;
137
- std::mt19937 gen(rd());
138
- std::uniform_int_distribution<int> dis(0, 255);
139
-
140
- for (size_t i = prefix_len; i < BT_PEER_ID_SIZE; ++i) {
141
- peer_id[i] = static_cast<uint8_t>(dis(gen));
142
- }
143
-
144
- return peer_id;
145
- }
146
-
147
- /**
148
- * @brief Generate a peer ID with timestamp-based randomness
149
- *
150
- * Uses current time for additional entropy in the random portion
151
- *
152
- * @param client_id Client identifier prefix
153
- * @return Generated peer ID
154
- */
155
- inline PeerID generate_peer_id_with_timestamp(const std::string& client_id = "-LR0001-") {
156
- PeerID peer_id{};
157
-
158
- // Copy client ID prefix
159
- size_t prefix_len = (std::min)(client_id.size(), static_cast<size_t>(8));
160
- for (size_t i = 0; i < prefix_len; ++i) {
161
- peer_id[i] = static_cast<uint8_t>(client_id[i]);
162
- }
163
-
164
- // Use timestamp for seed
165
- auto now = std::chrono::high_resolution_clock::now();
166
- auto seed = static_cast<unsigned int>(
167
- std::chrono::duration_cast<std::chrono::nanoseconds>(
168
- now.time_since_epoch()
169
- ).count()
170
- );
171
-
172
- std::mt19937 gen(seed);
173
- std::uniform_int_distribution<int> dis(0, 255);
174
-
175
- for (size_t i = prefix_len; i < BT_PEER_ID_SIZE; ++i) {
176
- peer_id[i] = static_cast<uint8_t>(dis(gen));
177
- }
178
-
179
- return peer_id;
180
- }
181
-
182
- //=============================================================================
183
- // Conversion Utilities
184
- //=============================================================================
185
-
186
- /**
187
- * @brief Convert peer ID to printable string
188
- *
189
- * Non-printable characters are shown as hex escapes
190
- *
191
- * @param id Peer ID to convert
192
- * @return String representation
193
- */
194
- inline std::string peer_id_to_string(const PeerID& id) {
195
- std::ostringstream oss;
196
- for (uint8_t byte : id) {
197
- if (byte >= 32 && byte < 127) {
198
- oss << static_cast<char>(byte);
199
- } else {
200
- oss << "\\x" << std::hex << std::setw(2) << std::setfill('0')
201
- << static_cast<int>(byte);
202
- }
203
- }
204
- return oss.str();
205
- }
206
-
207
- /**
208
- * @brief Convert peer ID to hex string
209
- *
210
- * @param id Peer ID to convert
211
- * @return 40-character hex string
212
- */
213
- inline std::string peer_id_to_hex(const PeerID& id) {
214
- std::ostringstream oss;
215
- oss << std::hex << std::setfill('0');
216
- for (uint8_t byte : id) {
217
- oss << std::setw(2) << static_cast<int>(byte);
218
- }
219
- return oss.str();
220
- }
221
-
222
- /**
223
- * @brief Convert info hash to hex string
224
- *
225
- * @param hash Info hash to convert
226
- * @return 40-character hex string
227
- */
228
- inline std::string info_hash_to_hex(const BtInfoHash& hash) {
229
- std::ostringstream oss;
230
- oss << std::hex << std::setfill('0');
231
- for (uint8_t byte : hash) {
232
- oss << std::setw(2) << static_cast<int>(byte);
233
- }
234
- return oss.str();
235
- }
236
-
237
- /**
238
- * @brief Convert hex string to info hash
239
- *
240
- * @param hex 40-character hex string
241
- * @return Info hash, or zero-filled array on error
242
- */
243
- inline BtInfoHash hex_to_info_hash(const std::string& hex) {
244
- BtInfoHash hash{};
245
- if (hex.length() != 40) {
246
- return hash;
247
- }
248
-
249
- for (size_t i = 0; i < 20; ++i) {
250
- std::string byte_str = hex.substr(i * 2, 2);
251
- try {
252
- hash[i] = static_cast<uint8_t>(std::stoul(byte_str, nullptr, 16));
253
- } catch (...) {
254
- return BtInfoHash{};
255
- }
256
- }
257
-
258
- return hash;
259
- }
260
-
261
- /**
262
- * @brief Check if info hash is all zeros (invalid)
263
- *
264
- * @param hash Info hash to check
265
- * @return true if all zeros
266
- */
267
- inline bool is_zero_hash(const BtInfoHash& hash) {
268
- for (uint8_t byte : hash) {
269
- if (byte != 0) return false;
270
- }
271
- return true;
272
- }
273
-
274
- //=============================================================================
275
- // Client ID Parsing (BEP 20)
276
- //=============================================================================
277
-
278
- namespace detail {
279
-
280
- /**
281
- * @brief Decode a version digit from peer ID (supports 0-9 and A-Z)
282
- */
283
- inline int decode_version_digit(uint8_t c) {
284
- if (c >= '0' && c <= '9') return c - '0';
285
- if (c >= 'A' && c <= 'Z') return c - 'A' + 10;
286
- if (c >= 'a' && c <= 'z') return c - 'a' + 10;
287
- return 0;
288
- }
289
-
290
- /**
291
- * @brief Azureus-style client name lookup table
292
- * Based on BEP 20 and libtorrent's identify_client implementation
293
- */
294
- inline const char* lookup_az_client(const char* code) {
295
- // Sorted alphabetically by 2-char code for binary search potential
296
- // Using linear search for simplicity - table is small enough
297
- struct Entry { const char* code; const char* name; };
298
- static const Entry entries[] = {
299
- {"7T", "aTorrent"},
300
- {"AB", "AnyEvent BitTorrent"},
301
- {"AG", "Ares"},
302
- {"AR", "Arctic Torrent"},
303
- {"AT", "Artemis"},
304
- {"AV", "Avicora"},
305
- {"AX", "BitPump"},
306
- {"AZ", "Azureus"},
307
- {"A~", "Ares"},
308
- {"BB", "BitBuddy"},
309
- {"BC", "BitComet"},
310
- {"BE", "baretorrent"},
311
- {"BF", "Bitflu"},
312
- {"BG", "BTG"},
313
- {"BI", "BiglyBT"},
314
- {"BL", "BitBlinder"},
315
- {"BP", "BitTorrent Pro"},
316
- {"BR", "BitRocket"},
317
- {"BS", "BTSlave"},
318
- {"BT", "BitTorrent"},
319
- {"BU", "BigUp"},
320
- {"BW", "BitWombat"},
321
- {"BX", "BittorrentX"},
322
- {"CD", "Enhanced CTorrent"},
323
- {"CT", "CTorrent"},
324
- {"DE", "Deluge"},
325
- {"DP", "Propagate Data Client"},
326
- {"EB", "EBit"},
327
- {"ES", "electric sheep"},
328
- {"FC", "FileCroc"},
329
- {"FT", "FoxTorrent"},
330
- {"FW", "FrostWire"},
331
- {"FX", "Freebox BitTorrent"},
332
- {"GS", "GSTorrent"},
333
- {"HK", "Hekate"},
334
- {"HL", "Halite"},
335
- {"HN", "Hydranode"},
336
- {"IL", "iLivid"},
337
- {"KC", "Koinonein"},
338
- {"KG", "KGet"},
339
- {"KT", "KTorrent"},
340
- {"LC", "LeechCraft"},
341
- {"LH", "LH-ABC"},
342
- {"LK", "Linkage"},
343
- {"LP", "lphant"},
344
- {"LR", "librats"},
345
- {"LT", "libtorrent"},
346
- {"LW", "Limewire"},
347
- {"ML", "MLDonkey"},
348
- {"MO", "Mono Torrent"},
349
- {"MP", "MooPolice"},
350
- {"MR", "Miro"},
351
- {"MT", "Moonlight Torrent"},
352
- {"NX", "Net Transport"},
353
- {"OS", "OneSwarm"},
354
- {"OT", "OmegaTorrent"},
355
- {"PD", "Pando"},
356
- {"QD", "QQDownload"},
357
- {"QT", "Qt 4"},
358
- {"RT", "Retriever"},
359
- {"RZ", "RezTorrent"},
360
- {"SB", "Swiftbit"},
361
- {"SD", "Xunlei"},
362
- {"SK", "spark"},
363
- {"SN", "ShareNet"},
364
- {"SS", "SwarmScope"},
365
- {"ST", "SymTorrent"},
366
- {"SZ", "Shareaza"},
367
- {"S~", "Shareaza (beta)"},
368
- {"TB", "Torch"},
369
- {"TL", "Tribler"},
370
- {"TN", "Torrent.NET"},
371
- {"TR", "Transmission"},
372
- {"TS", "TorrentStorm"},
373
- {"TT", "TuoTu"},
374
- {"UL", "uLeecher"},
375
- {"UM", "uTorrent Mac"},
376
- {"UT", "uTorrent"},
377
- {"VG", "Vagaa"},
378
- {"WT", "BitLet"},
379
- {"WY", "FireTorrent"},
380
- {"XF", "Xfplay"},
381
- {"XL", "Xunlei"},
382
- {"XS", "XSwifter"},
383
- {"XT", "XanTorrent"},
384
- {"XX", "Xtorrent"},
385
- {"ZO", "Zona"},
386
- {"ZT", "ZipTorrent"},
387
- {"lt", "rTorrent"},
388
- {"pX", "pHoeniX"},
389
- {"qB", "qBittorrent"},
390
- {"st", "SharkTorrent"},
391
- };
392
-
393
- for (const auto& e : entries) {
394
- if (e.code[0] == code[0] && e.code[1] == code[1]) {
395
- return e.name;
396
- }
397
- }
398
- return nullptr;
399
- }
400
-
401
- /**
402
- * @brief Generic (non-standard) client name lookup
403
- */
404
- inline const char* lookup_generic_client(const uint8_t* id) {
405
- struct Entry { int offset; const char* pattern; const char* name; };
406
- static const Entry entries[] = {
407
- {0, "Deadman Walking-", "Deadman"},
408
- {5, "Azureus", "Azureus 2.0.3.2"},
409
- {0, "DansClient", "XanTorrent"},
410
- {4, "btfans", "SimpleBT"},
411
- {0, "PRC.P---", "Bittorrent Plus! II"},
412
- {0, "P87.P---", "Bittorrent Plus!"},
413
- {0, "S587Plus", "Bittorrent Plus!"},
414
- {0, "martini", "Martini Man"},
415
- {0, "Plus---", "Bittorrent Plus"},
416
- {0, "turbobt", "TurboBT"},
417
- {0, "a00---0", "Swarmy"},
418
- {0, "a02---0", "Swarmy"},
419
- {0, "T00---0", "Teeweety"},
420
- {0, "BTDWV-", "Deadman Walking"},
421
- {2, "BS", "BitSpirit"},
422
- {0, "-SP", "BitSpirit 3.6"},
423
- {0, "Pando-", "Pando"},
424
- {0, "LIME", "LimeWire"},
425
- {0, "btuga", "BTugaXP"},
426
- {0, "oernu", "BTugaXP"},
427
- {0, "Mbrst", "Burst!"},
428
- {0, "PEERAPP", "PeerApp"},
429
- {0, "Plus", "Plus!"},
430
- {0, "-Qt-", "Qt"},
431
- {0, "exbc", "BitComet"},
432
- {0, "DNA", "BitTorrent DNA"},
433
- {0, "-G3", "G3 Torrent"},
434
- {0, "-FG", "FlashGet"},
435
- {0, "-ML", "MLdonkey"},
436
- {0, "-MG", "Media Get"},
437
- {0, "XBT", "XBT"},
438
- {0, "OP", "Opera"},
439
- {2, "RS", "Rufus"},
440
- {0, "AZ2500BT", "BitTyrant"},
441
- {0, "btpd/", "BitTorrent Protocol Daemon"},
442
- {0, "TIX", "Tixati"},
443
- {0, "QVOD", "Qvod"},
444
- };
445
-
446
- for (const auto& e : entries) {
447
- const char* p = e.pattern;
448
- const char* s = reinterpret_cast<const char*>(id) + e.offset;
449
- size_t len = std::strlen(p);
450
- if (e.offset + len <= BT_PEER_ID_SIZE && std::memcmp(s, p, len) == 0) {
451
- return e.name;
452
- }
453
- }
454
- return nullptr;
455
- }
456
-
457
- } // namespace detail
458
-
459
- /**
460
- * @brief Identify BitTorrent client from peer ID (BEP 20)
461
- *
462
- * Supports three encoding styles:
463
- * - Azureus-style: -XX1234-xxxxxxxxxxxx
464
- * - Shadow-style: Xyyy--xxxxxxxxxxxxxx
465
- * - Mainline-style: M1-2-3--xxxxxxxxxxxx
466
- * Also recognizes many non-standard encodings.
467
- *
468
- * @param id 20-byte peer ID
469
- * @return Human-readable client name with version, or "Unknown [...]"
470
- */
471
- inline std::string identify_client(const PeerID& id) {
472
- // Check if all zeros
473
- bool all_zero = true;
474
- for (uint8_t b : id) { if (b != 0) { all_zero = false; break; } }
475
- if (all_zero) return "Unknown";
476
-
477
- // Check non-standard encodings first
478
- const char* generic = detail::lookup_generic_client(id.data());
479
- if (generic) return generic;
480
-
481
- // Check Bits on Wheels special case
482
- if (id[0] == '-' && id[1] == 'B' && id[2] == 'O' && id[3] == 'W' && id[7] == '-') {
483
- return "Bits on Wheels " + std::string(reinterpret_cast<const char*>(id.data()) + 4, 3);
484
- }
485
-
486
- // Azureus-style: -XX1234-
487
- if (id[0] == '-' && id[7] == '-' &&
488
- (id[1] >= 'A' || id[1] >= 'a') &&
489
- id[3] >= '0' && id[4] >= '0' && id[5] >= '0' && id[6] >= '0') {
490
-
491
- char code[3] = {static_cast<char>(id[1]), static_cast<char>(id[2]), '\0'};
492
-
493
- int v1 = detail::decode_version_digit(id[3]);
494
- int v2 = detail::decode_version_digit(id[4]);
495
- int v3 = detail::decode_version_digit(id[5]);
496
- int v4 = detail::decode_version_digit(id[6]);
497
-
498
- const char* name = detail::lookup_az_client(code);
499
- std::string client_name = name ? name : std::string("Unknown (") + code + ")";
500
-
501
- std::string version = std::to_string(v1) + "." + std::to_string(v2) + "." + std::to_string(v3);
502
- if (v4 != 0) {
503
- version += "." + std::to_string(v4);
504
- }
505
-
506
- return client_name + " " + version;
507
- }
508
-
509
- // Shadow-style: first char is client, next 3 are version
510
- if ((id[0] >= 'A' && id[0] <= 'Z') || (id[0] >= 'a' && id[0] <= 'z')) {
511
- // Check for shadow format: X + 3 version bytes + "--"
512
- if (id[4] == '-' && id[5] == '-') {
513
- if (id[1] >= '0' && id[2] >= '0' && id[3] >= '0') {
514
- char c = static_cast<char>(id[0]);
515
- const char* name = nullptr;
516
- switch (c) {
517
- case 'A': name = "ABC"; break;
518
- case 'M': name = "Mainline"; break;
519
- case 'O': name = "Osprey Permaseed"; break;
520
- case 'Q': name = "BTQueue"; break;
521
- case 'R': name = "Tribler"; break;
522
- case 'S': name = "Shadow"; break;
523
- case 'T': name = "BitTornado"; break;
524
- case 'U': name = "UPnP"; break;
525
- default: break;
526
- }
527
- if (name) {
528
- int v1 = detail::decode_version_digit(id[1]);
529
- int v2 = detail::decode_version_digit(id[2]);
530
- int v3 = detail::decode_version_digit(id[3]);
531
- return std::string(name) + " " + std::to_string(v1) + "." +
532
- std::to_string(v2) + "." + std::to_string(v3);
533
- }
534
- }
535
- }
536
-
537
- // Mainline-style: M1-2-3--
538
- char ids[21];
539
- std::memcpy(ids, id.data(), 20);
540
- ids[20] = '\0';
541
- char name_ch = '\0';
542
- int v1 = 0, v2 = 0, v3 = 0;
543
- if (std::sscanf(ids, "%c%3d-%3d-%3d--", &name_ch, &v1, &v2, &v3) == 4 &&
544
- name_ch >= 32 && name_ch < 127) {
545
- const char* name = nullptr;
546
- switch (name_ch) {
547
- case 'M': name = "Mainline"; break;
548
- default: break;
549
- }
550
- if (name) {
551
- return std::string(name) + " " + std::to_string(v1) + "." +
552
- std::to_string(v2) + "." + std::to_string(v3);
553
- }
554
- }
555
- }
556
-
557
- // All zeros in first 12 bytes - special cases
558
- bool first_12_zero = true;
559
- for (int i = 0; i < 12; ++i) { if (id[i] != 0) { first_12_zero = false; break; } }
560
- if (first_12_zero) {
561
- if (id[12] == 0x97) return "Experimental 3.2.1b2";
562
- if (id[12] == 0x00) return "Experimental 3.1";
563
- return "Generic";
564
- }
565
-
566
- // Unknown - show printable representation
567
- std::string unknown("Unknown [");
568
- for (uint8_t c : id) {
569
- unknown += (c >= 32 && c < 127) ? static_cast<char>(c) : '.';
570
- }
571
- unknown += "]";
572
- return unknown;
573
- }
574
-
575
- //=============================================================================
576
- // Piece/Block Structures
577
- //=============================================================================
578
-
579
- /**
580
- * @brief Represents a block within a piece
581
- */
582
- struct BlockInfo {
583
- uint32_t piece_index; ///< Index of the piece
584
- uint32_t offset; ///< Offset within the piece
585
- uint32_t length; ///< Length of the block
586
-
587
- BlockInfo() : piece_index(0), offset(0), length(0) {}
588
- BlockInfo(uint32_t piece, uint32_t off, uint32_t len)
589
- : piece_index(piece), offset(off), length(len) {}
590
-
591
- bool operator==(const BlockInfo& other) const {
592
- return piece_index == other.piece_index
593
- && offset == other.offset
594
- && length == other.length;
595
- }
596
-
597
- bool operator!=(const BlockInfo& other) const {
598
- return !(*this == other);
599
- }
600
-
601
- bool operator<(const BlockInfo& other) const {
602
- if (piece_index != other.piece_index) return piece_index < other.piece_index;
603
- if (offset != other.offset) return offset < other.offset;
604
- return length < other.length;
605
- }
606
- };
607
-
608
- /**
609
- * @brief Hash function for BlockInfo (for use in unordered containers)
610
- */
611
- struct BlockInfoHash {
612
- size_t operator()(const BlockInfo& b) const {
613
- return std::hash<uint64_t>()(
614
- (static_cast<uint64_t>(b.piece_index) << 32) |
615
- (static_cast<uint64_t>(b.offset) << 16) |
616
- b.length
617
- );
618
- }
619
- };
620
-
621
- } // namespace librats
@@ -1,75 +0,0 @@
1
- #include "chained_send_buffer.h"
2
- #include <cstring>
3
- #include <algorithm>
4
-
5
- namespace librats {
6
-
7
- void ChainedSendBuffer::append(std::vector<uint8_t> data) {
8
- if (data.empty()) return;
9
-
10
- total_bytes_ += data.size();
11
- chunks_.emplace_back(std::move(data));
12
- }
13
-
14
- void ChainedSendBuffer::append(const uint8_t* data, size_t length) {
15
- if (length == 0) return;
16
-
17
- std::vector<uint8_t> chunk(data, data + length);
18
- append(std::move(chunk));
19
- }
20
-
21
- const uint8_t* ChainedSendBuffer::front_data() const {
22
- if (chunks_.empty()) {
23
- return nullptr;
24
- }
25
- return chunks_.front().current();
26
- }
27
-
28
- size_t ChainedSendBuffer::front_size() const {
29
- if (chunks_.empty()) {
30
- return 0;
31
- }
32
- return chunks_.front().remaining();
33
- }
34
-
35
- void ChainedSendBuffer::pop_front(size_t bytes) {
36
- while (bytes > 0 && !chunks_.empty()) {
37
- SendChunk& front = chunks_.front();
38
- size_t remaining = front.remaining();
39
-
40
- if (bytes >= remaining) {
41
- // Consume entire chunk
42
- bytes -= remaining;
43
- total_bytes_ -= remaining;
44
- chunks_.pop_front();
45
- } else {
46
- // Partial consume
47
- front.offset += bytes;
48
- total_bytes_ -= bytes;
49
- bytes = 0;
50
- }
51
- }
52
- }
53
-
54
- void ChainedSendBuffer::clear() {
55
- chunks_.clear();
56
- total_bytes_ = 0;
57
- }
58
-
59
- size_t ChainedSendBuffer::copy_to(uint8_t* buffer, size_t max_bytes) const {
60
- size_t copied = 0;
61
-
62
- for (const auto& chunk : chunks_) {
63
- if (copied >= max_bytes) break;
64
-
65
- size_t remaining = chunk.remaining();
66
- size_t to_copy = (std::min)(remaining, max_bytes - copied);
67
-
68
- std::memcpy(buffer + copied, chunk.current(), to_copy);
69
- copied += to_copy;
70
- }
71
-
72
- return copied;
73
- }
74
-
75
- } // namespace librats