aboutsummaryrefslogtreecommitdiff
path: root/cmd/mobius-hotline-server
diff options
context:
space:
mode:
authorJeff Halter <868228+jhalter@users.noreply.github.com>2026-06-12 08:47:54 -0700
committerJeff Halter <868228+jhalter@users.noreply.github.com>2026-06-12 08:47:54 -0700
commitc15f8510fbd5ccf9a122f88d6e975d1ef69e00b3 (patch)
tree1ba7e392610637ed792d0003568cf9edb6adc526 /cmd/mobius-hotline-server
parentb2c462a3a1353f0653a5964b3a6924538ce83523 (diff)
Fix data races on ClientConn state, banner reload, and rate limiter growth
ClientConn's mutable session state (Flags, UserName, Icon, IdleTime, AutoReply) was guarded inconsistently: two mutexes (FlagsMU and mu) covered some paths while others mutated or read the fields with no locking at all, including HandleSetClientUserInfo, HandleUpdateUser (which writes other clients' admin flag), the login flow, the HTTP API handlers, and the keepalive loop. Consolidate on a single mutex with accessor methods (SetFlag/IsFlagSet/FlagBytes, SetUserName/GetUserName, and so on) used by all production code; direct field access remains for test construction. The idle/away logic moves into incrementIdleTime and clearIdleAndAway helpers that report whether a notification is needed, so SendAll is no longer called while holding the lock. HandleRejectChatInvite also no longer appends to the username slice, which could write past its length into the backing buffer. The server banner is now behind Banner/SetBanner with an RWMutex: the SIGHUP reload previously reassigned the field while banner download goroutines read it, and nilled it when the file read failed. Reload now keeps the previous banner on failure. Per-IP rate limiter entries now record a last-seen time, and the keepalive ticker evicts entries idle for over seven days, so the map no longer grows unboundedly with each unique client IP.
Diffstat (limited to 'cmd/mobius-hotline-server')
-rw-r--r--cmd/mobius-hotline-server/main.go9
1 files changed, 6 insertions, 3 deletions
diff --git a/cmd/mobius-hotline-server/main.go b/cmd/mobius-hotline-server/main.go
index 1c298a2..117cb2a 100644
--- a/cmd/mobius-hotline-server/main.go
+++ b/cmd/mobius-hotline-server/main.go
@@ -159,11 +159,12 @@ func main() {
}
bannerPath := path.Join(*configDir, config.BannerFile)
- srv.Banner, err = os.ReadFile(bannerPath)
+ banner, err := os.ReadFile(bannerPath)
if err != nil {
slogger.Error("Error loading banner", "err", err)
os.Exit(1)
}
+ srv.SetBanner(banner)
reloadFunc := func() {
if err := srv.MessageBoard.(*mobius.FlatNews).Reload(); err != nil {
@@ -185,11 +186,13 @@ func main() {
slogger.Error("Error reloading agreement", "err", err)
}
- // Let's try to reload the banner
+ // Let's try to reload the banner. On failure, keep serving the previous banner.
bannerPath := path.Join(*configDir, config.BannerFile)
- srv.Banner, err = os.ReadFile(bannerPath)
+ banner, err := os.ReadFile(bannerPath)
if err != nil {
slogger.Error("Error reloading banner", "err", err)
+ } else {
+ srv.SetBanner(banner)
}
}