Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling server.closeConnections() or server.close(true) prevents stats collection #555

Closed
marcplouhinec opened this issue Oct 11, 2024 · 4 comments
Labels
t-platform Issues with this label are in the ownership of the platform team. validated Issues that are resolved and their solutions fulfill the acceptance criteria.

Comments

@marcplouhinec
Copy link
Contributor

I’m using proxy-chain to monitor proxy traffic consumption, but I noticed that I was undercounting the number of transmitted bytes.

Before starting to use the proxy, I register a listener on the connectionClosed event like this:

server.on('connectionClosed', ({ connectionId, stats }) => {
    if (stats) {
        // Process statistics
    }
});

After finishing with the proxy, I call server.close(true). However, when the connectionClosed events are fired, the stats are always undefined.

Upon investigating the implementation of server.close(), I found that it calls server.closeConnections() when the first parameter is true.

The issue appears to be caused by this line in server.ts, line 636:

    closeConnections(): void {
        this.log(null, 'Closing pending sockets');

        for (const socket of this.connections.values()) {
            socket.destroy();
        }

        this.connections.clear(); // <-- The problem

        this.log(null, `Destroyed ${this.connections.size} pending sockets`);
    }

Unlike the closeConnection(connectionId: number) method just above in the same file, this function clears the this.connections map. I’m not sure why this line was added, or if removing it has any negative side effects, but typically each entry in this map is removed by the socket's close event listener, as seen in server.registerConnection() line 215:

    registerConnection(socket: Socket): void {
        // ...

        socket.on('close', () => {
            this.emit('connectionClosed', {
                connectionId: unique,
                stats: this.getConnectionStats(unique), // <--  Stats are obtained here
            });

            this.connections.delete(unique); // <-- Connection is deleted after emitting stats
        });
        // ..
    }

It’s critical that this.connections is modified after server.getConnectionStats() is called:

    getConnectionStats(connectionId: number): ConnectionStats | undefined {
        const socket = this.connections.get(connectionId); // <-- Needs the entry here; otherwise, stats are undefined
        if (!socket) return undefined;

        const targetStats = getTargetStats(socket);

        const result = {
            srcTxBytes: socket.bytesWritten,
            srcRxBytes: socket.bytesRead,
            trgTxBytes: targetStats.bytesWritten,
            trgRxBytes: targetStats.bytesRead,
        };

        return result;
    }

In summary, calling server.closeConnections() or server.close(true) prevents stats collection by clearing this.connections before server.getConnectionStats() can retrieve the necessary information.

Workaround

Currently, I avoid the issue by manually closing connections like this:

const connectionIds = server.getConnectionIds();
for (const connectionId of connectionIds) {
    server.closeConnection(connectionId);
}
await server.close(false);

Proposed Fix

I suggest removing this line in server.ts. If this solution is acceptable, I can submit a pull request with the fix. What do you think?

@jancurn
Copy link
Member

jancurn commented Oct 14, 2024

Hey @marcplouhinec, thank you for your report and suggested fix. Your proposed fix makes sense - please can you prepare a pull request?

@marcplouhinec
Copy link
Contributor Author

marcplouhinec commented Oct 14, 2024

Hi @jancurn , ok, please wait

@marcplouhinec
Copy link
Contributor Author

@jancurn Here is my pull request: #556

@fnesveda fnesveda added the t-platform Issues with this label are in the ownership of the platform team. label Oct 14, 2024
@jirimoravcik
Copy link
Member

Hello, the PR has been merged and a new version 2.5.4 has been released. Thanks for your contribution!

@fnesveda fnesveda added the validated Issues that are resolved and their solutions fulfill the acceptance criteria. label Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t-platform Issues with this label are in the ownership of the platform team. validated Issues that are resolved and their solutions fulfill the acceptance criteria.
Projects
None yet
Development

No branches or pull requests

4 participants