1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6 7const assert = require('assert'); 8const fixtures = require('../common/fixtures'); 9const tls = require('tls'); 10 11const tick = require('../common/tick'); 12const initHooks = require('./init-hooks'); 13const { checkInvocations } = require('./hook-checks'); 14 15const hooks = initHooks(); 16hooks.enable(); 17 18// TODO(@sam-github) assumes server handshake completes before client, true for 19// 1.2, not for 1.3. Might need a rewrite for TLS1.3. 20tls.DEFAULT_MAX_VERSION = 'TLSv1.2'; 21 22// 23// Creating server and listening on port 24// 25const server = tls 26 .createServer({ 27 cert: fixtures.readKey('rsa_cert.crt'), 28 key: fixtures.readKey('rsa_private.pem') 29 }) 30 .on('listening', common.mustCall(onlistening)) 31 .on('secureConnection', common.mustCall(onsecureConnection)) 32 .listen(0); 33 34let svr, client; 35function onlistening() { 36 // 37 // Creating client and connecting it to server 38 // 39 tls 40 .connect(server.address().port, { rejectUnauthorized: false }) 41 .on('secureConnect', common.mustCall(onsecureConnect)); 42 43 const as = hooks.activitiesOfTypes('TLSWRAP'); 44 assert.strictEqual(as.length, 1); 45 svr = as[0]; 46 47 assert.strictEqual(svr.type, 'TLSWRAP'); 48 assert.strictEqual(typeof svr.uid, 'number'); 49 assert.strictEqual(typeof svr.triggerAsyncId, 'number'); 50 checkInvocations(svr, { init: 1 }, 'server: when client connecting'); 51} 52 53function onsecureConnection() { 54 // 55 // Server received client connection 56 // 57 const as = hooks.activitiesOfTypes('TLSWRAP'); 58 assert.strictEqual(as.length, 2); 59 // TODO(@sam-github) This happens after onsecureConnect, with TLS1.3. 60 client = as[1]; 61 assert.strictEqual(client.type, 'TLSWRAP'); 62 assert.strictEqual(typeof client.uid, 'number'); 63 assert.strictEqual(typeof client.triggerAsyncId, 'number'); 64 65 // TODO(thlorenz) which callback did the server wrap execute that already 66 // finished as well? 67 checkInvocations(svr, { init: 1, before: 1, after: 1 }, 68 'server: when server has secure connection'); 69 70 checkInvocations(client, { init: 1, before: 2, after: 1 }, 71 'client: when server has secure connection'); 72} 73 74function onsecureConnect() { 75 // 76 // Client connected to server 77 // 78 checkInvocations(svr, { init: 1, before: 2, after: 1 }, 79 'server: when client connected'); 80 checkInvocations(client, { init: 1, before: 2, after: 2 }, 81 'client: when client connected'); 82 83 // 84 // Destroying client socket 85 // 86 this.destroy(); // This destroys client before server handshakes, with TLS1.3 87 checkInvocations(svr, { init: 1, before: 2, after: 1 }, 88 'server: when destroying client'); 89 checkInvocations(client, { init: 1, before: 2, after: 2 }, 90 'client: when destroying client'); 91 92 tick(5, tick1); 93 function tick1() { 94 checkInvocations(svr, { init: 1, before: 2, after: 2 }, 95 'server: when client destroyed'); 96 // TODO: why is client not destroyed here even after 5 ticks? 97 // or could it be that it isn't actually destroyed until 98 // the server is closed? 99 if (client.before.length < 3) { 100 tick(5, tick1); 101 return; 102 } 103 checkInvocations(client, { init: 1, before: 3, after: 3 }, 104 'client: when client destroyed'); 105 // 106 // Closing server 107 // 108 server.close(common.mustCall(onserverClosed)); 109 // No changes to invocations until server actually closed below 110 checkInvocations(svr, { init: 1, before: 2, after: 2 }, 111 'server: when closing server'); 112 checkInvocations(client, { init: 1, before: 3, after: 3 }, 113 'client: when closing server'); 114 } 115} 116 117function onserverClosed() { 118 // 119 // Server closed 120 // 121 tick(1E4, common.mustCall(() => { 122 checkInvocations(svr, { init: 1, before: 2, after: 2 }, 123 'server: when server closed'); 124 checkInvocations(client, { init: 1, before: 3, after: 3 }, 125 'client: when server closed'); 126 })); 127} 128 129process.on('exit', onexit); 130 131function onexit() { 132 hooks.disable(); 133 hooks.sanityCheck('TLSWRAP'); 134 135 checkInvocations(svr, { init: 1, before: 2, after: 2 }, 136 'server: when process exits'); 137 checkInvocations(client, { init: 1, before: 3, after: 3 }, 138 'client: when process exits'); 139} 140