Local<Value> TLSWrap::GetSSLError(int status, int* err, const char** msg) {
EscapableHandleScope scope(env()->isolate());
+ // ssl_ is already destroyed in reading EOF by close notify alert.
+ if (ssl_ == nullptr)
+ return Local<Value>();
+
*err = SSL_get_error(ssl_, status);
switch (*err) {
case SSL_ERROR_NONE:
OnRead(UV_EOF, nullptr);
}
- if (read == -1) {
+ // We need to check whether an error occurred or the connection was
+ // shutdown cleanly (SSL_ERROR_ZERO_RETURN) even when read == 0.
+ // See iojs#1642 and SSL_read(3SSL) for details.
+ if (read <= 0) {
int err;
Local<Value> arg = GetSSLError(read, &err, nullptr);
--- /dev/null
+var common = require('../common');
+var assert = require('assert');
+
+if (!common.opensslCli) {
+ console.error('Skipping because node compiled without OpenSSL CLI.');
+ process.exit(0);
+}
+
+if (!common.hasCrypto) {
+ console.log('1..0 # Skipped: missing crypto');
+ process.exit();
+}
+
+var tls = require('tls');
+var net = require('net');
+var fs = require('fs');
+
+var success = false;
+
+function filenamePEM(n) {
+ return require('path').join(common.fixturesDir, 'keys', n + '.pem');
+}
+
+function loadPEM(n) {
+ return fs.readFileSync(filenamePEM(n));
+}
+
+var opts = {
+ key: loadPEM('agent2-key'),
+ cert: loadPEM('agent2-cert')
+};
+
+var max_iter = 20;
+var iter = 0;
+
+var server = tls.createServer(opts, function(s) {
+ s.pipe(s);
+ s.on('error', function(e) {
+ // ignore error
+ });
+});
+
+server.listen(common.PORT, function() {
+ sendClient();
+});
+
+
+function sendClient() {
+ var client = tls.connect(common.PORT, {
+ rejectUnauthorized: false
+ });
+ client.on('data', function(chunk) {
+ if (iter++ === 2) sendBADTLSRecord();
+ if (iter < max_iter) {
+ client.write('a');
+ return;
+ }
+ client.end();
+ server.close();
+ success = true;
+ });
+ client.write('a');
+ client.on('error', function(e) {
+ // ignore error
+ });
+ client.on('close', function() {
+ server.close();
+ });
+}
+
+
+function sendBADTLSRecord() {
+ var BAD_RECORD = new Buffer([0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
+ var socket = net.connect(common.PORT);
+ var client = tls.connect({
+ socket: socket,
+ rejectUnauthorized: false
+ }, function() {
+ socket.write(BAD_RECORD);
+ socket.end();
+ });
+ client.on('error', function(e) {
+ // ignore error
+ });
+}
+
+process.on('exit', function() {
+ assert(iter === max_iter);
+ assert(success);
+});