• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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