diff options
author | Fedor Indutny <fedor@indutny.com> | 2016-11-12 16:08:59 -0500 |
---|---|---|
committer | Fedor Indutny <fedor@indutny.com> | 2016-11-15 15:15:05 -0500 |
commit | 478fabf3e4eb11899e64333e8ce8125cfb74824c (patch) | |
tree | 83d8e566051b0008851b3e58479164f92bf71324 /test/parallel/test-tls-writewrap-leak.js | |
parent | a804627837c69920f34dcfa6d2331e16c64f8fd6 (diff) | |
download | android-node-v8-478fabf3e4eb11899e64333e8ce8125cfb74824c.tar.gz android-node-v8-478fabf3e4eb11899e64333e8ce8125cfb74824c.tar.bz2 android-node-v8-478fabf3e4eb11899e64333e8ce8125cfb74824c.zip |
tls: fix leak of WriteWrap+TLSWrap combination
Writing data to TLSWrap instance during handshake will result in it
being queued in `write_item_queue_`. This queue won't get cleared up
until the end of the handshake.
Technically, it gets cleared on `~TLSWrap` invocation, however this
won't ever happen because every `WriteWrap` holds a reference to the
`TLSWrap` through JS object, meaning that they are doomed to be alive
for eternity.
To breach this dreadful contract a knight shall embark from the
`close` function to kill the dragon of memory leak with his magic
spear of `destroySSL`.
`destroySSL` cleans up `write_item_queue_` and frees `SSL` structure,
both are good for memory usage.
PR-URL: https://github.com/nodejs/node/pull/9586
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'test/parallel/test-tls-writewrap-leak.js')
-rw-r--r-- | test/parallel/test-tls-writewrap-leak.js | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/test/parallel/test-tls-writewrap-leak.js b/test/parallel/test-tls-writewrap-leak.js new file mode 100644 index 0000000000..cc55192229 --- /dev/null +++ b/test/parallel/test-tls-writewrap-leak.js @@ -0,0 +1,26 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const assert = require('assert'); +const net = require('net'); +const tls = require('tls'); + +const server = net.createServer(common.mustCall((c) => { + c.destroy(); +})).listen(0, common.mustCall(() => { + const c = tls.connect({ port: server.address().port }); + c.on('error', () => { + // Otherwise `.write()` callback won't be invoked. + c.destroyed = false; + }); + + c.write('hello', common.mustCall((err) => { + assert.equal(err.code, 'ECANCELED'); + server.close(); + })); +})); |