Repository: nodejs/node
Pull request: net: always publish to 'net.client.socket' diagnostics channel

Previously, the 'net.client.socket' diagnostics channel was only published to when `net.connect()` was called. This change ensures the message is also published for the following calls:

- `net.createConnection()`
- `net.Socket#connect()`
- `tls.connect()`

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: doc/api/diagnostics_channel.md
patch: @@ -1292,9 +1292,9 @@ Emitted when a `import()` throws an error. See [`error` event][].
 
 `net.client.socket`
 
-* `socket` {net.Socket}
+* `socket` {net.Socket|tls.TLSSocket}
 
-Emitted when a new TCP or pipe client socket is created.
+Emitted when a new TCP or pipe client socket connection is created.
 
 `net.server.socket`
 

filename: lib/net.js
patch: @@ -238,11 +238,6 @@ function connect(...args) {
   debug('createConnection', normalized);
   const socket = new Socket(options);
 
-  if (netClientSocketChannel.hasSubscribers) {
-    netClientSocketChannel.publish({
-      socket,
-    });
-  }
   if (options.timeout) {
     socket.setTimeout(options.timeout);
   }
@@ -1238,6 +1233,12 @@ Socket.prototype.connect = function(...args) {
   const options = normalized[0];
   const cb = normalized[1];
 
+  if (netClientSocketChannel.hasSubscribers) {
+    netClientSocketChannel.publish({
+      socket: this,
+    });
+  }
+
   if (cb !== null) {
     this.once('connect', cb);
   }

filename: test/parallel/test-diagnostics-channel-net-client-socket-tls.js
patch: @@ -0,0 +1,32 @@
+'use strict';
+const common = require('../common');
+if (!common.hasCrypto)
+  common.skip('missing crypto');
+
+// This test ensures that the 'net.client.socket' diagnostics channel publishes
+// a message when tls.connect() is used to create a socket connection.
+
+const assert = require('assert');
+const dc = require('diagnostics_channel');
+const fixtures = require('../common/fixtures');
+const tls = require('tls');
+
+const options = {
+  key: fixtures.readKey('agent1-key.pem'),
+  cert: fixtures.readKey('agent1-cert.pem'),
+  rejectUnauthorized: false,
+};
+
+dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
+  assert.strictEqual(socket instanceof tls.TLSSocket, true);
+}));
+
+const server = tls.createServer(options, common.mustCall((socket) => {
+  socket.destroy();
+  server.close();
+}));
+
+server.listen({ port: 0 }, common.mustCall(() => {
+  const { port } = server.address();
+  tls.connect(port, options);
+}));

filename: test/parallel/test-diagnostics-channel-net.js
patch: @@ -1,5 +1,6 @@
 'use strict';
 const common = require('../common');
+const Countdown = require('../common/countdown');
 const assert = require('assert');
 const net = require('net');
 const dc = require('diagnostics_channel');
@@ -18,19 +19,23 @@ function testDiagnosticChannel(subscribers, test, after) {
 
 const testSuccessfulListen = common.mustCall(() => {
   let cb;
-  const server = net.createServer(common.mustCall((socket) => {
-    socket.destroy();
+  const netClientSocketCount = 3;
+  const countdown = new Countdown(netClientSocketCount, () => {
     server.close();
     cb();
-  }));
+  });
+  const server = net.createServer(common.mustCall((socket) => {
+    socket.destroy();
+    countdown.dec();
+  }, netClientSocketCount));
 
   dc.subscribe('net.client.socket', common.mustCall(({ socket }) => {
     assert.strictEqual(isNetSocket(socket), true);
-  }));
+  }, netClientSocketCount));
 
   dc.subscribe('net.server.socket', common.mustCall(({ socket }) => {
     assert.strictEqual(isNetSocket(socket), true);
-  }));
+  }, netClientSocketCount));
 
   testDiagnosticChannel(
     {
@@ -48,8 +53,13 @@ const testSuccessfulListen = common.mustCall(() => {
     common.mustCall((callback) => {
       cb = callback;
       server.listen({ port: 0, customOption: true }, () => {
+        // All supported ways of creating a net client socket connection.
         const { port } = server.address();
         net.connect(port);
+
+        net.createConnection(port);
+
+        new net.Socket().connect(port);
       });
     }),
     testFailingListen