mirror of
https://github.com/nodejs/node.git
synced 2025-08-15 13:48:44 +02:00
net: enable autoSelectFamily by default
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: https://github.com/nodejs/node/pull/46790 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
This commit is contained in:
parent
069365c5bd
commit
8b51c1a869
22 changed files with 147 additions and 94 deletions
70
lib/net.js
70
lib/net.js
|
@ -23,6 +23,7 @@
|
|||
|
||||
const {
|
||||
ArrayIsArray,
|
||||
ArrayPrototypeIncludes,
|
||||
ArrayPrototypeIndexOf,
|
||||
ArrayPrototypePush,
|
||||
Boolean,
|
||||
|
@ -97,6 +98,7 @@ const {
|
|||
ERR_INVALID_HANDLE_TYPE,
|
||||
ERR_SERVER_ALREADY_LISTEN,
|
||||
ERR_SERVER_NOT_RUNNING,
|
||||
ERR_SOCKET_CONNECTION_TIMEOUT,
|
||||
ERR_SOCKET_CLOSED,
|
||||
ERR_SOCKET_CLOSED_BEFORE_CONNECTION,
|
||||
ERR_MISSING_ARGS,
|
||||
|
@ -127,7 +129,7 @@ let cluster;
|
|||
let dns;
|
||||
let BlockList;
|
||||
let SocketAddress;
|
||||
let autoSelectFamilyDefault = getOptionValue('--enable-network-family-autoselection');
|
||||
let autoSelectFamilyDefault = getOptionValue('--network-family-autoselection');
|
||||
let autoSelectFamilyAttemptTimeoutDefault = 250;
|
||||
|
||||
const { clearTimeout, setTimeout } = require('timers');
|
||||
|
@ -1092,6 +1094,11 @@ function internalConnectMultiple(context, canceled) {
|
|||
|
||||
// All connections have been tried without success, destroy with error
|
||||
if (canceled || context.current === context.addresses.length) {
|
||||
if (context.errors.length === 0) {
|
||||
self.destroy(new ERR_SOCKET_CONNECTION_TIMEOUT());
|
||||
return;
|
||||
}
|
||||
|
||||
self.destroy(aggregateErrors(context.errors));
|
||||
return;
|
||||
}
|
||||
|
@ -1322,6 +1329,7 @@ function lookupAndConnect(self, options) {
|
|||
options,
|
||||
dnsopts,
|
||||
port,
|
||||
localAddress,
|
||||
localPort,
|
||||
autoSelectFamilyAttemptTimeout,
|
||||
);
|
||||
|
@ -1364,7 +1372,9 @@ function lookupAndConnect(self, options) {
|
|||
});
|
||||
}
|
||||
|
||||
function lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options, dnsopts, port, localPort, timeout) {
|
||||
function lookupAndConnectMultiple(
|
||||
self, async_id_symbol, lookup, host, options, dnsopts, port, localAddress, localPort, timeout,
|
||||
) {
|
||||
defaultTriggerAsyncIdScope(self[async_id_symbol], function emitLookup() {
|
||||
lookup(host, dnsopts, function emitLookup(err, addresses) {
|
||||
// It's possible we were destroyed while looking this up.
|
||||
|
@ -1385,6 +1395,7 @@ function lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options,
|
|||
// Filter addresses by only keeping the one which are either IPv4 or IPV6.
|
||||
// The first valid address determines which group has preference on the
|
||||
// alternate family sorting which happens later.
|
||||
const validAddresses = [[], []];
|
||||
const validIps = [[], []];
|
||||
let destinations;
|
||||
for (let i = 0, l = addresses.length; i < l; i++) {
|
||||
|
@ -1397,12 +1408,19 @@ function lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options,
|
|||
destinations = addressType === 6 ? { 6: 0, 4: 1 } : { 4: 0, 6: 1 };
|
||||
}
|
||||
|
||||
ArrayPrototypePush(validIps[destinations[addressType]], address);
|
||||
const destination = destinations[addressType];
|
||||
|
||||
// Only try an address once
|
||||
if (!ArrayPrototypeIncludes(validIps[destination], ip)) {
|
||||
ArrayPrototypePush(validAddresses[destination], address);
|
||||
ArrayPrototypePush(validIps[destination], ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// When no AAAA or A records are available, fail on the first one
|
||||
if (!validIps[0].length && !validIps[1].length) {
|
||||
if (!validAddresses[0].length && !validAddresses[1].length) {
|
||||
const { address: firstIp, family: firstAddressType } = addresses[0];
|
||||
|
||||
if (!isIP(firstIp)) {
|
||||
|
@ -1420,16 +1438,36 @@ function lookupAndConnectMultiple(self, async_id_symbol, lookup, host, options,
|
|||
|
||||
// Sort addresses alternating families
|
||||
const toAttempt = [];
|
||||
for (let i = 0, l = MathMax(validIps[0].length, validIps[1].length); i < l; i++) {
|
||||
if (i in validIps[0]) {
|
||||
ArrayPrototypePush(toAttempt, validIps[0][i]);
|
||||
for (let i = 0, l = MathMax(validAddresses[0].length, validAddresses[1].length); i < l; i++) {
|
||||
if (i in validAddresses[0]) {
|
||||
ArrayPrototypePush(toAttempt, validAddresses[0][i]);
|
||||
}
|
||||
if (i in validIps[1]) {
|
||||
ArrayPrototypePush(toAttempt, validIps[1][i]);
|
||||
if (i in validAddresses[1]) {
|
||||
ArrayPrototypePush(toAttempt, validAddresses[1][i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (toAttempt.length === 1) {
|
||||
debug('connect/multiple: only one address found, switching back to single connection');
|
||||
const { address: ip, family: addressType } = toAttempt[0];
|
||||
|
||||
self._unrefTimer();
|
||||
defaultTriggerAsyncIdScope(
|
||||
self[async_id_symbol],
|
||||
internalConnect,
|
||||
self,
|
||||
ip,
|
||||
port,
|
||||
addressType,
|
||||
localAddress,
|
||||
localPort,
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.autoSelectFamilyAttemptedAddresses = [];
|
||||
debug('connect/multiple: will try the following addresses', toAttempt);
|
||||
|
||||
const context = {
|
||||
socket: self,
|
||||
|
@ -1543,6 +1581,13 @@ function afterConnect(status, handle, req, readable, writable) {
|
|||
}
|
||||
|
||||
function afterConnectMultiple(context, status, handle, req, readable, writable) {
|
||||
// One of the connection has completed and correctly dispatched but after timeout, ignore this one
|
||||
if (context[kTimeoutTriggered]) {
|
||||
debug('connect/multiple: ignoring successful but timedout connection to %s:%s', req.address, req.port);
|
||||
handle.close();
|
||||
return;
|
||||
}
|
||||
|
||||
const self = context.socket;
|
||||
|
||||
// Make sure another connection is not spawned
|
||||
|
@ -1571,13 +1616,6 @@ function afterConnectMultiple(context, status, handle, req, readable, writable)
|
|||
return;
|
||||
}
|
||||
|
||||
// One of the connection has completed and correctly dispatched but after timeout, ignore this one
|
||||
if (context[kTimeoutTriggered]) {
|
||||
debug('connect/multiple: ignoring successful but timedout connection to %s:%s', req.address, req.port);
|
||||
handle.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (context.current > 1 && self[kReinitializeHandle]) {
|
||||
self[kReinitializeHandle](handle);
|
||||
handle = self._handle;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue