diff options
author | Daeyeon Jeong <daeyeon.dev@gmail.com> | 2022-08-01 09:37:45 +0300 |
---|---|---|
committer | Juan José Arboleda <soyjuanarbol@gmail.com> | 2022-10-11 22:45:21 +0300 |
commit | 1400796cefa83502b5e7a23251f68972922488df (patch) | |
tree | 417d4a6ce4fb6a00245623a40dbc781213b5e236 /lib | |
parent | e7d30b4b491cad0430a96fef20c602496a1597a8 (diff) |
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 daeyeon.dev@gmail.com
PR-URL: https://github.com/nodejs/node/pull/44021
Fixes: https://github.com/nodejs/node/issues/43963
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/_tls_wrap.js | 4 | ||||
-rw-r--r-- | lib/net.js | 33 |
2 files changed, 30 insertions, 7 deletions
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index eda0c0987f9..37ec68e880e 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -424,6 +424,10 @@ function onerror(err) { if (!owner._secureEstablished) { // When handshake fails control is not yet released, // so self._tlsError will return null instead of actual error + + // Set closing the socket after emitting an event since the socket needs to + // be accessible when the `tlsClientError` event is emmited. + owner._closeAfterHandlingError = true; owner.destroy(err); } else if (owner._tlsOptions?.isServer && owner._rejectUnauthorized && diff --git a/lib/net.js b/lib/net.js index 6b5ce6f91eb..7ae9ede39bb 100644 --- a/lib/net.js +++ b/lib/net.js @@ -102,6 +102,7 @@ const { uvExceptionWithHostPort, } = require('internal/errors'); const { isUint8Array } = require('internal/util/types'); +const { queueMicrotask } = require('internal/process/task_queues'); const { validateAbortSignal, validateFunction, @@ -293,6 +294,19 @@ function initSocketHandle(self) { } } +function closeSocketHandle(self, isException, isCleanupPending = false) { + if (self._handle) { + self._handle.close(() => { + debug('emit close'); + self.emit('close', isException); + if (isCleanupPending) { + self._handle.onread = noop; + self._handle = null; + self._sockname = null; + } + }); + } +} const kBytesRead = Symbol('kBytesRead'); const kBytesWritten = Symbol('kBytesWritten'); @@ -341,6 +355,7 @@ function Socket(options) { this[kBuffer] = null; this[kBufferCb] = null; this[kBufferGen] = null; + this._closeAfterHandlingError = false; if (typeof options === 'number') options = { fd: options }; // Legacy interface. @@ -760,15 +775,19 @@ Socket.prototype._destroy = function(exception, cb) { }); if (err) this.emit('error', errnoException(err, 'reset')); + } else if (this._closeAfterHandlingError) { + // Enqueue closing the socket as a microtask, so that the socket can be + // accessible when an `error` event is handled in the `next tick queue`. + queueMicrotask(() => closeSocketHandle(this, isException, true)); } else { - this._handle.close(() => { - debug('emit close'); - this.emit('close', isException); - }); + closeSocketHandle(this, isException); + } + + if (!this._closeAfterHandlingError) { + this._handle.onread = noop; + this._handle = null; + this._sockname = null; } - this._handle.onread = noop; - this._handle = null; - this._sockname = null; cb(exception); } else { cb(exception); |