From be1f3f9cf834d3365e57b5742aa765fe0dc365c0 Mon Sep 17 00:00:00 2001 From: uzlopak Date: Thu, 22 Aug 2024 04:22:49 +0200 Subject: [PATCH] tls: wrap ssl errors in ECONNRESET --- lib/_tls_wrap.js | 14 +++++++++++++- lib/internal/errors.js | 4 ++-- test/parallel/test-tls-min-max-version.js | 12 ++++++++++-- test/parallel/test-tls-set-sigalgs.js | 10 ++++++---- test/parallel/test-tls-sni-servername.js | 2 +- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 2273b3c91b62b4..cb4c0f3d4ef459 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -464,7 +464,19 @@ function onerror(err) { // Set closing the socket after emitting an event since the socket needs to // be accessible when the `tlsClientError` event is emitted. owner._closeAfterHandlingError = true; - owner.destroy(err); + + this._hadError = true; + const error = new ConnResetException('Client network socket disconnected ' + + 'before secure TLS connection was ' + + 'established', { cause: err }); + const options = owner[kConnectOptions]; + if (options) { + error.path = options.path; + error.host = options.host; + error.port = options.port; + error.localAddress = options.localAddress; + } + owner.destroy(error); } else if (owner._tlsOptions?.isServer && owner._rejectUnauthorized && /peer did not return a certificate/.test(err.message)) { diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 95acfef204734b..c2a4a1afcdf492 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -829,8 +829,8 @@ class DNSException extends Error { } class ConnResetException extends Error { - constructor(msg) { - super(msg); + constructor(msg, opts) { + super(msg, opts); this.code = 'ECONNRESET'; } diff --git a/test/parallel/test-tls-min-max-version.js b/test/parallel/test-tls-min-max-version.js index ab351558a4c8b3..636e3b92009689 100644 --- a/test/parallel/test-tls-min-max-version.js +++ b/test/parallel/test-tls-min-max-version.js @@ -61,11 +61,19 @@ function test(cmin, cmax, cprot, smin, smax, sprot, proto, cerr, serr) { if (cerr === 'ERR_SSL_UNSUPPORTED_PROTOCOL' && pair.client.err.code === 'ERR_SSL_VERSION_TOO_LOW') cerr = 'ERR_SSL_VERSION_TOO_LOW'; - assert.strictEqual(pair.client.err.code, cerr); + if (cerr === 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION' || cerr === 'ERR_SSL_UNSUPPORTED_PROTOCOL') { + assert.strictEqual(pair.client.err.code, 'ECONNRESET'); + } else { + assert.strictEqual(pair.client.err.code, cerr); + } } if (serr) { assert(pair.server.err); - assert.strictEqual(pair.server.err.code, serr); + if (serr === 'ERR_SSL_TLSV1_ALERT_PROTOCOL_VERSION' || serr === 'ERR_SSL_UNSUPPORTED_PROTOCOL') { + assert.strictEqual(pair.server.err.code, 'ECONNRESET'); + } else { + assert.strictEqual(pair.server.err.code, serr); + } } return cleanup(); } diff --git a/test/parallel/test-tls-set-sigalgs.js b/test/parallel/test-tls-set-sigalgs.js index ffe950a0d21f86..a485dfafade4af 100644 --- a/test/parallel/test-tls-set-sigalgs.js +++ b/test/parallel/test-tls-set-sigalgs.js @@ -42,13 +42,15 @@ function test(csigalgs, ssigalgs, shared_sigalgs, cerr, serr) { ); } else { if (serr) { - assert(pair.server.err); - assert.strictEqual(pair.server.err.code, serr); + assert(pair.server.err.cause); + assert.strictEqual(pair.server.err.code, 'ECONNRESET'); + assert.strictEqual(pair.server.err.cause.code, serr); } if (cerr) { - assert(pair.client.err); - assert.strictEqual(pair.client.err.code, cerr); + assert(pair.client.err.cause); + assert.strictEqual(pair.client.err.code, 'ECONNRESET'); + assert.strictEqual(pair.client.err.cause.code, cerr); } } diff --git a/test/parallel/test-tls-sni-servername.js b/test/parallel/test-tls-sni-servername.js index 2c5785df5426c9..2e5c1657e6c914 100644 --- a/test/parallel/test-tls-sni-servername.js +++ b/test/parallel/test-tls-sni-servername.js @@ -25,7 +25,7 @@ function test(options) { const server = tls.createServer(serverOptions, common.mustNotCall()); server.on('tlsClientError', common.mustCall((err, socket) => { - assert.strictEqual(err.message, 'Invalid SNI context'); + assert.strictEqual(err.cause.message, 'Invalid SNI context'); // The `servername` should match. assert.strictEqual(socket.servername, options.servername); }));