Commit 1ef43aea167 for nodejs

commit 1ef43aea1670900e01b64d901346ae0090cbe649
Author: Harjoth Khara <harjoth.khara@gmail.com>
Date:   Wed Oct 28 12:34:49 2026 -0700

    net,tls: fix session reuse with provided sockets

    Preserve literal IP hosts on net.Socket before connection. This keeps
    wrapped TLS sessions bound to the correct peer when tls.connect() uses a
    provided socket.

    Fixes: https://github.com/nodejs/node/issues/64402
    Signed-off-by: harjoth <harjoth.khara@gmail.com>
    Assisted-by: Codex
    PR-URL: https://github.com/nodejs/node/pull/64430
    Reviewed-By: Tim Perry <pimterry@gmail.com>

diff --git a/lib/net.js b/lib/net.js
index 5d20ea3ff45..ae7cca8ed6e 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -1887,6 +1887,8 @@ function lookupAndConnect(self, options) {

   // If host is an IP, skip performing a lookup
   const addressType = isIP(host);
+  // Retain the host before the IP fast path for TLS session identity binding.
+  self._host = host;
   if (addressType) {
     // An adopted BoundSocket needs no lookup: issue connect(2) in-tick so the
     // kernel-resolved concrete source address is observable synchronously.
@@ -1928,7 +1930,6 @@ function lookupAndConnect(self, options) {

   debug('connect: find host', host);
   debug('connect: dns options', dnsopts);
-  self._host = host;
   const lookup = options.lookup || dns.lookup;

   if (dnsopts.family !== 4 && dnsopts.family !== 6 && !localAddress && autoSelectFamily) {
diff --git a/test/parallel/test-tls-session-reuse-provided-socket.js b/test/parallel/test-tls-session-reuse-provided-socket.js
new file mode 100644
index 00000000000..e23d4424463
--- /dev/null
+++ b/test/parallel/test-tls-session-reuse-provided-socket.js
@@ -0,0 +1,99 @@
+// Flags: --expose-internals
+'use strict';
+const common = require('../common');
+if (!common.hasCrypto)
+  common.skip('missing crypto');
+
+const assert = require('assert');
+const fixtures = require('../common/fixtures');
+const { hasMultiLocalhost } = require('../common/net');
+const net = require('net');
+const tls = require('tls');
+const { once } = require('events');
+
+async function connectWithSession(
+  socket, session, maxVersion, expectedReuse = true, servername,
+) {
+  const tlsSocket = tls.connect({
+    socket,
+    session,
+    servername,
+    maxVersion,
+    rejectUnauthorized: false,
+  });
+  const close = once(tlsSocket, 'close');
+  tlsSocket.resume();
+  await once(tlsSocket, 'secureConnect');
+  assert.strictEqual(tlsSocket.isSessionReused(), expectedReuse);
+  await close;
+}
+
+async function connectAndCaptureSession(
+  port, maxVersion, host = '127.0.0.1', lookup,
+) {
+  const socket = tls.connect({
+    host,
+    lookup,
+    port,
+    maxVersion,
+    rejectUnauthorized: false,
+  });
+  const close = once(socket, 'close');
+  const sessionPromise = once(socket, 'session').then(([session]) => session);
+  socket.resume();
+  await once(socket, 'secureConnect');
+  assert.strictEqual(socket.isSessionReused(), false);
+  const session = await sessionPromise;
+  assert(Buffer.isBuffer(session));
+  await close;
+  return session;
+}
+
+async function testVersion(maxVersion) {
+  const server = tls.createServer({
+    key: fixtures.readKey('agent1-key.pem'),
+    cert: fixtures.readKey('agent1-cert.pem'),
+    minVersion: maxVersion,
+    maxVersion,
+  }, (socket) => socket.end('ok'));
+
+  server.listen(0, '0.0.0.0');
+  await once(server, 'listening');
+  const { port } = server.address();
+  const session = await connectAndCaptureSession(port, maxVersion);
+
+  let socket = net.connect({ host: '127.0.0.1', port });
+  await once(socket, 'connect');
+  await connectWithSession(socket, session, maxVersion);
+
+  socket = net.connect({ host: '127.0.0.1', port });
+  await connectWithSession(socket, session, maxVersion);
+
+  if (hasMultiLocalhost()) {
+    socket = net.connect({ host: '127.0.0.2', port });
+    await connectWithSession(socket, session, maxVersion, false);
+  }
+
+  const lookup = (_hostname, _options, callback) => {
+    if (_options.all) {
+      callback(null, [{ address: '127.0.0.1', family: 4 }]);
+    } else {
+      callback(null, '127.0.0.1', 4);
+    }
+  };
+  const hostnameSession = await connectAndCaptureSession(
+    port, maxVersion, 'localhost', lookup);
+  socket = net.connect({ host: 'localhost', port, lookup });
+  await connectWithSession(socket, hostnameSession, maxVersion);
+
+  socket = net.connect({ host: '127.0.0.1', port });
+  await connectWithSession(socket, session, maxVersion, false, 'localhost');
+
+  server.close();
+  await once(server, 'close');
+}
+
+(async function() {
+  await testVersion('TLSv1.2');
+  await testVersion('TLSv1.3');
+})().then(common.mustCall());