From 24774cc1a59e42e766357debab8e4560e2ce0046 Mon Sep 17 00:00:00 2001 From: Steven Date: Fri, 28 Aug 2026 13:24:32 -0400 Subject: [PATCH] tls: initialize session and SNI before connecting A synchronous custom lookup can abort the socket before tls.connect() applies the session and SNI, leaving the TLS handle unavailable. Initialize both before starting the connection so the original socket error is emitted normally. Assisted-by: Codex Signed-off-by: Steven --- lib/internal/tls/wrap.js | 13 +++++------ test/parallel/test-tls-connect-sync-lookup.js | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 test/parallel/test-tls-connect-sync-lookup.js diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js index 1c6e0577ce3d..a9f1b0742731 100644 --- a/lib/internal/tls/wrap.js +++ b/lib/internal/tls/wrap.js @@ -1898,6 +1898,12 @@ exports.connect = function connect(...args) { if (cb) tlssock.once('secureConnect', cb); + if (options.session) + tlssock.setSession(options.session); + + if (options.servername) + tlssock.setServername(options.servername); + if (!options.socket) { // If user provided the socket, it's their responsibility to manage its // connectivity. If we created one internally, we connect it. @@ -1910,13 +1916,6 @@ exports.connect = function connect(...args) { tlssock._releaseControl(); - if (options.session) - tlssock.setSession(options.session); - - if (options.servername) { - tlssock.setServername(options.servername); - } - if (options.socket) tlssock._start(); diff --git a/test/parallel/test-tls-connect-sync-lookup.js b/test/parallel/test-tls-connect-sync-lookup.js new file mode 100644 index 000000000000..172eb192bb40 --- /dev/null +++ b/test/parallel/test-tls-connect-sync-lookup.js @@ -0,0 +1,22 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const tls = require('node:tls'); + +// Verify that a synchronous lookup cannot interrupt TLS socket initialization. +const controller = new AbortController(); +const socket = tls.connect({ + host: 'example.com', + servername: 'example.com', + port: 443, + signal: controller.signal, + lookup(_hostname, _options, callback) { + callback(null, [{ address: '2001:db8::1', family: 6 }]); + controller.abort(); + }, +}); + +socket.on('error', common.mustCall());