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,742 +0,0 @@
1
- #include "bt_peer_connection.h"
2
- #include "bencode.h"
3
- #include "logger.h"
4
- #include <algorithm>
5
- #include <cstring>
6
-
7
- namespace librats {
8
-
9
- //=============================================================================
10
- // Helpers
11
- //=============================================================================
12
-
13
- const char* peer_state_to_string(PeerConnectionState state) {
14
- switch (state) {
15
- case PeerConnectionState::Disconnected: return "Disconnected";
16
- case PeerConnectionState::Connecting: return "Connecting";
17
- case PeerConnectionState::Handshaking: return "Handshaking";
18
- case PeerConnectionState::Connected: return "Connected";
19
- case PeerConnectionState::Closing: return "Closing";
20
- default: return "Unknown";
21
- }
22
- }
23
-
24
- double PeerStats::download_rate() const {
25
- // Simple calculation - would need sliding window for accuracy
26
- auto now = std::chrono::steady_clock::now();
27
- auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - connected_at).count();
28
- if (duration <= 0) return 0.0;
29
- return static_cast<double>(bytes_downloaded) / duration;
30
- }
31
-
32
- double PeerStats::upload_rate() const {
33
- auto now = std::chrono::steady_clock::now();
34
- auto duration = std::chrono::duration_cast<std::chrono::seconds>(now - connected_at).count();
35
- if (duration <= 0) return 0.0;
36
- return static_cast<double>(bytes_uploaded) / duration;
37
- }
38
-
39
- //=============================================================================
40
- // Constructor/Destructor
41
- //=============================================================================
42
-
43
- BtPeerConnection::BtPeerConnection(const BtInfoHash& info_hash,
44
- const PeerID& our_peer_id,
45
- uint32_t num_pieces)
46
- : socket_fd_(-1)
47
- , port_(0)
48
- , state_(PeerConnectionState::Disconnected)
49
- , our_info_hash_(info_hash)
50
- , our_peer_id_(our_peer_id)
51
- , num_pieces_(num_pieces)
52
- , info_hash_known_(true) // Outgoing: info_hash is known
53
- , peer_info_hash_{}
54
- , peer_id_{}
55
- , handshake_received_(false)
56
- , handshake_sent_(false)
57
- , extension_handshake_received_(false)
58
- , peer_metadata_size_(0)
59
- , peer_ut_metadata_id_(0)
60
- , am_choking_(true)
61
- , am_interested_(false)
62
- , peer_choking_(true)
63
- , peer_interested_(false)
64
- , peer_pieces_(num_pieces)
65
- , peer_has_all_(false)
66
- , bitfield_received_(false)
67
- , recv_buffer_(8192) // Initial receive buffer capacity
68
- , max_pending_requests_(BT_DEFAULT_REQUEST_QUEUE_SIZE) {
69
- }
70
-
71
- BtPeerConnection::BtPeerConnection(const PeerID& our_peer_id)
72
- : socket_fd_(-1)
73
- , port_(0)
74
- , state_(PeerConnectionState::Disconnected)
75
- , our_info_hash_{}
76
- , our_peer_id_(our_peer_id)
77
- , num_pieces_(0)
78
- , info_hash_known_(false) // Incoming: info_hash unknown until handshake
79
- , peer_info_hash_{}
80
- , peer_id_{}
81
- , handshake_received_(false)
82
- , handshake_sent_(false)
83
- , extension_handshake_received_(false)
84
- , peer_metadata_size_(0)
85
- , peer_ut_metadata_id_(0)
86
- , am_choking_(true)
87
- , am_interested_(false)
88
- , peer_choking_(true)
89
- , peer_interested_(false)
90
- , peer_pieces_(0) // Will be resized after set_torrent_info
91
- , peer_has_all_(false)
92
- , bitfield_received_(false)
93
- , recv_buffer_(8192)
94
- , max_pending_requests_(BT_DEFAULT_REQUEST_QUEUE_SIZE) {
95
- }
96
-
97
- BtPeerConnection::~BtPeerConnection() {
98
- close();
99
- }
100
-
101
- BtPeerConnection::BtPeerConnection(BtPeerConnection&& other) noexcept
102
- : socket_fd_(other.socket_fd_)
103
- , ip_(std::move(other.ip_))
104
- , port_(other.port_)
105
- , state_(other.state_.load())
106
- , our_info_hash_(std::move(other.our_info_hash_))
107
- , our_peer_id_(std::move(other.our_peer_id_))
108
- , num_pieces_(other.num_pieces_)
109
- , info_hash_known_(other.info_hash_known_)
110
- , peer_info_hash_(std::move(other.peer_info_hash_))
111
- , peer_id_(std::move(other.peer_id_))
112
- , peer_extensions_(other.peer_extensions_)
113
- , handshake_received_(other.handshake_received_)
114
- , handshake_sent_(other.handshake_sent_)
115
- , extension_handshake_received_(other.extension_handshake_received_)
116
- , peer_metadata_size_(other.peer_metadata_size_)
117
- , peer_ut_metadata_id_(other.peer_ut_metadata_id_)
118
- , am_choking_(other.am_choking_)
119
- , am_interested_(other.am_interested_)
120
- , peer_choking_(other.peer_choking_)
121
- , peer_interested_(other.peer_interested_)
122
- , peer_pieces_(std::move(other.peer_pieces_))
123
- , peer_has_all_(other.peer_has_all_)
124
- , bitfield_received_(other.bitfield_received_)
125
- , recv_buffer_(std::move(other.recv_buffer_))
126
- , send_buffer_(std::move(other.send_buffer_))
127
- , pending_requests_(std::move(other.pending_requests_))
128
- , max_pending_requests_(other.max_pending_requests_)
129
- , stats_(other.stats_)
130
- , on_message_(std::move(other.on_message_))
131
- , on_state_change_(std::move(other.on_state_change_))
132
- , on_handshake_(std::move(other.on_handshake_))
133
- , on_error_(std::move(other.on_error_))
134
- , on_info_hash_(std::move(other.on_info_hash_)) {
135
- other.socket_fd_ = -1;
136
- other.state_ = PeerConnectionState::Disconnected;
137
- }
138
-
139
- BtPeerConnection& BtPeerConnection::operator=(BtPeerConnection&& other) noexcept {
140
- if (this != &other) {
141
- close();
142
-
143
- socket_fd_ = other.socket_fd_;
144
- ip_ = std::move(other.ip_);
145
- port_ = other.port_;
146
- state_ = other.state_.load();
147
- our_info_hash_ = std::move(other.our_info_hash_);
148
- our_peer_id_ = std::move(other.our_peer_id_);
149
- num_pieces_ = other.num_pieces_;
150
- info_hash_known_ = other.info_hash_known_;
151
- peer_info_hash_ = std::move(other.peer_info_hash_);
152
- peer_id_ = std::move(other.peer_id_);
153
- peer_extensions_ = other.peer_extensions_;
154
- handshake_received_ = other.handshake_received_;
155
- handshake_sent_ = other.handshake_sent_;
156
- extension_handshake_received_ = other.extension_handshake_received_;
157
- peer_metadata_size_ = other.peer_metadata_size_;
158
- peer_ut_metadata_id_ = other.peer_ut_metadata_id_;
159
- am_choking_ = other.am_choking_;
160
- am_interested_ = other.am_interested_;
161
- peer_choking_ = other.peer_choking_;
162
- peer_interested_ = other.peer_interested_;
163
- peer_pieces_ = std::move(other.peer_pieces_);
164
- peer_has_all_ = other.peer_has_all_;
165
- recv_buffer_ = std::move(other.recv_buffer_);
166
- send_buffer_ = std::move(other.send_buffer_);
167
- pending_requests_ = std::move(other.pending_requests_);
168
- max_pending_requests_ = other.max_pending_requests_;
169
- stats_ = other.stats_;
170
- on_message_ = std::move(other.on_message_);
171
- on_state_change_ = std::move(other.on_state_change_);
172
- on_handshake_ = std::move(other.on_handshake_);
173
- on_error_ = std::move(other.on_error_);
174
- on_info_hash_ = std::move(other.on_info_hash_);
175
-
176
- other.socket_fd_ = -1;
177
- other.state_ = PeerConnectionState::Disconnected;
178
- }
179
- return *this;
180
- }
181
-
182
- //=============================================================================
183
- // Connection Management
184
- //=============================================================================
185
-
186
- void BtPeerConnection::set_socket(int socket_fd) {
187
- socket_fd_ = socket_fd;
188
- // Only transition to Handshaking if currently Disconnected.
189
- // This prevents accidentally resetting state if set_socket is called
190
- // after handshake is already complete (e.g., from a callback).
191
- if (socket_fd >= 0 && state_ == PeerConnectionState::Disconnected) {
192
- set_state(PeerConnectionState::Handshaking);
193
- stats_.connected_at = std::chrono::steady_clock::now();
194
- }
195
- }
196
-
197
- void BtPeerConnection::set_address(const std::string& ip, uint16_t port) {
198
- ip_ = ip;
199
- port_ = port;
200
- }
201
-
202
- void BtPeerConnection::start_handshake() {
203
- if (handshake_sent_) return;
204
-
205
- LOG_DEBUG("BtPeerConn", "Sending handshake to " + ip_);
206
- auto hs = BtHandshake::encode_with_extensions(our_info_hash_, our_peer_id_);
207
- queue_send(hs);
208
- handshake_sent_ = true;
209
- }
210
-
211
- void BtPeerConnection::close() {
212
- if (state_ == PeerConnectionState::Disconnected) return;
213
-
214
- set_state(PeerConnectionState::Closing);
215
-
216
- // Clear buffers
217
- recv_buffer_.clear();
218
- send_buffer_.clear();
219
- pending_requests_.clear();
220
-
221
- // Socket closing should be handled by the owner
222
- socket_fd_ = -1;
223
-
224
- set_state(PeerConnectionState::Disconnected);
225
-
226
- // Clear callbacks to prevent dangling pointer issues
227
- // Important: Must be done AFTER state callbacks are invoked
228
- on_message_ = nullptr;
229
- on_state_change_ = nullptr;
230
- on_handshake_ = nullptr;
231
- on_error_ = nullptr;
232
- on_info_hash_ = nullptr;
233
- }
234
-
235
- void BtPeerConnection::set_torrent_info(const BtInfoHash& info_hash, uint32_t num_pieces) {
236
- our_info_hash_ = info_hash;
237
- num_pieces_ = num_pieces;
238
- info_hash_known_ = true;
239
-
240
- // Resize peer_pieces bitfield if needed
241
- if (peer_pieces_.size() != num_pieces) {
242
- // If peer sent HaveAll before we had metadata, set all bits now
243
- if (peer_has_all_) {
244
- peer_pieces_ = Bitfield(num_pieces);
245
- peer_pieces_.set_all();
246
- LOG_DEBUG("BtPeerConn", "Peer " + ip_ + " had sent HaveAll, setting all " +
247
- std::to_string(num_pieces) + " pieces");
248
- } else {
249
- // Peer may have sent a bitfield before we knew num_pieces.
250
- // The bitfield was decoded with size bf_len*8 which may differ from actual num_pieces.
251
- // Use resize() to adjust to correct size while preserving existing bit data.
252
- // This is important: the extra padding bits at the end are meaningless anyway.
253
- size_t old_size = peer_pieces_.size();
254
- size_t old_count = peer_pieces_.count();
255
- peer_pieces_.resize(num_pieces);
256
- LOG_DEBUG("BtPeerConn", "Peer " + ip_ + " bitfield resized from " +
257
- std::to_string(old_size) + " to " + std::to_string(num_pieces) +
258
- " bits (had " + std::to_string(old_count) + " pieces, now " +
259
- std::to_string(peer_pieces_.count()) + ")");
260
- }
261
- }
262
-
263
- LOG_DEBUG("BtPeerConn", "Set torrent info for " + ip_ +
264
- ": info_hash=" + info_hash_to_hex(info_hash).substr(0, 8) +
265
- "..., num_pieces=" + std::to_string(num_pieces) +
266
- ", peer_has_all=" + (peer_has_all_ ? "yes" : "no"));
267
- }
268
-
269
- void BtPeerConnection::set_state(PeerConnectionState new_state) {
270
- PeerConnectionState old_state = state_.exchange(new_state);
271
- if (old_state != new_state && on_state_change_) {
272
- on_state_change_(this, new_state);
273
- }
274
- }
275
-
276
- //=============================================================================
277
- // Data Processing
278
- //=============================================================================
279
-
280
- void BtPeerConnection::process_incoming() {
281
- if (recv_buffer_.empty()) return;
282
-
283
- stats_.last_message_at = std::chrono::steady_clock::now();
284
-
285
- LOG_DEBUG("BtPeerConn", "process_incoming: " + std::to_string(recv_buffer_.size()) +
286
- " bytes from " + ip_);
287
-
288
- // Process handshake first
289
- if (!handshake_received_) {
290
- process_handshake();
291
- }
292
-
293
- // Then process messages
294
- if (handshake_received_) {
295
- process_messages();
296
- }
297
-
298
- // Periodically normalize buffer to reclaim space
299
- if (recv_buffer_.front_waste() > 4096) {
300
- recv_buffer_.normalize();
301
- }
302
- }
303
-
304
- void BtPeerConnection::process_handshake() {
305
- if (recv_buffer_.size() < BT_HANDSHAKE_SIZE) {
306
- LOG_DEBUG("BtPeerConn", "process_handshake: waiting for more data, have " +
307
- std::to_string(recv_buffer_.size()) + "/" + std::to_string(BT_HANDSHAKE_SIZE) + " bytes");
308
- return; // Wait for more data
309
- }
310
-
311
- auto hs = BtHandshake::decode(recv_buffer_.data(), recv_buffer_.size());
312
- if (!hs) {
313
- LOG_ERROR("BtPeerConn", "Invalid handshake from " + ip_);
314
- if (on_error_) {
315
- on_error_(this, "Invalid handshake");
316
- }
317
- close();
318
- return;
319
- }
320
-
321
- // Store peer info
322
- peer_info_hash_ = hs->info_hash;
323
- peer_id_ = hs->peer_id;
324
- peer_extensions_ = hs->extensions;
325
-
326
- // For incoming connections, we need to notify about the info_hash first
327
- // so NetworkManager can look up the torrent and call set_torrent_info()
328
- if (!info_hash_known_) {
329
- LOG_DEBUG("BtPeerConn", "Incoming connection: notifying info_hash " +
330
- info_hash_to_hex(hs->info_hash).substr(0, 8) + "...");
331
-
332
- if (on_info_hash_) {
333
- on_info_hash_(this, hs->info_hash);
334
- }
335
-
336
- // After callback, info_hash should be set via set_torrent_info()
337
- // If not, the connection should be closed by the callback handler
338
- if (!info_hash_known_) {
339
- LOG_ERROR("BtPeerConn", "Unknown torrent from " + ip_ +
340
- ", info_hash=" + info_hash_to_hex(hs->info_hash).substr(0, 8) + "...");
341
- if (on_error_) {
342
- on_error_(this, "Unknown torrent");
343
- }
344
- close();
345
- return;
346
- }
347
- }
348
-
349
- // Verify info hash matches (for outgoing connections, or after set_torrent_info)
350
- if (hs->info_hash != our_info_hash_) {
351
- LOG_ERROR("BtPeerConn", "Info hash mismatch from " + ip_);
352
- if (on_error_) {
353
- on_error_(this, "Info hash mismatch");
354
- }
355
- close();
356
- return;
357
- }
358
-
359
- handshake_received_ = true;
360
-
361
- // Identify client from peer_id
362
- peer_client_name_ = identify_client(peer_id_);
363
-
364
- // Format peer_id for logging (first 8 chars, printable only)
365
- std::string peer_id_str;
366
- for (size_t i = 0; i < 8 && i < peer_id_.size(); ++i) {
367
- char c = static_cast<char>(peer_id_[i]);
368
- peer_id_str += (c >= 32 && c < 127) ? c : '.';
369
- }
370
-
371
- LOG_INFO("BtPeerConn", "Handshake received from " + ip_ + ", peer_id=" + peer_id_str +
372
- ", client=" + peer_client_name_ +
373
- ", ext_protocol=" + (hs->extensions.extension_protocol ? "yes" : "no") +
374
- ", fast=" + (hs->extensions.fast ? "yes" : "no"));
375
-
376
- // Consume handshake from buffer - O(1) operation!
377
- recv_buffer_.consume(BT_HANDSHAKE_SIZE);
378
-
379
- // Notify
380
- if (on_handshake_) {
381
- on_handshake_(this, *hs);
382
- }
383
-
384
- // If we haven't sent our handshake yet, do it now
385
- if (!handshake_sent_) {
386
- start_handshake();
387
- }
388
-
389
- // Transition to connected
390
- set_state(PeerConnectionState::Connected);
391
- }
392
-
393
- void BtPeerConnection::process_messages() {
394
- while (!recv_buffer_.empty()) {
395
- // Check for complete message
396
- size_t msg_len = BtMessageDecoder::message_length(
397
- recv_buffer_.data(), recv_buffer_.size());
398
-
399
- if (msg_len == 0) {
400
- break; // Incomplete message
401
- }
402
-
403
- // Check for keep-alive
404
- if (BtMessageDecoder::is_keepalive(recv_buffer_.data(), recv_buffer_.size())) {
405
- LOG_DEBUG("BtPeerConn", "Received keep-alive from " + ip_);
406
- recv_buffer_.consume(4); // O(1) operation!
407
- continue;
408
- }
409
-
410
- // Decode message
411
- auto msg = BtMessageDecoder::decode(
412
- recv_buffer_.data(), recv_buffer_.size(), num_pieces_);
413
-
414
- if (msg) {
415
- handle_message(*msg);
416
- ++stats_.messages_received;
417
- } else {
418
- LOG_WARN("BtPeerConn", "Failed to decode message from " + ip_ +
419
- ", msg_len=" + std::to_string(msg_len));
420
- }
421
-
422
- // Consume processed message - O(1) operation!
423
- recv_buffer_.consume(msg_len);
424
- }
425
- }
426
-
427
- void BtPeerConnection::handle_message(const BtMessage& msg) {
428
- // Log message details based on type
429
- std::string log_detail;
430
- switch (msg.type) {
431
- case BtMessageType::Have:
432
- log_detail = " piece=" + std::to_string(msg.have_piece);
433
- break;
434
- case BtMessageType::Bitfield:
435
- if (msg.bitfield) {
436
- log_detail = " bits=" + std::to_string(msg.bitfield->count());
437
- }
438
- break;
439
- case BtMessageType::Request:
440
- if (msg.request) {
441
- log_detail = " piece=" + std::to_string(msg.request->piece_index) +
442
- " begin=" + std::to_string(msg.request->begin) +
443
- " len=" + std::to_string(msg.request->length);
444
- }
445
- break;
446
- case BtMessageType::Piece:
447
- if (msg.piece) {
448
- log_detail = " piece=" + std::to_string(msg.piece->piece_index) +
449
- " begin=" + std::to_string(msg.piece->begin) +
450
- " len=" + std::to_string(msg.piece->data.size());
451
- }
452
- break;
453
- case BtMessageType::Extended:
454
- log_detail = " ext_id=" + std::to_string(msg.extension_id) +
455
- " payload=" + std::to_string(msg.extension_payload.size()) + " bytes";
456
- break;
457
- default:
458
- break;
459
- }
460
-
461
- LOG_DEBUG("BtPeerConn", "handle_message: " + std::string(message_type_to_string(msg.type)) +
462
- " from " + ip_ + log_detail);
463
-
464
- switch (msg.type) {
465
- case BtMessageType::Choke:
466
- peer_choking_ = true;
467
- break;
468
-
469
- case BtMessageType::Unchoke:
470
- peer_choking_ = false;
471
- break;
472
-
473
- case BtMessageType::Interested:
474
- peer_interested_ = true;
475
- break;
476
-
477
- case BtMessageType::NotInterested:
478
- peer_interested_ = false;
479
- break;
480
-
481
- case BtMessageType::Have:
482
- // Skip if we don't have metadata yet (magnet link scenario)
483
- if (num_pieces_ == 0) {
484
- LOG_DEBUG("BtPeerConn", "Ignoring HAVE (no metadata yet) from " + ip_);
485
- break;
486
- }
487
- // Validate piece index
488
- if (msg.have_piece >= num_pieces_) {
489
- LOG_WARN("BtPeerConn", "Invalid HAVE index " + std::to_string(msg.have_piece) +
490
- " >= " + std::to_string(num_pieces_) + " from " + ip_);
491
- break;
492
- }
493
- // Ignore redundant HAVE
494
- if (peer_pieces_.get_bit(msg.have_piece)) {
495
- LOG_DEBUG("BtPeerConn", "Redundant HAVE for piece " + std::to_string(msg.have_piece));
496
- break;
497
- }
498
- peer_pieces_.set_bit(msg.have_piece);
499
- break;
500
-
501
- case BtMessageType::Bitfield:
502
- if (msg.bitfield) {
503
- // Validate bitfield size
504
- if (num_pieces_ > 0 && msg.bitfield->size() != num_pieces_) {
505
- LOG_WARN("BtPeerConn", "Invalid bitfield size " + std::to_string(msg.bitfield->size()) +
506
- " expected " + std::to_string(num_pieces_) + " from " + ip_);
507
- // Resize to match expected size
508
- peer_pieces_ = *msg.bitfield;
509
- peer_pieces_.resize(num_pieces_);
510
- } else {
511
- peer_pieces_ = *msg.bitfield;
512
- }
513
- peer_has_all_ = false; // Explicit bitfield takes precedence over HaveAll
514
- bitfield_received_ = true;
515
- }
516
- break;
517
-
518
- case BtMessageType::Piece:
519
- if (msg.piece) {
520
- RequestMessage req(msg.piece->piece_index, msg.piece->begin,
521
- static_cast<uint32_t>(msg.piece->data.size()));
522
-
523
- // Check if this block was requested
524
- bool was_requested = has_pending_request(req);
525
- if (!was_requested) {
526
- LOG_DEBUG("BtPeerConn", "Received unrequested piece " +
527
- std::to_string(msg.piece->piece_index) + " from " + ip_);
528
- // Still process it, but mark as potentially wasteful
529
- }
530
-
531
- stats_.bytes_downloaded += msg.piece->data.size();
532
- stats_.last_piece_at = std::chrono::steady_clock::now();
533
- ++stats_.pieces_received;
534
-
535
- // Remove from pending requests
536
- remove_pending_request(req);
537
- }
538
- break;
539
-
540
- case BtMessageType::HaveAll:
541
- peer_has_all_ = true;
542
- bitfield_received_ = true;
543
- // If we have metadata (num_pieces_ > 0), set all bits now
544
- // Otherwise, we'll resize and set in set_torrent_info()
545
- if (peer_pieces_.size() > 0) {
546
- peer_pieces_.set_all();
547
- }
548
- break;
549
-
550
- case BtMessageType::HaveNone:
551
- peer_has_all_ = false;
552
- bitfield_received_ = true;
553
- peer_pieces_.clear_all();
554
- break;
555
-
556
- case BtMessageType::Extended:
557
- // Parse extension handshake (ext_id=0) and store data for late callback registration
558
- if (msg.extension_id == 0 && !msg.extension_payload.empty()) {
559
- parse_extension_handshake(msg.extension_payload);
560
- }
561
- break;
562
-
563
- default:
564
- break;
565
- }
566
-
567
- // Notify callback
568
- if (on_message_) {
569
- on_message_(this, msg);
570
- }
571
- }
572
-
573
- void BtPeerConnection::parse_extension_handshake(const std::vector<uint8_t>& payload) {
574
- // Parse the bencoded extension handshake to extract metadata info
575
- // This data is stored so Torrent can access it even if callback wasn't set yet
576
-
577
- BencodeValue decoded;
578
- try {
579
- decoded = BencodeDecoder::decode(payload);
580
- } catch (...) {
581
- LOG_DEBUG("BtPeerConn", "Failed to decode extension handshake from " + ip_);
582
- return;
583
- }
584
-
585
- if (!decoded.is_dict()) {
586
- return;
587
- }
588
-
589
- const auto& dict = decoded.as_dict();
590
- extension_handshake_received_ = true;
591
-
592
- // Extract metadata_size if present
593
- auto metadata_size_it = dict.find("metadata_size");
594
- if (metadata_size_it != dict.end() && metadata_size_it->second.is_integer()) {
595
- peer_metadata_size_ = static_cast<size_t>(metadata_size_it->second.as_integer());
596
- LOG_DEBUG("BtPeerConn", "Peer " + ip_ + " has metadata_size=" +
597
- std::to_string(peer_metadata_size_));
598
- }
599
-
600
- // Extract ut_metadata message ID from 'm' dictionary
601
- auto m_it = dict.find("m");
602
- if (m_it != dict.end() && m_it->second.is_dict()) {
603
- const auto& m = m_it->second.as_dict();
604
- auto ut_metadata_it = m.find("ut_metadata");
605
- if (ut_metadata_it != m.end() && ut_metadata_it->second.is_integer()) {
606
- peer_ut_metadata_id_ = static_cast<uint8_t>(ut_metadata_it->second.as_integer());
607
- LOG_DEBUG("BtPeerConn", "Peer " + ip_ + " ut_metadata_id=" +
608
- std::to_string(peer_ut_metadata_id_));
609
- }
610
- }
611
-
612
- // Extract client version string from 'v' field
613
- auto v_it = dict.find("v");
614
- if (v_it != dict.end() && v_it->second.is_string()) {
615
- peer_client_name_ = v_it->second.as_string();
616
- LOG_INFO("BtPeerConn", "Peer " + ip_ + " client: " + peer_client_name_);
617
- }
618
- }
619
-
620
- void BtPeerConnection::queue_send(const std::vector<uint8_t>& data) {
621
- send_buffer_.append(data.data(), data.size());
622
- LOG_DEBUG("BtPeerConn", "queue_send: " + std::to_string(data.size()) + " bytes to " + ip_ +
623
- ", buffer now " + std::to_string(send_buffer_.size()) + " bytes");
624
- }
625
-
626
- //=============================================================================
627
- // Protocol State
628
- //=============================================================================
629
-
630
- bool BtPeerConnection::peer_has_piece(uint32_t piece) const {
631
- return peer_pieces_.get_bit(piece);
632
- }
633
-
634
- //=============================================================================
635
- // Sending Messages
636
- //=============================================================================
637
-
638
- void BtPeerConnection::send_choke() {
639
- LOG_DEBUG("BtPeerConn", "send_choke to " + ip_);
640
- am_choking_ = true;
641
- queue_send(BtMessageEncoder::encode_choke());
642
- ++stats_.messages_sent;
643
- }
644
-
645
- void BtPeerConnection::send_unchoke() {
646
- LOG_DEBUG("BtPeerConn", "send_unchoke to " + ip_);
647
- am_choking_ = false;
648
- queue_send(BtMessageEncoder::encode_unchoke());
649
- ++stats_.messages_sent;
650
- }
651
-
652
- void BtPeerConnection::send_interested() {
653
- LOG_DEBUG("BtPeerConn", "send_interested to " + ip_);
654
- am_interested_ = true;
655
- queue_send(BtMessageEncoder::encode_interested());
656
- ++stats_.messages_sent;
657
- }
658
-
659
- void BtPeerConnection::send_not_interested() {
660
- LOG_DEBUG("BtPeerConn", "send_not_interested to " + ip_);
661
- am_interested_ = false;
662
- queue_send(BtMessageEncoder::encode_not_interested());
663
- ++stats_.messages_sent;
664
- }
665
-
666
- void BtPeerConnection::send_have(uint32_t piece_index) {
667
- LOG_DEBUG("BtPeerConn", "send_have piece=" + std::to_string(piece_index) + " to " + ip_);
668
- queue_send(BtMessageEncoder::encode_have(piece_index));
669
- ++stats_.messages_sent;
670
- }
671
-
672
- void BtPeerConnection::send_bitfield(const Bitfield& bitfield) {
673
- LOG_DEBUG("BtPeerConn", "send_bitfield bits=" + std::to_string(bitfield.count()) + " to " + ip_);
674
- queue_send(BtMessageEncoder::encode_bitfield(bitfield));
675
- ++stats_.messages_sent;
676
- }
677
-
678
- void BtPeerConnection::send_request(uint32_t piece, uint32_t begin, uint32_t length) {
679
- LOG_DEBUG("BtPeerConn", "send_request piece=" + std::to_string(piece) +
680
- " begin=" + std::to_string(begin) + " len=" + std::to_string(length) + " to " + ip_);
681
- queue_send(BtMessageEncoder::encode_request(piece, begin, length));
682
- ++stats_.messages_sent;
683
-
684
- add_pending_request(RequestMessage(piece, begin, length));
685
- }
686
-
687
- void BtPeerConnection::send_piece(uint32_t piece, uint32_t begin,
688
- const uint8_t* data, size_t length) {
689
- LOG_DEBUG("BtPeerConn", "send_piece piece=" + std::to_string(piece) +
690
- " begin=" + std::to_string(begin) + " len=" + std::to_string(length) + " to " + ip_);
691
- queue_send(BtMessageEncoder::encode_piece(piece, begin, data, length));
692
- stats_.bytes_uploaded += length;
693
- ++stats_.pieces_sent;
694
- ++stats_.messages_sent;
695
- }
696
-
697
- void BtPeerConnection::send_cancel(uint32_t piece, uint32_t begin, uint32_t length) {
698
- LOG_DEBUG("BtPeerConn", "send_cancel piece=" + std::to_string(piece) +
699
- " begin=" + std::to_string(begin) + " len=" + std::to_string(length) + " to " + ip_);
700
- queue_send(BtMessageEncoder::encode_cancel(piece, begin, length));
701
- ++stats_.messages_sent;
702
-
703
- remove_pending_request(RequestMessage(piece, begin, length));
704
- }
705
-
706
- void BtPeerConnection::send_keepalive() {
707
- LOG_DEBUG("BtPeerConn", "send_keepalive to " + ip_);
708
- queue_send(BtMessageEncoder::encode_keepalive());
709
- }
710
-
711
- void BtPeerConnection::send_extended(uint8_t extension_id,
712
- const std::vector<uint8_t>& payload) {
713
- LOG_DEBUG("BtPeerConn", "send_extended ext_id=" + std::to_string(extension_id) +
714
- " payload=" + std::to_string(payload.size()) + " bytes to " + ip_);
715
- queue_send(BtMessageEncoder::encode_extended(extension_id, payload));
716
- ++stats_.messages_sent;
717
- }
718
-
719
- //=============================================================================
720
- // Request Tracking
721
- //=============================================================================
722
-
723
- void BtPeerConnection::add_pending_request(const RequestMessage& req) {
724
- // Avoid duplicates
725
- auto it = std::find(pending_requests_.begin(), pending_requests_.end(), req);
726
- if (it == pending_requests_.end()) {
727
- pending_requests_.push_back(req);
728
- }
729
- }
730
-
731
- void BtPeerConnection::remove_pending_request(const RequestMessage& req) {
732
- auto it = std::find(pending_requests_.begin(), pending_requests_.end(), req);
733
- if (it != pending_requests_.end()) {
734
- pending_requests_.erase(it);
735
- }
736
- }
737
-
738
- void BtPeerConnection::clear_pending_requests() {
739
- pending_requests_.clear();
740
- }
741
-
742
- } // namespace librats