Skip to content

Commit d12d8cd

Browse files
authored
net: rework autoSelectFamily implementation
PR-URL: #46587 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 2636b55 commit d12d8cd

16 files changed

+250
-128
lines changed

doc/api/net.md

+43-21
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ For TCP connections, available `options` are:
941941
* `autoSelectFamilyAttemptTimeout` {number}: The amount of time in milliseconds to wait
942942
for a connection attempt to finish before trying the next address when using the `autoSelectFamily` option.
943943
If set to a positive integer less than `10`, then the value `10` will be used instead.
944-
**Default:** `250`.
944+
**Default:** initially `250`, but it can be changed at runtime using [`net.setDefaultAutoSelectFamilyAttemptTimeout(value)`][]
945945

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

@@ -1528,26 +1528,6 @@ immediately initiates connection with
15281528
[`socket.connect(port[, host][, connectListener])`][`socket.connect(port)`],
15291529
then returns the `net.Socket` that starts the connection.
15301530

1531-
## `net.setDefaultAutoSelectFamily(value)`
1532-
1533-
<!-- YAML
1534-
added: v19.4.0
1535-
-->
1536-
1537-
Sets the default value of the `autoSelectFamily` option of [`socket.connect(options)`][].
1538-
1539-
* `value` {boolean} The new default value. The initial default value is `false`.
1540-
1541-
## `net.getDefaultAutoSelectFamily()`
1542-
1543-
<!-- YAML
1544-
added: v19.4.0
1545-
-->
1546-
1547-
Gets the current default value of the `autoSelectFamily` option of [`socket.connect(options)`][].
1548-
1549-
* Returns: {boolean} The current default value of the `autoSelectFamily` option.
1550-
15511531
## `net.createServer([options][, connectionListener])`
15521532

