tls: nullify `.ssl` on handle close
authorFedor Indutny <fedor@indutny.com>
Tue, 9 Feb 2016 21:00:24 +0000 (16:00 -0500)
committerMyles Borins <mborins@us.ibm.com>
Wed, 2 Mar 2016 22:01:11 +0000 (14:01 -0800)
This is an intermediate fix for an issue of accessing `TLSWrap` fields
after the parent handle was destroyed. While `close` listener cleans up
this field automatically, it can be done even earlier at the
`TLSWrap.close` call.

Proper fix is going to be submitted and landed after this one.

Fix: #5108
PR-URL: https://github.com/nodejs/node/pull/5168
Reviewed-By: Shigeki Ohtsu <ohtsu@iij.ad.jp>
lib/_tls_wrap.js
test/parallel/test-tls-regr-gh-5108.js [new file with mode: 0644]

index ca5933c..2077bf0 100644 (file)
@@ -313,6 +313,9 @@ proxiedMethods.forEach(function(name) {
 });
 
 tls_wrap.TLSWrap.prototype.close = function closeProxy(cb) {
+  if (this.owner)
+    this.owner.ssl = null;
+
   if (this._parentWrap && this._parentWrap._handle === this._parent) {
     this._parentWrap.once('close', cb);
     return this._parentWrap.destroy();
diff --git a/test/parallel/test-tls-regr-gh-5108.js b/test/parallel/test-tls-regr-gh-5108.js
new file mode 100644 (file)
index 0000000..5efcb76
--- /dev/null
@@ -0,0 +1,42 @@
+'use strict';
+const common = require('../common');
+
+if (!common.hasCrypto) {
+  console.log('1..0 # Skipped: missing crypto');
+  return;
+}
+
+const assert = require('assert');
+const tls = require('tls');
+const fs = require('fs');
+
+const options = {
+  key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
+  cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
+};
+
+
+const server = tls.createServer(options, function(s) {
+  s.end('hello');
+}).listen(common.PORT, function() {
+  const opts = {
+    port: common.PORT,
+    rejectUnauthorized: false
+  };
+  const client = tls.connect(opts, function() {
+    putImmediate(client);
+  });
+});
+
+
+function putImmediate(client) {
+  setImmediate(function() {
+    if (client.ssl) {
+      const fd = client.ssl.fd;
+      assert(!!fd);
+      putImmediate(client);
+    } else {
+      server.close();
+    }
+  });
+}