Skip to content

Commit

Permalink
tls: Closing parent socket also closes the tls sock
Browse files Browse the repository at this point in the history
PR-URL: nodejs/node-v0.x-archive#25642
Reviewed-By: jasnell - James M Snell <jasnell@gmail.com>
  • Loading branch information
dnakamura authored and jasnell committed Aug 27, 2015
1 parent a24db43 commit 0363cf4
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
4 changes: 4 additions & 0 deletions lib/_tls_wrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ function onocspresponse(resp) {
function TLSSocket(socket, options) {
// Disallow wrapping TLSSocket in TLSSocket
assert(!(socket instanceof TLSSocket));
var self = this;

net.Socket.call(this, {
handle: socket && socket._handle,
Expand All @@ -241,6 +242,9 @@ function TLSSocket(socket, options) {

if (socket) {
this._parent = socket;
socket._destroy = function(exception) {
self._destroy(exception);
};
// To prevent assertion in afterConnect()
this._connecting = socket._connecting;
}
Expand Down
18 changes: 10 additions & 8 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,12 +468,10 @@ Socket.prototype._destroy = function(exception, cb) {
return;
}

self._connecting = false;

this.readable = this.writable = false;

for (var s = this; s !== null; s = s._parent)
for (var s = this; s !== null; s = s._parent) {
timers.unenroll(s);
s._connecting = s.readable = s.writable = false;
}

debug('close');
if (this._handle) {
Expand All @@ -482,16 +480,20 @@ Socket.prototype._destroy = function(exception, cb) {
var isException = exception ? true : false;
this._handle.close(function() {
debug('emit close');
self.emit('close', isException);
for (var s = self; s !== null; s = s._parent)
s.emit('close', isException);
});
this._handle.onread = noop;
this._handle = null;
for (var s = this; s !== null; s = s._parent)
s._handle = null;
}

// we set destroyed to true before firing error callbacks in order
// to make it re-entrance safe in case Socket.prototype.destroy()
// is called within callbacks
this.destroyed = true;
for (var s = this; s !== null; s = s._parent)
s.destroyed = true;

fireErrorCallbacks();

if (this.server) {
Expand Down
55 changes: 55 additions & 0 deletions test/simple/test-tls-destroy-socket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
if (!process.versions.openssl) {
console.error('Skipping because node compiled without OpenSSL.');
process.exit(0);
}

var common = require('../common');
var assert = require('assert');
var tls = require('tls');
var fs = require('fs');

var options = {
key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem')
};

var normalSock = null;
var hasError = false;
var tlsCloseCount = 0;
var sockCloseCount = 0;

var server = tls.createServer(options, function(secureSock) {
secureSock.on('error', function() {
hasError = true;
});
secureSock.on('close', function() {
tlsCloseCount++;
});
normalSock.on('close', function() {
sockCloseCount++;
});

normalSock.destroy();
secureSock.write('Test!', function(err) {
assert(err);
});
});

server.on('connection', function(sock) {
normalSock = sock;
});

server.listen(common.PORT, function() {
var c = tls.connect(common.PORT, {rejectUnauthorized: false});
c.on('error', function() {}); // ignore socket hangup error

c.on('end', function() {
server.close();
});

process.on('exit', function() {
assert(hasError);
assert.equal(tlsCloseCount, 1);
assert.equal(sockCloseCount, 1);
});
});

0 comments on commit 0363cf4

Please sign in to comment.