tls,http2: handle writes after SSL destroy more gracefully
This might otherwise result in a hard crash when trying to write to a socket after a sudden disconnect. Note that the test here uses an aborted `h2load` run to create the failing requests; That’s far from ideal, but it provides a reasonably reliably reproduction at this point. PR-URL: https://github.com/nodejs/node/pull/18987 Fixes: https://github.com/nodejs/node/issues/18973 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
This commit is contained in:
parent
b24d65dcdc
commit
0c25cdf39a
@ -553,7 +553,12 @@ int TLSWrap::DoWrite(WriteWrap* w,
|
||||
size_t count,
|
||||
uv_stream_t* send_handle) {
|
||||
CHECK_EQ(send_handle, nullptr);
|
||||
CHECK_NE(ssl_, nullptr);
|
||||
|
||||
if (ssl_ == nullptr) {
|
||||
ClearError();
|
||||
error_ = "Write after DestroySSL";
|
||||
return UV_EPROTO;
|
||||
}
|
||||
|
||||
bool empty = true;
|
||||
|
||||
@ -593,12 +598,6 @@ int TLSWrap::DoWrite(WriteWrap* w,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssl_ == nullptr) {
|
||||
ClearError();
|
||||
error_ = "Write after DestroySSL";
|
||||
return UV_EPROTO;
|
||||
}
|
||||
|
||||
crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
|
||||
|
||||
int written = 0;
|
||||
|
32
test/parallel/test-http2-tls-disconnect.js
Normal file
32
test/parallel/test-http2-tls-disconnect.js
Normal file
@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
|
||||
const child_process = require('child_process');
|
||||
const http2 = require('http2');
|
||||
const fs = require('fs');
|
||||
|
||||
const key = fixtures.readKey('agent8-key.pem', 'binary');
|
||||
const cert = fixtures.readKey('agent8-cert.pem', 'binary');
|
||||
|
||||
const server = http2.createSecureServer({ key, cert }, (request, response) => {
|
||||
fs.createReadStream(process.execPath).pipe(response);
|
||||
});
|
||||
|
||||
// This should be doable with a reproduction purely written in Node;
|
||||
// that just requires somebody to take the time and actually do it.
|
||||
server.listen(0, () => {
|
||||
const proc = child_process.spawn('h2load', [
|
||||
'-n', '1000',
|
||||
`https://localhost:${server.address().port}/`
|
||||
]);
|
||||
proc.on('error', (err) => {
|
||||
if (err.code === 'ENOENT')
|
||||
common.skip('no h2load');
|
||||
});
|
||||
proc.on('exit', () => server.close());
|
||||
setTimeout(() => proc.kill(2), 100);
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user