Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit bada87b

Browse files
indutnytrevnorris
authored andcommitted
net: unref timer in parent sockets
`TLSSocket` wraps the original `net.Socket`, but writes/reads to/from `TLSSocket` do not touch the timers of original `net.Socket`. Introduce `socket._parent` property, and iterate through all parents to unref timers and prevent timeout event on original `net.Socket`. Fix: #9242 PR-URL: nodejs/node#891 Reviewed-By: Colin Ihrig <[email protected]>
1 parent b3aa876 commit bada87b

File tree

3 files changed

+75
-9
lines changed

3 files changed

+75
-9
lines changed

lib/_tls_wrap.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,11 @@ function TLSSocket(socket, options) {
236236
writable: false
237237
});
238238

239-
// To prevent assertion in afterConnect()
240-
if (socket)
239+
if (socket) {
240+
this._parent = socket;
241+
// To prevent assertion in afterConnect()
241242
this._connecting = socket._connecting;
243+
}
242244

243245
this._tlsOptions = options;
244246
this._secureEstablished = false;

lib/net.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ function Socket(options) {
140140
this._connecting = false;
141141
this._hadError = false;
142142
this._handle = null;
143+
this._parent = null;
143144
this._host = null;
144145

145146
if (util.isNumber(options))
@@ -199,6 +200,13 @@ function Socket(options) {
199200
}
200201
util.inherits(Socket, stream.Duplex);
201202

203+
204+
Socket.prototype._unrefTimer = function unrefTimer() {
205+
for (var s = this; s !== null; s = s._parent)
206+
timers._unrefActive(s);
207+
};
208+
209+
202210
// the user has called .end(), and all the bytes have been
203211
// sent out to the other side.
204212
// If allowHalfOpen is false, or if the readable side has
@@ -464,7 +472,8 @@ Socket.prototype._destroy = function(exception, cb) {
464472

465473
this.readable = this.writable = false;
466474

467-
timers.unenroll(this);
475+
for (var s = this; s !== null; s = s._parent)
476+
timers.unenroll(s);
468477

469478
debug('close');
470479
if (this._handle) {
@@ -509,7 +518,7 @@ function onread(nread, buffer) {
509518
var self = handle.owner;
510519
assert(handle === self._handle, 'handle != self._handle');
511520

512-
timers._unrefActive(self);
521+
self._unrefTimer();
513522

514523
debug('onread', nread);
515524

@@ -641,7 +650,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
641650
this._pendingData = null;
642651
this._pendingEncoding = '';
643652

644-
timers._unrefActive(this);
653+
this._unrefTimer();
645654

646655
if (!this._handle) {
647656
this._destroy(new Error('This socket is closed.'), cb);
@@ -769,7 +778,7 @@ function afterWrite(status, handle, req, err) {
769778
return;
770779
}
771780

772-
timers._unrefActive(self);
781+
self._unrefTimer();
773782

774783
if (self !== process.stderr && self !== process.stdout)
775784
debug('afterWrite call cb');
@@ -872,7 +881,7 @@ Socket.prototype.connect = function(options, cb) {
872881
self.once('connect', cb);
873882
}
874883

875-
timers._unrefActive(this);
884+
this._unrefTimer();
876885

877886
self._connecting = true;
878887
self.writable = true;
@@ -924,7 +933,7 @@ Socket.prototype.connect = function(options, cb) {
924933
self._destroy();
925934
});
926935
} else {
927-
timers._unrefActive(self);
936+
self._unrefTimer();
928937
connect(self,
929938
ip,
930939
port,
@@ -969,7 +978,7 @@ function afterConnect(status, handle, req, readable, writable) {
969978
if (status == 0) {
970979
self.readable = readable;
971980
self.writable = writable;
972-
timers._unrefActive(self);
981+
self._unrefTimer();
973982

974983
self.emit('connect');
975984

test/simple/test-tls-wrap-timeout.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright Joyent, Inc. and other Node contributors.
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a
4+
// copy of this software and associated documentation files (the
5+
// "Software"), to deal in the Software without restriction, including
6+
// without limitation the rights to use, copy, modify, merge, publish,
7+
// distribute, sublicense, and/or sell copies of the Software, and to permit
8+
// persons to whom the Software is furnished to do so, subject to the
9+
// following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included
12+
// in all copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15+
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17+
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18+
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20+
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21+
22+
if (!process.versions.openssl) process.exit();
23+
24+
var common = require('../common');
25+
var assert = require('assert');
26+
var net = require('net');
27+
var tls = require('tls');
28+
var fs = require('fs');
29+
30+
var options = {
31+
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
32+
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
33+
};
34+
35+
var server = tls.createServer(options, function(c) {
36+
setTimeout(function() {
37+
c.write('hello');
38+
setTimeout(function() {
39+
c.destroy();
40+
server.close();
41+
}, 75);
42+
}, 75);
43+
});
44+
45+
server.listen(common.PORT, function() {
46+
var socket = net.connect(common.PORT, function() {
47+
socket.setTimeout(120, assert.fail);
48+
49+
var tsocket = tls.connect({
50+
socket: socket,
51+
rejectUnauthorized: false
52+
});
53+
tsocket.resume();
54+
});
55+
});

0 commit comments

Comments
 (0)