File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1023,6 +1023,23 @@ added: v23.8.0
10231023
10241024When ` true ` , indicates that the endpoint should bind only to IPv6 addresses.
10251025
1026+ #### ` endpointOptions.reusePort `
1027+
1028+ <!-- YAML
1029+ added: REPLACEME
1030+ -->
1031+
1032+ * Type: {boolean}
1033+ * Default: ` false `
1034+
1035+ When ` true ` , allows multiple endpoints (across separate processes) to bind to
1036+ the same address and port. The kernel will load-balance incoming UDP datagrams
1037+ across all sockets bound with this option. This enables horizontal scaling of
1038+ QUIC servers by running multiple Node.js processes on the same port.
1039+
1040+ Supported on Linux 3.9+ and DragonFlyBSD 3.6+. On unsupported platforms, the
1041+ bind will fail with an error.
1042+
10261043#### ` endpointOptions.maxConnectionsPerHost `
10271044
10281045<!-- YAML
Original file line number Diff line number Diff line change @@ -195,6 +195,7 @@ const onSessionHandshakeChannel = dc.channel('quic.session.handshake');
195195 * @property {string|SocketAddress } [address] The local address to bind to
196196 * @property {bigint|number } [addressLRUSize] The size of the address LRU cache
197197 * @property {boolean } [ipv6Only] Use IPv6 only
198+ * @property {boolean } [reusePort] Enable SO_REUSEPORT for multi-process load balancing
198199 * @property {bigint|number } [maxConnectionsPerHost] The maximum number of connections per host
199200 * @property {bigint|number } [maxConnectionsTotal] The maximum number of total connections
200201 * @property {bigint|number } [maxRetries] The maximum number of retries
@@ -1559,6 +1560,7 @@ class QuicEndpoint {
15591560 udpTTL,
15601561 validateAddress,
15611562 ipv6Only,
1563+ reusePort,
15621564 cc,
15631565 resetTokenSecret,
15641566 tokenSecret,
@@ -1592,6 +1594,7 @@ class QuicEndpoint {
15921594 udpTTL,
15931595 validateAddress,
15941596 ipv6Only,
1597+ reusePort,
15951598 cc,
15961599 resetTokenSecret,
15971600 tokenSecret,
Original file line number Diff line number Diff line change @@ -84,6 +84,7 @@ class Packet;
8484 V (initial_max_streams_bidi, " initialMaxStreamsBidi" ) \
8585 V (initial_max_streams_uni, " initialMaxStreamsUni" ) \
8686 V (ipv6_only, " ipv6Only" ) \
87+ V (reuse_port, " reusePort" ) \
8788 V (keylog, " keylog" ) \
8889 V (keys, " keys" ) \
8990 V (logstream, " LogStream" ) \
Original file line number Diff line number Diff line change @@ -191,7 +191,7 @@ Maybe<Endpoint::Options> Endpoint::Options::From(Environment* env,
191191 !SET (max_connections_per_host) || !SET (max_connections_total) ||
192192 !SET (max_stateless_resets) || !SET (address_lru_size) ||
193193 !SET (max_retries) || !SET (validate_address) ||
194- !SET (disable_stateless_reset) || !SET (ipv6_only) ||
194+ !SET (disable_stateless_reset) || !SET (ipv6_only) || ! SET (reuse_port) ||
195195#ifdef DEBUG
196196 !SET (rx_loss) || !SET (tx_loss) ||
197197#endif
@@ -262,6 +262,7 @@ std::string Endpoint::Options::ToString() const {
262262 res += prefix + " reset token secret: " + reset_token_secret.ToString ();
263263 res += prefix + " token secret: " + token_secret.ToString ();
264264 res += prefix + " ipv6 only: " + boolToString (ipv6_only);
265+ res += prefix + " reuse port: " + boolToString (reuse_port);
265266 res += prefix +
266267 " udp receive buffer size: " + std::to_string (udp_receive_buffer_size);
267268 res +=
@@ -376,6 +377,7 @@ int Endpoint::UDP::Bind(const Options& options) {
376377 int flags = 0 ;
377378 if (options.local_address ->family () == AF_INET6 && options.ipv6_only )
378379 flags |= UV_UDP_IPV6ONLY ;
380+ if (options.reuse_port ) flags |= UV_UDP_REUSEPORT ;
379381 int err = uv_udp_bind (&impl_->handle_ , options.local_address ->data (), flags);
380382 int size;
381383
Original file line number Diff line number Diff line change @@ -140,6 +140,12 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
140140 // flag on the underlying uv_udp_t.
141141 bool ipv6_only = false ;
142142
143+ // When true, multiple endpoints (across separate processes) can bind to
144+ // the same address:port and the kernel will load-balance incoming UDP
145+ // datagrams across them. This sets the UV_UDP_REUSEPORT flag on the
146+ // underlying uv_udp_t. Supported on Linux 3.9+ and DragonFlyBSD 3.6+.
147+ bool reuse_port = false ;
148+
143149 uint32_t udp_receive_buffer_size = 0 ;
144150 uint32_t udp_send_buffer_size = 0 ;
145151
You can’t perform that action at this time.
0 commit comments