Skip to content

Commit

Permalink
net: rework autoSelectFamily implementation
Browse files Browse the repository at this point in the history
PR-URL: #46587
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
ShogunPanda authored and targos committed Mar 13, 2023
1 parent fc319d6 commit e0d098b
Show file tree
Hide file tree
Showing 16 changed files with 250 additions and 128 deletions.
64 changes: 43 additions & 21 deletions doc/api/net.md
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,7 @@ For TCP connections, available `options` are:
* `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`.
**Default:** initially `250`, but it can be changed at runtime using [`net.setDefaultAutoSelectFamilyAttemptTimeout(value)`][]

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

Expand Down Expand Up @@ -1526,26 +1526,6 @@ immediately initiates connection with
[`socket.connect(port[, host][, connectListener])`][`socket.connect(port)`],
then returns the `net.Socket` that starts the connection.

## `net.setDefaultAutoSelectFamily(value)`

<!-- YAML
added: v19.4.0
-->

Sets the default value of the `autoSelectFamily` option of [`socket.connect(options)`][].

* `value` {boolean} The new default value. The initial default value is `false`.

## `net.getDefaultAutoSelectFamily()`

<!-- YAML
added: v19.4.0
-->

Gets the current default value of the `autoSelectFamily` option of [`socket.connect(options)`][].

* Returns: {boolean} The current default value of the `autoSelectFamily` option.

## `net.createServer([options][, connectionListener])`

<!-- YAML
Expand Down Expand Up @@ -1640,6 +1620,47 @@ Use `nc` to connect to a Unix domain socket server:
$ nc -U /tmp/echo.sock
```

## `net.getDefaultAutoSelectFamily()`

<!-- YAML
added: v19.4.0
-->

Gets the current default value of the `autoSelectFamily` option of [`socket.connect(options)`][].

* Returns: {boolean} The current default value of the `autoSelectFamily` option.

## `net.setDefaultAutoSelectFamily(value)`

<!-- YAML
added: v19.4.0
-->

Sets the default value of the `autoSelectFamily` option of [`socket.connect(options)`][].

* `value` {boolean} The new default value. The initial default value is `false`.

## `net.getDefaultAutoSelectFamilyAttemptTimeout()`

<!-- YAML
added: REPLACEME
-->

Gets the current default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][].

* Returns: {number} The current default value of the `autoSelectFamilyAttemptTimeout` option.

## `net.setDefaultAutoSelectFamilyAttemptTimeout(value)`

<!-- YAML
added: REPLACEME
-->

Sets the default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][].

* `value` {number} The new default value, which must be a positive number. If the number is less than `10`,
the value `10` is used insted The initial default value is `250`.

## `net.isIP(input)`

<!-- YAML
Expand Down Expand Up @@ -1725,6 +1746,7 @@ net.isIPv6('fhqwhgads'); // returns false
[`net.createConnection(port, host)`]: #netcreateconnectionport-host-connectlistener
[`net.createServer()`]: #netcreateserveroptions-connectionlistener
[`net.setDefaultAutoSelectFamily(value)`]: #netsetdefaultautoselectfamilyvalue
[`net.setDefaultAutoSelectFamilyAttemptTimeout(value)`]: #netsetdefaultautoselectfamilyattempttimeoutvalue
[`new net.Socket(options)`]: #new-netsocketoptions
[`readable.setEncoding()`]: stream.md#readablesetencodingencoding
[`server.close()`]: #serverclosecallback
Expand Down
70 changes: 44 additions & 26 deletions lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +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 { kReinitializeHandle } = 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 @@ -633,14 +633,27 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) {
return res;
};

TLSSocket.prototype[kWrapConnectedHandle] = function(handle) {
this._handle = this._wrapHandle(null, handle);
TLSSocket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) {
const originalServername = this._handle.getServername();
const originalSession = this._handle.getSession();

this.handle = this._wrapHandle(null, handle);
this.ssl = this._handle;

net.Socket.prototype[kReinitializeHandle].call(this, this.handle);
this._init();

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

if (originalSession) {
this.setSession(originalSession);
}

if (originalServername) {
this.setServername(originalServername);
}
};

// This eliminates a cyclic reference to TLSWrap
Expand Down Expand Up @@ -679,6 +692,30 @@ TLSSocket.prototype._destroySSL = function _destroySSL() {
this[kIsVerified] = false;
};

function keylogNewListener(event) {
if (event !== 'keylog')
return;

// Guard against enableKeylogCallback after destroy
if (!this._handle) return;
this._handle.enableKeylogCallback();

// Remove this listener since it's no longer needed.
this.removeListener('newListener', keylogNewListener);
}

function newListener(event) {
if (event !== 'session')
return;

// Guard against enableSessionCallbacks after destroy
if (!this._handle) return;
this._handle.enableSessionCallbacks();

// Remove this listener since it's no longer needed.
this.removeListener('newListener', newListener);
}

// Constructor guts, arbitrarily factored out.
let warnOnTlsKeylog = true;
let warnOnTlsKeylogError = true;
Expand All @@ -704,18 +741,9 @@ TLSSocket.prototype._init = function(socket, wrap) {

// Only call .onkeylog if there is a keylog listener.
ssl.onkeylog = onkeylog;
this.on('newListener', keylogNewListener);

function keylogNewListener(event) {
if (event !== 'keylog')
return;

// Guard against enableKeylogCallback after destroy
if (!this._handle) return;
this._handle.enableKeylogCallback();

// Remove this listener since it's no longer needed.
this.removeListener('newListener', keylogNewListener);
if (this.listenerCount('newListener', keylogNewListener) === 0) {
this.on('newListener', keylogNewListener);
}

if (options.isServer) {
Expand Down Expand Up @@ -750,18 +778,8 @@ TLSSocket.prototype._init = function(socket, wrap) {
ssl.onnewsession = onnewsessionclient;

// Only call .onnewsession if there is a session listener.
this.on('newListener', newListener);

function newListener(event) {
if (event !== 'session')
return;

// Guard against enableSessionCallbacks after destroy
if (!this._handle) return;
this._handle.enableSessionCallbacks();

// Remove this listener since it's no longer needed.
this.removeListener('newListener', newListener);
if (this.listenerCount('newListener', newListener) === 0) {
this.on('newListener', newListener);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/internal/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function makeSyncWrite(fd) {
}

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

0 comments on commit e0d098b

Please sign in to comment.