Skip to content

Commit 1400796

Browse files
daeyeonjuanarbol
authored andcommitted
net,tls: pass a valid socket on tlsClientError
On the 'tlsClientError' event, the `tlsSocket` instance is passed as `closed` status. Thus, users can't get information such as `remote address`, `remoteFamily`, and so on. This adds a flag to close a socket after emitting an `error` event. Signed-off-by: Daeyeon Jeong [email protected] PR-URL: #44021 Fixes: #43963 Reviewed-By: Paolo Insogna <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent e7d30b4 commit 1400796

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

lib/_tls_wrap.js

+4
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,10 @@ function onerror(err) {
424424
if (!owner._secureEstablished) {
425425
// When handshake fails control is not yet released,
426426
// so self._tlsError will return null instead of actual error
427+
428+
// Set closing the socket after emitting an event since the socket needs to
429+
// be accessible when the `tlsClientError` event is emmited.
430+
owner._closeAfterHandlingError = true;
427431
owner.destroy(err);
428432
} else if (owner._tlsOptions?.isServer &&
429433
owner._rejectUnauthorized &&

lib/net.js

+26-7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const {
102102
uvExceptionWithHostPort,
103103
} = require('internal/errors');
104104
const { isUint8Array } = require('internal/util/types');
105+
const { queueMicrotask } = require('internal/process/task_queues');
105106
const {
106107
validateAbortSignal,
107108
validateFunction,
@@ -293,6 +294,19 @@ function initSocketHandle(self) {
293294
}
294295
}
295296

297+
function closeSocketHandle(self, isException, isCleanupPending = false) {
298+
if (self._handle) {
299+
self._handle.close(() => {
300+
debug('emit close');
301+
self.emit('close', isException);
302+
if (isCleanupPending) {
303+
self._handle.onread = noop;
304+
self._handle = null;
305+
self._sockname = null;
306+
}
307+
});
308+
}
309+
}
296310

297311
const kBytesRead = Symbol('kBytesRead');
298312
const kBytesWritten = Symbol('kBytesWritten');
@@ -341,6 +355,7 @@ function Socket(options) {
341355
this[kBuffer] = null;
342356
this[kBufferCb] = null;
343357
this[kBufferGen] = null;
358+
this._closeAfterHandlingError = false;
344359

345360
if (typeof options === 'number')
346361
options = { fd: options }; // Legacy interface.
@@ -760,15 +775,19 @@ Socket.prototype._destroy = function(exception, cb) {
760775
});
761776
if (err)
762777
this.emit('error', errnoException(err, 'reset'));
778+
} else if (this._closeAfterHandlingError) {
779+
// Enqueue closing the socket as a microtask, so that the socket can be
780+
// accessible when an `error` event is handled in the `next tick queue`.
781+
queueMicrotask(() => closeSocketHandle(this, isException, true));
763782
} else {
764-
this._handle.close(() => {
765-
debug('emit close');
766-
this.emit('close', isException);
767-
});
783+
closeSocketHandle(this, isException);
784+
}
785+
786+
if (!this._closeAfterHandlingError) {
787+
this._handle.onread = noop;
788+
this._handle = null;
789+
this._sockname = null;
768790
}
769-
this._handle.onread = noop;
770-
this._handle = null;
771-
this._sockname = null;
772791
cb(exception);
773792
} else {
774793
cb(exception);
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
const common = require('../common');
3+
const https = require('node:https');
4+
const assert = require('node:assert');
5+
6+
const server = https.createServer();
7+
8+
server.on(
9+
'tlsClientError',
10+
common.mustCall((exception, tlsSocket) => {
11+
assert.strictEqual(exception !== undefined, true);
12+
assert.strictEqual(Object.keys(tlsSocket.address()).length !== 0, true);
13+
assert.strictEqual(tlsSocket.localAddress !== undefined, true);
14+
assert.strictEqual(tlsSocket.localPort !== undefined, true);
15+
assert.strictEqual(tlsSocket.remoteAddress !== undefined, true);
16+
assert.strictEqual(tlsSocket.remoteFamily !== undefined, true);
17+
assert.strictEqual(tlsSocket.remotePort !== undefined, true);
18+
}),
19+
);
20+
21+
server.listen(0, () => {
22+
const req = https.request({
23+
hostname: '127.0.0.1',
24+
port: server.address().port,
25+
});
26+
req.on(
27+
'error',
28+
common.mustCall(() => server.close()),
29+
);
30+
req.end();
31+
});

0 commit comments

Comments
 (0)