chore: cherry-pick tls shutdown crash fix from upstream (#39928)
This commit is contained in:
parent
ba8915242a
commit
5f712fa325
5 changed files with 437 additions and 0 deletions
|
@ -44,3 +44,7 @@ chore_update_fixtures_errors_force_colors_snapshot.patch
|
||||||
fix_assert_module_in_the_renderer_process.patch
|
fix_assert_module_in_the_renderer_process.patch
|
||||||
src_cast_v8_object_getinternalfield_return_value_to_v8_value.patch
|
src_cast_v8_object_getinternalfield_return_value_to_v8_value.patch
|
||||||
fix_add_trusted_space_and_trusted_lo_space_to_the_v8_heap.patch
|
fix_add_trusted_space_and_trusted_lo_space_to_the_v8_heap.patch
|
||||||
|
tls_ensure_tls_sockets_are_closed_if_the_underlying_wrap_closes.patch
|
||||||
|
test_deflake_test-tls-socket-close.patch
|
||||||
|
net_fix_crash_due_to_simultaneous_close_shutdown_on_js_stream.patch
|
||||||
|
net_use_asserts_in_js_socket_stream_to_catch_races_in_future.patch
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tim Perry <pimterry@gmail.com>
|
||||||
|
Date: Thu, 24 Aug 2023 16:05:02 +0100
|
||||||
|
Subject: net: fix crash due to simultaneous close/shutdown on JS Stream
|
||||||
|
Sockets
|
||||||
|
|
||||||
|
A JS stream socket wraps a stream, exposing it as a socket for something
|
||||||
|
on top which needs a socket specifically (e.g. an HTTP server).
|
||||||
|
|
||||||
|
If the internal stream is closed in the same tick as the layer on top
|
||||||
|
attempts to close this stream, the race between doShutdown and doClose
|
||||||
|
results in an uncatchable exception. A similar race can happen with
|
||||||
|
doClose and doWrite.
|
||||||
|
|
||||||
|
It seems legitimate these can happen in parallel, so this resolves that
|
||||||
|
by explicitly detecting and handling that situation: if a close is in
|
||||||
|
progress, both doShutdown & doWrite allow doClose to run
|
||||||
|
finishShutdown/Write for them, cancelling the operation, without trying
|
||||||
|
to use this._handle (which will be null) in the meantime.
|
||||||
|
|
||||||
|
PR-URL: https://github.com/nodejs/node/pull/49400
|
||||||
|
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||||
|
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js
|
||||||
|
index 8bc19296620b3fd0e5487165743f0f1bc2d342e7..68e1802a63b012b59418b79a0e68de5147543a23 100644
|
||||||
|
--- a/lib/internal/js_stream_socket.js
|
||||||
|
+++ b/lib/internal/js_stream_socket.js
|
||||||
|
@@ -21,6 +21,7 @@ const { ERR_STREAM_WRAP } = require('internal/errors').codes;
|
||||||
|
const kCurrentWriteRequest = Symbol('kCurrentWriteRequest');
|
||||||
|
const kCurrentShutdownRequest = Symbol('kCurrentShutdownRequest');
|
||||||
|
const kPendingShutdownRequest = Symbol('kPendingShutdownRequest');
|
||||||
|
+const kPendingClose = Symbol('kPendingClose');
|
||||||
|
|
||||||
|
function isClosing() { return this[owner_symbol].isClosing(); }
|
||||||
|
|
||||||
|
@@ -94,6 +95,7 @@ class JSStreamSocket extends Socket {
|
||||||
|
this[kCurrentWriteRequest] = null;
|
||||||
|
this[kCurrentShutdownRequest] = null;
|
||||||
|
this[kPendingShutdownRequest] = null;
|
||||||
|
+ this[kPendingClose] = false;
|
||||||
|
this.readable = stream.readable;
|
||||||
|
this.writable = stream.writable;
|
||||||
|
|
||||||
|
@@ -135,10 +137,17 @@ class JSStreamSocket extends Socket {
|
||||||
|
this[kPendingShutdownRequest] = req;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
assert(this[kCurrentWriteRequest] === null);
|
||||||
|
assert(this[kCurrentShutdownRequest] === null);
|
||||||
|
this[kCurrentShutdownRequest] = req;
|
||||||
|
|
||||||
|
+ if (this[kPendingClose]) {
|
||||||
|
+ // If doClose is pending, the stream & this._handle are gone. We can't do
|
||||||
|
+ // anything. doClose will call finishShutdown with ECANCELED for us shortly.
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const handle = this._handle;
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
@@ -164,6 +173,13 @@ class JSStreamSocket extends Socket {
|
||||||
|
assert(this[kCurrentWriteRequest] === null);
|
||||||
|
assert(this[kCurrentShutdownRequest] === null);
|
||||||
|
|
||||||
|
+ if (this[kPendingClose]) {
|
||||||
|
+ // If doClose is pending, the stream & this._handle are gone. We can't do
|
||||||
|
+ // anything. doClose will call finishWrite with ECANCELED for us shortly.
|
||||||
|
+ this[kCurrentWriteRequest] = req; // Store req, for doClose to cancel
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
const handle = this._handle;
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
@@ -217,6 +233,8 @@ class JSStreamSocket extends Socket {
|
||||||
|
}
|
||||||
|
|
||||||
|
doClose(cb) {
|
||||||
|
+ this[kPendingClose] = true;
|
||||||
|
+
|
||||||
|
const handle = this._handle;
|
||||||
|
|
||||||
|
// When sockets of the "net" module destroyed, they will call
|
||||||
|
@@ -234,6 +252,8 @@ class JSStreamSocket extends Socket {
|
||||||
|
this.finishWrite(handle, uv.UV_ECANCELED);
|
||||||
|
this.finishShutdown(handle, uv.UV_ECANCELED);
|
||||||
|
|
||||||
|
+ this[kPendingClose] = false;
|
||||||
|
+
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
diff --git a/test/parallel/test-http2-client-connection-tunnelling.js b/test/parallel/test-http2-client-connection-tunnelling.js
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..6e04121ca71ea81f49c7f50ec11d7fac735c80a9
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/parallel/test-http2-client-connection-tunnelling.js
|
||||||
|
@@ -0,0 +1,71 @@
|
||||||
|
+'use strict';
|
||||||
|
+
|
||||||
|
+const common = require('../common');
|
||||||
|
+const fixtures = require('../common/fixtures');
|
||||||
|
+if (!common.hasCrypto)
|
||||||
|
+ common.skip('missing crypto');
|
||||||
|
+const assert = require('assert');
|
||||||
|
+const net = require('net');
|
||||||
|
+const tls = require('tls');
|
||||||
|
+const h2 = require('http2');
|
||||||
|
+
|
||||||
|
+// This test sets up an H2 proxy server, and tunnels a request over one of its streams
|
||||||
|
+// back to itself, via TLS, and then closes the TLS connection. On some Node versions
|
||||||
|
+// (v18 & v20 up to 20.5.1) the resulting JS Stream Socket fails to shutdown correctly
|
||||||
|
+// in this case, and crashes due to a null pointer in finishShutdown.
|
||||||
|
+
|
||||||
|
+const tlsOptions = {
|
||||||
|
+ key: fixtures.readKey('agent1-key.pem'),
|
||||||
|
+ cert: fixtures.readKey('agent1-cert.pem'),
|
||||||
|
+ ALPNProtocols: ['h2']
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+const netServer = net.createServer((socket) => {
|
||||||
|
+ socket.allowHalfOpen = false;
|
||||||
|
+ // ^ This allows us to trigger this reliably, but it's not strictly required
|
||||||
|
+ // for the bug and crash to happen, skipping this just fails elsewhere later.
|
||||||
|
+
|
||||||
|
+ h2Server.emit('connection', socket);
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+const h2Server = h2.createSecureServer(tlsOptions, (req, res) => {
|
||||||
|
+ res.writeHead(200);
|
||||||
|
+ res.end();
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+h2Server.on('connect', (req, res) => {
|
||||||
|
+ res.writeHead(200, {});
|
||||||
|
+ netServer.emit('connection', res.stream);
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+netServer.listen(0, common.mustCall(() => {
|
||||||
|
+ const proxyClient = h2.connect(`https://localhost:${netServer.address().port}`, {
|
||||||
|
+ rejectUnauthorized: false
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ const proxyReq = proxyClient.request({
|
||||||
|
+ ':method': 'CONNECT',
|
||||||
|
+ ':authority': 'example.com:443'
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ proxyReq.on('response', common.mustCall((response) => {
|
||||||
|
+ assert.strictEqual(response[':status'], 200);
|
||||||
|
+
|
||||||
|
+ // Create a TLS socket within the tunnel, and start sending a request:
|
||||||
|
+ const tlsSocket = tls.connect({
|
||||||
|
+ socket: proxyReq,
|
||||||
|
+ ALPNProtocols: ['h2'],
|
||||||
|
+ rejectUnauthorized: false
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ proxyReq.on('close', common.mustCall(() => {
|
||||||
|
+ proxyClient.close();
|
||||||
|
+ netServer.close();
|
||||||
|
+ }));
|
||||||
|
+
|
||||||
|
+ // Forcibly kill the TLS socket
|
||||||
|
+ tlsSocket.destroy();
|
||||||
|
+
|
||||||
|
+ // This results in an async error in affected Node versions, before the 'close' event
|
||||||
|
+ }));
|
||||||
|
+}));
|
|
@ -0,0 +1,30 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tim Perry <pimterry@gmail.com>
|
||||||
|
Date: Fri, 25 Aug 2023 14:16:35 +0100
|
||||||
|
Subject: net: use asserts in JS Socket Stream to catch races in future
|
||||||
|
|
||||||
|
PR-URL: https://github.com/nodejs/node/pull/49400
|
||||||
|
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||||
|
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/lib/internal/js_stream_socket.js b/lib/internal/js_stream_socket.js
|
||||||
|
index 68e1802a63b012b59418b79a0e68de5147543a23..70d6d03069f3f1e85e66864c6c1e6de6084f5ea6 100644
|
||||||
|
--- a/lib/internal/js_stream_socket.js
|
||||||
|
+++ b/lib/internal/js_stream_socket.js
|
||||||
|
@@ -149,6 +149,7 @@ class JSStreamSocket extends Socket {
|
||||||
|
}
|
||||||
|
|
||||||
|
const handle = this._handle;
|
||||||
|
+ assert(handle !== null);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
// Ensure that write is dispatched asynchronously.
|
||||||
|
@@ -181,6 +182,8 @@ class JSStreamSocket extends Socket {
|
||||||
|
}
|
||||||
|
|
||||||
|
const handle = this._handle;
|
||||||
|
+ assert(handle !== null);
|
||||||
|
+
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
let pending = bufs.length;
|
28
patches/node/test_deflake_test-tls-socket-close.patch
Normal file
28
patches/node/test_deflake_test-tls-socket-close.patch
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Luigi Pinca <luigipinca@gmail.com>
|
||||||
|
Date: Wed, 13 Sep 2023 08:04:39 +0200
|
||||||
|
Subject: test: deflake test-tls-socket-close
|
||||||
|
|
||||||
|
Move the check for the destroyed state of the remote socket to the inner
|
||||||
|
`setImmediate()`.
|
||||||
|
|
||||||
|
Refs: https://github.com/nodejs/node/pull/49327#issuecomment-1712525257
|
||||||
|
PR-URL: https://github.com/nodejs/node/pull/49575
|
||||||
|
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
|
||||||
|
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
|
||||||
|
|
||||||
|
diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js
|
||||||
|
index 667b291309a4c5636a2c658fa8204b32c2e4df46..70af760d53bb4ddab62c99180d505e943ec269f6 100644
|
||||||
|
--- a/test/parallel/test-tls-socket-close.js
|
||||||
|
+++ b/test/parallel/test-tls-socket-close.js
|
||||||
|
@@ -44,9 +44,9 @@ function connectClient(server) {
|
||||||
|
|
||||||
|
setImmediate(() => {
|
||||||
|
assert.strictEqual(netSocket.destroyed, true);
|
||||||
|
- assert.strictEqual(clientTlsSocket.destroyed, true);
|
||||||
|
|
||||||
|
setImmediate(() => {
|
||||||
|
+ assert.strictEqual(clientTlsSocket.destroyed, true);
|
||||||
|
assert.strictEqual(serverTlsSocket.destroyed, true);
|
||||||
|
|
||||||
|
tlsServer.close();
|
|
@ -0,0 +1,204 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tim Perry <1526883+pimterry@users.noreply.github.com>
|
||||||
|
Date: Fri, 1 Sep 2023 09:00:05 +0200
|
||||||
|
Subject: tls: ensure TLS Sockets are closed if the underlying wrap closes
|
||||||
|
|
||||||
|
This fixes a potential segfault, among various other likely-related
|
||||||
|
issues, which all occur because TLSSockets were not informed if their
|
||||||
|
underlying stream was closed in many cases.
|
||||||
|
|
||||||
|
This also significantly modifies an existing TLS test. With this change
|
||||||
|
in place, that test no longer works, as it tries to mess with internals
|
||||||
|
to trigger a race, and those internals are now cleaned up earlier. This
|
||||||
|
test has been simplified to a more general TLS shutdown test.
|
||||||
|
|
||||||
|
PR-URL: https://github.com/nodejs/node/pull/49327
|
||||||
|
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||||
|
Reviewed-By: Debadree Chatterjee <debadree333@gmail.com>
|
||||||
|
|
||||||
|
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
|
||||||
|
index 1eff3b3fba8a05d5fade43c6cb00b6621daa8c3d..5bed23e1355e5e5a1965f15ca270fb372f751d66 100644
|
||||||
|
--- a/lib/_tls_wrap.js
|
||||||
|
+++ b/lib/_tls_wrap.js
|
||||||
|
@@ -629,6 +629,9 @@ TLSSocket.prototype._wrapHandle = function(wrap, handle) {
|
||||||
|
defineHandleReading(this, handle);
|
||||||
|
|
||||||
|
this.on('close', onSocketCloseDestroySSL);
|
||||||
|
+ if (wrap) {
|
||||||
|
+ wrap.on('close', () => this.destroy());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
diff --git a/test/parallel/test-http2-socket-close.js b/test/parallel/test-http2-socket-close.js
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..02db77bcf8480c79c77175ba802f9fe10ffc4efe
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/parallel/test-http2-socket-close.js
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+'use strict';
|
||||||
|
+
|
||||||
|
+const common = require('../common');
|
||||||
|
+const fixtures = require('../common/fixtures');
|
||||||
|
+if (!common.hasCrypto)
|
||||||
|
+ common.skip('missing crypto');
|
||||||
|
+const assert = require('assert');
|
||||||
|
+const net = require('net');
|
||||||
|
+const h2 = require('http2');
|
||||||
|
+
|
||||||
|
+const tlsOptions = {
|
||||||
|
+ key: fixtures.readKey('agent1-key.pem'),
|
||||||
|
+ cert: fixtures.readKey('agent1-cert.pem'),
|
||||||
|
+ ALPNProtocols: ['h2']
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+// Create a net server that upgrades sockets to HTTP/2 manually, handles the
|
||||||
|
+// request, and then shuts down via a short socket timeout and a longer H2 session
|
||||||
|
+// timeout. This is an unconventional way to shut down a session (the underlying
|
||||||
|
+// socket closing first) but it should work - critically, it shouldn't segfault
|
||||||
|
+// (as it did until Node v20.5.1).
|
||||||
|
+
|
||||||
|
+let serverRawSocket;
|
||||||
|
+let serverH2Session;
|
||||||
|
+
|
||||||
|
+const netServer = net.createServer((socket) => {
|
||||||
|
+ serverRawSocket = socket;
|
||||||
|
+ h2Server.emit('connection', socket);
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+const h2Server = h2.createSecureServer(tlsOptions, (req, res) => {
|
||||||
|
+ res.writeHead(200);
|
||||||
|
+ res.end();
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+h2Server.on('session', (session) => {
|
||||||
|
+ serverH2Session = session;
|
||||||
|
+});
|
||||||
|
+
|
||||||
|
+netServer.listen(0, common.mustCall(() => {
|
||||||
|
+ const proxyClient = h2.connect(`https://localhost:${netServer.address().port}`, {
|
||||||
|
+ rejectUnauthorized: false
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ proxyClient.on('close', common.mustCall(() => {
|
||||||
|
+ netServer.close();
|
||||||
|
+ }));
|
||||||
|
+
|
||||||
|
+ const req = proxyClient.request({
|
||||||
|
+ ':method': 'GET',
|
||||||
|
+ ':path': '/'
|
||||||
|
+ });
|
||||||
|
+
|
||||||
|
+ req.on('response', common.mustCall((response) => {
|
||||||
|
+ assert.strictEqual(response[':status'], 200);
|
||||||
|
+
|
||||||
|
+ // Asynchronously shut down the server's connections after the response,
|
||||||
|
+ // but not in the order it typically expects:
|
||||||
|
+ setTimeout(() => {
|
||||||
|
+ serverRawSocket.destroy();
|
||||||
|
+
|
||||||
|
+ setTimeout(() => {
|
||||||
|
+ serverH2Session.close();
|
||||||
|
+ }, 10);
|
||||||
|
+ }, 10);
|
||||||
|
+ }));
|
||||||
|
+}));
|
||||||
|
diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js
|
||||||
|
index 87355cf8d7bd2d07bb0fab59491b68f3963f8809..667b291309a4c5636a2c658fa8204b32c2e4df46 100644
|
||||||
|
--- a/test/parallel/test-tls-socket-close.js
|
||||||
|
+++ b/test/parallel/test-tls-socket-close.js
|
||||||
|
@@ -8,37 +8,18 @@ const tls = require('tls');
|
||||||
|
const net = require('net');
|
||||||
|
const fixtures = require('../common/fixtures');
|
||||||
|
|
||||||
|
-// Regression test for https://github.com/nodejs/node/issues/8074
|
||||||
|
-//
|
||||||
|
-// This test has a dependency on the order in which the TCP connection is made,
|
||||||
|
-// and TLS server handshake completes. It assumes those server side events occur
|
||||||
|
-// before the client side write callback, which is not guaranteed by the TLS
|
||||||
|
-// API. It usually passes with TLS1.3, but TLS1.3 didn't exist at the time the
|
||||||
|
-// bug existed.
|
||||||
|
-//
|
||||||
|
-// Pin the test to TLS1.2, since the test shouldn't be changed in a way that
|
||||||
|
-// doesn't trigger a segfault in Node.js 7.7.3:
|
||||||
|
-// https://github.com/nodejs/node/issues/13184#issuecomment-303700377
|
||||||
|
-tls.DEFAULT_MAX_VERSION = 'TLSv1.2';
|
||||||
|
-
|
||||||
|
const key = fixtures.readKey('agent2-key.pem');
|
||||||
|
const cert = fixtures.readKey('agent2-cert.pem');
|
||||||
|
|
||||||
|
-let tlsSocket;
|
||||||
|
-// tls server
|
||||||
|
+let serverTlsSocket;
|
||||||
|
const tlsServer = tls.createServer({ cert, key }, (socket) => {
|
||||||
|
- tlsSocket = socket;
|
||||||
|
- socket.on('error', common.mustCall((error) => {
|
||||||
|
- assert.strictEqual(error.code, 'EINVAL');
|
||||||
|
- tlsServer.close();
|
||||||
|
- netServer.close();
|
||||||
|
- }));
|
||||||
|
+ serverTlsSocket = socket;
|
||||||
|
});
|
||||||
|
|
||||||
|
+// A plain net server, that manually passes connections to the TLS
|
||||||
|
+// server to be upgraded
|
||||||
|
let netSocket;
|
||||||
|
-// plain tcp server
|
||||||
|
const netServer = net.createServer((socket) => {
|
||||||
|
- // If client wants to use tls
|
||||||
|
tlsServer.emit('connection', socket);
|
||||||
|
|
||||||
|
netSocket = socket;
|
||||||
|
@@ -46,35 +27,32 @@ const netServer = net.createServer((socket) => {
|
||||||
|
connectClient(netServer);
|
||||||
|
}));
|
||||||
|
|
||||||
|
+// A client that connects, sends one message, and closes the raw connection:
|
||||||
|
function connectClient(server) {
|
||||||
|
- const tlsConnection = tls.connect({
|
||||||
|
+ const clientTlsSocket = tls.connect({
|
||||||
|
host: 'localhost',
|
||||||
|
port: server.address().port,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
|
||||||
|
- tlsConnection.write('foo', 'utf8', common.mustCall(() => {
|
||||||
|
+ clientTlsSocket.write('foo', 'utf8', common.mustCall(() => {
|
||||||
|
assert(netSocket);
|
||||||
|
netSocket.setTimeout(common.platformTimeout(10), common.mustCall(() => {
|
||||||
|
- assert(tlsSocket);
|
||||||
|
- // This breaks if TLSSocket is already managing the socket:
|
||||||
|
+ assert(serverTlsSocket);
|
||||||
|
+
|
||||||
|
netSocket.destroy();
|
||||||
|
- const interval = setInterval(() => {
|
||||||
|
- // Checking this way allows us to do the write at a time that causes a
|
||||||
|
- // segmentation fault (not always, but often) in Node.js 7.7.3 and
|
||||||
|
- // earlier. If we instead, for example, wait on the `close` event, then
|
||||||
|
- // it will not segmentation fault, which is what this test is all about.
|
||||||
|
- if (tlsSocket._handle._parent.bytesRead === 0) {
|
||||||
|
- tlsSocket.write('bar');
|
||||||
|
- clearInterval(interval);
|
||||||
|
- }
|
||||||
|
- }, 1);
|
||||||
|
+
|
||||||
|
+ setImmediate(() => {
|
||||||
|
+ assert.strictEqual(netSocket.destroyed, true);
|
||||||
|
+ assert.strictEqual(clientTlsSocket.destroyed, true);
|
||||||
|
+
|
||||||
|
+ setImmediate(() => {
|
||||||
|
+ assert.strictEqual(serverTlsSocket.destroyed, true);
|
||||||
|
+
|
||||||
|
+ tlsServer.close();
|
||||||
|
+ netServer.close();
|
||||||
|
+ });
|
||||||
|
+ });
|
||||||
|
}));
|
||||||
|
}));
|
||||||
|
- tlsConnection.on('error', (e) => {
|
||||||
|
- // Tolerate the occasional ECONNRESET.
|
||||||
|
- // Ref: https://github.com/nodejs/node/issues/13184
|
||||||
|
- if (e.code !== 'ECONNRESET')
|
||||||
|
- throw e;
|
||||||
|
- });
|
||||||
|
}
|
Loading…
Reference in a new issue