Skip to content

StreamWrap doesn't properly close the wrapped connection #14605

@tigerbot

Description

@tigerbot

When emitting anything other than a fully opened net.Socket object to a TLS server that stream/connection gets wrapped in a way that prevents it from being properly closed when the decrypted side of the connection is destroyed. This makes it difficult to wrap encrypted sockets to get around issue #8752 when I need to peek at the data on the connection before giving it the the TLS server.

You can see that the client connection never receives the close event in the following test case

'use strict';
function log() {
  var args = Array.prototype.slice.call(arguments);
  args.unshift(process.uptime().toFixed(3));
  console.log.apply(console, args);
}

var net = require('net');
var tls = require('tls');
var socketPair = require('socket-pair');
var tlsOpts = require('localhost.daplie.me-certificates').merge({});

var tlsServer = tls.createServer(tlsOpts, function (socket) {
  socket.on('close', function () {
    log('decrypted connection closed');
  });
  socket.write('Hello World');
  socket.destroy();
});

function wrapConn(conn, firstChunk) {
  var reader = socketPair.create(function (err, writer) {
    if (err) {
      reader.emit('error', err);
      return;
    }

    conn.pipe(writer);
    writer.pipe(conn);
    process.nextTick(function () {
      conn.unshift(firstChunk);
    });

    conn.on('close', writer.destroy.bind(writer));
    writer.on('close', conn.destroy.bind(conn));
  });

  return reader;
}

var server = net.createServer(function (conn) {
  // tlsServer.emit('connection', conn);
  conn.once('data', function (chunk) {
    // use data to determine what to do with connection.
    tlsServer.emit('connection', wrapConn(conn, chunk));
  });
});

server.listen(0, function () {
  var port = server.address().port;
  var conn = tls.connect({port: port, rejectUnauthorized: false}, function () {
    conn.on('data', function (chunk) {
      log('client received data:', chunk.toString());
    });
    conn.on('close', function () {
      log('client connection closed');
      server.close();
      socketPair.closeAll();
    });
  });
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    c++Issues and PRs that require attention from people who are familiar with C++.tlsIssues and PRs related to the tls subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions