@encharm/cws 4.5.3 → 4.6.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 (288) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/CLAUDE.md +81 -0
  3. package/README.md +10 -3
  4. package/dist/bindings/cws_darwin_arm64_node115.node +0 -0
  5. package/dist/bindings/cws_darwin_arm64_node127.node +0 -0
  6. package/dist/bindings/cws_darwin_arm64_node137.node +0 -0
  7. package/dist/bindings/cws_darwin_arm64_node147.node +0 -0
  8. package/dist/bindings/cws_linux_arm64_node115.node +0 -0
  9. package/dist/bindings/cws_linux_arm64_node127.node +0 -0
  10. package/dist/bindings/cws_linux_arm64_node137.node +0 -0
  11. package/dist/bindings/cws_linux_arm64_node147.node +0 -0
  12. package/dist/bindings/cws_linux_x64_node115.node +0 -0
  13. package/dist/bindings/cws_linux_x64_node127.node +0 -0
  14. package/dist/bindings/cws_linux_x64_node137.node +0 -0
  15. package/dist/bindings/cws_linux_x64_node147.node +0 -0
  16. package/dist/bindings/cws_win32_x64_node115.node +0 -0
  17. package/dist/bindings/cws_win32_x64_node127.node +0 -0
  18. package/dist/bindings/cws_win32_x64_node137.node +0 -0
  19. package/dist/bindings/cws_win32_x64_node147.node +0 -0
  20. package/package.json +1 -1
  21. package/src/Addon.cpp +2 -1
  22. package/src/Addon.h +70 -14
  23. package/src/Hub.h +1 -0
  24. package/src/Networking.h +11 -0
  25. package/src/Socket.h +201 -6
  26. package/src/WebSocket.cpp +4 -1
  27. package/src/cSNode.cpp +2 -0
  28. package/src/cSNode.h +4 -0
  29. package/src/headers/26/acorn_version.h +6 -0
  30. package/src/headers/26/aliased_buffer-inl.h +264 -0
  31. package/src/headers/26/aliased_buffer.h +205 -0
  32. package/src/headers/26/aliased_struct-inl.h +143 -0
  33. package/src/headers/26/aliased_struct.h +248 -0
  34. package/src/headers/26/amaro_version.h +6 -0
  35. package/src/headers/26/async_context_frame.h +33 -0
  36. package/src/headers/26/async_wrap-inl.h +123 -0
  37. package/src/headers/26/async_wrap.h +254 -0
  38. package/src/headers/26/base_object-inl.h +333 -0
  39. package/src/headers/26/base_object.h +339 -0
  40. package/src/headers/26/base_object_types.h +76 -0
  41. package/src/headers/26/blob_serializer_deserializer-inl.h +385 -0
  42. package/src/headers/26/blob_serializer_deserializer.h +142 -0
  43. package/src/headers/26/builtin_info.h +57 -0
  44. package/src/headers/26/callback_queue-inl.h +97 -0
  45. package/src/headers/26/callback_queue.h +79 -0
  46. package/src/headers/26/cares_wrap.h +475 -0
  47. package/src/headers/26/cleanup_queue-inl.h +36 -0
  48. package/src/headers/26/cleanup_queue.h +79 -0
  49. package/src/headers/26/compile_cache.h +134 -0
  50. package/src/headers/26/connect_wrap.h +26 -0
  51. package/src/headers/26/connection_wrap.h +30 -0
  52. package/src/headers/26/cppgc_helpers-inl.h +69 -0
  53. package/src/headers/26/cppgc_helpers.h +162 -0
  54. package/src/headers/26/crypto/crypto_aes.h +107 -0
  55. package/src/headers/26/crypto/crypto_argon2.h +88 -0
  56. package/src/headers/26/crypto/crypto_bio.h +193 -0
  57. package/src/headers/26/crypto/crypto_chacha20_poly1305.h +62 -0
  58. package/src/headers/26/crypto/crypto_cipher.h +291 -0
  59. package/src/headers/26/crypto/crypto_common.h +48 -0
  60. package/src/headers/26/crypto/crypto_context.h +219 -0
  61. package/src/headers/26/crypto/crypto_dh.h +104 -0
  62. package/src/headers/26/crypto/crypto_dsa.h +50 -0
  63. package/src/headers/26/crypto/crypto_ec.h +102 -0
  64. package/src/headers/26/crypto/crypto_hash.h +157 -0
  65. package/src/headers/26/crypto/crypto_hkdf.h +62 -0
  66. package/src/headers/26/crypto/crypto_hmac.h +92 -0
  67. package/src/headers/26/crypto/crypto_kem.h +131 -0
  68. package/src/headers/26/crypto/crypto_keygen.h +382 -0
  69. package/src/headers/26/crypto/crypto_keys.h +366 -0
  70. package/src/headers/26/crypto/crypto_kmac.h +79 -0
  71. package/src/headers/26/crypto/crypto_pbkdf2.h +76 -0
  72. package/src/headers/26/crypto/crypto_pqc.h +39 -0
  73. package/src/headers/26/crypto/crypto_random.h +127 -0
  74. package/src/headers/26/crypto/crypto_rsa.h +108 -0
  75. package/src/headers/26/crypto/crypto_scrypt.h +85 -0
  76. package/src/headers/26/crypto/crypto_sig.h +159 -0
  77. package/src/headers/26/crypto/crypto_spkac.h +21 -0
  78. package/src/headers/26/crypto/crypto_timing.h +20 -0
  79. package/src/headers/26/crypto/crypto_tls.h +342 -0
  80. package/src/headers/26/crypto/crypto_turboshake.h +105 -0
  81. package/src/headers/26/crypto/crypto_util.h +775 -0
  82. package/src/headers/26/crypto/crypto_x509.h +140 -0
  83. package/src/headers/26/dataqueue/queue.h +311 -0
  84. package/src/headers/26/debug_utils-inl.h +291 -0
  85. package/src/headers/26/debug_utils.h +200 -0
  86. package/src/headers/26/diagnosticfilename-inl.h +33 -0
  87. package/src/headers/26/embedded_data.h +17 -0
  88. package/src/headers/26/encoding_binding.h +59 -0
  89. package/src/headers/26/env-inl.h +956 -0
  90. package/src/headers/26/env.h +1294 -0
  91. package/src/headers/26/env_properties.h +562 -0
  92. package/src/headers/26/ffi/data.h +30 -0
  93. package/src/headers/26/ffi/fast.h +96 -0
  94. package/src/headers/26/ffi/jit_memory.h +26 -0
  95. package/src/headers/26/ffi/types.h +99 -0
  96. package/src/headers/26/handle_wrap.h +123 -0
  97. package/src/headers/26/histogram-inl.h +211 -0
  98. package/src/headers/26/histogram.h +474 -0
  99. package/src/headers/26/inspector/dom_storage_agent.h +68 -0
  100. package/src/headers/26/inspector/inspector_object_utils.h +38 -0
  101. package/src/headers/26/inspector/io_agent.h +30 -0
  102. package/src/headers/26/inspector/main_thread_interface.h +116 -0
  103. package/src/headers/26/inspector/network_agent.h +110 -0
  104. package/src/headers/26/inspector/network_inspector.h +45 -0
  105. package/src/headers/26/inspector/network_requests_buffer.h +195 -0
  106. package/src/headers/26/inspector/network_resource_manager.h +29 -0
  107. package/src/headers/26/inspector/node_json.h +24 -0
  108. package/src/headers/26/inspector/node_string.h +101 -0
  109. package/src/headers/26/inspector/notification_emitter.h +38 -0
  110. package/src/headers/26/inspector/protocol_helper.h +27 -0
  111. package/src/headers/26/inspector/runtime_agent.h +41 -0
  112. package/src/headers/26/inspector/storage_agent.h +33 -0
  113. package/src/headers/26/inspector/target_agent.h +59 -0
  114. package/src/headers/26/inspector/target_manager.h +70 -0
  115. package/src/headers/26/inspector/tracing_agent.h +43 -0
  116. package/src/headers/26/inspector/worker_agent.h +40 -0
  117. package/src/headers/26/inspector/worker_inspector.h +124 -0
  118. package/src/headers/26/inspector_agent.h +168 -0
  119. package/src/headers/26/inspector_io.h +78 -0
  120. package/src/headers/26/inspector_profiler.h +149 -0
  121. package/src/headers/26/inspector_socket.h +60 -0
  122. package/src/headers/26/inspector_socket_server.h +110 -0
  123. package/src/headers/26/js_native_api.h +634 -0
  124. package/src/headers/26/js_native_api_types.h +244 -0
  125. package/src/headers/26/js_native_api_v8.h +485 -0
  126. package/src/headers/26/js_native_api_v8_internals.h +45 -0
  127. package/src/headers/26/js_stream.h +57 -0
  128. package/src/headers/26/json_utils.h +172 -0
  129. package/src/headers/26/large_pages/node_large_page.h +34 -0
  130. package/src/headers/26/lru_cache-inl.h +69 -0
  131. package/src/headers/26/memory_tracker-inl.h +461 -0
  132. package/src/headers/26/memory_tracker.h +341 -0
  133. package/src/headers/26/module_wrap.h +231 -0
  134. package/src/headers/26/ncrypto.h +2008 -0
  135. package/src/headers/26/node.h +1693 -0
  136. package/src/headers/26/node_api.h +265 -0
  137. package/src/headers/26/node_api_internals.h +48 -0
  138. package/src/headers/26/node_api_types.h +58 -0
  139. package/src/headers/26/node_binding.h +170 -0
  140. package/src/headers/26/node_blob.h +160 -0
  141. package/src/headers/26/node_bob-inl.h +36 -0
  142. package/src/headers/26/node_bob.h +107 -0
  143. package/src/headers/26/node_buffer.h +92 -0
  144. package/src/headers/26/node_builtins.h +239 -0
  145. package/src/headers/26/node_concepts.h +46 -0
  146. package/src/headers/26/node_config_file.h +77 -0
  147. package/src/headers/26/node_constants.h +82 -0
  148. package/src/headers/26/node_context_data.h +171 -0
  149. package/src/headers/26/node_contextify.h +261 -0
  150. package/src/headers/26/node_crypto.h +66 -0
  151. package/src/headers/26/node_debug.h +30 -0
  152. package/src/headers/26/node_diagnostics_channel.h +121 -0
  153. package/src/headers/26/node_dir.h +52 -0
  154. package/src/headers/26/node_dotenv.h +45 -0
  155. package/src/headers/26/node_errors.h +378 -0
  156. package/src/headers/26/node_exit_code.h +54 -0
  157. package/src/headers/26/node_external_reference.h +171 -0
  158. package/src/headers/26/node_ffi.h +212 -0
  159. package/src/headers/26/node_file-inl.h +421 -0
  160. package/src/headers/26/node_file.h +561 -0
  161. package/src/headers/26/node_file_utils.h +39 -0
  162. package/src/headers/26/node_hash.h +212 -0
  163. package/src/headers/26/node_http2.h +1202 -0
  164. package/src/headers/26/node_http2_state.h +159 -0
  165. package/src/headers/26/node_http_common-inl.h +199 -0
  166. package/src/headers/26/node_http_common.h +535 -0
  167. package/src/headers/26/node_i18n.h +132 -0
  168. package/src/headers/26/node_internals.h +485 -0
  169. package/src/headers/26/node_locks.h +184 -0
  170. package/src/headers/26/node_main_instance.h +67 -0
  171. package/src/headers/26/node_mem-inl.h +113 -0
  172. package/src/headers/26/node_mem.h +45 -0
  173. package/src/headers/26/node_messaging.h +389 -0
  174. package/src/headers/26/node_metadata.h +172 -0
  175. package/src/headers/26/node_modules.h +102 -0
  176. package/src/headers/26/node_mutex.h +323 -0
  177. package/src/headers/26/node_object_wrap.h +145 -0
  178. package/src/headers/26/node_options-inl.h +524 -0
  179. package/src/headers/26/node_options.h +710 -0
  180. package/src/headers/26/node_perf.h +167 -0
  181. package/src/headers/26/node_perf_common.h +103 -0
  182. package/src/headers/26/node_platform.h +290 -0
  183. package/src/headers/26/node_process-inl.h +26 -0
  184. package/src/headers/26/node_process.h +112 -0
  185. package/src/headers/26/node_profiling.h +38 -0
  186. package/src/headers/26/node_realm-inl.h +156 -0
  187. package/src/headers/26/node_realm.h +236 -0
  188. package/src/headers/26/node_report.h +43 -0
  189. package/src/headers/26/node_revert.h +82 -0
  190. package/src/headers/26/node_root_certs.h +2937 -0
  191. package/src/headers/26/node_sea.h +101 -0
  192. package/src/headers/26/node_shadow_realm.h +46 -0
  193. package/src/headers/26/node_snapshot_builder.h +57 -0
  194. package/src/headers/26/node_snapshotable.h +167 -0
  195. package/src/headers/26/node_sockaddr-inl.h +248 -0
  196. package/src/headers/26/node_sockaddr.h +459 -0
  197. package/src/headers/26/node_sqlite.h +607 -0
  198. package/src/headers/26/node_stat_watcher.h +73 -0
  199. package/src/headers/26/node_task_runner.h +92 -0
  200. package/src/headers/26/node_threadsafe_cow-inl.h +54 -0
  201. package/src/headers/26/node_threadsafe_cow.h +105 -0
  202. package/src/headers/26/node_union_bytes.h +81 -0
  203. package/src/headers/26/node_url.h +101 -0
  204. package/src/headers/26/node_url_pattern.h +118 -0
  205. package/src/headers/26/node_v8.h +78 -0
  206. package/src/headers/26/node_v8_embedder.h +26 -0
  207. package/src/headers/26/node_v8_platform-inl.h +96 -0
  208. package/src/headers/26/node_version.h +116 -0
  209. package/src/headers/26/node_wasi.h +184 -0
  210. package/src/headers/26/node_wasm_web_api.h +55 -0
  211. package/src/headers/26/node_watchdog.h +164 -0
  212. package/src/headers/26/node_webstorage.h +62 -0
  213. package/src/headers/26/node_worker.h +162 -0
  214. package/src/headers/26/path.h +36 -0
  215. package/src/headers/26/permission/boolean_permission.h +50 -0
  216. package/src/headers/26/permission/fs_permission.h +192 -0
  217. package/src/headers/26/permission/permission.h +155 -0
  218. package/src/headers/26/permission/permission_base.h +79 -0
  219. package/src/headers/26/pipe_wrap.h +80 -0
  220. package/src/headers/26/quic/application.h +279 -0
  221. package/src/headers/26/quic/arena.h +373 -0
  222. package/src/headers/26/quic/bindingdata.h +440 -0
  223. package/src/headers/26/quic/cid.h +127 -0
  224. package/src/headers/26/quic/data.h +358 -0
  225. package/src/headers/26/quic/defs.h +417 -0
  226. package/src/headers/26/quic/endpoint.h +519 -0
  227. package/src/headers/26/quic/guard.h +5 -0
  228. package/src/headers/26/quic/http3.h +25 -0
  229. package/src/headers/26/quic/packet.h +166 -0
  230. package/src/headers/26/quic/preferredaddress.h +72 -0
  231. package/src/headers/26/quic/session.h +770 -0
  232. package/src/headers/26/quic/session_manager.h +107 -0
  233. package/src/headers/26/quic/sessionticket.h +110 -0
  234. package/src/headers/26/quic/streams.h +518 -0
  235. package/src/headers/26/quic/tlscontext.h +353 -0
  236. package/src/headers/26/quic/tokens.h +263 -0
  237. package/src/headers/26/quic/transportparams.h +184 -0
  238. package/src/headers/26/req_wrap-inl.h +175 -0
  239. package/src/headers/26/req_wrap.h +79 -0
  240. package/src/headers/26/spawn_sync.h +243 -0
  241. package/src/headers/26/stream_base-inl.h +170 -0
  242. package/src/headers/26/stream_base.h +487 -0
  243. package/src/headers/26/stream_pipe.h +76 -0
  244. package/src/headers/26/stream_wrap.h +137 -0
  245. package/src/headers/26/string_bytes.h +114 -0
  246. package/src/headers/26/string_decoder-inl.h +31 -0
  247. package/src/headers/26/string_decoder.h +49 -0
  248. package/src/headers/26/tcp_wrap.h +138 -0
  249. package/src/headers/26/threadpoolwork-inl.h +70 -0
  250. package/src/headers/26/timer_wrap-inl.h +32 -0
  251. package/src/headers/26/timer_wrap.h +87 -0
  252. package/src/headers/26/timers.h +70 -0
  253. package/src/headers/26/tracing/agent.h +125 -0
  254. package/src/headers/26/tracing/agent_legacy.h +146 -0
  255. package/src/headers/26/tracing/agent_perfetto.h +145 -0
  256. package/src/headers/26/tracing/node_trace_buffer.h +91 -0
  257. package/src/headers/26/tracing/node_trace_writer.h +79 -0
  258. package/src/headers/26/tracing/trace_event.h +27 -0
  259. package/src/headers/26/tracing/trace_event_helper.h +40 -0
  260. package/src/headers/26/tracing/trace_event_legacy.h +1113 -0
  261. package/src/headers/26/tracing/trace_event_legacy_inl.h +711 -0
  262. package/src/headers/26/tracing/trace_event_perfetto.h +47 -0
  263. package/src/headers/26/tracing/traced_value.h +167 -0
  264. package/src/headers/26/tty_wrap.h +65 -0
  265. package/src/headers/26/udp_wrap.h +231 -0
  266. package/src/headers/26/undici_version.h +6 -0
  267. package/src/headers/26/util-inl.h +788 -0
  268. package/src/headers/26/util.h +1207 -0
  269. package/src/headers/26/v8-cpp-heap-external.h +56 -0
  270. package/src/headers/26/v8-external-memory-accounter.h +60 -0
  271. package/src/headers/26/v8-fast-api-calls.h +784 -0
  272. package/src/headers/26/v8-inspector-protocol.h +13 -0
  273. package/src/headers/26/v8-inspector.h +458 -0
  274. package/src/headers/26/v8-metrics.h +273 -0
  275. package/src/headers/26/v8-trace-categories.h +28 -0
  276. package/src/headers/26/v8-unwinder-state.h +30 -0
  277. package/src/headers/26/v8-util.h +549 -0
  278. package/src/headers/26/v8-value-serializer-version.h +24 -0
  279. package/src/headers/26/v8-version-string.h +38 -0
  280. package/src/headers/26/v8-wasm-trap-handler-posix.h +31 -0
  281. package/src/headers/26/v8-wasm-trap-handler-win.h +28 -0
  282. package/src/headers/26/zlib_version.h +6 -0
  283. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Info.plist +0 -20
  284. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Resources/DWARF/cws_darwin_arm64_node115.node +0 -0
  285. package/dist/bindings/cws_darwin_arm64_node115.node.dSYM/Contents/Resources/Relocations/aarch64/cws_darwin_arm64_node115.node.yml +0 -931
  286. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Info.plist +0 -20
  287. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Resources/DWARF/cws_darwin_arm64_node127.node +0 -0
  288. package/dist/bindings/cws_darwin_arm64_node127.node.dSYM/Contents/Resources/Relocations/aarch64/cws_darwin_arm64_node127.node.yml +0 -931
