Skip to content

Commit 121ed91

Browse files
committed
tls: fix tls.connect() resource leak
The 'secureConnect' event listener was attached with .on(), which blocked it from getting garbage collected. Use .once() instead. Fixes #4308.
1 parent 4cb17cb commit 121ed91

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

lib/tls.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ exports.connect = function(/* [port, host], options, cb */) {
12521252

12531253
var cleartext = pipe(pair, socket);
12541254
if (cb) {
1255-
cleartext.on('secureConnect', cb);
1255+
cleartext.once('secureConnect', cb);
12561256
}
12571257

12581258
if (!options.socket) {
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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+
// Flags: --expose-gc
23+
24+
var common = require('../common');
25+
var assert = require('assert');
26+
var tls = require('tls');
27+
var fs = require('fs');
28+
29+
assert(typeof gc === 'function', 'Run this test with --expose-gc');
30+
31+
tls.createServer({
32+
cert: fs.readFileSync(common.fixturesDir + '/test_cert.pem'),
33+
key: fs.readFileSync(common.fixturesDir + '/test_key.pem')
34+
}).listen(common.PORT);
35+
36+
(function() {
37+
// 2**26 == 64M entries
38+
for (var i = 0, junk = [123.456]; i < 26; ++i) junk = junk.concat(junk);
39+
40+
var options = { rejectUnauthorized: false };
41+
tls.connect(common.PORT, '127.0.0.1', options, function() {
42+
assert(junk.length != 0); // keep reference alive
43+
setTimeout(done, 10);
44+
gc();
45+
});
46+
})();
47+
48+
function done() {
49+
var before = process.memoryUsage().rss;
50+
gc();
51+
var after = process.memoryUsage().rss;
52+
var reclaimed = (before - after) / 1024;
53+
console.log('%d kB reclaimed', reclaimed);
54+
assert(reclaimed > 256 * 1024); // it's more like 512M on x64
55+
process.exit();
56+
}

0 commit comments

Comments
 (0)