X-Git-Url: https://git.r.bdr.sh/rbdr/mobius/blobdiff_plain/fd740bc499ebc6d3a381479316f74cdc736d02de..50c837fe10df05b9cc08decb1add122fb935e8fa:/hotline/server.go?ds=sidebyside diff --git a/hotline/server.go b/hotline/server.go index 58a9209..04ac8c7 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -13,6 +13,7 @@ import ( "log" "log/slog" "net" + "os" "strings" "sync" "time" @@ -240,15 +241,9 @@ const trackerUpdateFrequency = 300 // registerWithTrackers runs every trackerUpdateFrequency seconds to update the server's tracker entry on all configured // trackers. func (s *Server) registerWithTrackers(ctx context.Context) { - ticker := time.NewTicker(trackerUpdateFrequency * time.Second) - defer ticker.Stop() - for { - select { - case <-ctx.Done(): - return - case <-ticker.C: - if s.Config.EnableTrackerRegistration { + if s.Config.EnableTrackerRegistration { + for _, t := range s.Config.Trackers { tr := &TrackerRegistration{ UserCount: len(s.ClientMgr.List()), PassID: s.TrackerPassID, @@ -257,15 +252,23 @@ func (s *Server) registerWithTrackers(ctx context.Context) { } binary.BigEndian.PutUint16(tr.Port[:], uint16(s.Port)) - for _, t := range s.Config.Trackers { - if err := register(&RealDialer{}, t, tr); err != nil { - s.Logger.Error(fmt.Sprintf("Unable to register with tracker %v", t), "error", err) - } + // Check the tracker string for a password. This is janky but avoids a breaking change to the Config + // Trackers field. + splitAddr := strings.Split(":", t) + if len(splitAddr) == 3 { + tr.Password = splitAddr[2] + } + + if err := register(&RealDialer{}, t, tr); err != nil { + s.Logger.Error(fmt.Sprintf("Unable to register with tracker %v", t), "error", err) } } } + // Using time.Ticker with for/select would be more idiomatic, but it's super annoying that it doesn't tick on + // first pass. Revist, maybe. + // https://github.com/golang/go/issues/17601 + time.Sleep(trackerUpdateFrequency * time.Second) } - } const ( @@ -586,3 +589,18 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro } return nil } + +func (s *Server) SendAll(t TranType, fields ...Field) { + for _, c := range s.ClientMgr.List() { + s.outbox <- NewTransaction(t, c.ID, fields...) + } +} + +func (s *Server) Shutdown(msg []byte) { + s.Logger.Info("Shutdown signal received") + s.SendAll(TranDisconnectMsg, NewField(FieldData, msg)) + + time.Sleep(3 * time.Second) + + os.Exit(0) +}