Skip to content

Commit

Permalink
net: add autoSelectFamily and autoSelectFamilyAttemptTimeout options
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
ShogunPanda authored and danielleadams committed Jan 3, 2023
1 parent 8203c02 commit 048795d
Show file tree
Hide file tree
Showing 9 changed files with 932 additions and 7 deletions.
18 changes: 18 additions & 0 deletions doc/api/net.md
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,9 @@ behavior.
<!-- YAML
added: v0.1.90
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/44731
description: Added the `autoSelectFamily` option.
- version: v17.7.0
pr-url: https://github.com/nodejs/node/pull/41310
description: The `noDelay`, `keepAlive`, and `keepAliveInitialDelay`
Expand Down Expand Up @@ -898,6 +901,20 @@ For TCP connections, available `options` are:
**Default:** `false`.
* `keepAliveInitialDelay` {number} If set to a positive number, it sets the initial delay before
the first keepalive probe is sent on an idle socket.**Default:** `0`.
* `autoSelectFamily` {boolean}: If set to `true`, it enables a family autodetection algorithm
that loosely implements section 5 of [RFC 8305][].
The `all` option passed to lookup is set to `true` and the sockets attempts to connect to all
obtained IPv6 and IPv4 addresses, in sequence, until a connection is established.
The first returned AAAA address is tried first, then the first returned A address and so on.
Each connection attempt is given the amount of time specified by the `autoSelectFamilyAttemptTimeout`
option before timing out and trying the next address.
Ignored if the `family` option is not `0` or if `localAddress` is set.
Connection errors are not emitted if at least one connection succeeds.
**Default:** `false`.
* `autoSelectFamilyAttemptTimeout` {number}: The amount of time in milliseconds to wait
for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option.
If set to a positive integer less than `10`, then the value `10` will be used instead.
**Default:** `250`.

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

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

[IPC]: #ipc-support
[Identifying paths for IPC connections]: #identifying-paths-for-ipc-connections
[RFC 8305]: https://www.rfc-editor.org/rfc/rfc8305.txt
[Readable Stream]: stream.md#class-streamreadable
[`'close'`]: #event-close
[`'connect'`]: #event-connect
Expand Down
18 changes: 14 additions & 4 deletions lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const EE = require('events');
const net = require('net');
const tls = require('tls');
const common = require('_tls_common');
const { kWrapConnectedHandle } = require('internal/net');
const JSStreamSocket = require('internal/js_stream_socket');
const { Buffer } = require('buffer');
let debug = require('internal/util/debuglog').debuglog('tls', (fn) => {
Expand Down Expand Up @@ -598,11 +599,10 @@ TLSSocket.prototype.disableRenegotiation = function disableRenegotiation() {
this[kDisableRenegotiation] = true;
};

TLSSocket.prototype._wrapHandle = function(wrap) {
let handle;

if (wrap)
TLSSocket.prototype._wrapHandle = function(wrap, handle) {
if (!handle && wrap) {
handle = wrap._handle;
}

const options = this._tlsOptions;
if (!handle) {
Expand Down Expand Up @@ -633,6 +633,16 @@ TLSSocket.prototype._wrapHandle = function(wrap) {
return res;
};

TLSSocket.prototype[kWrapConnectedHandle] = function(handle) {
this._handle = this._wrapHandle(null, handle);
this.ssl = this._handle;
this._init();

if (this._tlsOptions.enableTrace) {
this._handle.enableTrace();
}
};

// This eliminates a cyclic reference to TLSWrap
// Ref: https://github.com/nodejs/node/commit/f7620fb96d339f704932f9bb9a0dceb9952df2d4
function defineHandleReading(socket, handle) {
Expand Down
8 changes: 8 additions & 0 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ const aggregateTwoErrors = hideStackFrames((innerError, outerError) => {
return innerError || outerError;
});

const aggregateErrors = hideStackFrames((errors, message, code) => {
// eslint-disable-next-line no-restricted-syntax
const err = new AggregateError(new SafeArrayIterator(errors), message);
err.code = errors[0]?.code;
return err;
});

// Lazily loaded
let util;
let assert;
Expand Down Expand Up @@ -893,6 +900,7 @@ function determineSpecificType(value) {
module.exports = {
AbortError,
aggregateTwoErrors,
aggregateErrors,
captureLargerStackTrace,
codes,
connResetException,
Expand Down
1 change: 1 addition & 0 deletions lib/internal/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function makeSyncWrite(fd) {
}

module.exports = {
kWrapConnectedHandle: Symbol('wrapConnectedHandle'),
isIP,
isIPv4,
isIPv6,
Expand Down
Loading

0 comments on commit 048795d

Please sign in to comment.