Skip to content

Commit 048795d

Browse files
ShogunPandadanielleadams
authored andcommitted
net: add autoSelectFamily and autoSelectFamilyAttemptTimeout options
PR-URL: #44731 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 8203c02 commit 048795d

9 files changed

+932
-7
lines changed

doc/api/net.md

+18
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,9 @@ behavior.
854854
<!-- YAML
855855
added: v0.1.90
856856
changes:
857+
- version: REPLACEME
858+
pr-url: https://github.com/nodejs/node/pull/44731
859+
description: Added the `autoSelectFamily` option.
857860
- version: v17.7.0
858861
pr-url: https://github.com/nodejs/node/pull/41310
859862
description: The `noDelay`, `keepAlive`, and `keepAliveInitialDelay`
@@ -898,6 +901,20 @@ For TCP connections, available `options` are:
898901
**Default:** `false`.
899902
* `keepAliveInitialDelay` {number} If set to a positive number, it sets the initial delay before
900903
the first keepalive probe is sent on an idle socket.**Default:** `0`.
904+
* `autoSelectFamily` {boolean}: If set to `true`, it enables a family autodetection algorithm
905+
that loosely implements section 5 of [RFC 8305][].
906+
The `all` option passed to lookup is set to `true` and the sockets attempts to connect to all
907+
obtained IPv6 and IPv4 addresses, in sequence, until a connection is established.
908+
The first returned AAAA address is tried first, then the first returned A address and so on.
909+
Each connection attempt is given the amount of time specified by the `autoSelectFamilyAttemptTimeout`
910+
option before timing out and trying the next address.
911+
Ignored if the `family` option is not `0` or if `localAddress` is set.
912+
Connection errors are not emitted if at least one connection succeeds.
913+
**Default:** `false`.
914+
* `autoSelectFamilyAttemptTimeout` {number}: The amount of time in milliseconds to wait
915+
for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option.
916+
If set to a positive integer less than `10`, then the value `10` will be used instead.
917+
**Default:** `250`.
901918

902919
For [IPC][] connections, available `options` are:
903920

@@ -1622,6 +1639,7 @@ net.isIPv6('fhqwhgads'); // returns false
16221639

16231640
[IPC]: #ipc-support
16241641
[Identifying paths for IPC connections]: #identifying-paths-for-ipc-connections
1642+
[RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.txt
16251643
[Readable Stream]: stream.md#class-streamreadable
16261644
[`'close'`]: #event-close
16271645
[`'connect'`]: #event-connect

lib/_tls_wrap.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ const EE = require('events');
5454
const net = require('net');
5555
const tls = require('tls');
5656
const common = require('_tls_common');
57+
const { kWrapConnectedHandle } = require('internal/net');
5758
const JSStreamSocket = require('internal/js_stream_socket');
5859
const { Buffer } = require('buffer');
5960
let debug = require('internal/util/debuglog').debuglog('tls', (fn) => {
@@ -598,11 +599,10 @@ TLSSocket.prototype.disableRenegotiation = function disableRenegotiation() {
598599
this[kDisableRenegotiation] = true;
599600
};
600601

601-
TLSSocket.prototype._wrapHandle = function(wrap) {
602-
let handle;
603-
604-
if (wrap)
602+
TLSSocket.prototype._wrapHandle = function(wrap, handle) {
603+
if (!handle && wrap) {
605604
handle = wrap._handle;
605+
}
606606

607607
const options = this._tlsOptions;
608608
if (!handle) {
@@ -633,6 +633,16 @@ TLSSocket.prototype._wrapHandle = function(wrap) {
633633
return res;
634634
};
635635

636+
TLSSocket.prototype[kWrapConnectedHandle] = function(handle) {
637+
this._handle = this._wrapHandle(null, handle);
638+
this.ssl = this._handle;
639+
this._init();
640+
641+
if (this._tlsOptions.enableTrace) {
642+
this._handle.enableTrace();
643+
}
644+
};
645+
636646
// This eliminates a cyclic reference to TLSWrap
637647
// Ref: https://github.com/nodejs/node/commit/f7620fb96d339f704932f9bb9a0dceb9952df2d4
638648
function defineHandleReading(socket, handle) {

lib/internal/errors.js

+8
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ const aggregateTwoErrors = hideStackFrames((innerError, outerError) => {
168168
return innerError || outerError;
169169
});
170170

171+
const aggregateErrors = hideStackFrames((errors, message, code) => {
172+
// eslint-disable-next-line no-restricted-syntax
173+
const err = new AggregateError(new SafeArrayIterator(errors), message);
174+
err.code = errors[0]?.code;
175+
return err;
176+
});
177+
171178
// Lazily loaded
172179
let util;
173180
let assert;
@@ -893,6 +900,7 @@ function determineSpecificType(value) {
893900
module.exports = {
894901
AbortError,
895902
aggregateTwoErrors,
903+
aggregateErrors,
896904
captureLargerStackTrace,
897905
codes,
898906
connResetException,

lib/internal/net.js

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ function makeSyncWrite(fd) {
6767
}
6868

6969
module.exports = {
70+
kWrapConnectedHandle: Symbol('wrapConnectedHandle'),
7071
isIP,
7172
isIPv4,
7273
isIPv6,

0 commit comments

Comments
 (0)