15531533
<!-- YAML
@@ -1642,6 +1622,47 @@ Use `nc` to connect to a Unix domain socket server:
16421622
$ nc -U /tmp/echo.sock
16431623
```
16441624

1625+
## `net.getDefaultAutoSelectFamily()`
1626+
1627+
<!-- YAML
1628+
added: v19.4.0
1629+
-->
1630+
1631+
Gets the current default value of the `autoSelectFamily` option of [`socket.connect(options)`][].
1632+
1633+
* Returns: {boolean} The current default value of the `autoSelectFamily` option.
1634+
1635+
## `net.setDefaultAutoSelectFamily(value)`
1636+
1637+
<!-- YAML
1638+
added: v19.4.0
1639+
-->
1640+
1641+
Sets the default value of the `autoSelectFamily` option of [`socket.connect(options)`][].
1642+
1643+
* `value` {boolean} The new default value. The initial default value is `false`.
1644+
1645+
## `net.getDefaultAutoSelectFamilyAttemptTimeout()`
1646+
1647+
<!-- YAML
1648+
added: REPLACEME
1649+
-->
1650+
1651+
Gets the current default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][].
1652+
1653+
* Returns: {number} The current default value of the `autoSelectFamilyAttemptTimeout` option.
1654+
1655+
## `net.setDefaultAutoSelectFamilyAttemptTimeout(value)`
1656+
1657+
<!-- YAML
1658+
added: REPLACEME
1659+
-->
1660+
1661+
Sets the default value of the `autoSelectFamilyAttemptTimeout` option of [`socket.connect(options)`][].
1662+
1663+
* `value` {number} The new default value, which must be a positive number. If the number is less than `10`,
1664+
the value `10` is used insted The initial default value is `250`.
1665+
16451666
## `net.isIP(input)`
16461667

16471668
<!-- YAML
@@ -1727,6 +1748,7 @@ net.isIPv6('fhqwhgads'); // returns false
17271748
[`net.createConnection(port, host)`]: #netcreateconnectionport-host-connectlistener
17281749
[`net.createServer()`]: #netcreateserveroptions-connectionlistener
17291750
[`net.setDefaultAutoSelectFamily(value)`]: #netsetdefaultautoselectfamilyvalue
1751+
[`net.setDefaultAutoSelectFamilyAttemptTimeout(value)`]: #netsetdefaultautoselectfamilyattempttimeoutvalue
17301752
[`new net.Socket(options)`]: #new-netsocketoptions
17311753
[`readable.setEncoding()`]: stream.md#readablesetencodingencoding
17321754
[`server.close()`]: #serverclosecallback

lib/_tls_wrap.js

+44-26
Original file line numberDiff line numberDiff line change
@@ -54,7 +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');
57+
const { kReinitializeHandle } = require('internal/net');
5858
const JSStreamSocket = require('internal/js_stream_socket');
5959
const { Buffer } = require('buffer');
6060
let debug = require('internal/util/debuglog').debuglog('tls', (fn) => {
@@ -633,14 +633,27 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) {
633633
return res;
634634
};
635635

636-
TLSSocket.prototype[kWrapConnectedHandle] = function(handle) {
637-
this._handle = this._wrapHandle(null, handle);
636+
TLSSocket.prototype[kReinitializeHandle] = function reinitializeHandle(handle) {
637+
const originalServername = this._handle.getServername();
638+
const originalSession = this._handle.getSession();
639+
640+
this.handle = this._wrapHandle(null, handle);
638641
this.ssl = this._handle;
642+
643+
net.Socket.prototype[kReinitializeHandle].call(this, this.handle);
639644
this._init();
640645

641646
if (this._tlsOptions.enableTrace) {
642647
this._handle.enableTrace();
643648
}
649+
650+
if (originalSession) {
651+
this.setSession(originalSession);
652+
}
653+
654+
if (originalServername) {
655+
this.setServername(originalServername);
656+
}
644657
};
645658

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

695+
function keylogNewListener(event) {
696+
if (event !== 'keylog')
697+
return;
698+
699+
// Guard against enableKeylogCallback after destroy
700+
if (!this._handle) return;
701+
this._handle.enableKeylogCallback();
702+
703+
// Remove this listener since it's no longer needed.
704+
this.removeListener('newListener', keylogNewListener);
705+
}
706+
707+
function newListener(event) {
708+
if (event !== 'session')
709+
return;
710+
711+
// Guard against enableSessionCallbacks after destroy
712+
if (!this._handle) return;
713+
this._handle.enableSessionCallbacks();
714+
715+
// Remove this listener since it's no longer needed.
716+
this.removeListener('newListener', newListener);
717+
}
718+
682719
// Constructor guts, arbitrarily factored out.
683720
let warnOnTlsKeylog = true;
684721
let warnOnTlsKeylogError = true;
@@ -704,18 +741,9 @@ TLSSocket.prototype._init = function(socket, wrap) {
704741

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

709-
function keylogNewListener(event) {
710-
if (event !== 'keylog')
711-
return;
712-
713-
// Guard against enableKeylogCallback after destroy
714-
if (!this._handle) return;
715-
this._handle.enableKeylogCallback();
716-
717-
// Remove this listener since it's no longer needed.
718-
this.removeListener('newListener', keylogNewListener);
745+
if (this.listenerCount('newListener', keylogNewListener) === 0) {
746+
this.on('newListener', keylogNewListener);
719747
}
720748

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

752780
// Only call .onnewsession if there is a session listener.
753-
this.on('newListener', newListener);
754-
755-
function newListener(event) {
756-
if (event !== 'session')
757-
return;
758-
759-
// Guard against enableSessionCallbacks after destroy
760-
if (!this._handle) return;
761-
this._handle.enableSessionCallbacks();
762-
763-
// Remove this listener since it's no longer needed.
764-
this.removeListener('newListener', newListener);
781+
if (this.listenerCount('newListener', newListener) === 0) {
782+
this.on('newListener', newListener);
765783
}
766784
}
767785

lib/internal/net.js

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

6969
module.exports = {
70-
kWrapConnectedHandle: Symbol('wrapConnectedHandle'),
70+
kReinitializeHandle: Symbol('reinitializeHandle'),
7171
isIP,
7272
isIPv4,
7373
isIPv6,

0 commit comments

Comments
 (0)