network: fix premature connection closures with node 20 and above
the happy eyeballs implementation in node is buggy. ipv4 and ipv6 connections are made in parallel and whichever responds first is chosen. when there is no ipv6 (immediately errors with ENETUNREACH/EHOSTUNREACH) and when ipv4 is > 250ms, the code erroneously times out. see also https://github.com/nodejs/node/issues/54359 reproduction for those servers: const options = { hostname: 'www.cloudron.io', port: 80, path: '/', method: 'HEAD', // family: 4, // uncomment to make it work }; const req = require('http').request(options, (res) => { console.log('statusCode:', res.statusCode); res.on('data', () => {}); // drain }); req.on('socket', (socket) => console.log('Socket assigned to request', socket);); req.on('error', (e) => console.error(e)); req.end();
This commit is contained in:
@@ -13,6 +13,7 @@ const apptask = require('./apptask.js'),
|
||||
externalLdap = require('./externalldap.js'),
|
||||
fs = require('fs'),
|
||||
mailServer = require('./mailserver.js'),
|
||||
net = require('net'),
|
||||
reverseProxy = require('./reverseproxy.js'),
|
||||
safe = require('safetydance'),
|
||||
system = require('./system.js'),
|
||||
@@ -57,6 +58,11 @@ async function setupLogging() {
|
||||
process.stdout.logFile = logFile; // used by update task
|
||||
}
|
||||
|
||||
// happy eyeballs workaround. see box.js for detailed note
|
||||
async function setupNetworking() {
|
||||
net.setDefaultAutoSelectFamilyAttemptTimeout(5000);
|
||||
}
|
||||
|
||||
// this is also used as the 'uncaughtException' handler which can only have synchronous functions
|
||||
function exitSync(status) {
|
||||
if (status.error) fs.write(logFd, status.error.stack + '\n', function () {});
|
||||
@@ -70,6 +76,7 @@ const startTime = new Date();
|
||||
|
||||
async.series([
|
||||
setupLogging,
|
||||
setupNetworking,
|
||||
database.initialize,
|
||||
], async function (initError) {
|
||||
if (initError) {
|
||||
|
||||
Reference in New Issue
Block a user