@@ -0,0 +1,519 @@
1
+ #pragma once
2
+
3
+ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4
+
5
+ #include <aliased_struct.h>
6
+ #include <async_wrap.h>
7
+ #include <env.h>
8
+ #include <node_sockaddr.h>
9
+ #include <timer_wrap.h>
10
+ #include <uv.h>
11
+ #include <v8.h>
12
+ #include <algorithm>
13
+ #include <optional>
14
+ #include "arena.h"
15
+ #include "bindingdata.h"
16
+ #include "packet.h"
17
+ #include "session.h"
18
+ #include "session_manager.h"
19
+ #include "sessionticket.h"
20
+ #include "tokens.h"
21
+
22
+ namespace node::quic {
23
+
24
+ // An Endpoint encapsulates the UDP local port binding and is responsible for
25
+ // sending and receiving QUIC packets. A single endpoint can act as both a QUIC
26
+ // client and server simultaneously.
27
+ class Endpoint final : public AsyncWrap, public Packet::Listener {
28
+ public:
29
+ // The socket address LRU is used for tracking validated remote addresses.
30
+ static constexpr uint64_t DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE = 1024;
31
+
32
+ // Default rate limits for stateless responses. These are global token
33
+ // bucket limits that cap the total rate of each response type regardless
34
+ // of source address. This prevents spoofed-source floods from bypassing
35
+ // per-host limits (which are keyed by source IP and trivially defeated
36
+ // by rotating spoofed addresses). The rate is in responses per second
37
+ // and the burst is the maximum tokens the bucket can hold.
38
+ static constexpr double DEFAULT_RETRY_RATE = 100;
39
+ static constexpr double DEFAULT_RETRY_BURST = 200;
40
+ static constexpr double DEFAULT_STATELESS_RESET_RATE = 100;
41
+ static constexpr double DEFAULT_STATELESS_RESET_BURST = 200;
42
+ static constexpr double DEFAULT_VERSION_NEGOTIATION_RATE = 100;
43
+ static constexpr double DEFAULT_VERSION_NEGOTIATION_BURST = 200;
44
+ static constexpr double DEFAULT_IMMEDIATE_CLOSE_RATE = 100;
45
+ static constexpr double DEFAULT_IMMEDIATE_CLOSE_BURST = 200;
46
+
47
+ // Per-host session creation rate limit. This is tracked per validated
48
+ // remote address in the address LRU, preventing a single source from
49
+ // churning through sessions faster than the server can handle. Unlike
50
+ // the global stateless response buckets, this only applies after address
51
+ // validation (spoofed sources can't reach this path).
52
+ static constexpr double DEFAULT_SESSION_CREATION_RATE = 50;
53
+ static constexpr double DEFAULT_SESSION_CREATION_BURST = 100;
54
+
55
+ // Endpoint configuration options
56
+ struct Options final : public MemoryRetainer {
57
+ // The local socket address to which the UDP port will be bound. The port
58
+ // may be 0 to have Node.js select an available port. IPv6 or IPv4 addresses
59
+ // may be used. When using IPv6, dual mode will be supported by default.
60
+ std::shared_ptr<SocketAddress> local_address;
61
+
62
+ // Retry tokens issued by the Endpoint are time-limited. By default, retry
63
+ // tokens expire after DEFAULT_RETRYTOKEN_EXPIRATION *seconds*. This is an
64
+ // arbitrary choice that is not mandated by the QUIC specification; so we
65
+ // can choose any value that makes sense here. Retry tokens are sent to the
66
+ // client, which echoes them back to the server in a subsequent set of
67
+ // packets, which means the expiration must be set high enough to allow a
68
+ // reasonable round-trip time for the session TLS handshake to complete.
69
+ uint64_t retry_token_expiration =
70
+ RetryToken::QUIC_DEFAULT_RETRYTOKEN_EXPIRATION / NGTCP2_SECONDS;
71
+
72
+ // Tokens issued using NEW_TOKEN are time-limited. By default, tokens expire
73
+ // after QUIC_DEFAULT_REGULARTOKEN_EXPIRATION *seconds*.
74
+ uint64_t token_expiration =
75
+ RegularToken::QUIC_DEFAULT_REGULARTOKEN_EXPIRATION / NGTCP2_SECONDS;
76
+
77
+ // For tracking the path verification status of remote hosts, we maintain
78
+ // an LRU cache of the most recently seen hosts.
79
+ uint64_t address_lru_size = DEFAULT_MAX_SOCKETADDRESS_LRU_SIZE;
80
+
81
+ // Global token bucket rate limits for stateless responses. These cap
82
+ // the total rate of each response type regardless of source address,
83
+ // preventing spoofed-source floods. Rate is in responses per second,
84
+ // burst is the maximum number of responses that can be sent in a burst.
85
+ double retry_rate = DEFAULT_RETRY_RATE;
86
+ double retry_burst = DEFAULT_RETRY_BURST;
87
+ double stateless_reset_rate = DEFAULT_STATELESS_RESET_RATE;
88
+ double stateless_reset_burst = DEFAULT_STATELESS_RESET_BURST;
89
+ double version_negotiation_rate = DEFAULT_VERSION_NEGOTIATION_RATE;
90
+ double version_negotiation_burst = DEFAULT_VERSION_NEGOTIATION_BURST;
91
+ double immediate_close_rate = DEFAULT_IMMEDIATE_CLOSE_RATE;
92
+ double immediate_close_burst = DEFAULT_IMMEDIATE_CLOSE_BURST;
93
+
94
+ // Per-host session creation rate limit. Tracked per validated remote
95
+ // address in the address LRU. Set to high values for benchmarking
96
+ // where traffic comes from a single source.
97
+ double session_creation_rate = DEFAULT_SESSION_CREATION_RATE;
98
+ double session_creation_burst = DEFAULT_SESSION_CREATION_BURST;
99
+
100
+ // The validate_address parameter instructs the Endpoint to perform explicit
101
+ // address validation using retry tokens. This is strongly recommended and
102
+ // should only be disabled in trusted, closed environments as a performance
103
+ // optimization.
104
+ bool validate_address = true;
105
+
106
+ // The stateless reset mechanism can be disabled. This should rarely ever be
107
+ // needed, and should only ever be done in trusted, closed environments as a
108
+ // performance optimization.
109
+ bool disable_stateless_reset = false;
110
+
111
+ #ifdef DEBUG
112
+ // The rx_loss and tx_loss parameters are debugging tools that allow the
113
+ // Endpoint to simulate random packet loss. The value for each parameter is
114
+ // a value between 0.0 and 1.0 indicating a probability of packet loss. Each
115
+ // time a packet is sent or received, the packet loss bit is calculated and
116
+ // if true, the packet is silently dropped. This should only ever be used
117
+ // for testing and debugging. There is never a reason why rx_loss and
118
+ // tx_loss should ever be used in a production system.
119
+ double rx_loss = 0.0;
120
+ double tx_loss = 0.0;
121
+ #endif // DEBUG
122
+
123
+ // By default, when the endpoint is created, it will generate a
124
+ // reset_token_secret at random. This is a secret used in generating
125
+ // stateless reset tokens. In order for stateless reset to be effective,
126
+ // however, it is necessary to use a deterministic secret that persists
127
+ // across ngtcp2 endpoints and sessions. This means that the endpoint
128
+ // configuration really should have a reset token secret passed in.
129
+ TokenSecret reset_token_secret;
130
+
131
+ // The secret used for generating new regular tokens.
132
+ TokenSecret token_secret;
133
+
134
+ // When the local_address specifies an IPv6 local address to bind to, the
135
+ // ipv6_only parameter determines whether dual stack mode (supporting both
136
+ // IPv6 and IPv4) transparently is supported. This sets the UV_UDP_IPV6ONLY
137
+ // flag on the underlying uv_udp_t.
138
+ bool ipv6_only = false;
139
+
140
+ // When true, multiple endpoints (across separate processes) can bind to
141
+ // the same address:port and the kernel will load-balance incoming UDP
142
+ // datagrams across them. This sets the UV_UDP_REUSEPORT flag on the
143
+ // underlying uv_udp_t. Supported on Linux 3.9+ and DragonFlyBSD 3.6+.
144
+ bool reuse_port = false;
145
+
146
+ uint32_t udp_receive_buffer_size = 0;
147
+ uint32_t udp_send_buffer_size = 0;
148
+
149
+ // The UDP TTL configuration is the number of network hops a packet will be
150
+ // forwarded through. The default is 64. The value is in the range 1 to 255.
151
+ // Setting to 0 uses the default.
152
+ uint8_t udp_ttl = 0;
153
+
154
+ // When an endpoint becomes idle (not listening and no primary sessions),
155
+ // it will be destroyed after this many seconds. A value of 0 means
156
+ // destroy immediately when idle (default, preserves pre-SessionManager
157
+ // behavior). A positive value keeps the endpoint alive for potential
158
+ // reuse by future connect() or listen() calls.
159
+ static constexpr uint64_t DEFAULT_IDLE_TIMEOUT = 0;
160
+ uint64_t idle_timeout = DEFAULT_IDLE_TIMEOUT;
161
+
162
+ // Optional block list for filtering incoming packets by source address.
163
+ // When block_list_policy is DENY, packets from addresses matching the
164
+ // block list are dropped. When ALLOW, only packets from addresses
165
+ // matching the block list are accepted (all others dropped).
166
+ enum class BlockListPolicy : uint8_t {
167
+ DENY, // Drop packets from matching addresses (blocklist)
168
+ ALLOW, // Drop packets from non-matching addresses (allowlist)
169
+ };
170
+ std::shared_ptr<SocketAddressBlockList> block_list;
171
+ BlockListPolicy block_list_policy = BlockListPolicy::DENY;
172
+
173
+ void MemoryInfo(MemoryTracker* tracker) const override;
174
+ SET_MEMORY_INFO_NAME(Endpoint::Config)
175
+ SET_SELF_SIZE(Options)
176
+
177
+ static v8::Maybe<Options> From(Environment* env,
178
+ v8::Local<v8::Value> value);
179
+
180
+ std::string ToString() const;
181
+ };
182
+
183
+ JS_CONSTRUCTOR(Endpoint);
184
+ JS_BINDING_INIT_BOILERPLATE();
185
+
186
+ Endpoint(Environment* env,
187
+ v8::Local<v8::Object> object,
188
+ const Endpoint::Options& options);
189
+
190
+ inline operator Packet::Listener*() {
191
+ return this;
192
+ }
193
+
194
+ inline const Options& options() const {
195
+ return options_;
196
+ }
197
+
198
+ // While the busy flag is set, the Endpoint will reject all initial packets
199
+ // with a SERVER_BUSY response. This allows us to build a circuit breaker
200
+ // directly into the implementation, explicitly signaling that the server is
201
+ // blocked when activity is too high.
202
+ void MarkAsBusy(bool on = true);
203
+
204
+ // Use the endpoint's token secret to generate a new token.
205
+ RegularToken GenerateNewToken(uint32_t version,
206
+ const SocketAddress& remote_address);
207
+
208
+ // Use the endpoint's reset token secret to generate a new stateless reset.
209
+ StatelessResetToken GenerateNewStatelessResetToken(uint8_t* token,
210
+ const CID& cid) const;
211
+
212
+ void AddSession(const CID& cid, BaseObjectPtr<Session> session);
213
+ void RemoveSession(const CID& cid, const SocketAddress& remote_address);
214
+ BaseObjectPtr<Session> FindSession(const CID& cid);
215
+
216
+ // A single session may be associated with multiple CIDs.
217
+ // AssociateCID registers the mapping both in the Endpoint and the inner
218
+ // Endpoint.
219
+ void AssociateCID(const CID& cid, const CID& scid);
220
+ void DisassociateCID(const CID& cid);
221
+
222
+ // Associates a given stateless reset token with the session. This allows
223
+ // stateless reset tokens to be recognized and dispatched to the proper
224
+ // Endpoint and Session for processing.
225
+ void AssociateStatelessResetToken(const StatelessResetToken& token,
226
+ Session* session);
227
+ void DisassociateStatelessResetToken(const StatelessResetToken& token);
228
+
229
+ void Send(Packet::Ptr packet);
230
+
231
+ // Attempt synchronous send via uv_udp_try_send. If the socket is
232
+ // writable, the packet is sent immediately and the Ptr is released.
233
+ // If the socket is not writable (UV_EAGAIN), falls back to the
234
+ // async Send path. Used by the deferred flush callback to avoid
235
+ // the one-tick latency of async uv_udp_send.
236
+ void SendOrTrySend(Packet::Ptr packet);
237
+
238
+ // Send a batch of packets using uv_udp_try_send2 (sendmmsg) for
239
+ // synchronous batched delivery. Packets successfully sent are released
240
+ // immediately. On EAGAIN or partial send, remaining packets fall back
241
+ // to async uv_udp_send. The Packet::Ptr array is consumed: all entries
242
+ // will be empty (released or moved) on return.
243
+ void SendBatch(Packet::Ptr* packets, size_t count);
244
+
245
+ // Acquire a Packet from the pool. length sets the initial working
246
+ // size (must be <= pool capacity). The slot is always allocated at
247
+ // full capacity to avoid fragmentation.
248
+ Packet::Ptr CreatePacket(const SocketAddress& destination,
249
+ size_t length = kDefaultMaxPacketLength,
250
+ const char* diagnostic_label = nullptr);
251
+
252
+ // Generates and sends a retry packet. This is terminal for the connection.
253
+ // Retry packets are used to force explicit path validation by issuing a token
254
+ // to the peer that it must thereafter include in all subsequent initial
255
+ // packets. Upon receiving a retry packet, the peer must termination it's
256
+ // initial attempt to establish a connection and start a new attempt.
257
+ //
258
+ // Retry packets will only ever be generated by QUIC servers, and only if the
259
+ // QuicSocket is configured for explicit path validation. There is no way for
260
+ // a client to force a retry packet to be created. However, once a client
261
+ // determines that explicit path validation is enabled, it could attempt to
262
+ // DOS by sending a large number of malicious initial packets to intentionally
263
+ // ellicit retry packets (It can do so by intentionally sending initial
264
+ // packets that ignore the retry token). To help mitigate that risk, we limit
265
+ // the number of retries we send to a given remote endpoint.
266
+ void SendRetry(const PathDescriptor& options, uint64_t now);
267
+
268
+ // Sends a version negotiation packet. This is terminal for the connection and
269
+ // is sent only when a QUIC packet is received for an unsupported QUIC
270
+ // version. It is possible that a malicious packet triggered this so we need
271
+ // to be careful not to commit too many resources.
272
+ void SendVersionNegotiation(const PathDescriptor& options, uint64_t now);
273
+
274
+ // Possibly generates and sends a stateless reset packet. This is terminal for
275
+ // the connection. It is possible that a malicious packet triggered this so we
276
+ // need to be careful not to commit too many resources.
277
+ bool SendStatelessReset(const PathDescriptor& options,
278
+ size_t source_len,
279
+ uint64_t now);
280
+
281
+ // Shutdown a connection prematurely, before a Session is created. This should
282
+ // only be called at the start of a session before the crypto keys have been
283
+ // established.
284
+ void SendImmediateConnectionClose(const PathDescriptor& options,
285
+ QuicError error,
286
+ uint64_t now);
287
+
288
+ // Listen for connections (act as a server).
289
+ void Listen(const Session::Options& options);
290
+
291
+ // Create a new client-side Session.
292
+ BaseObjectPtr<Session> Connect(
293
+ const SocketAddress& remote_address,
294
+ const Session::Options& options,
295
+ std::optional<SessionTicket> sessionTicket = std::nullopt);
296
+
297
+ // Returns the local address only if the endpoint has been bound. Before
298
+ // the endpoint is bound, or after it is closed, this will abort due to
299
+ // a failed check so it is important to check `is_closed()` before calling.
300
+ SocketAddress local_address() const;
301
+
302
+ void MemoryInfo(MemoryTracker* tracker) const override;
303
+ SET_MEMORY_INFO_NAME(Endpoint)
304
+ SET_SELF_SIZE(Endpoint)
305
+
306
+ struct Stats;
307
+ struct State;
308
+
309
+ private:
310
+ class UDP final : public MemoryRetainer {
311
+ public:
312
+ explicit UDP(Endpoint* endpoint);
313
+ ~UDP() override;
314
+
315
+ int Bind(const Endpoint::Options& config);
316
+ int Start();
317
+ void Stop();
318
+ void Close();
319
+ int Send(Packet::Ptr packet);
320
+
321
+ // Synchronous send using uv_udp_try_send. Returns the number of
322
+ // bytes sent on success, UV_EAGAIN if the socket is not writable
323
+ // or the send queue is non-empty, or another negative error code.
324
+ // The Ptr is not consumed — the caller manages the lifecycle.
325
+ int TrySend(const Packet::Ptr& packet);
326
+
327
+ // Synchronous batched send using uv_udp_try_send2 (sendmmsg).
328
+ // Takes pre-built libuv argument arrays. Returns the number of
329
+ // messages successfully sent (>= 0), or a negative error code.
330
+ int TrySendBatch(uv_buf_t* bufs[],
331
+ unsigned int nbufs[],
332
+ struct sockaddr* addrs[],
333
+ size_t count);
334
+
335
+ // Returns the local UDP socket address to which we are bound,
336
+ // or fail with an assert if we are not bound.
337
+ SocketAddress local_address() const;
338
+
339
+ bool is_bound() const;
340
+ bool is_closed() const;
341
+ bool is_closed_or_closing() const;
342
+ operator bool() const;
343
+
344
+ void Ref();
345
+ void Unref();
346
+
347
+ void MemoryInfo(node::MemoryTracker* tracker) const override;
348
+ SET_MEMORY_INFO_NAME(Endpoint::UDP)
349
+ SET_SELF_SIZE(UDP)
350
+
351
+ private:
352
+ class Impl;
353
+
354
+ BaseObjectWeakPtr<Impl> impl_;
355
+ struct Flags {
356
+ uint8_t is_bound : 1 = 0;
357
+ uint8_t is_started : 1 = 0;
358
+ uint8_t is_closed : 1 = 0;
359
+ };
360
+ Flags flags_;
361
+ };
362
+
363
+ bool is_closed() const;
364
+ bool is_closing() const;
365
+ bool is_listening() const;
366
+
367
+ bool Start();
368
+
369
+ // Destroy the endpoint if...
370
+ // * There are no sessions,
371
+ // * There are no sent packets with pending done callbacks, and
372
+ // * We're not listening for new initial packets.
373
+ void MaybeDestroy();
374
+
375
+ // Specifies the general reason the endpoint is being destroyed.
376
+ enum class CloseContext : uint8_t {
377
+ CLOSE,
378
+ BIND_FAILURE,
379
+ START_FAILURE,
380
+ RECEIVE_FAILURE,
381
+ SEND_FAILURE,
382
+ LISTEN_FAILURE,
383
+ };
384
+
385
+ void Destroy(CloseContext context = CloseContext::CLOSE, int status = 0);
386
+
387
+ // A graceful close will destroy the endpoint once all existing sessions
388
+ // have ended normally. Creating new sessions (inbound or outbound) will
389
+ // be prevented.
390
+ void CloseGracefully();
391
+
392
+ void PacketDone(int status) override;
393
+
394
+ void EmitNewSession(const BaseObjectPtr<Session>& session);
395
+ void EmitClose(CloseContext context, int status);
396
+
397
+ // JavaScript API
398
+
399
+ // Create a new Endpoint.
400
+ // @param Endpoint::Options options - Options to configure the Endpoint.
401
+ JS_METHOD(New);
402
+
403
+ // Methods on the Endpoint instance:
404
+
405
+ // Create a new client Session on this endpoint.
406
+ // @param node::SocketAddress local_address - The local address to bind to.
407
+ // @param Session::Options options - Options to configure the Session.
408
+ // @param v8::ArrayBufferView session_ticket - The session ticket to use for
409
+ // the Session.
410
+ // @param v8::ArrayBufferView remote_transport_params - The remote transport
411
+ // params.
412
+ JS_METHOD(DoConnect);
413
+
414
+ // Start listening as a QUIC server
415
+ // @param Session::Options options - Options to configure the Session.
416
+ JS_METHOD(DoListen);
417
+
418
+ // Mark the Endpoint as busy, temporarily pausing handling of new initial
419
+ // packets.
420
+ // @param bool on - If true, mark the Endpoint as busy.
421
+ JS_METHOD(MarkBusy);
422
+
423
+ // DoCloseGracefully is the signal that endpoint should close. Any packets
424
+ // that are already in the queue or in flight will be allowed to finish, but
425
+ // the EndpoingWrap will be otherwise no longer able to receive or send
426
+ // packets.
427
+ JS_METHOD(DoCloseGracefully);
428
+
429
+ JS_METHOD(DoSetSNIContexts);
430
+
431
+ // Get the local address of the Endpoint.
432
+ // @return node::SocketAddress - The local address of the Endpoint.
433
+ JS_METHOD(LocalAddress);
434
+
435
+ // Ref() causes a listening Endpoint to keep the event loop active.
436
+ JS_METHOD(Ref);
437
+
438
+ void Receive(const uint8_t* data, size_t len, const SocketAddress& from);
439
+
440
+ AliasedStruct<Stats> stats_;
441
+ AliasedStruct<State> state_;
442
+ const Options options_;
443
+ ArenaPool<Packet> packet_pool_;
444
+ UDP udp_;
445
+
446
+ // Idle timer: started when the endpoint becomes idle (not listening,
447
+ // no primary sessions). When it fires, the endpoint is destroyed.
448
+ // Stopped when a new session is added or listening begins.
449
+ TimerWrapHandle idle_timer_;
450
+
451
+ struct ServerState {
452
+ Session::Options options;
453
+ std::shared_ptr<TLSContext> tls_context;
454
+ };
455
+ // Set if/when the endpoint is configured to listen.
456
+ std::optional<ServerState> server_state_ = std::nullopt;
457
+
458
+ // Count of sessions for which this endpoint is the primary endpoint.
459
+ // Drives ref/unref and idle timer logic. The actual session-to-endpoint
460
+ // mapping is maintained by the SessionManager.
461
+ size_t primary_session_count_ = 0;
462
+
463
+ // Per-endpoint CID -> SCID mapping for peer-chosen CIDs from connection
464
+ // establishment (config.dcid, config.ocid). These are kept per-endpoint
465
+ // because peer-chosen values can collide across endpoints (e.g., a
466
+ // client's random outgoing DCID matching an incoming DCID on the server
467
+ // endpoint). Locally-generated CIDs that need cross-endpoint routing
468
+ // (preferred address, multipath) go in SessionManager::dcid_to_scid_.
469
+ //
470
+ // Endpoint::FindSession does a three-tier lookup:
471
+ // 1. SessionManager::sessions_[cid] (direct SCID match)
472
+ // 2. SessionManager::dcid_to_scid_[cid] (cross-endpoint CID)
473
+ // 3. Endpoint::dcid_to_scid_[cid] (peer-chosen CID)
474
+ // Each tier resolves to an SCID and looks up SessionManager::sessions_.
475
+ CID::Map<CID> dcid_to_scid_;
476
+
477
+ SessionManager& session_manager() const;
478
+
479
+ struct SocketAddressInfoTraits final {
480
+ struct Type final {
481
+ uint64_t timestamp;
482
+ bool validated;
483
+ TokenBucket session_creation_bucket;
484
+ };
485
+
486
+ static bool CheckExpired(const SocketAddress& address,
487
+ const Type& type,
488
+ uint64_t now);
489
+ static void Touch(const SocketAddress& address, Type* type, uint64_t now);
490
+ };
491
+
492
+ SocketAddressLRU<SocketAddressInfoTraits> addr_validation_lru_;
493
+
494
+ // Global token buckets for stateless response rate limiting.
495
+ // These cap the total server-wide rate of each response type,
496
+ // regardless of source address.
497
+ TokenBucket retry_bucket_;
498
+ TokenBucket stateless_reset_bucket_;
499
+ TokenBucket version_negotiation_bucket_;
500
+ TokenBucket immediate_close_bucket_;
501
+
502
+ // Per-IP connection counts for maxConnectionsPerHost enforcement.
503
+ // Only populated when max_connections_per_host > 0. Entries are
504
+ // added in AddSession and removed when the count reaches 0 in
505
+ // RemoveSession. The map size is bounded by the number of active
506
+ // sessions (each entry has count >= 1).
507
+ SocketAddress::IpMap<uint16_t> conn_counts_per_host_;
508
+
509
+ CloseContext close_context_ = CloseContext::CLOSE;
510
+ int close_status_ = 0;
511
+
512
+ friend class UDP;
513
+ friend class Packet;
514
+ friend class Session;
515
+ };
516
+
517
+ } // namespace node::quic
518
+
519
+ #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ #ifndef QUIC_NGTCP2_USE_OPENSSL_3_5
4
+ #define OPENSSL_NO_QUIC 1
5
+ #endif
@@ -0,0 +1,25 @@
1
+ #pragma once
2
+
3
+ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
4
+
5
+ #include <memory>
6
+ #include <optional>
7
+ #include "application.h"
8
+ #include "session.h"
9
+
10
+ namespace node::quic {
11
+
12
+ // Create an HTTP/3 Application implementation for the given session.
13
+ // Uses the Application_Options from the session's config for HTTP/3
14
+ // specific settings (qpack, max header length, etc.).
15
+ std::unique_ptr<Session::Application> CreateHttp3Application(
16
+ Session* session, const Session::Application_Options& options);
17
+
18
+ // Parse HTTP/3 specific session ticket app data. Called from
19
+ // Application::ParseTicketData() when the type byte is HTTP3.
20
+ // The data includes the type byte prefix.
21
+ std::optional<PendingTicketAppData> ParseHttp3TicketData(const uv_buf_t& data);
22
+
23
+ } // namespace node::quic
24
+
25
+ #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS