]> git.r.bdr.sh - rbdr/mobius/commitdiff
Add support for trackers that require a password
authorJeff Halter <redacted>
Fri, 19 Jul 2024 00:28:17 +0000 (17:28 -0700)
committerJeff Halter <redacted>
Fri, 19 Jul 2024 00:30:34 +0000 (17:30 -0700)
cmd/mobius-hotline-server/mobius/config/config.yaml
hotline/server.go
hotline/tracker.go

index 3cf8951a05644457618b37f928901aeb7b45e545..0801621db131f65e4c61c7b029af13ae77407812 100644 (file)
@@ -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:
index cfdb6b3a4ce52709c8ca28b1c5bf77e0b32c7f66..04ac8c7119c4d0dafbece1047026b78d5e805297 100644 (file)
@@ -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 (
index 2d655d97b5762c26ddd16a078b5f1033447d2a5a..a3e077eceb68d7a898a15f7b88599e4337e021a2 100644 (file)
@@ -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) {