Commit 9827749beea for nodejs
commit 9827749beea94be479943e462e5bd374a74aff7a
Author: Steven <steven@ceriously.com>
Date: Fri Sep 25 09:50:11 2026 -0400
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 <steven@ceriously.com>
PR-URL: https://github.com/nodejs/node/pull/65624
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js
index a8d549a1aad..60c1634b02b 100644
--- a/lib/internal/tls/wrap.js
+++ b/lib/internal/tls/wrap.js
@@ -1912,6 +1912,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.
@@ -1924,13 +1930,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 00000000000..172eb192bb4
--- /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());