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,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