diff --git a/cmd/mobius-hotline-server/mobius/config/config.yaml b/cmd/mobius-hotline-server/mobius/config/config.yaml index 3cf8951..0801621 100644 --- a/cmd/mobius-hotline-server/mobius/config/config.yaml +++ b/cmd/mobius-hotline-server/mobius/config/config.yaml @@ -17,12 +17,13 @@ FileRoot: Files # Enable tracker registration. Must be "true" or "false". EnableTrackerRegistration: false -# List of trackers to register with +# List of trackers to register with in colon delimited form of hostname/port/password (optional). Trackers: - hltracker.com:5499 - tracker.preterhuman.net:5499 - saddle.dyndns.org:5499 - hotline.kicks-ass.net:5499 +# - example-tracker-with-password.com:5499:mypassword # Preserve resource forks and file type/creator codes for files uploaded by Macintosh clients. # This comes with trade-offs. For more details, see: diff --git a/hotline/server.go b/hotline/server.go index cfdb6b3..04ac8c7 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -241,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, @@ -258,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 ( diff --git a/hotline/tracker.go b/hotline/tracker.go index 2d655d9..a3e077e 100644 --- a/hotline/tracker.go +++ b/hotline/tracker.go @@ -18,6 +18,7 @@ type TrackerRegistration struct { PassID [4]byte // Random number generated by the server Name string // Server Name Description string // Description of the server + Password string // Tracker password, if required by tracker readOffset int // Internal offset to track read progress } @@ -37,6 +38,8 @@ func (tr *TrackerRegistration) Read(p []byte) (int, error) { []byte(tr.Name), []byte{uint8(len(tr.Description))}, []byte(tr.Description), + []byte{uint8(len(tr.Password))}, + []byte(tr.Password), ) if tr.readOffset >= len(buf) {