librats 1.0.2 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (313) hide show
  1. package/README.md +137 -332
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +271 -696
  4. package/lib/index.js +383 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +396 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +731 -0
  10. package/native-src/src/librats/bindings/rats.h +352 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +42 -0
  73. package/native-src/src/librats/core/types.h +93 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/config.h +110 -0
  144. package/native-src/src/librats/node/dial_service.h +54 -0
  145. package/native-src/src/librats/node/dialer.cpp +264 -0
  146. package/native-src/src/librats/node/dialer.h +188 -0
  147. package/native-src/src/librats/node/host_events.h +26 -0
  148. package/native-src/src/librats/node/identify.cpp +130 -0
  149. package/native-src/src/librats/node/identify.h +71 -0
  150. package/native-src/src/librats/node/nat_status.cpp +103 -0
  151. package/native-src/src/librats/node/nat_status.h +118 -0
  152. package/native-src/src/librats/node/node.cpp +826 -0
  153. package/native-src/src/librats/node/node.h +333 -0
  154. package/native-src/src/librats/node/node_context.h +33 -0
  155. package/native-src/src/librats/node/peer_network.h +91 -0
  156. package/native-src/src/librats/peer/peer.h +49 -0
  157. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  158. package/native-src/src/librats/peer/peer_book.h +88 -0
  159. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  160. package/native-src/src/librats/peer/peer_id.h +62 -0
  161. package/native-src/src/librats/peer/peer_info.h +37 -0
  162. package/native-src/src/librats/peer/peer_table.cpp +137 -0
  163. package/native-src/src/librats/peer/peer_table.h +148 -0
  164. package/native-src/src/librats/security/handshaker.h +66 -0
  165. package/native-src/src/librats/security/identity.h +43 -0
  166. package/native-src/src/librats/security/noise_security.cpp +122 -0
  167. package/native-src/src/librats/security/noise_security.h +37 -0
  168. package/native-src/src/librats/security/plaintext_security.h +106 -0
  169. package/native-src/src/librats/security/session.h +37 -0
  170. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  171. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  172. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  173. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  174. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  176. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  177. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  178. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  179. package/native-src/src/librats/subsystems/hole_punch.cpp +532 -0
  180. package/native-src/src/librats/subsystems/hole_punch.h +266 -0
  181. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  182. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  184. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  185. package/native-src/src/librats/subsystems/message_json.h +88 -0
  186. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  188. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  189. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  190. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  192. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  193. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  194. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  195. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  196. package/native-src/src/librats/transport/connection.cpp +343 -0
  197. package/native-src/src/librats/transport/connection.h +283 -0
  198. package/native-src/src/librats/transport/link.h +96 -0
  199. package/native-src/src/librats/transport/reactor.cpp +540 -0
  200. package/native-src/src/librats/transport/reactor.h +224 -0
  201. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  202. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  203. package/native-src/src/librats/transport/tcp_link.h +43 -0
  204. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  205. package/native-src/src/librats/transport/udp_mux.h +363 -0
  206. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  207. package/native-src/src/librats/transport/udp_packet.h +190 -0
  208. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  209. package/native-src/src/librats/transport/udp_stream.h +614 -0
  210. package/native-src/src/librats/util/features.h.in +51 -0
  211. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  212. package/native-src/src/librats/util/fs.h +136 -0
  213. package/native-src/src/librats/util/json.cpp +1002 -0
  214. package/native-src/src/librats/util/json.h +444 -0
  215. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  216. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  217. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  218. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  219. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  220. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  221. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  222. package/native-src/src/librats/util/rats_export.h +69 -0
  223. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  224. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  225. package/native-src/src/librats/wire/frame.cpp +76 -0
  226. package/native-src/src/librats/wire/frame.h +110 -0
  227. package/native-src/src/librats/wire/message_router.cpp +45 -0
  228. package/native-src/src/librats/wire/message_router.h +47 -0
  229. package/package.json +5 -4
  230. package/scripts/build-librats.js +1 -0
  231. package/scripts/postinstall.js +3 -3
  232. package/scripts/prepare-package.js +4 -4
  233. package/scripts/verify-installation.js +63 -105
  234. package/src/librats_node.cpp +1042 -1324
  235. package/native-src/src/bencode.cpp +0 -485
  236. package/native-src/src/bencode.h +0 -145
  237. package/native-src/src/bittorrent.cpp +0 -14
  238. package/native-src/src/bittorrent.h +0 -74
  239. package/native-src/src/bt_bitfield.cpp +0 -372
  240. package/native-src/src/bt_bitfield.h +0 -316
  241. package/native-src/src/bt_choker.cpp +0 -228
  242. package/native-src/src/bt_choker.h +0 -147
  243. package/native-src/src/bt_client.cpp +0 -1047
  244. package/native-src/src/bt_client.h +0 -445
  245. package/native-src/src/bt_create_torrent.cpp +0 -677
  246. package/native-src/src/bt_create_torrent.h +0 -473
  247. package/native-src/src/bt_extension.cpp +0 -469
  248. package/native-src/src/bt_extension.h +0 -309
  249. package/native-src/src/bt_file_storage.cpp +0 -261
  250. package/native-src/src/bt_file_storage.h +0 -298
  251. package/native-src/src/bt_handshake.cpp +0 -134
  252. package/native-src/src/bt_handshake.h +0 -157
  253. package/native-src/src/bt_messages.cpp +0 -364
  254. package/native-src/src/bt_messages.h +0 -324
  255. package/native-src/src/bt_network.cpp +0 -1007
  256. package/native-src/src/bt_network.h +0 -417
  257. package/native-src/src/bt_peer_connection.cpp +0 -742
  258. package/native-src/src/bt_peer_connection.h +0 -592
  259. package/native-src/src/bt_piece_picker.cpp +0 -786
  260. package/native-src/src/bt_piece_picker.h +0 -473
  261. package/native-src/src/bt_resume_data.cpp +0 -410
  262. package/native-src/src/bt_resume_data.h +0 -249
  263. package/native-src/src/bt_torrent.cpp +0 -2120
  264. package/native-src/src/bt_torrent.h +0 -641
  265. package/native-src/src/bt_torrent_info.cpp +0 -659
  266. package/native-src/src/bt_torrent_info.h +0 -418
  267. package/native-src/src/bt_types.h +0 -621
  268. package/native-src/src/chained_send_buffer.cpp +0 -75
  269. package/native-src/src/chained_send_buffer.h +0 -137
  270. package/native-src/src/crypto/hkdf.c +0 -266
  271. package/native-src/src/crypto/poly1305.h +0 -36
  272. package/native-src/src/dht.cpp +0 -3311
  273. package/native-src/src/dht.h +0 -717
  274. package/native-src/src/disk_io.cpp +0 -632
  275. package/native-src/src/disk_io.h +0 -315
  276. package/native-src/src/file_transfer.cpp +0 -1415
  277. package/native-src/src/file_transfer.h +0 -286
  278. package/native-src/src/fs.h +0 -108
  279. package/native-src/src/gossipsub.cpp +0 -1139
  280. package/native-src/src/gossipsub.h +0 -403
  281. package/native-src/src/ice.cpp +0 -893
  282. package/native-src/src/ice.h +0 -559
  283. package/native-src/src/json.hpp +0 -25526
  284. package/native-src/src/librats.cpp +0 -2378
  285. package/native-src/src/librats.h +0 -2324
  286. package/native-src/src/librats_bittorrent.cpp +0 -601
  287. package/native-src/src/librats_c.cpp +0 -1557
  288. package/native-src/src/librats_c.h +0 -323
  289. package/native-src/src/librats_discovery.cpp +0 -402
  290. package/native-src/src/librats_encryption.cpp +0 -275
  291. package/native-src/src/librats_file_transfer.cpp +0 -144
  292. package/native-src/src/librats_gossipsub.cpp +0 -289
  293. package/native-src/src/librats_ice.cpp +0 -213
  294. package/native-src/src/librats_log_macros.h +0 -36
  295. package/native-src/src/librats_logging.cpp +0 -173
  296. package/native-src/src/librats_mdns.cpp +0 -166
  297. package/native-src/src/librats_persistence.cpp +0 -796
  298. package/native-src/src/librats_portmap.cpp +0 -419
  299. package/native-src/src/librats_reconnection.cpp +0 -218
  300. package/native-src/src/librats_statistic.cpp +0 -105
  301. package/native-src/src/librats_storage.cpp +0 -189
  302. package/native-src/src/rats_export.h +0 -17
  303. package/native-src/src/receive_buffer.cpp +0 -82
  304. package/native-src/src/receive_buffer.h +0 -127
  305. package/native-src/src/socket.h +0 -228
  306. package/native-src/src/threadmanager.cpp +0 -105
  307. package/native-src/src/threadmanager.h +0 -53
  308. package/native-src/src/tracker.cpp +0 -1264
  309. package/native-src/src/tracker.h +0 -319
  310. package/native-src/src/turn.cpp +0 -762
  311. package/native-src/src/turn.h +0 -460
  312. package/native-src/src/wakeup_pipe.h +0 -60
  313. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,469 +0,0 @@
1
- #include "bt_extension.h"
2
- #include "bt_peer_connection.h"
3
-
4
- #include <algorithm>
5
- #include <cstring>
6
-
7
- namespace librats {
8
-
9
- //=============================================================================
10
- // ExtensionManager
11
- //=============================================================================
12
-
13
- ExtensionManager::ExtensionManager(BtPeerConnection* conn)
14
- : conn_(conn) {
15
- }
16
-
17
- void ExtensionManager::register_extension(std::shared_ptr<BtExtension> extension,
18
- uint8_t local_id) {
19
- extensions_[extension->name()] = extension;
20
- local_id_map_[local_id] = extension;
21
- }
22
-
23
- std::shared_ptr<BtExtension> ExtensionManager::get_extension(const std::string& name) {
24
- auto it = extensions_.find(name);
25
- if (it != extensions_.end()) {
26
- return it->second;
27
- }
28
- return nullptr;
29
- }
30
-
31
- std::vector<uint8_t> ExtensionManager::create_handshake() {
32
- BencodeValue handshake = BencodeValue::create_dict();
33
-
34
- // Build 'm' dictionary with extension name -> our local ID
35
- BencodeValue m = BencodeValue::create_dict();
36
- for (const auto& [local_id, ext] : local_id_map_) {
37
- m[ext->name()] = BencodeValue(static_cast<int64_t>(local_id));
38
- }
39
- handshake["m"] = m;
40
-
41
- // Let each extension add its data
42
- for (const auto& [name, ext] : extensions_) {
43
- ext->add_handshake_data(handshake.as_dict());
44
- }
45
-
46
- // Add client ID
47
- handshake["v"] = BencodeValue("librats");
48
-
49
- return handshake.encode();
50
- }
51
-
52
- void ExtensionManager::process_handshake(const std::vector<uint8_t>& payload) {
53
- // Decode bencoded handshake
54
- BencodeValue decoded;
55
- try {
56
- decoded = BencodeDecoder::decode(payload);
57
- } catch (...) {
58
- return;
59
- }
60
-
61
- if (!decoded.is_dict()) {
62
- return;
63
- }
64
-
65
- const auto& dict = decoded.as_dict();
66
-
67
- // Extract metadata_size if present
68
- auto metadata_size_it = dict.find("metadata_size");
69
- if (metadata_size_it != dict.end() && metadata_size_it->second.is_integer()) {
70
- metadata_size_ = static_cast<size_t>(metadata_size_it->second.as_integer());
71
- }
72
-
73
- // Parse 'm' dictionary for extension IDs
74
- auto m_it = dict.find("m");
75
- if (m_it != dict.end() && m_it->second.is_dict()) {
76
- const auto& m = m_it->second.as_dict();
77
-
78
- for (const auto& [name, ext] : extensions_) {
79
- auto ext_it = m.find(name);
80
- if (ext_it != m.end() && ext_it->second.is_integer()) {
81
- uint8_t peer_id = static_cast<uint8_t>(ext_it->second.as_integer());
82
- ext->set_peer_msg_id(peer_id);
83
- if (peer_id != 0) {
84
- peer_id_map_[peer_id] = ext;
85
- }
86
- }
87
- }
88
- }
89
-
90
- // Notify all extensions of handshake
91
- for (const auto& [name, ext] : extensions_) {
92
- ext->on_handshake(dict);
93
- }
94
- }
95
-
96
- bool ExtensionManager::handle_message(uint8_t extension_id,
97
- const std::vector<uint8_t>& payload) {
98
- // Extension ID 0 is handshake
99
- if (extension_id == 0) {
100
- process_handshake(payload);
101
- return true;
102
- }
103
-
104
- // Find extension by our local ID
105
- auto it = local_id_map_.find(extension_id);
106
- if (it != local_id_map_.end()) {
107
- return it->second->on_message(extension_id, payload);
108
- }
109
-
110
- return false;
111
- }
112
-
113
- void ExtensionManager::send_message(const std::string& extension_name,
114
- const std::vector<uint8_t>& payload) {
115
- auto ext = get_extension(extension_name);
116
- if (!ext || !ext->peer_supports()) {
117
- return;
118
- }
119
-
120
- // Send using peer's message ID
121
- if (conn_) {
122
- conn_->send_extended(ext->peer_msg_id(), payload);
123
- }
124
- }
125
-
126
- //=============================================================================
127
- // UtMetadataExtension
128
- //=============================================================================
129
-
130
- UtMetadataExtension::UtMetadataExtension(size_t metadata_size,
131
- const std::vector<uint8_t>* our_metadata)
132
- : metadata_size_(metadata_size)
133
- , our_metadata_(our_metadata)
134
- , metadata_complete_(false) {
135
-
136
- if (metadata_size_ > 0) {
137
- uint32_t pieces = num_pieces();
138
- pieces_received_.resize(pieces, false);
139
- pieces_requested_.resize(pieces, false);
140
- received_metadata_.resize(metadata_size_);
141
- }
142
- }
143
-
144
- void UtMetadataExtension::on_handshake(const BencodeDict& handshake) {
145
- auto it = handshake.find("metadata_size");
146
- if (it != handshake.end() && it->second.is_integer()) {
147
- size_t new_size = static_cast<size_t>(it->second.as_integer());
148
-
149
- if (metadata_size_ == 0 && new_size > 0) {
150
- metadata_size_ = new_size;
151
- uint32_t pieces = num_pieces();
152
- pieces_received_.resize(pieces, false);
153
- pieces_requested_.resize(pieces, false);
154
- received_metadata_.resize(metadata_size_);
155
- }
156
- }
157
- }
158
-
159
- bool UtMetadataExtension::on_message(uint8_t /*msg_id*/,
160
- const std::vector<uint8_t>& payload) {
161
- // Decode the message
162
- BencodeValue decoded;
163
- try {
164
- decoded = BencodeDecoder::decode(payload);
165
- } catch (...) {
166
- return false;
167
- }
168
-
169
- if (!decoded.is_dict()) {
170
- return false;
171
- }
172
-
173
- const auto& dict = decoded.as_dict();
174
-
175
- auto msg_type_it = dict.find("msg_type");
176
- if (msg_type_it == dict.end() || !msg_type_it->second.is_integer()) {
177
- return false;
178
- }
179
-
180
- uint8_t msg_type = static_cast<uint8_t>(msg_type_it->second.as_integer());
181
-
182
- switch (static_cast<UtMetadataMessageType>(msg_type)) {
183
- case UtMetadataMessageType::Request:
184
- handle_request(dict);
185
- break;
186
- case UtMetadataMessageType::Data:
187
- handle_data(dict, payload);
188
- break;
189
- case UtMetadataMessageType::Reject:
190
- handle_reject(dict);
191
- break;
192
- default:
193
- return false;
194
- }
195
-
196
- return true;
197
- }
198
-
199
- void UtMetadataExtension::add_handshake_data(BencodeDict& handshake) {
200
- if (our_metadata_ && !our_metadata_->empty()) {
201
- handshake["metadata_size"] = BencodeValue(static_cast<int64_t>(our_metadata_->size()));
202
- }
203
- }
204
-
205
- std::vector<uint8_t> UtMetadataExtension::create_request(uint32_t piece) {
206
- BencodeValue msg = BencodeValue::create_dict();
207
- msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Request));
208
- msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
209
-
210
- if (piece < pieces_requested_.size()) {
211
- pieces_requested_[piece] = true;
212
- }
213
-
214
- return msg.encode();
215
- }
216
-
217
- std::vector<uint8_t> UtMetadataExtension::create_data(uint32_t piece,
218
- const std::vector<uint8_t>& data) {
219
- BencodeValue msg = BencodeValue::create_dict();
220
- msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Data));
221
- msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
222
- msg["total_size"] = BencodeValue(static_cast<int64_t>(metadata_size_));
223
-
224
- std::vector<uint8_t> result = msg.encode();
225
-
226
- // Append raw data after bencoded dict
227
- result.insert(result.end(), data.begin(), data.end());
228
-
229
- return result;
230
- }
231
-
232
- std::vector<uint8_t> UtMetadataExtension::create_reject(uint32_t piece) {
233
- BencodeValue msg = BencodeValue::create_dict();
234
- msg["msg_type"] = BencodeValue(static_cast<int64_t>(UtMetadataMessageType::Reject));
235
- msg["piece"] = BencodeValue(static_cast<int64_t>(piece));
236
- return msg.encode();
237
- }
238
-
239
- uint32_t UtMetadataExtension::num_pieces() const {
240
- if (metadata_size_ == 0) return 0;
241
- return static_cast<uint32_t>((metadata_size_ + BT_METADATA_PIECE_SIZE - 1) / BT_METADATA_PIECE_SIZE);
242
- }
243
-
244
- void UtMetadataExtension::handle_request(const BencodeDict& msg) {
245
- auto piece_it = msg.find("piece");
246
- if (piece_it == msg.end() || !piece_it->second.is_integer()) {
247
- return;
248
- }
249
-
250
- uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
251
-
252
- // If we have metadata, we could respond here
253
- // This would require access to the connection to send
254
- (void)piece;
255
- }
256
-
257
- void UtMetadataExtension::handle_data(const BencodeDict& msg,
258
- const std::vector<uint8_t>& payload) {
259
- auto piece_it = msg.find("piece");
260
- if (piece_it == msg.end() || !piece_it->second.is_integer()) {
261
- return;
262
- }
263
-
264
- uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
265
-
266
- if (piece >= num_pieces()) {
267
- return;
268
- }
269
-
270
- // Find where the data starts (after the bencoded dict)
271
- // The dict ends with 'e', so we need to find the end of the dict
272
- size_t dict_end = 0;
273
- int depth = 0;
274
- for (size_t i = 0; i < payload.size(); ++i) {
275
- if (payload[i] == 'd' || payload[i] == 'l') {
276
- ++depth;
277
- } else if (payload[i] == 'e') {
278
- --depth;
279
- if (depth == 0) {
280
- dict_end = i + 1;
281
- break;
282
- }
283
- } else if (std::isdigit(payload[i])) {
284
- // Skip string
285
- size_t len = 0;
286
- while (i < payload.size() && std::isdigit(payload[i])) {
287
- len = len * 10 + (payload[i] - '0');
288
- ++i;
289
- }
290
- if (i < payload.size() && payload[i] == ':') {
291
- i += len; // Skip the string content
292
- }
293
- } else if (payload[i] == 'i') {
294
- // Skip integer
295
- while (i < payload.size() && payload[i] != 'e') {
296
- ++i;
297
- }
298
- }
299
- }
300
-
301
- if (dict_end >= payload.size()) {
302
- return;
303
- }
304
-
305
- // Copy data to correct position
306
- size_t offset = static_cast<size_t>(piece) * BT_METADATA_PIECE_SIZE;
307
- size_t data_size = payload.size() - dict_end;
308
- size_t to_copy = (std::min)(data_size, metadata_size_ - offset);
309
-
310
- if (offset + to_copy <= received_metadata_.size()) {
311
- std::memcpy(received_metadata_.data() + offset, payload.data() + dict_end, to_copy);
312
- pieces_received_[piece] = true;
313
-
314
- check_complete();
315
- }
316
- }
317
-
318
- void UtMetadataExtension::handle_reject(const BencodeDict& msg) {
319
- auto piece_it = msg.find("piece");
320
- if (piece_it == msg.end() || !piece_it->second.is_integer()) {
321
- return;
322
- }
323
-
324
- uint32_t piece = static_cast<uint32_t>(piece_it->second.as_integer());
325
-
326
- if (piece < pieces_requested_.size()) {
327
- pieces_requested_[piece] = false; // Can retry later
328
- }
329
- }
330
-
331
- void UtMetadataExtension::check_complete() {
332
- for (bool received : pieces_received_) {
333
- if (!received) return;
334
- }
335
-
336
- metadata_complete_ = true;
337
-
338
- if (on_metadata_complete_) {
339
- on_metadata_complete_(received_metadata_);
340
- }
341
- }
342
-
343
- uint32_t UtMetadataExtension::next_piece_to_request() const {
344
- for (uint32_t i = 0; i < num_pieces(); ++i) {
345
- if (!pieces_received_[i] && !pieces_requested_[i]) {
346
- return i;
347
- }
348
- }
349
- return num_pieces();
350
- }
351
-
352
- //=============================================================================
353
- // UtPexExtension
354
- //=============================================================================
355
-
356
- UtPexExtension::UtPexExtension() {
357
- }
358
-
359
- void UtPexExtension::on_handshake(const BencodeDict& /*handshake*/) {
360
- // Nothing to do
361
- }
362
-
363
- bool UtPexExtension::on_message(uint8_t /*msg_id*/,
364
- const std::vector<uint8_t>& payload) {
365
- BencodeValue decoded;
366
- try {
367
- decoded = BencodeDecoder::decode(payload);
368
- } catch (...) {
369
- return false;
370
- }
371
-
372
- if (!decoded.is_dict()) {
373
- return false;
374
- }
375
-
376
- const auto& dict = decoded.as_dict();
377
-
378
- std::vector<PexPeer> added, dropped;
379
-
380
- // Parse added peers (IPv4)
381
- auto added_it = dict.find("added");
382
- if (added_it != dict.end() && added_it->second.is_string()) {
383
- added = parse_peers(added_it->second.as_string());
384
- }
385
-
386
- // Parse dropped peers
387
- auto dropped_it = dict.find("dropped");
388
- if (dropped_it != dict.end() && dropped_it->second.is_string()) {
389
- dropped = parse_peers(dropped_it->second.as_string());
390
- }
391
-
392
- if (on_peers_) {
393
- on_peers_(added, dropped);
394
- }
395
-
396
- return true;
397
- }
398
-
399
- void UtPexExtension::add_handshake_data(BencodeDict& /*handshake*/) {
400
- // Nothing to add
401
- }
402
-
403
- std::vector<uint8_t> UtPexExtension::create_message(const std::vector<PexPeer>& added,
404
- const std::vector<PexPeer>& dropped) {
405
- BencodeValue msg = BencodeValue::create_dict();
406
-
407
- // Encode added peers in compact format (6 bytes each: 4 IP + 2 port)
408
- std::string added_compact;
409
- for (const auto& peer : added) {
410
- // Parse IP
411
- uint32_t ip_parts[4];
412
- if (sscanf(peer.ip.c_str(), "%u.%u.%u.%u",
413
- &ip_parts[0], &ip_parts[1], &ip_parts[2], &ip_parts[3]) == 4) {
414
- added_compact += static_cast<char>(ip_parts[0]);
415
- added_compact += static_cast<char>(ip_parts[1]);
416
- added_compact += static_cast<char>(ip_parts[2]);
417
- added_compact += static_cast<char>(ip_parts[3]);
418
- added_compact += static_cast<char>((peer.port >> 8) & 0xFF);
419
- added_compact += static_cast<char>(peer.port & 0xFF);
420
- }
421
- }
422
- msg["added"] = BencodeValue(added_compact);
423
-
424
- // Encode dropped peers
425
- std::string dropped_compact;
426
- for (const auto& peer : dropped) {
427
- uint32_t ip_parts[4];
428
- if (sscanf(peer.ip.c_str(), "%u.%u.%u.%u",
429
- &ip_parts[0], &ip_parts[1], &ip_parts[2], &ip_parts[3]) == 4) {
430
- dropped_compact += static_cast<char>(ip_parts[0]);
431
- dropped_compact += static_cast<char>(ip_parts[1]);
432
- dropped_compact += static_cast<char>(ip_parts[2]);
433
- dropped_compact += static_cast<char>(ip_parts[3]);
434
- dropped_compact += static_cast<char>((peer.port >> 8) & 0xFF);
435
- dropped_compact += static_cast<char>(peer.port & 0xFF);
436
- }
437
- }
438
- msg["dropped"] = BencodeValue(dropped_compact);
439
-
440
- return msg.encode();
441
- }
442
-
443
- std::vector<PexPeer> UtPexExtension::parse_peers(const std::string& compact_peers) {
444
- std::vector<PexPeer> peers;
445
-
446
- // Each peer is 6 bytes: 4 for IP, 2 for port
447
- for (size_t i = 0; i + 6 <= compact_peers.size(); i += 6) {
448
- PexPeer peer;
449
-
450
- // Parse IP
451
- char ip_str[16];
452
- snprintf(ip_str, sizeof(ip_str), "%u.%u.%u.%u",
453
- static_cast<unsigned char>(compact_peers[i]),
454
- static_cast<unsigned char>(compact_peers[i + 1]),
455
- static_cast<unsigned char>(compact_peers[i + 2]),
456
- static_cast<unsigned char>(compact_peers[i + 3]));
457
- peer.ip = ip_str;
458
-
459
- // Parse port (big-endian)
460
- peer.port = (static_cast<uint16_t>(static_cast<unsigned char>(compact_peers[i + 4])) << 8) |
461
- static_cast<uint16_t>(static_cast<unsigned char>(compact_peers[i + 5]));
462
-
463
- peers.push_back(peer);
464
- }
465
-
466
- return peers;
467
- }
468
-
469
- } // namespace librats