Skip to content

What is the recommended way to get total network bytes (including overhead) for a TLSSocket? #5111

@bliuchak

Description

@bliuchak

Node.js Version

v22.13.0

NPM Version

v10.9.2

Operating System

Darwin 24.6.0

Subsystem

tls

Description

Hello,

Could you please clarify what the recommended and stable way is to obtain the total bytes transferred for a TLSSocket (i.e., application data + TLS overhead)?

My goal is to measure the complete network footprint of an https connection, including the handshake and all TLS record overhead.

I've found that I can access the underlying net.Socket via tlsSocket._parent inside the secureConnection event listener. As shown in the reproduction below, the bytesRead/bytesWritten properties on this _parent socket correctly report the total network traffic, whereas the TLSSocket's properties only count the decrypted/unencrypted application data.

My main concern is that _parent appears to be an internal, undocumented property.

  1. Is it safe and stable to rely on tlsSocket._parent in production?
  2. If not, what is the intended public API to get this information?

Thank you!


References:

Minimal Reproduction

  1. Generate Certs:

    mkdir certs
    cd certs
    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem -subj "/C=US/ST=State/L=City/O=Organization/OU=Unit/CN=localhost"
    openssl req -newkey rsa:2048 -nodes -keyout client_key.pem -out client_req.pem -subj "/C=US/ST=State/L=City/O=Organization/OU=Unit/CN=client"
    openssl x509 -req -in client_req.pem -CA cert.pem -CAkey key.pem -CAcreateserial -out client_cert.pem -days 365
    
  2. Server Code (server.js):

    const https = require('node:https');
    const fs = require('node:fs');
    
    const server = https.createServer({
        key: fs.readFileSync('certs/key.pem'),
        cert: fs.readFileSync('certs/cert.pem'),
    }, (_, res) => {
        res.writeHead(200);
        res.end('Success!\n');
    });
    
    server.on('secureConnection', (tlsSocket) => {
        // Handshake bytes aren't included into initial bytes.
        console.log(`\nInitial bytesRead on secureConnection: ${tlsSocket.bytesRead}`);
        console.log(`Initial bytesWritten on secureConnection: ${tlsSocket.bytesWritten}`);
    
        tlsSocket.on('close', () => {
            // TLS Socket contains only application data.
            console.log(`\nTLS Socket bytesRead on close: ${tlsSocket.bytesRead}`);
            console.log(`TLS Socket bytesWritten on close: ${tlsSocket.bytesWritten}`);
    
            // Parent Socket (net.Socket) contains both TLS overhead and application data.
            console.log(`\nParent Socket bytesRead on close: ${tlsSocket._parent?.bytesRead}`);
            console.log(`Parent Socket bytesWritten on close: ${tlsSocket._parent?.bytesWritten}`);
        });
    });
    
    server.listen(8443);
  3. Client Request:

    curl --insecure https://localhost:8443
    

Output

Initial bytesRead on secureConnection: 0
Initial bytesWritten on secureConnection: 0

TLS Socket bytesRead on close: 77
TLS Socket bytesWritten on close: 150

Parent Socket bytesRead on close: 522
Parent Socket bytesWritten on close: 2185

Before You Submit

  • I have looked for issues that already exist before submitting this
  • My issue follows the guidelines in the README file, and follows the 'How to ask a good question' guide at https://stackoverflow.com/help/how-to-ask

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions