11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciif (!common.hasCrypto)
41cb0ef41Sopenharmony_ci  common.skip('missing crypto');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst tls = require('tls');
81cb0ef41Sopenharmony_ciconst net = require('net');
91cb0ef41Sopenharmony_ciconst fixtures = require('../common/fixtures');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci// Regression test for https://github.com/nodejs/node/issues/8074
121cb0ef41Sopenharmony_ci//
131cb0ef41Sopenharmony_ci// This test has a dependency on the order in which the TCP connection is made,
141cb0ef41Sopenharmony_ci// and TLS server handshake completes. It assumes those server side events occur
151cb0ef41Sopenharmony_ci// before the client side write callback, which is not guaranteed by the TLS
161cb0ef41Sopenharmony_ci// API. It usually passes with TLS1.3, but TLS1.3 didn't exist at the time the
171cb0ef41Sopenharmony_ci// bug existed.
181cb0ef41Sopenharmony_ci//
191cb0ef41Sopenharmony_ci// Pin the test to TLS1.2, since the test shouldn't be changed in a way that
201cb0ef41Sopenharmony_ci// doesn't trigger a segfault in Node.js 7.7.3:
211cb0ef41Sopenharmony_ci//   https://github.com/nodejs/node/issues/13184#issuecomment-303700377
221cb0ef41Sopenharmony_citls.DEFAULT_MAX_VERSION = 'TLSv1.2';
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciconst key = fixtures.readKey('agent2-key.pem');
251cb0ef41Sopenharmony_ciconst cert = fixtures.readKey('agent2-cert.pem');
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cilet tlsSocket;
281cb0ef41Sopenharmony_ci// tls server
291cb0ef41Sopenharmony_ciconst tlsServer = tls.createServer({ cert, key }, (socket) => {
301cb0ef41Sopenharmony_ci  tlsSocket = socket;
311cb0ef41Sopenharmony_ci  socket.on('error', common.mustCall((error) => {
321cb0ef41Sopenharmony_ci    assert.strictEqual(error.code, 'EINVAL');
331cb0ef41Sopenharmony_ci    tlsServer.close();
341cb0ef41Sopenharmony_ci    netServer.close();
351cb0ef41Sopenharmony_ci  }));
361cb0ef41Sopenharmony_ci});
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_cilet netSocket;
391cb0ef41Sopenharmony_ci// plain tcp server
401cb0ef41Sopenharmony_ciconst netServer = net.createServer((socket) => {
411cb0ef41Sopenharmony_ci  // If client wants to use tls
421cb0ef41Sopenharmony_ci  tlsServer.emit('connection', socket);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  netSocket = socket;
451cb0ef41Sopenharmony_ci}).listen(0, common.mustCall(function() {
461cb0ef41Sopenharmony_ci  connectClient(netServer);
471cb0ef41Sopenharmony_ci}));
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_cifunction connectClient(server) {
501cb0ef41Sopenharmony_ci  const tlsConnection = tls.connect({
511cb0ef41Sopenharmony_ci    host: 'localhost',
521cb0ef41Sopenharmony_ci    port: server.address().port,
531cb0ef41Sopenharmony_ci    rejectUnauthorized: false
541cb0ef41Sopenharmony_ci  });
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  tlsConnection.write('foo', 'utf8', common.mustCall(() => {
571cb0ef41Sopenharmony_ci    assert(netSocket);
581cb0ef41Sopenharmony_ci    netSocket.setTimeout(common.platformTimeout(10), common.mustCall(() => {
591cb0ef41Sopenharmony_ci      assert(tlsSocket);
601cb0ef41Sopenharmony_ci      // This breaks if TLSSocket is already managing the socket:
611cb0ef41Sopenharmony_ci      netSocket.destroy();
621cb0ef41Sopenharmony_ci      const interval = setInterval(() => {
631cb0ef41Sopenharmony_ci        // Checking this way allows us to do the write at a time that causes a
641cb0ef41Sopenharmony_ci        // segmentation fault (not always, but often) in Node.js 7.7.3 and
651cb0ef41Sopenharmony_ci        // earlier. If we instead, for example, wait on the `close` event, then
661cb0ef41Sopenharmony_ci        // it will not segmentation fault, which is what this test is all about.
671cb0ef41Sopenharmony_ci        if (tlsSocket._handle._parent.bytesRead === 0) {
681cb0ef41Sopenharmony_ci          tlsSocket.write('bar');
691cb0ef41Sopenharmony_ci          clearInterval(interval);
701cb0ef41Sopenharmony_ci        }
711cb0ef41Sopenharmony_ci      }, 1);
721cb0ef41Sopenharmony_ci    }));
731cb0ef41Sopenharmony_ci  }));
741cb0ef41Sopenharmony_ci  tlsConnection.on('error', (e) => {
751cb0ef41Sopenharmony_ci    // Tolerate the occasional ECONNRESET.
761cb0ef41Sopenharmony_ci    // Ref: https://github.com/nodejs/node/issues/13184
771cb0ef41Sopenharmony_ci    if (e.code !== 'ECONNRESET')
781cb0ef41Sopenharmony_ci      throw e;
791cb0ef41Sopenharmony_ci  });
801cb0ef41Sopenharmony_ci}
81