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,496 @@
1
+ #pragma once
2
+
3
+ #include "librats/core/address.h"
4
+ #include "librats/core/bytes.h"
5
+
6
+ #include <string>
7
+ #include <functional>
8
+ #include <optional>
9
+ #include <vector>
10
+ #include <cstddef>
11
+ #include <cstdint>
12
+
13
+ #ifdef _WIN32
14
+ #include <winsock2.h>
15
+ #include <ws2tcpip.h>
16
+ #ifdef _MSC_VER
17
+ #pragma comment(lib, "ws2_32.lib")
18
+ #endif
19
+ #else
20
+ #include <sys/socket.h>
21
+ #include <arpa/inet.h>
22
+ #include <netinet/in.h>
23
+ #include <unistd.h>
24
+ #endif
25
+
26
+ namespace librats {
27
+
28
+ /*
29
+ * socket_t and the sentinel values live in the namespace, and the macros carry
30
+ * the RATS_ prefix, because this header is installed: a bare `socket_t` typedef
31
+ * or a bare `closesocket` macro at global scope collides with any other library
32
+ * that installs the same portability shim (and a function-like macro named
33
+ * `closesocket` would silently rewrite the consumer's own calls). Use
34
+ * close_socket() below rather than reintroducing that macro.
35
+ */
36
+ #ifdef _WIN32
37
+ typedef SOCKET socket_t;
38
+ #define RATS_INVALID_SOCKET INVALID_SOCKET
39
+ #define RATS_SOCKET_ERROR SOCKET_ERROR
40
+ #else
41
+ typedef int socket_t;
42
+ #define RATS_INVALID_SOCKET -1
43
+ #define RATS_SOCKET_ERROR -1
44
+ #endif
45
+
46
+ /**
47
+ * Address family for socket creation
48
+ */
49
+ enum class AddressFamily {
50
+ IPv4, // IPv4 only
51
+ IPv6, // IPv6 only
52
+ DualStack // IPv6 socket with IPv4 support (default)
53
+ };
54
+
55
+ /**
56
+ * Whether a socket bound with `af` can send to an address of the given family
57
+ * at all.
58
+ *
59
+ * A socket cannot leave its own family: sendto() with a sockaddr of the wrong
60
+ * one is refused outright. On a datagram socket that refusal arrives per packet
61
+ * and says nothing about the destination, so a caller that does not ask this
62
+ * first cannot tell "unreachable" from "not answering yet" — it only finds out
63
+ * once the retransmissions run out.
64
+ *
65
+ * This is the exact inverse of the sockaddr build_udp_dest_addr() produces, and
66
+ * lives next to the family it switches on so the two cannot drift apart.
67
+ */
68
+ constexpr bool family_can_reach(AddressFamily af, bool dest_is_v6) noexcept {
69
+ switch (af) {
70
+ case AddressFamily::IPv4: return !dest_is_v6;
71
+ case AddressFamily::IPv6: return dest_is_v6; // V6ONLY: no mapped IPv4
72
+ case AddressFamily::DualStack: return true; // IPv4 goes out as ::ffff:a.b.c.d
73
+ }
74
+ return false;
75
+ }
76
+
77
+ // Socket Library Initialization
78
+ /**
79
+ * Initialize the socket library
80
+ * @return true if successful, false otherwise
81
+ */
82
+ bool init_socket_library();
83
+
84
+ /**
85
+ * Cleanup the socket library
86
+ */
87
+ void cleanup_socket_library();
88
+
89
+ // TCP Socket Functions
90
+ /**
91
+ * Create a TCP client socket and connect to a server using dual stack (IPv6 with IPv4 fallback)
92
+ * @param host The hostname or IP address to connect to
93
+ * @param port The port number to connect to
94
+ * @param timeout_ms Connection timeout in milliseconds (0 for blocking)
95
+ * @return Socket handle, or RATS_INVALID_SOCKET on error
96
+ */
97
+ socket_t create_tcp_client(const std::string& host, int port, int timeout_ms = 0);
98
+
99
+ /**
100
+ * Begin a non-blocking TCP connect (for use with an IOPoller / reactor).
101
+ *
102
+ * Creates a non-blocking socket and initiates connect() without waiting. The
103
+ * returned socket's connection is typically still in progress: register it for
104
+ * writable, and once it signals writable call tcp_connect_result() to learn the
105
+ * outcome. Prefers IPv6, falls back to IPv4 at resolution time.
106
+ *
107
+ * @param host The hostname or IP address to connect to
108
+ * @param port The port number to connect to
109
+ * @return A non-blocking socket with a connect in progress (or completed), or
110
+ * RATS_INVALID_SOCKET if the socket could not be created/resolved.
111
+ */
112
+ socket_t tcp_connect_start(const std::string& host, int port);
113
+
114
+ /**
115
+ * Report the result of a non-blocking connect once the socket is writable.
116
+ * @param socket The socket previously returned by tcp_connect_start()
117
+ * @return 0 if the connection succeeded, otherwise the socket error code.
118
+ */
119
+ int tcp_connect_result(socket_t socket);
120
+
121
+ /**
122
+ * Create a TCP server socket and bind to a port
123
+ * @param port The port number to bind to
124
+ * @param backlog The maximum number of pending connections
125
+ * @param bind_address The interface IP address to bind to (empty for all interfaces)
126
+ * @param af Address family (DualStack by default)
127
+ * @return Socket handle, or RATS_INVALID_SOCKET on error
128
+ */
129
+ socket_t create_tcp_server(int port, int backlog = 5, const std::string& bind_address = "",
130
+ AddressFamily af = AddressFamily::DualStack);
131
+
132
+ /**
133
+ * Accept a client connection on a server socket
134
+ * @param server_socket The server socket handle
135
+ * @return Client socket handle, or RATS_INVALID_SOCKET on error
136
+ */
137
+ socket_t accept_client(socket_t server_socket);
138
+
139
+ /**
140
+ * Keep a peer that hung up from killing the process with SIGPIPE.
141
+ *
142
+ * Writing to a socket whose peer has closed raises SIGPIPE, whose default
143
+ * disposition terminates the process. Linux suppresses it per-send with
144
+ * MSG_NOSIGNAL; macOS/BSD have no such flag and suppress it per-socket instead, so
145
+ * every TCP socket we may send on has to carry SO_NOSIGPIPE. Windows has no SIGPIPE
146
+ * at all, and there this is a no-op.
147
+ *
148
+ * The socket helpers here (create_tcp_client / tcp_connect_start / accept_client)
149
+ * already do this. Call it yourself only when you take a socket straight from
150
+ * ::accept() — the option is *not* inherited from the listening socket.
151
+ */
152
+ void suppress_sigpipe(socket_t socket);
153
+
154
+ /**
155
+ * Get the peer address (IP:port) from a connected socket
156
+ * @param socket The connected socket handle
157
+ * @return Peer address string in format "IP:port", or empty string on error
158
+ */
159
+ std::string get_peer_address(socket_t socket);
160
+
161
+ /**
162
+ * Get the peer endpoint as a numeric Address, straight from getpeername() with no
163
+ * textual round-trip (IpAddress::from_sockaddr). Returns nullopt on error or an
164
+ * unsupported address family. Note the port is the peer's ephemeral SOURCE port,
165
+ * not its listen port.
166
+ */
167
+ std::optional<Address> get_peer_endpoint(socket_t socket);
168
+
169
+ /**
170
+ * Send data through a TCP socket
171
+ * @param socket The socket handle
172
+ * @param data The binary data to send
173
+ * @return Number of bytes sent, or -1 on error
174
+ */
175
+ int send_tcp_data(socket_t socket, const std::vector<uint8_t>& data);
176
+
177
+ /// Most slices send_vectored() will pass to the kernel in one call. Callers size
178
+ /// their slice arrays with this; anything beyond it simply goes out next round.
179
+ ///
180
+ /// Sized so the syscall runs out of *bytes* before it runs out of slices. A queued
181
+ /// message costs two slices (its length prefix + its body), so 64 slices would cap a
182
+ /// single send at 32 messages — with small frames that is ~45 KiB, well under what a
183
+ /// socket will take, and a backlog would need more syscalls than a plain contiguous
184
+ /// buffer. 256 slices (4 KiB of ByteView on the stack) keeps the kernel, not this
185
+ /// array, the limiting factor. send_vectored() additionally clamps to IOV_MAX.
186
+ constexpr size_t kMaxSendSlices = 256;
187
+
188
+ /**
189
+ * Scatter/gather send: hand several non-contiguous slices to the kernel in a
190
+ * single syscall (sendmsg on POSIX, WSASend on Windows). A backlog of framed
191
+ * messages then costs one syscall instead of one per message — the reason
192
+ * ChainedSendBuffer::gather() exists.
193
+ *
194
+ * Non-blocking sockets may accept only part of the data, exactly as send() does.
195
+ *
196
+ * @param socket The socket handle
197
+ * @param slices Contiguous runs to send, in order (slices beyond kMaxSendSlices
198
+ * are ignored — the caller sends them on the next round)
199
+ * @param count Number of slices
200
+ * @return Bytes accepted (possibly a partial write), or -1 on error, in which case
201
+ * errno / WSAGetLastError() holds the reason (EWOULDBLOCK when the socket's
202
+ * send buffer is full).
203
+ */
204
+ std::ptrdiff_t send_vectored(socket_t socket, const ByteView* slices, size_t count);
205
+
206
+ /**
207
+ * Receive data from a TCP socket
208
+ * @param socket The socket handle
209
+ * @param buffer_size Maximum number of bytes to receive
210
+ * @return Received binary data, empty vector on error
211
+ */
212
+ std::vector<uint8_t> receive_tcp_data(socket_t socket, size_t buffer_size = 1024);
213
+
214
+ /**
215
+ * Send a length-prefixed framed message through a TCP socket
216
+ * @param socket The socket handle
217
+ * @param message The binary message to send
218
+ * @return Total bytes sent (including length prefix), or -1 on error
219
+ */
220
+ int send_tcp_message(socket_t socket, const std::vector<uint8_t>& message);
221
+
222
+ /**
223
+ * Receive a complete length-prefixed framed message from a TCP socket
224
+ * @param socket The socket handle
225
+ * @return Complete binary message, empty vector on error or connection close
226
+ */
227
+ std::vector<uint8_t> receive_tcp_message(socket_t socket);
228
+
229
+ /**
230
+ * Send string data through a TCP socket (converts to binary)
231
+ * @param socket The socket handle
232
+ * @param data The string data to send
233
+ * @return Number of bytes sent, or -1 on error
234
+ */
235
+ int send_tcp_string(socket_t socket, const std::string& data);
236
+
237
+ // UDP Socket Functions
238
+ /**
239
+ * Create a UDP socket and bind to a port
240
+ * @param port The port to bind to (0 for any available port)
241
+ * @param bind_address The interface IP address to bind to (empty for all interfaces)
242
+ * @param af Address family (DualStack by default)
243
+ * @return UDP socket handle, or RATS_INVALID_SOCKET on error
244
+ */
245
+ socket_t create_udp_socket(int port = 0, const std::string& bind_address = "",
246
+ AddressFamily af = AddressFamily::DualStack);
247
+
248
+ /**
249
+ * Send UDP data to a destination host and port
250
+ * @param socket The UDP socket handle
251
+ * @param data The data to send
252
+ * @param host The destination hostname or IP address
253
+ * @param port The destination port
254
+ * @param af Address family matching the socket (DualStack by default)
255
+ * @return Number of bytes sent, or -1 on error
256
+ */
257
+ int send_udp_data(socket_t socket, const std::vector<uint8_t>& data, const std::string& host, int port,
258
+ AddressFamily af = AddressFamily::DualStack);
259
+
260
+ /**
261
+ * Send UDP data to a numeric Address. Unlike the host-string overload this does no
262
+ * hostname resolution and no inet_pton — the destination sockaddr is filled straight
263
+ * from the address bytes (an IPv4 address is mapped to ::ffff:x.x.x.x on a
264
+ * DualStack/IPv6 socket). This is the hot path for engines like the DHT that already
265
+ * hold resolved addresses.
266
+ * @return Number of bytes sent, or -1 on error
267
+ */
268
+ int send_udp_data(socket_t socket, const std::vector<uint8_t>& data, const Address& dest,
269
+ AddressFamily af = AddressFamily::DualStack);
270
+
271
+ /**
272
+ * Ask the kernel for larger socket buffers (SO_RCVBUF / SO_SNDBUF).
273
+ *
274
+ * Matters most for a datagram socket carrying many peers at once: the kernel has
275
+ * nowhere to put a datagram that arrives while the receive buffer is full, so it
276
+ * drops it — and a burst that overruns a small default buffer becomes a
277
+ * retransmission storm rather than a queue. Best effort: the OS may clamp the
278
+ * request, which is fine.
279
+ *
280
+ * @param recv_bytes Requested receive buffer; 0 leaves it alone.
281
+ * @param send_bytes Requested send buffer; 0 leaves it alone.
282
+ * @return true if every requested direction was accepted.
283
+ */
284
+ bool set_socket_buffer_sizes(socket_t socket, int recv_bytes, int send_bytes);
285
+
286
+ /**
287
+ * Turn Nagle's algorithm off on a TCP socket (TCP_NODELAY).
288
+ *
289
+ * Nagle holds a small write back until the last one is acknowledged, so that
290
+ * several of them can be coalesced into one segment. That is the kernel doing —
291
+ * late, and with no knowledge of what is coming — the batching a sender is
292
+ * better placed to do itself. With the send queue aggregating whole batches of
293
+ * frames into one write (see Connection::send), the coalescing has already
294
+ * happened by the time the kernel sees the bytes, and all Nagle can still add is
295
+ * the delay.
296
+ *
297
+ * Order matters: switching this on *without* that aggregation is a large step
298
+ * backwards, because then Nagle is the only thing merging small frames at all.
299
+ *
300
+ * @return true if the option was accepted.
301
+ */
302
+ bool set_tcp_nodelay(socket_t socket);
303
+
304
+ /**
305
+ * Send one datagram straight from a raw buffer — no std::vector, no resolution.
306
+ *
307
+ * The allocation-free form of send_udp_data(), for engines that emit a packet per
308
+ * call from a reusable scratch buffer (the reliable-UDP transport builds every
309
+ * header + payload into one stack buffer and hands it here).
310
+ *
311
+ * @return Bytes sent, 0 if the send would block (a full socket send buffer — the
312
+ * datagram is simply dropped, exactly as a congested link would), or -1 on
313
+ * a real error.
314
+ */
315
+ std::ptrdiff_t send_udp_to(socket_t socket, const void* data, size_t len,
316
+ const Address& dest, AddressFamily af = AddressFamily::DualStack);
317
+
318
+ /**
319
+ * Receive one datagram into a caller-owned buffer, without blocking.
320
+ *
321
+ * The counterpart of send_udp_to() for a socket driven by an IOPoller: it never
322
+ * waits, so the caller loops until it reports "nothing left".
323
+ *
324
+ * @param from Filled with the sender's endpoint on success.
325
+ * @return Bytes received (0 is a legal empty datagram), -1 when nothing is pending
326
+ * (would-block) and -2 on a socket error.
327
+ */
328
+ constexpr std::ptrdiff_t kUdpRecvWouldBlock = -1;
329
+ constexpr std::ptrdiff_t kUdpRecvError = -2;
330
+ std::ptrdiff_t recv_udp_from(socket_t socket, void* buffer, size_t len, Address& from);
331
+
332
+ // ── Batched datagram I/O ────────────────────────────────────────────────────
333
+ //
334
+ // A reliability layer built on datagrams moves one packet per call, so a bulk
335
+ // transfer at a 1200-byte payload costs tens of thousands of syscalls per
336
+ // megabyte — measurably the single largest cost on that path, well above the
337
+ // framing, the congestion control and the encryption put together. Linux (and
338
+ // the BSDs that copied it) can carry a whole array of datagrams per call;
339
+ // everywhere else these fall back to a loop over the single-datagram forms, so
340
+ // callers need no #ifdef and no second code path.
341
+
342
+ /**
343
+ * Datagrams one batched call moves. 32 is enough to make the syscall a rounding
344
+ * error against the work of building the packets, while keeping the per-call
345
+ * scratch (one message header, one iovec and one address per slot) small enough
346
+ * to live on the stack.
347
+ */
348
+ constexpr size_t kUdpBatchMax = 32;
349
+
350
+ // recvmmsg/sendmmsg — one syscall for a whole array of datagrams. Linux has had
351
+ // both since 2.6.33 (bionic exposes them from API 21); everything else takes the
352
+ // loop fallback below. FreeBSD has them too, but only as of 11, and the version
353
+ // guard is not worth the cost of being wrong there.
354
+ #if defined(__linux__) && (!defined(__ANDROID__) || __ANDROID_API__ >= 21)
355
+ #define RATS_HAVE_MMSG 1
356
+ #endif
357
+
358
+ /**
359
+ * Whether a batched call really is one syscall here, or a loop wearing the same
360
+ * interface.
361
+ *
362
+ * Both forms are correct everywhere, so this is not needed to *use* them. It
363
+ * matters to a caller deciding whether to stage datagrams for later: staging pays
364
+ * a copy per datagram to save syscalls, and where the loop fallback is in force
365
+ * there are no syscalls to save — so the copy would be pure loss and the caller
366
+ * should hand each datagram over as it is produced instead.
367
+ */
368
+ #ifdef RATS_HAVE_MMSG
369
+ constexpr bool kUdpBatchIsOneSyscall = true;
370
+ #else
371
+ constexpr bool kUdpBatchIsOneSyscall = false;
372
+ #endif
373
+
374
+ /**
375
+ * One datagram in a batch. The payload buffer belongs to the caller — a receive
376
+ * loop reuses the same storage every round and a send path stages into it — so a
377
+ * batch of any size costs no allocation.
378
+ */
379
+ struct UdpBatchSlot {
380
+ uint8_t* data = nullptr; ///< caller-owned payload buffer
381
+ size_t len = 0; ///< receive in: capacity, out: bytes filled; send: bytes to send
382
+ Address endpoint; ///< receive out: the sender; send in: the destination
383
+ };
384
+
385
+ /**
386
+ * Receive up to `count` datagrams, in one syscall where the platform has one.
387
+ *
388
+ * Each slot must point at a buffer with `len` bytes of room; on return `len` is
389
+ * what actually arrived and `endpoint` is who sent it. A datagram larger than the
390
+ * slot is truncated, exactly as recvfrom() would truncate it.
391
+ *
392
+ * @return Datagrams filled (> 0), kUdpRecvWouldBlock when nothing is pending, or
393
+ * kUdpRecvError. A result shorter than `count` does NOT prove the queue is
394
+ * empty — a per-datagram error truncates the batch too — so a caller that
395
+ * must drain (an edge-triggered poller) loops until kUdpRecvWouldBlock.
396
+ */
397
+ std::ptrdiff_t recv_udp_batch(socket_t socket, UdpBatchSlot* slots, size_t count);
398
+
399
+ /**
400
+ * Send `count` datagrams, in one syscall where the platform has one.
401
+ *
402
+ * @return How many the socket accepted. The caller must treat the whole batch as
403
+ * spent regardless: a datagram the socket refused (a full send buffer) is
404
+ * indistinguishable from one the path dropped, and retransmission covers
405
+ * both — so the count is for diagnostics, not for a retry.
406
+ */
407
+ size_t send_udp_batch(socket_t socket, const UdpBatchSlot* slots, size_t count,
408
+ AddressFamily af = AddressFamily::DualStack);
409
+
410
+ /**
411
+ * Receive UDP data with optional timeout
412
+ * @param socket The UDP socket handle
413
+ * @param buffer_size Maximum number of bytes to receive
414
+ * @param sender_peer Output parameter for the sender's peer info
415
+ * @param timeout_ms Timeout in milliseconds (-1 for blocking, 0 for non-blocking, >0 for timeout)
416
+ * @param interrupt_fd Optional second socket to watch; when it becomes readable the
417
+ * call returns immediately with an empty vector (used to wake a
418
+ * blocking receive on shutdown). RATS_INVALID_SOCKET disables it.
419
+ * @param error_out Optional output flag distinguishing the reasons an empty vector can
420
+ * mean: set to true only when select()/recvfrom() failed hard (a dead
421
+ * socket, e.g. EBADF), false for a timeout, an interrupt or an empty
422
+ * datagram. A polling loop needs this to tell "nothing arrived" from
423
+ * "this socket will never deliver again" instead of spinning forever.
424
+ * Errors that concern a signal or one destination rather than the
425
+ * socket (EINTR, ECONNREFUSED / WSAECONNRESET, WSAENETRESET) count as
426
+ * "nothing arrived" — same classification as recv_udp_from().
427
+ * @return Received data, empty vector on timeout, error or interrupt
428
+ */
429
+ std::vector<uint8_t> receive_udp_data(socket_t socket, size_t buffer_size, Address& sender_peer,
430
+ int timeout_ms = -1,
431
+ socket_t interrupt_fd = RATS_INVALID_SOCKET,
432
+ bool* error_out = nullptr);
433
+
434
+ // Common Socket Functions
435
+ /**
436
+ * Close a socket
437
+ * @param socket The socket handle to close
438
+ * @param force If true, send RST instead of FIN (avoids TIME_WAIT)
439
+ */
440
+ void close_socket(socket_t socket, bool force = false);
441
+
442
+ /**
443
+ * Check if a socket is valid
444
+ * @param socket The socket handle to check
445
+ * @return true if valid, false otherwise
446
+ */
447
+ bool is_valid_socket(socket_t socket);
448
+
449
+ /**
450
+ * Set socket to non-blocking mode
451
+ * @param socket The socket handle
452
+ * @return true if successful, false otherwise
453
+ */
454
+ bool set_socket_nonblocking(socket_t socket);
455
+
456
+ /**
457
+ * Set socket to blocking mode
458
+ * @param socket The socket handle
459
+ * @return true if successful, false otherwise
460
+ */
461
+ bool set_socket_blocking(socket_t socket);
462
+
463
+ /**
464
+ * Connect to a socket address with timeout
465
+ * @param socket The socket handle (should be non-blocking)
466
+ * @param addr The socket address structure
467
+ * @param addr_len Length of the address structure
468
+ * @param timeout_ms Connection timeout in milliseconds
469
+ * @return true if connected successfully, false on timeout or error
470
+ */
471
+ bool connect_with_timeout(socket_t socket, struct sockaddr* addr, socklen_t addr_len, int timeout_ms);
472
+
473
+ /**
474
+ * Get the port that a socket is bound to
475
+ * @param socket The socket handle
476
+ * @return The bound port, or 0 on error
477
+ */
478
+ int get_bound_port(socket_t socket);
479
+
480
+ /**
481
+ * Whether the last socket call in this thread failed because that particular
482
+ * port cannot be had — it is taken (EADDRINUSE / WSAEADDRINUSE), or on Windows
483
+ * it falls in a reserved range (WSAEACCES).
484
+ *
485
+ * Meant for the one caller that has to tell those apart from every other bind
486
+ * failure: they are the only ones worth answering by moving to another port,
487
+ * since the rest — a privileged port, a bind address not on this host, IPv6
488
+ * switched off — fail identically on all 65535 of them. The socket factories
489
+ * above preserve the failing errno across their own cleanup, so this still
490
+ * reports the bind error and not the close() that followed it.
491
+ *
492
+ * @return true if another port would plausibly work
493
+ */
494
+ bool last_error_was_port_unavailable();
495
+
496
+ } // namespace librats
@@ -0,0 +1,105 @@
1
+ #pragma once
2
+
3
+ /**
4
+ * @file timer_queue.h
5
+ * @brief Deadline-ordered timer set driven by the reactor loop.
6
+ *
7
+ * Backs handshake timeouts, reconnection backoff, keep-alives, etc. The reactor
8
+ * asks next_timeout_ms() to size its poll wait, then calls run_due() once it
9
+ * wakes. Cancellation is lazy (tombstone set) so cancel() is O(1) and never has
10
+ * to find the entry in the heap.
11
+ *
12
+ * Complexity: schedule O(log n), run_due amortised O(log n) per fired timer.
13
+ * A hashed timing wheel can replace this behind the same interface if O(1)
14
+ * scheduling ever becomes necessary; for thousands of timers a heap is ample.
15
+ *
16
+ * Single-threaded: only ever touched by the owning reactor thread.
17
+ */
18
+
19
+ #include "librats/core/types.h"
20
+
21
+ #include <algorithm>
22
+ #include <chrono>
23
+ #include <functional>
24
+ #include <unordered_set>
25
+ #include <vector>
26
+
27
+ namespace librats {
28
+
29
+ class TimerQueue {
30
+ public:
31
+ using Clock = std::chrono::steady_clock;
32
+ using Callback = std::function<void()>;
33
+
34
+ /// Schedule `cb` to fire after `delay`. Returns a handle for cancel().
35
+ TimerId schedule(Clock::duration delay, Callback cb) {
36
+ const TimerId id = ++last_id_;
37
+ heap_.push_back(Entry{Clock::now() + delay, id, std::move(cb)});
38
+ std::push_heap(heap_.begin(), heap_.end(), later_first_);
39
+ return id;
40
+ }
41
+
42
+ /// Cancel a pending timer. Safe even if it has already fired or never existed.
43
+ void cancel(TimerId id) {
44
+ if (id != kInvalidTimerId) cancelled_.insert(id);
45
+ }
46
+
47
+ /// Milliseconds until the next timer is due, clamped to [0, max_ms].
48
+ int next_timeout_ms(int max_ms) const {
49
+ if (heap_.empty()) return max_ms;
50
+ const auto now = Clock::now();
51
+ const auto due = heap_.front().when;
52
+ if (due <= now) return 0;
53
+ // Round UP: truncating a sub-millisecond remainder to 0 would make the
54
+ // reactor poll with a 0 ms timeout and busy-spin until the deadline
55
+ // instead of sleeping through it. ceil guarantees the wait covers the
56
+ // timer, so it fires on wake rather than after a CPU-burning spin.
57
+ const auto ms = std::chrono::ceil<std::chrono::milliseconds>(due - now).count();
58
+ return static_cast<int>(std::min<long long>(ms, max_ms));
59
+ }
60
+
61
+ /// Fire every timer whose deadline has passed (skipping cancelled ones).
62
+ void run_due() {
63
+ const auto now = Clock::now();
64
+ while (!heap_.empty() && heap_.front().when <= now) {
65
+ std::pop_heap(heap_.begin(), heap_.end(), later_first_);
66
+ Entry e = std::move(heap_.back());
67
+ heap_.pop_back();
68
+
69
+ auto it = cancelled_.find(e.id);
70
+ if (it != cancelled_.end()) {
71
+ cancelled_.erase(it);
72
+ continue;
73
+ }
74
+ e.cb();
75
+ }
76
+ }
77
+
78
+ /// Drop every pending timer, tombstones included. For an owner being torn
79
+ /// down that may be started again: nothing scheduled by one run should still
80
+ /// be due in the next. Ids keep counting up, so a handle held across the gap
81
+ /// can never come to name a timer of the new run.
82
+ void clear() {
83
+ heap_.clear();
84
+ cancelled_.clear();
85
+ }
86
+
87
+ bool empty() const { return heap_.empty(); }
88
+
89
+ private:
90
+ struct Entry {
91
+ Clock::time_point when;
92
+ TimerId id;
93
+ Callback cb;
94
+ };
95
+ // Min-heap on `when`: std::*_heap are max-heaps, so invert the comparison.
96
+ struct LaterFirst {
97
+ bool operator()(const Entry& a, const Entry& b) const { return a.when > b.when; }
98
+ } later_first_;
99
+
100
+ std::vector<Entry> heap_;
101
+ std::unordered_set<TimerId> cancelled_;
102
+ TimerId last_id_ = kInvalidTimerId;
103
+ };
104
+
105
+ } // namespace librats
@@ -0,0 +1,43 @@
1
+ #include "librats/core/types.h"
2
+
3
+ namespace librats {
4
+
5
+ const char* to_string(ConnState s) noexcept {
6
+ switch (s) {
7
+ case ConnState::Connecting: return "Connecting";
8
+ case ConnState::Handshaking: return "Handshaking";
9
+ case ConnState::Established: return "Established";
10
+ case ConnState::Closing: return "Closing";
11
+ case ConnState::Closed: return "Closed";
12
+ }
13
+ return "?";
14
+ }
15
+
16
+ const char* to_string(CloseReason r) noexcept {
17
+ switch (r) {
18
+ case CloseReason::LocalClose: return "LocalClose";
19
+ case CloseReason::PeerClosed: return "PeerClosed";
20
+ case CloseReason::PeerReset: return "PeerReset";
21
+ case CloseReason::ConnectFailed: return "ConnectFailed";
22
+ case CloseReason::HandshakeFailed: return "HandshakeFailed";
23
+ case CloseReason::ProtocolError: return "ProtocolError";
24
+ case CloseReason::SlowConsumer: return "SlowConsumer";
25
+ case CloseReason::ReactorShutdown: return "ReactorShutdown";
26
+ case CloseReason::DuplicateConn: return "DuplicateConn";
27
+ case CloseReason::PeerLimit: return "PeerLimit";
28
+ case CloseReason::IdleTimeout: return "IdleTimeout";
29
+ case CloseReason::DialSuperseded: return "DialSuperseded";
30
+ }
31
+ return "?";
32
+ }
33
+
34
+ const char* to_string(TransportKind t) noexcept {
35
+ switch (t) {
36
+ case TransportKind::Tcp: return "tcp";
37
+ case TransportKind::Udp: return "udp";
38
+ case TransportKind::Relay: return "relay";
39
+ }
40
+ return "?";
41
+ }
42
+
43
+ } // namespace librats