Skip to content

Commit 3ba75b3

Browse files
daeyeonruyadorno
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 daeyeon.dev@gmail.com PR-URL: #44021Fixes: #43963 Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent ea48c56 commit 3ba75b3

3 files changed

Lines changed: 61 additions & 7 deletions

File tree

‎lib/_tls_wrap.js‎

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

‎lib/net.js‎

Lines changed: 26 additions & 7 deletions
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,
@@ -284,6 +285,19 @@ function initSocketHandle(self) {
284285
}
285286
}
286287

288+
functioncloseSocketHandle(self,isException,isCleanupPending=false){
289+
if(self._handle){
290+
self._handle.close(()=>{
291+
debug('emit close');
292+
self.emit('close',isException);
293+
if(isCleanupPending){
294+
self._handle.onread=noop;
295+
self._handle=null;
296+
self._sockname=null;
297+
}
298+
});
299+
}
300+
}
287301

288302
constkBytesRead=Symbol('kBytesRead');
289303
constkBytesWritten=Symbol('kBytesWritten');
@@ -332,6 +346,7 @@ function Socket(options) {
332346
this[kBuffer]=null;
333347
this[kBufferCb]=null;
334348
this[kBufferGen]=null;
349+
this._closeAfterHandlingError=false;
335350

336351
if(typeofoptions==='number')
337352
options={fd: options};// Legacy interface.
@@ -751,15 +766,19 @@ Socket.prototype._destroy = function(exception, cb) {
751766
});
752767
if(err)
753768
this.emit('error',errnoException(err,'reset'));
769+
}elseif(this._closeAfterHandlingError){
770+
// Enqueue closing the socket as a microtask, so that the socket can be
771+
// accessible when an `error` event is handled in the `next tick queue`.
772+
queueMicrotask(()=>closeSocketHandle(this,isException,true));
754773
}else{
755-
this._handle.close(()=>{
756-
debug('emit close');
757-
this.emit('close',isException);
758-
});
774+
closeSocketHandle(this,isException);
775+
}
776+
777+
if(!this._closeAfterHandlingError){
778+
this._handle.onread=noop;
779+
this._handle=null;
780+
this._sockname=null;
759781
}
760-
this._handle.onread=noop;
761-
this._handle=null;
762-
this._sockname=null;
763782
cb(exception);
764783
}else{
765784
cb(exception);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
constcommon=require('../common');
3+
consthttps=require('node:https');
4+
constassert=require('node:assert');
5+
6+
constserver=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+
constreq=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)