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