From 229cca918d31e14add4b2ef74647d4f991739bdb Mon Sep 17 00:00:00 2001
From: "Rob Swindell (on Windows)" <rob@synchro.net>
Date: Sun, 24 Sep 2023 01:27:01 -0700
Subject: [PATCH] Close node socket after waiting one hour to go inactive to
 run exclusive event

After 90 minutes of waiting, we'll do the same abort wait (and run the event
anyway), but closing the node's socket should be enough to get the node_thread
to terminate and set the node status back to NODE_WFC.

Apparently some sysops like to leave their terminals idling (e.g. running MRC)
and never disconnect and since they're T-exempt, the BBS won't limit their
time online to allow events to run. Exclusive events will wait for all nodes
to become inactive, but give up after 90 minutes of waiting and run the event
anyway and set node status to WFC at the end. If the node was actually still
connected/in-use, this could lead to the (new) critical error messages logged
"!Node X status is WFC, but the node socket (N) and thread are still in use!"
and other chaos (NODE STATUS FIXUP and the like).

This should prevent all that by just abruptly disconnecting the node after
waiting 60 minutes for the sysop to gracefully disconnect. The log message
when this happens:
"!TIRED of waiting for node N to become inactive (status=X), closing socket Y"
---
 src/sbbs3/main.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 283d806aad..9de5a24437 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -3198,8 +3198,14 @@ void event_thread(void* arg)
 								break;
 							sbbs->lprintf(LOG_DEBUG,"Waiting for node %d (status=%d)"
 								,j, node.status);
+							if (now - start > (60 * 60) && node_socket[j - 1] != INVALID_SOCKET) {
+								sbbs->lprintf(LOG_WARNING, "!TIRED of waiting for node %d to become inactive (status=%d), closing socket %d"
+									,j, node.status, node_socket[j - 1]);
+								close_socket(node_socket[j - 1]);
+								node_socket[j - 1] = INVALID_SOCKET;
+							}
 							if(now-start>(90*60)) {
-								sbbs->lprintf(LOG_WARNING,"!TIMEOUT waiting for node %d to become inactive (status=%d)"
+								sbbs->lprintf(LOG_WARNING,"!TIMEOUT waiting for node %d to become inactive (status=%d), aborting wait"
 									,j, node.status);
 								break;
 							}
-- 
GitLab