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,677 +0,0 @@
1
- #include "bt_create_torrent.h"
2
- #include "sha1.h"
3
- #include "fs.h"
4
-
5
- #include <fstream>
6
- #include <algorithm>
7
- #include <cstring>
8
-
9
- namespace librats {
10
-
11
- //=============================================================================
12
- // TorrentCreator Implementation
13
- //=============================================================================
14
-
15
- TorrentCreator::TorrentCreator(const std::string& path,
16
- const TorrentCreatorConfig& config)
17
- : base_path_(path)
18
- , comment_(config.comment)
19
- , created_by_(config.created_by)
20
- , creation_date_(config.creation_date)
21
- , is_private_(config.is_private)
22
- , piece_size_(config.piece_size)
23
- , info_hash_valid_(false) {
24
-
25
- // Determine name from path
26
- std::string name = get_filename_from_path(path);
27
- if (name.empty()) {
28
- name = path;
29
- }
30
- files_.set_name(name);
31
-
32
- // Scan files if path exists
33
- if (file_exists(path) || directory_exists(path)) {
34
- if (config.include_hidden_files) {
35
- scan_files(nullptr);
36
- } else {
37
- scan_files([](const std::string& p) {
38
- std::string filename = get_filename_from_path(p);
39
- return filename.empty() || filename[0] != '.';
40
- });
41
- }
42
- }
43
- }
44
-
45
- TorrentCreator::TorrentCreator(FileStorage&& storage,
46
- const std::string& base_path,
47
- const TorrentCreatorConfig& config)
48
- : base_path_(base_path)
49
- , files_(std::move(storage))
50
- , comment_(config.comment)
51
- , created_by_(config.created_by)
52
- , creation_date_(config.creation_date)
53
- , is_private_(config.is_private)
54
- , piece_size_(config.piece_size)
55
- , info_hash_valid_(false) {
56
- }
57
-
58
- //=============================================================================
59
- // File Management
60
- //=============================================================================
61
-
62
- size_t TorrentCreator::scan_files(FileFilterCallback filter) {
63
- // Clear existing files but keep name
64
- std::string name = files_.name();
65
- files_ = FileStorage();
66
- files_.set_name(name);
67
- piece_hashes_.clear();
68
- info_hash_valid_ = false;
69
-
70
- if (is_directory(base_path_.c_str())) {
71
- scan_directory(base_path_, "", filter);
72
- } else if (file_exists(base_path_.c_str())) {
73
- // Single file
74
- int64_t size = get_file_size(base_path_.c_str());
75
- if (size >= 0) {
76
- std::string filename = get_filename_from_path(base_path_);
77
- files_.add_file(filename, size);
78
- }
79
- }
80
-
81
- return files_.num_files();
82
- }
83
-
84
- void TorrentCreator::scan_directory(const std::string& dir_path,
85
- const std::string& relative_prefix,
86
- FileFilterCallback filter) {
87
- std::vector<DirectoryEntry> entries;
88
- if (!list_directory(dir_path.c_str(), entries)) {
89
- return;
90
- }
91
-
92
- // Sort entries for consistent ordering
93
- std::sort(entries.begin(), entries.end(),
94
- [](const DirectoryEntry& a, const DirectoryEntry& b) {
95
- return a.name < b.name;
96
- });
97
-
98
- for (const auto& entry : entries) {
99
- // Skip . and ..
100
- if (entry.name == "." || entry.name == "..") {
101
- continue;
102
- }
103
-
104
- std::string full_path = combine_paths(dir_path, entry.name);
105
- std::string relative_path = relative_prefix.empty()
106
- ? entry.name
107
- : relative_prefix + "/" + entry.name;
108
-
109
- // Apply filter
110
- if (filter && !filter(full_path)) {
111
- continue;
112
- }
113
-
114
- if (entry.is_directory) {
115
- // Recurse into directory
116
- scan_directory(full_path, relative_path, filter);
117
- } else {
118
- // Add file
119
- files_.add_file(relative_path, static_cast<int64_t>(entry.size));
120
- }
121
- }
122
- }
123
-
124
- bool TorrentCreator::add_file(const std::string& relative_path, int64_t size) {
125
- if (relative_path.empty() || size < 0) {
126
- return false;
127
- }
128
-
129
- files_.add_file(relative_path, size);
130
- piece_hashes_.clear();
131
- info_hash_valid_ = false;
132
- return true;
133
- }
134
-
135
- //=============================================================================
136
- // Properties
137
- //=============================================================================
138
-
139
- void TorrentCreator::set_name(const std::string& name) {
140
- files_.set_name(name);
141
- info_hash_valid_ = false;
142
- }
143
-
144
- void TorrentCreator::set_piece_size(uint32_t size) {
145
- // Validate piece size (must be power of 2, >= 16 KiB)
146
- if (size > 0) {
147
- if (size < 16 * 1024) {
148
- size = 16 * 1024;
149
- }
150
- // Round up to power of 2
151
- uint32_t power = 1;
152
- while (power < size) {
153
- power *= 2;
154
- }
155
- size = power;
156
- }
157
-
158
- piece_size_ = size;
159
- piece_hashes_.clear();
160
- info_hash_valid_ = false;
161
- }
162
-
163
- uint32_t TorrentCreator::auto_detect_piece_size() const {
164
- int64_t total = total_size();
165
-
166
- // Size thresholds and corresponding piece sizes
167
- // Based on libtorrent's algorithm
168
- static const struct {
169
- int64_t threshold;
170
- uint32_t piece_size;
171
- } size_table[] = {
172
- { 2684355LL, 16 * 1024 }, // -> 16 KiB
173
- { 10737418LL, 32 * 1024 }, // -> 32 KiB
174
- { 42949673LL, 64 * 1024 }, // -> 64 KiB
175
- { 171798692LL, 128 * 1024 }, // -> 128 KiB
176
- { 687194767LL, 256 * 1024 }, // -> 256 KiB
177
- { 2748779069LL, 512 * 1024 }, // -> 512 KiB
178
- { 10995116278LL, 1024 * 1024 }, // -> 1 MiB
179
- { 43980465111LL, 2 * 1024 * 1024 }, // -> 2 MiB
180
- { 175921860444LL, 4 * 1024 * 1024 }, // -> 4 MiB
181
- { 703687441777LL, 8 * 1024 * 1024 }, // -> 8 MiB
182
- { 2814749767106LL, 16 * 1024 * 1024 } // -> 16 MiB
183
- };
184
-
185
- for (const auto& entry : size_table) {
186
- if (total < entry.threshold) {
187
- return entry.piece_size;
188
- }
189
- }
190
-
191
- return 16 * 1024 * 1024; // Max 16 MiB
192
- }
193
-
194
- //=============================================================================
195
- // Trackers and Seeds
196
- //=============================================================================
197
-
198
- void TorrentCreator::add_tracker(const std::string& url, int tier) {
199
- if (url.empty()) return;
200
-
201
- // Check for duplicates
202
- for (const auto& t : trackers_) {
203
- if (t.first == url) return;
204
- }
205
-
206
- trackers_.emplace_back(url, tier);
207
-
208
- // Sort by tier
209
- std::sort(trackers_.begin(), trackers_.end(),
210
- [](const auto& a, const auto& b) { return a.second < b.second; });
211
- }
212
-
213
- std::vector<std::string> TorrentCreator::trackers() const {
214
- std::vector<std::string> result;
215
- result.reserve(trackers_.size());
216
- for (const auto& t : trackers_) {
217
- result.push_back(t.first);
218
- }
219
- return result;
220
- }
221
-
222
- void TorrentCreator::add_url_seed(const std::string& url) {
223
- if (!url.empty()) {
224
- url_seeds_.push_back(url);
225
- }
226
- }
227
-
228
- void TorrentCreator::add_http_seed(const std::string& url) {
229
- if (!url.empty()) {
230
- http_seeds_.push_back(url);
231
- }
232
- }
233
-
234
- void TorrentCreator::add_dht_node(const std::string& host, uint16_t port) {
235
- if (!host.empty() && port > 0) {
236
- dht_nodes_.emplace_back(host, port);
237
- }
238
- }
239
-
240
- //=============================================================================
241
- // Piece Hashing
242
- //=============================================================================
243
-
244
- bool TorrentCreator::set_piece_hashes(PieceHashProgressCallback progress_callback,
245
- TorrentCreateError* error) {
246
- if (files_.num_files() == 0) {
247
- if (error) error->message = "No files to hash";
248
- return false;
249
- }
250
-
251
- if (total_size() == 0) {
252
- if (error) error->message = "Total size is zero";
253
- return false;
254
- }
255
-
256
- // Determine piece size
257
- uint32_t psize = piece_size_;
258
- if (psize == 0) {
259
- psize = auto_detect_piece_size();
260
- }
261
- piece_size_ = psize;
262
-
263
- // Finalize file storage with piece size
264
- files_.set_piece_length(psize);
265
- files_.finalize();
266
-
267
- uint32_t num_pcs = files_.num_pieces();
268
- piece_hashes_.clear();
269
- piece_hashes_.reserve(num_pcs * 20);
270
-
271
- // Buffer for reading file data
272
- std::vector<uint8_t> piece_buffer(psize);
273
-
274
- // Current position in file storage
275
- uint32_t current_piece = 0;
276
- uint32_t piece_offset = 0;
277
-
278
- // For each file
279
- for (size_t file_idx = 0; file_idx < files_.num_files(); ++file_idx) {
280
- const FileEntry& entry = files_.file_at(file_idx);
281
-
282
- // Build full path to file
283
- std::string file_path;
284
- if (is_directory(base_path_.c_str())) {
285
- file_path = combine_paths(base_path_, entry.path);
286
- } else {
287
- file_path = base_path_;
288
- }
289
-
290
- // Open file
291
- std::ifstream file(file_path, std::ios::binary);
292
- if (!file) {
293
- if (error) error->message = "Failed to open file: " + file_path;
294
- return false;
295
- }
296
-
297
- int64_t remaining = entry.size;
298
- while (remaining > 0) {
299
- // How much to read for current piece
300
- uint32_t space_in_piece = psize - piece_offset;
301
- uint32_t to_read = static_cast<uint32_t>(std::min(static_cast<int64_t>(space_in_piece), remaining));
302
-
303
- // Read data
304
- if (!file.read(reinterpret_cast<char*>(piece_buffer.data() + piece_offset), to_read)) {
305
- if (error) error->message = "Failed to read file: " + file_path;
306
- return false;
307
- }
308
-
309
- piece_offset += to_read;
310
- remaining -= to_read;
311
-
312
- // If piece is complete, hash it
313
- if (piece_offset == psize) {
314
- SHA1 hasher;
315
- hasher.update(piece_buffer.data(), psize);
316
- std::string hex_hash = hasher.finalize();
317
-
318
- // Convert hex to bytes
319
- for (size_t i = 0; i < 40; i += 2) {
320
- uint8_t byte = static_cast<uint8_t>(
321
- std::stoul(hex_hash.substr(i, 2), nullptr, 16));
322
- piece_hashes_.push_back(byte);
323
- }
324
-
325
- ++current_piece;
326
- piece_offset = 0;
327
-
328
- // Progress callback
329
- if (progress_callback) {
330
- progress_callback(current_piece, num_pcs);
331
- }
332
- }
333
- }
334
- }
335
-
336
- // Hash final partial piece if any
337
- if (piece_offset > 0) {
338
- SHA1 hasher;
339
- hasher.update(piece_buffer.data(), piece_offset);
340
- std::string hex_hash = hasher.finalize();
341
-
342
- // Convert hex to bytes
343
- for (size_t i = 0; i < 40; i += 2) {
344
- uint8_t byte = static_cast<uint8_t>(
345
- std::stoul(hex_hash.substr(i, 2), nullptr, 16));
346
- piece_hashes_.push_back(byte);
347
- }
348
-
349
- ++current_piece;
350
-
351
- // Final progress callback
352
- if (progress_callback) {
353
- progress_callback(current_piece, num_pcs);
354
- }
355
- }
356
-
357
- info_hash_valid_ = false;
358
- return true;
359
- }
360
-
361
- //=============================================================================
362
- // Generation
363
- //=============================================================================
364
-
365
- BencodeValue TorrentCreator::build_info_dict() const {
366
- BencodeValue info = BencodeValue::create_dict();
367
-
368
- // Name (required)
369
- info["name"] = BencodeValue(files_.name());
370
-
371
- // Piece length (required)
372
- info["piece length"] = BencodeValue(static_cast<int64_t>(piece_size_));
373
-
374
- // Pieces (required) - concatenated SHA-1 hashes
375
- std::string pieces_str(piece_hashes_.begin(), piece_hashes_.end());
376
- info["pieces"] = BencodeValue(pieces_str);
377
-
378
- // Private flag
379
- if (is_private_) {
380
- info["private"] = BencodeValue(static_cast<int64_t>(1));
381
- }
382
-
383
- // File(s)
384
- if (files_.num_files() == 1) {
385
- // Single-file mode
386
- info["length"] = BencodeValue(files_.file_at(0).size);
387
- } else {
388
- // Multi-file mode
389
- BencodeValue files_list = BencodeValue::create_list();
390
-
391
- for (size_t i = 0; i < files_.num_files(); ++i) {
392
- const FileEntry& entry = files_.file_at(i);
393
-
394
- BencodeValue file_dict = BencodeValue::create_dict();
395
- file_dict["length"] = BencodeValue(entry.size);
396
-
397
- // Path components
398
- BencodeValue path_list = BencodeValue::create_list();
399
- std::string path = entry.path;
400
-
401
- // Split path by /
402
- size_t pos = 0;
403
- while (pos < path.size()) {
404
- size_t next = path.find('/', pos);
405
- if (next == std::string::npos) {
406
- next = path.size();
407
- }
408
- if (next > pos) {
409
- path_list.push_back(BencodeValue(path.substr(pos, next - pos)));
410
- }
411
- pos = next + 1;
412
- }
413
-
414
- file_dict["path"] = std::move(path_list);
415
- files_list.push_back(std::move(file_dict));
416
- }
417
-
418
- info["files"] = std::move(files_list);
419
- }
420
-
421
- return info;
422
- }
423
-
424
- BencodeValue TorrentCreator::build_torrent_dict() const {
425
- BencodeValue dict = BencodeValue::create_dict();
426
-
427
- // Info dictionary (required)
428
- dict["info"] = build_info_dict();
429
-
430
- // Announce (primary tracker)
431
- if (!trackers_.empty()) {
432
- dict["announce"] = BencodeValue(trackers_[0].first);
433
- }
434
-
435
- // Announce-list (multi-tracker)
436
- if (trackers_.size() > 1) {
437
- BencodeValue announce_list = BencodeValue::create_list();
438
- BencodeValue current_tier = BencodeValue::create_list();
439
- int current_tier_num = trackers_[0].second;
440
-
441
- for (const auto& tracker : trackers_) {
442
- if (tracker.second != current_tier_num) {
443
- announce_list.push_back(std::move(current_tier));
444
- current_tier = BencodeValue::create_list();
445
- current_tier_num = tracker.second;
446
- }
447
- current_tier.push_back(BencodeValue(tracker.first));
448
- }
449
- announce_list.push_back(std::move(current_tier));
450
-
451
- dict["announce-list"] = std::move(announce_list);
452
- }
453
-
454
- // Comment
455
- if (!comment_.empty()) {
456
- dict["comment"] = BencodeValue(comment_);
457
- }
458
-
459
- // Created by
460
- if (!created_by_.empty()) {
461
- dict["created by"] = BencodeValue(created_by_);
462
- }
463
-
464
- // Creation date
465
- if (creation_date_ != 0) {
466
- dict["creation date"] = BencodeValue(static_cast<int64_t>(creation_date_));
467
- }
468
-
469
- // URL seeds
470
- if (!url_seeds_.empty()) {
471
- if (url_seeds_.size() == 1) {
472
- dict["url-list"] = BencodeValue(url_seeds_[0]);
473
- } else {
474
- BencodeValue list = BencodeValue::create_list();
475
- for (const auto& seed : url_seeds_) {
476
- list.push_back(BencodeValue(seed));
477
- }
478
- dict["url-list"] = std::move(list);
479
- }
480
- }
481
-
482
- // HTTP seeds
483
- if (!http_seeds_.empty()) {
484
- if (http_seeds_.size() == 1) {
485
- dict["httpseeds"] = BencodeValue(http_seeds_[0]);
486
- } else {
487
- BencodeValue list = BencodeValue::create_list();
488
- for (const auto& seed : http_seeds_) {
489
- list.push_back(BencodeValue(seed));
490
- }
491
- dict["httpseeds"] = std::move(list);
492
- }
493
- }
494
-
495
- // DHT nodes
496
- if (!dht_nodes_.empty()) {
497
- BencodeValue nodes = BencodeValue::create_list();
498
- for (const auto& node : dht_nodes_) {
499
- BencodeValue node_entry = BencodeValue::create_list();
500
- node_entry.push_back(BencodeValue(node.first));
501
- node_entry.push_back(BencodeValue(static_cast<int64_t>(node.second)));
502
- nodes.push_back(std::move(node_entry));
503
- }
504
- dict["nodes"] = std::move(nodes);
505
- }
506
-
507
- return dict;
508
- }
509
-
510
- std::vector<uint8_t> TorrentCreator::generate(TorrentCreateError* error) const {
511
- if (piece_hashes_.empty()) {
512
- if (error) error->message = "Piece hashes not computed. Call set_piece_hashes() first.";
513
- return {};
514
- }
515
-
516
- if (files_.num_files() == 0) {
517
- if (error) error->message = "No files in torrent";
518
- return {};
519
- }
520
-
521
- BencodeValue torrent = build_torrent_dict();
522
- return torrent.encode();
523
- }
524
-
525
- bool TorrentCreator::save_to_file(const std::string& output_path,
526
- TorrentCreateError* error) const {
527
- auto data = generate(error);
528
- if (data.empty()) {
529
- return false;
530
- }
531
-
532
- std::ofstream file(output_path, std::ios::binary);
533
- if (!file) {
534
- if (error) error->message = "Failed to open output file: " + output_path;
535
- return false;
536
- }
537
-
538
- if (!file.write(reinterpret_cast<const char*>(data.data()), data.size())) {
539
- if (error) error->message = "Failed to write output file: " + output_path;
540
- return false;
541
- }
542
-
543
- return true;
544
- }
545
-
546
- std::optional<TorrentInfo> TorrentCreator::generate_torrent_info(TorrentCreateError* error) const {
547
- auto data = generate(error);
548
- if (data.empty()) {
549
- return std::nullopt;
550
- }
551
-
552
- TorrentParseError parse_error;
553
- auto result = TorrentInfo::from_bytes(data, &parse_error);
554
- if (!result && error) {
555
- error->message = parse_error.message;
556
- }
557
- return result;
558
- }
559
-
560
- BtInfoHash TorrentCreator::info_hash() const {
561
- if (info_hash_valid_) {
562
- return cached_info_hash_;
563
- }
564
-
565
- if (piece_hashes_.empty()) {
566
- return BtInfoHash{};
567
- }
568
-
569
- BencodeValue info_dict = build_info_dict();
570
- std::vector<uint8_t> info_bytes = info_dict.encode();
571
-
572
- SHA1 hasher;
573
- hasher.update(info_bytes.data(), info_bytes.size());
574
- std::string hex_hash = hasher.finalize();
575
-
576
- cached_info_hash_ = hex_to_info_hash(hex_hash);
577
- info_hash_valid_ = true;
578
-
579
- return cached_info_hash_;
580
- }
581
-
582
- std::string TorrentCreator::info_hash_hex() const {
583
- BtInfoHash hash = info_hash();
584
- return info_hash_to_hex(hash);
585
- }
586
-
587
- //=============================================================================
588
- // Convenience Functions
589
- //=============================================================================
590
-
591
- size_t add_files(FileStorage& storage, const std::string& path,
592
- FileFilterCallback filter) {
593
- size_t count = 0;
594
-
595
- if (is_directory(path.c_str())) {
596
- std::vector<DirectoryEntry> entries;
597
- if (!list_directory(path.c_str(), entries)) {
598
- return 0;
599
- }
600
-
601
- std::sort(entries.begin(), entries.end(),
602
- [](const DirectoryEntry& a, const DirectoryEntry& b) {
603
- return a.name < b.name;
604
- });
605
-
606
- for (const auto& entry : entries) {
607
- if (entry.name == "." || entry.name == "..") continue;
608
-
609
- std::string full_path = combine_paths(path, entry.name);
610
-
611
- if (filter && !filter(full_path)) continue;
612
-
613
- if (entry.is_directory) {
614
- count += add_files(storage, full_path, filter);
615
- } else {
616
- storage.add_file(entry.name, static_cast<int64_t>(entry.size));
617
- ++count;
618
- }
619
- }
620
- } else if (file_exists(path.c_str())) {
621
- if (!filter || filter(path)) {
622
- int64_t size = get_file_size(path.c_str());
623
- std::string filename = get_filename_from_path(path);
624
- storage.add_file(filename, size);
625
- ++count;
626
- }
627
- }
628
-
629
- return count;
630
- }
631
-
632
- bool create_torrent(const std::string& path,
633
- const std::string& output_path,
634
- const std::vector<std::string>& trackers,
635
- const std::string& comment,
636
- PieceHashProgressCallback progress_callback,
637
- TorrentCreateError* error) {
638
- TorrentCreatorConfig config;
639
- config.comment = comment;
640
- config.created_by = "librats";
641
-
642
- TorrentCreator creator(path, config);
643
-
644
- for (const auto& tracker : trackers) {
645
- creator.add_tracker(tracker);
646
- }
647
-
648
- if (!creator.set_piece_hashes(progress_callback, error)) {
649
- return false;
650
- }
651
-
652
- return creator.save_to_file(output_path, error);
653
- }
654
-
655
- std::vector<uint8_t> create_torrent_data(const std::string& path,
656
- const std::vector<std::string>& trackers,
657
- const std::string& comment,
658
- PieceHashProgressCallback progress_callback,
659
- TorrentCreateError* error) {
660
- TorrentCreatorConfig config;
661
- config.comment = comment;
662
- config.created_by = "librats";
663
-
664
- TorrentCreator creator(path, config);
665
-
666
- for (const auto& tracker : trackers) {
667
- creator.add_tracker(tracker);
668
- }
669
-
670
- if (!creator.set_piece_hashes(progress_callback, error)) {
671
- return {};
672
- }
673
-
674
- return creator.generate(error);
675
- }
676
-
677
- } // namespace librats