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
@@ -0,0 +1,283 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file connection.h
5
+ * @brief A single peer connection: byte-stream link, secure handshake, framing.
6
+ *
7
+ * A Connection is owned by exactly one Reactor and is only ever touched by that
8
+ * reactor's thread. Because of that single-threaded ownership it holds NO locks
9
+ * and uses NO atomics — all synchronisation lives at the reactor boundary (the
10
+ * task queue). This is the heart of the shared-nothing model.
11
+ *
12
+ * It is also transport-agnostic: everything here needs is an ordered, reliable,
13
+ * non-blocking byte stream, which is exactly what a Link is (see link.h). A
14
+ * connection over a kernel TCP socket and one over the library's reliable-UDP
15
+ * stream run the *same* code — same framing, same handshake, same backpressure —
16
+ * and differ only in which Link they hold.
17
+ *
18
+ * Lifecycle: Connecting → Handshaking → Established → Closing/Closed.
19
+ * - Connecting: outbound transport connect in flight (inbound skips this).
20
+ * - Handshaking: a Handshaker (from the reactor's SecurityProvider) runs to
21
+ * completion, yielding a Session and the remote PeerId.
22
+ * - Established: inbound blocks are decrypted into inner frames and delivered;
23
+ * outbound frames are encrypted and queued.
24
+ *
25
+ * The Connection reports events through a ConnectionDelegate and asks its Link
26
+ * to (dis)arm write-interest; it never touches the poller directly.
27
+ */
28
+
29
+ #include "librats/util/rats_export.h"
30
+ #include "librats/core/types.h"
31
+ #include "librats/core/bytes.h"
32
+ #include "librats/wire/frame.h"
33
+ #include "librats/peer/peer_id.h"
34
+ #include "librats/security/handshaker.h"
35
+ #include "librats/core/receive_buffer.h"
36
+ #include "librats/core/chained_send_buffer.h"
37
+ #include "librats/core/socket.h"
38
+ #include "librats/transport/link.h"
39
+
40
+ #include <atomic>
41
+ #include <memory>
42
+
43
+ namespace librats {
44
+
45
+ class Connection;
46
+ class Reactor;
47
+
48
+ /**
49
+ * @brief Sink for connection lifecycle and inbound frames.
50
+ *
51
+ * All callbacks run on the owning reactor's thread. `on_established` fires once
52
+ * the secure handshake completes (so conn.remote_id() is valid). `on_closed` is
53
+ * the last call and is invoked by the Reactor during teardown, so a delegate may
54
+ * safely close other connections from within it.
55
+ */
56
+ class RATS_API ConnectionDelegate {
57
+ public:
58
+ virtual ~ConnectionDelegate() = default;
59
+
60
+ /// Admission gate for a freshly accepted inbound socket, asked by the Reactor
61
+ /// before it adopts the connection (i.e. before any handshake cost is paid).
62
+ /// Returning false makes the Reactor close the socket immediately. Runs on the
63
+ /// acceptor reactor thread. Default: always admit.
64
+ virtual bool admit_inbound() { return true; }
65
+
66
+ virtual void on_established(Connection& conn) = 0;
67
+ virtual void on_frame(Connection& conn, const Frame& frame) = 0;
68
+ virtual void on_closed(Connection& conn, CloseReason reason) = 0;
69
+
70
+ /// The send queue crossed its low-water mark: `writable` is false when it
71
+ /// filled past the mark (send() will now answer "no room") and true when it
72
+ /// has drained back under, so a sender that was told to stop may start again.
73
+ /// Runs on the reactor thread — from inside send() for the first, from inside
74
+ /// the flush that emptied the queue for the second — so a handler must not
75
+ /// block. Default: ignore.
76
+ virtual void on_writable_changed(Connection& /*conn*/, bool /*writable*/) {}
77
+
78
+ /// An outbound dial died before there was ever a Connection to report it on —
79
+ /// an unresolvable host, no route, no socket. Without this a dial policy that
80
+ /// reserved the ConnId (see Reactor::connect) would wait out a timeout for an
81
+ /// attempt that never began. Runs on the reactor thread. Default: ignore.
82
+ virtual void on_dial_aborted(uint8_t /*reactor_index*/, ConnId /*id*/,
83
+ const std::string& /*host*/, uint16_t /*port*/) {}
84
+ };
85
+
86
+ class Connection {
87
+ public:
88
+ /// High-water mark for the memory held by the send queue; exceeding it closes the
89
+ /// connection with CloseReason::SlowConsumer.
90
+ static constexpr size_t kDefaultSendHighWater = 8 * 1024 * 1024;
91
+
92
+ /// Where send() starts answering "no room". A quarter of the hard limit, so a
93
+ /// caller that heeds the answer never comes near the point where the
94
+ /// connection is dropped, and one that ignores it is no worse off than before
95
+ /// this mark existed. This is the whole difference between a transport that
96
+ /// can be used correctly and one that merely disconnects you.
97
+ static constexpr size_t kDefaultSendLowWater = kDefaultSendHighWater / 4;
98
+
99
+ /// Queued bytes past which send() stops holding the batch back and writes
100
+ /// immediately. Aggregating below this is what turns a burst of small frames
101
+ /// into one system call; above it there is already enough to fill a write, so
102
+ /// waiting would only cost memory and delay.
103
+ static constexpr size_t kCoalesceLimit = 64 * 1024;
104
+
105
+ Connection(ConnId id, std::unique_ptr<Link> link, ConnRole role,
106
+ Reactor& reactor, ConnectionDelegate& delegate);
107
+ ~Connection();
108
+
109
+ Connection(const Connection&) = delete;
110
+ Connection& operator=(const Connection&) = delete;
111
+
112
+ // — identity / state (reactor thread) —
113
+ ConnId id() const noexcept { return id_; }
114
+ uint8_t reactor_index() const noexcept; ///< index of the owning reactor
115
+ Link& link() const noexcept { return *link_; }
116
+ /// The kernel socket behind this connection, or RATS_INVALID_SOCKET when the
117
+ /// transport has none of its own (UDP streams share the mux's socket).
118
+ socket_t socket() const noexcept { return link_->fd(); }
119
+ TransportKind transport() const noexcept { return link_->kind(); }
120
+ ConnRole role() const noexcept { return role_; }
121
+ ConnState state() const noexcept { return state_; }
122
+ CloseReason close_reason() const noexcept { return close_reason_; }
123
+ const PeerId& remote_id() const noexcept { return remote_id_; }
124
+ bool is_secure() const noexcept { return session_ && session_->is_secure(); }
125
+
126
+ /// Queue an application frame for the peer. No-op unless Established.
127
+ ///
128
+ /// @return whether there is still room for more. False means the queue is
129
+ /// past its low-water mark — this frame is queued like any other,
130
+ /// nothing is dropped, but the caller should stop and wait for
131
+ /// ConnectionDelegate::on_writable rather than keep piling on until
132
+ /// the connection is dropped as a slow consumer.
133
+ bool send(FrameHeader header, ByteView payload);
134
+
135
+ /// Whether the send queue currently has room (see send()).
136
+ bool writable() const noexcept { return !over_low_water_; }
137
+
138
+ /// Adopt the peer's in-transit counter: bytes a caller has handed to this
139
+ /// reactor that have not reached send() yet (see PeerTable::Entry::owed).
140
+ ///
141
+ /// They are as much of the backlog as the queue itself — held in the reactor's
142
+ /// task queue rather than in tx_, and on their way here — so the marks below
143
+ /// weigh them together with what is queued. Without that the two halves would
144
+ /// answer separately: a caller told "no room" because its charge crossed the
145
+ /// mark would be waiting for an opening from a queue that never crossed
146
+ /// anything, and so would never be told the room came back.
147
+ void set_in_transit(std::shared_ptr<const std::atomic<size_t>> owed) noexcept {
148
+ in_transit_ = std::move(owed);
149
+ }
150
+
151
+ /// What this connection is carrying: queued here plus still on its way.
152
+ size_t backlog() const noexcept {
153
+ // Watch the memory the queue actually holds, not just the bytes still owed
154
+ // to the socket: a partially sent chunk keeps its whole allocation, so
155
+ // allocated() is what a peer that stops reading can make us carry.
156
+ return tx_.allocated() +
157
+ (in_transit_ ? in_transit_->load(std::memory_order_relaxed) : 0);
158
+ }
159
+
160
+ /// Resize the send queue's marks. `high` is where the connection is dropped
161
+ /// as a slow consumer; the low-water mark send() reports against is derived
162
+ /// from it, so the two can never be set inconsistently. Called once, right
163
+ /// after the handshake, when the node's config asks for something other than
164
+ /// the default.
165
+ void set_send_high_water(size_t high) noexcept {
166
+ send_high_water_ = high;
167
+ send_low_water_ = high / 4;
168
+ }
169
+
170
+ /// Write out what send() queued during this reactor turn. Called by the
171
+ /// Reactor at the end of the turn; false ⇒ the connection must be torn down.
172
+ bool flush_pending();
173
+
174
+ /// Convenience: send raw bytes on an application channel.
175
+ bool send(uint16_t channel, ByteView payload) {
176
+ return send(FrameHeader{MessageType::App, 0, channel}, payload);
177
+ }
178
+
179
+ // — reactor-driven I/O callbacks. Return false to request teardown. —
180
+ bool on_readable();
181
+ bool on_writable();
182
+ bool on_error();
183
+
184
+ /// Bring an accepted (inbound) socket up: it is already connected, so begin
185
+ /// the handshake immediately. Called by the Reactor right after adopt().
186
+ void start_handshake();
187
+
188
+ /// Associate the establishment-timeout timer so it can be cancelled once the
189
+ /// connection reaches Established. Set by the Reactor after adopt().
190
+ void set_establish_timer(TimerId id) noexcept { establish_timer_ = id; }
191
+
192
+ /// Cancel the establishment-timeout timer if still armed; idempotent. Called
193
+ /// both on success (complete_established) and on teardown (Reactor::remove) so
194
+ /// the reaper can never outlive the connection and fire against a reused fd.
195
+ void cancel_establish_timer();
196
+
197
+ /// Periodic housekeeping, driven by the Reactor's maintenance timer. Hands back
198
+ /// the receive buffer of a peer that has gone quiet — a peer that sent one big
199
+ /// frame and then fell silent would otherwise sit on that allocation for the life
200
+ /// of the connection. Reactor thread; never closes the connection.
201
+ void on_maintenance_tick() { rx_.decay(); }
202
+
203
+ /// Record the address this outbound connection was dialed at (so the peer's
204
+ /// reconnect address is known). Set by the Reactor after adopt(); reactor thread.
205
+ void set_dial_address(std::string host, uint16_t port) {
206
+ dial_host_ = std::move(host);
207
+ dial_port_ = port;
208
+ }
209
+ bool has_dial_address() const noexcept { return dial_port_ != 0; }
210
+ const std::string& dial_host() const noexcept { return dial_host_; }
211
+ uint16_t dial_port() const noexcept { return dial_port_; }
212
+
213
+ /// The peer's IP as the link sees it, without the source port (ephemeral on
214
+ /// TCP, NAT-rewritten on UDP). Combined with the peer's advertised listen port
215
+ /// by the node's identify exchange to form a dialable address — the only way
216
+ /// to learn the dialable address of an *inbound* peer. Unspecified on error.
217
+ IpAddress remote_ip() const;
218
+
219
+ /// The peer's source endpoint as the link sees it, port included.
220
+ ///
221
+ /// The port is meaningless on TCP (an ephemeral one the peer's OS picked for an
222
+ /// outbound socket) but is NOT on a datagram link: there every peer shares one
223
+ /// socket, so what a NAT rewrote the source port to is exactly the port a third
224
+ /// party would have to aim at to reach this peer. That is what identify carries
225
+ /// on to it, and what a hole punch is aimed at. nullopt if the link cannot say.
226
+ std::optional<Address> remote_endpoint() const { return link_->remote_endpoint(); }
227
+
228
+ /// Tell the link the connection is going away, so a transport that owes the
229
+ /// peer a goodbye (or a last flush) can arrange it. Called by the Reactor
230
+ /// during teardown, before the Connection is destroyed.
231
+ void shutdown_link(CloseReason reason) { link_->close(reason); }
232
+
233
+ private:
234
+ void begin_handshake(); ///< transport up → Handshaking
235
+ size_t read_size() const; ///< bytes to offer the next recv() (see rx_need_)
236
+ bool process_blocks(); ///< decode every complete block in rx_; false ⇒ teardown
237
+ bool drive_handshake(ByteView body);///< feed one handshake block; false ⇒ teardown
238
+ bool deliver_frame(ByteView body); ///< decrypt+parse+dispatch; false ⇒ teardown
239
+ void complete_established(); ///< handshake done → Established
240
+ void queue_block(Bytes body); ///< length-prefix `body` into the send buffer
241
+ bool flush(); ///< drain tx_ to the socket; false ⇒ teardown
242
+ void arm_write();
243
+ void disarm_write();
244
+ bool fail(CloseReason); ///< record reason, return false (teardown)
245
+
246
+ ConnId id_;
247
+ std::unique_ptr<Link> link_;
248
+ ConnRole role_;
249
+ ConnState state_ = ConnState::Connecting;
250
+ CloseReason close_reason_ = CloseReason::PeerClosed;
251
+ Reactor& reactor_;
252
+ ConnectionDelegate& delegate_;
253
+
254
+ std::unique_ptr<Handshaker> handshaker_; ///< non-null only while Handshaking
255
+ std::unique_ptr<Session> session_; ///< non-null once Established
256
+ PeerId remote_id_;
257
+
258
+ ReceiveBuffer rx_; ///< allocates on first read, shrinks back when idle
259
+ /// Wire size of the block rx_ is mid-way through, once its length prefix has been
260
+ /// read; 0 when no block is in flight. Lets the next recv() size rx_ for the whole
261
+ /// block in one go instead of growing into it. Peer-declared, hence capped.
262
+ size_t rx_need_ = 0;
263
+ ChainedSendBuffer tx_;
264
+ bool want_write_ = false;
265
+ /// A flush is already booked for the end of this reactor turn, so further
266
+ /// frames only need to join the queue rather than book another one.
267
+ bool flush_queued_ = false;
268
+ /// The queue went past its low-water mark and the caller has been told to
269
+ /// stop; cleared, with a notification, once it drains back under.
270
+ bool over_low_water_ = false;
271
+ /// Inside the on_writable callback — see flush().
272
+ bool in_writable_ = false;
273
+ /// Charged by send() callers on any thread, discharged by the reactor task
274
+ /// just before the frame reaches send() — see set_in_transit().
275
+ std::shared_ptr<const std::atomic<size_t>> in_transit_;
276
+ size_t send_high_water_ = kDefaultSendHighWater;
277
+ size_t send_low_water_ = kDefaultSendLowWater;
278
+ TimerId establish_timer_ = kInvalidTimerId; ///< connect+handshake deadline
279
+ std::string dial_host_; ///< address we dialed (outbound)
280
+ uint16_t dial_port_ = 0;
281
+ };
282
+
283
+ } // namespace librats
@@ -0,0 +1,96 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file link.h
5
+ * @brief The byte-stream a Connection runs on, independent of how it is carried.
6
+ *
7
+ * Everything above this line — block framing, the Noise handshake, the Session,
8
+ * backpressure, the establish deadline — only ever needs an ordered, reliable,
9
+ * non-blocking byte stream. A Link is exactly that and nothing more, so the same
10
+ * Connection code drives a kernel TCP socket (TcpLink) and the library's own
11
+ * reliability layer over datagrams (UdpStreamLink → UdpStream). Neither transport
12
+ * is a special case of the other: both are first-class, and a peer connected over
13
+ * either is indistinguishable to every layer above.
14
+ *
15
+ * Ownership and threading follow the rest of the transport layer: a Link belongs
16
+ * to exactly one Connection, which belongs to exactly one Reactor, and is touched
17
+ * only by that reactor's thread. It therefore holds no locks and no atomics.
18
+ *
19
+ * The read/write calls mirror non-blocking socket semantics deliberately, because
20
+ * that is what the reactor loop is built around:
21
+ * - read() fills the caller's span and reports WouldBlock once the link has no
22
+ * more data ready, or Closed when the peer has finished sending.
23
+ * - write() takes what it can and reports WouldBlock when it can take no more;
24
+ * the Connection keeps the remainder queued and calls want_write(true)
25
+ * so it is told when to retry.
26
+ */
27
+
28
+ #include "librats/core/address.h"
29
+ #include "librats/core/bytes.h"
30
+ #include "librats/core/socket.h"
31
+ #include "librats/core/types.h"
32
+
33
+ #include <cstddef>
34
+ #include <optional>
35
+
36
+ namespace librats {
37
+
38
+ class Link {
39
+ public:
40
+ virtual ~Link() = default;
41
+
42
+ /// Outcome of a read/write attempt. `Closed` is orderly (the peer is done
43
+ /// sending); `Error` means the link is broken and must be torn down.
44
+ enum class Status { Ok, WouldBlock, Closed, Error };
45
+
46
+ struct IoResult {
47
+ size_t bytes = 0;
48
+ Status status = Status::WouldBlock;
49
+ };
50
+
51
+ virtual TransportKind kind() const noexcept = 0;
52
+
53
+ /// Read up to `into.size()` bytes. A Closed or Error result always carries
54
+ /// zero bytes — data and end-of-stream are never reported together, so the
55
+ /// caller drains first and only then sees the close.
56
+ virtual IoResult read(ByteSpan into) = 0;
57
+
58
+ /// Hand `count` contiguous slices to the link in order, writing as many bytes
59
+ /// as it will take (a partial write is normal and expected).
60
+ virtual IoResult write(const ByteView* slices, size_t count) = 0;
61
+
62
+ /// Called once the link reports writable while the connection is still
63
+ /// connecting. Returns false if the connect attempt failed.
64
+ virtual bool connect_completed() = 0;
65
+
66
+ /// Ask to be woken (via Connection::on_writable) when more can be written.
67
+ /// Called only when the state actually changes, so an implementation may
68
+ /// treat it as an unconditional set.
69
+ virtual void want_write(bool on) = 0;
70
+
71
+ /// The peer's endpoint. For TCP the port is the peer's *ephemeral* source
72
+ /// port, so only the IP is meaningful (see identify); for UDP it is the
73
+ /// endpoint datagrams are exchanged with. nullopt if not yet known.
74
+ virtual std::optional<Address> remote_endpoint() const = 0;
75
+
76
+ /// The kernel socket backing this link, or RATS_INVALID_SOCKET when the link
77
+ /// has none of its own (a UDP stream shares the mux's socket with every other
78
+ /// stream). The Reactor uses it to decide whether the link is poller-driven.
79
+ virtual socket_t fd() const noexcept { return RATS_INVALID_SOCKET; }
80
+
81
+ /// Told the ConnId the Reactor assigned, right after adoption. A link that has
82
+ /// to be reachable from somewhere other than its Connection (a UDP stream, from
83
+ /// the datagram path) needs it; a plain socket does not.
84
+ virtual void attach(ConnId) {}
85
+
86
+ /// Why the link broke, consulted when read/write reported Error. Lets a
87
+ /// transport that knows more than "the socket failed" — a dial that was never
88
+ /// answered, a peer that went silent — say so.
89
+ virtual CloseReason error_reason() const { return CloseReason::PeerReset; }
90
+
91
+ /// Begin an orderly shutdown. Called by the Reactor as it tears the connection
92
+ /// down; the Link may still linger internally to flush what it owes the peer.
93
+ virtual void close(CloseReason reason) = 0;
94
+ };
95
+
96
+ } // namespace librats