From 79c1a2dc99da6eac79f54b3d55715d9e4f354c15 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sun, 10 Mar 2024 00:43:38 +0100 Subject: [PATCH] Fix plugin hooks called before host removal (#607) Due a bad order of operations when a host connection was closed the event handler listening on "close" to remove the host from the hostConnections mapping was added after the HostConnection's event handler listening on "close" and invoking plugin hooks in response to the host going offline. This in turn causes plugins that send broadcasts in repsonse to thos hooks to throw an error due to the broadcast sending code assuming connections that exist are valid target to send messages to. Fix by ordering the listener for the removal of the host connection before the listener invoking plugin events. --- CHANGELOG.md | 1 + packages/controller/src/WsServer.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a15e75b4..31908653 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Many thanks to the following for contributing to this release: ### Changes - Fixed Inventory Sync reporting a negative database size [ยค598](https://github.com/clusterio/clusterio/pull/598). +- Fixed plugin events being invoked while a host connection was in an invalid state. Many thanks to the following for contributing to this release: [@Cooldude2606](https://github.com/Cooldude2606) diff --git a/packages/controller/src/WsServer.ts b/packages/controller/src/WsServer.ts index 50c37d9c..05576336 100644 --- a/packages/controller/src/WsServer.ts +++ b/packages/controller/src/WsServer.ts @@ -284,7 +284,9 @@ ${err.stack}` ); } - connection = new HostConnection(data, connector, this.controller, this.remoteAddr(req)); + // Handle close before HostConnection does. This avoids a host + // connection event happening between the connection breaking and + // it being removed from the host connections list. connector.on("close", () => { if (this.hostConnections.get(data.id) === connection) { this.hostConnections.delete(data.id); @@ -292,6 +294,8 @@ ${err.stack}` logger.warn("Unlisted HostConnection closed"); } }); + + connection = new HostConnection(data, connector, this.controller, this.remoteAddr(req)); this.hostConnections.set(data.id, connection); let src = new lib.Address(lib.Address.host, data.id); connector.ready(socket, src, sessionToken, undefined); @@ -331,10 +335,10 @@ ${err.stack}` let [connector, sessionToken] = this.createSession(new lib.Address(lib.Address.control, id)); logger.verbose(`WsServer | registered control ${id} from ${this.remoteAddr(req)}`); - let connection = new ControlConnection(data, connector, this.controller, user, id); connector.on("close", () => { this.controlConnections.delete(id); }); + let connection = new ControlConnection(data, connector, this.controller, user, id); this.controlConnections.set(id, connection); let account = new lib.AccountDetails( user.name,