diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2025-11-25 10:30:30 -0800 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2025-11-25 10:31:39 -0800 |
| commit | 8ddb9bb228389b198a76d6df21de005da4fad66b (patch) | |
| tree | e6e1d8de46beaf8e79fc8aa7edfe4c7263799fe9 /hotline | |
| parent | ab16c7d82c8381a4df80fef4b2fe81e7ff23dad8 (diff) | |
Add TLS port field to tracker registration protocol
Repurpose the previously unused 2-byte field in the tracker protocol to advertise the server's TLS port. This allows clients to discover which servers support TLS connections.
Note: currently only the official, original, 1990's Tracker software sends this server provided 2-byte field to tracker clients. I'm adding this to Mobius in the hope that the modern day trackers might update their behavior to match the original software, which would put these unused 2 bytes to a useful purpose.
Diffstat (limited to 'hotline')
| -rw-r--r-- | hotline/server.go | 1 | ||||
| -rw-r--r-- | hotline/tracker.go | 9 | ||||
| -rw-r--r-- | hotline/tracker_test.go | 90 |
3 files changed, 51 insertions, 49 deletions
diff --git a/hotline/server.go b/hotline/server.go index 2c25e93..9b74d99 100644 --- a/hotline/server.go +++ b/hotline/server.go @@ -368,6 +368,7 @@ func (s *Server) registerWithAllTrackers() { Description: s.Config.Description, } binary.BigEndian.PutUint16(tr.Port[:], uint16(s.Port)) + binary.BigEndian.PutUint16(tr.TLSPort[:], uint16(s.TLSPort)) tr.Password = parseTrackerPassword(t) diff --git a/hotline/tracker.go b/hotline/tracker.go index bfba69d..ee4fc05 100644 --- a/hotline/tracker.go +++ b/hotline/tracker.go @@ -15,6 +15,7 @@ import ( type TrackerRegistration struct { Port [2]byte // Server's listening TCP port number UserCount int // Number of users connected to this particular server + TLSPort [2]byte // TLSPort PassID [4]byte // Random number generated by the server Name string // Server Name Description string // Description of the server @@ -32,7 +33,7 @@ func (tr *TrackerRegistration) Read(p []byte) (int, error) { []byte{0x00, 0x01}, // Magic number, always 1 tr.Port[:], userCount, - []byte{0x00, 0x00}, // Magic number, always 0 + tr.TLSPort[:], tr.PassID[:], []byte{uint8(len(tr.Name))}, []byte(tr.Name), @@ -114,7 +115,7 @@ type ServerRecord struct { IPAddr [4]byte Port [2]byte NumUsers [2]byte // Number of users connected to this particular server - Unused [2]byte + TLSPort [2]byte NameSize byte // Length of Name string Name []byte // Server Name DescriptionSize byte @@ -182,7 +183,7 @@ func GetListing(conn io.ReadWriteCloser) ([]ServerRecord, error) { func readServerRecord(reader *bufio.Reader) (ServerRecord, error) { var srv ServerRecord - // Read fixed header: IP (4) + Port (2) + NumUsers (2) + Unused (2) = 10 bytes + // Read fixed header: IP (4) + Port (2) + NumUsers (2) + TLSPort (2) = 10 bytes header := make([]byte, 10) if _, err := io.ReadFull(reader, header); err != nil { return srv, fmt.Errorf("failed to read server header: %w", err) @@ -191,7 +192,7 @@ func readServerRecord(reader *bufio.Reader) (ServerRecord, error) { copy(srv.IPAddr[:], header[0:4]) copy(srv.Port[:], header[4:6]) copy(srv.NumUsers[:], header[6:8]) - copy(srv.Unused[:], header[8:10]) + copy(srv.TLSPort[:], header[8:10]) // Read name size nameSizeByte, err := reader.ReadByte() diff --git a/hotline/tracker_test.go b/hotline/tracker_test.go index 8295582..242deb1 100644 --- a/hotline/tracker_test.go +++ b/hotline/tracker_test.go @@ -104,7 +104,7 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 1, // IP address 0x1F, 0x90, // Port 8080 0x00, 0x10, // NumUsers 16 - 0x00, 0x00, // Unused + 0x00, 0x00, // TLSPort 0x04, // NameSize 'S', 'e', 'r', 'v', // Name 0x0B, // DescriptionSize @@ -113,7 +113,7 @@ func TestGetListing(t *testing.T) { 10, 0, 0, 1, // IP address 0x1F, 0x91, // Port 8081 0x00, 0x05, // NumUsers 5 - 0x00, 0x00, // Unused + 0x00, 0x00, // TLSPort 0x04, // NameSize 'S', 'e', 'r', 'v', // Name 0x0B, // DescriptionSize @@ -127,7 +127,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 1}, Port: [2]byte{0x1F, 0x90}, NumUsers: [2]byte{0x00, 0x10}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 4, Name: []byte("Serv"), DescriptionSize: 11, @@ -137,7 +137,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{10, 0, 0, 1}, Port: [2]byte{0x1F, 0x91}, NumUsers: [2]byte{0x00, 0x05}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 4, Name: []byte("Serv"), DescriptionSize: 11, @@ -217,19 +217,19 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 1, // IP address 0x1F, 0x90, // Port 8080 0x00, 0x0A, // NumUsers 10 - 0x00, 0x00, // Unused - 0x07, // NameSize + 0x00, 0x00, // TLSPort + 0x07, // NameSize 'S', 'e', 'r', 'v', 'e', 'r', '1', // Name - 0x0C, // DescriptionSize + 0x0C, // DescriptionSize 'F', 'i', 'r', 's', 't', ' ', 'b', 'a', 't', 'c', 'h', '1', // Description // ServerRecord 2 192, 168, 1, 2, // IP address 0x1F, 0x91, // Port 8081 0x00, 0x14, // NumUsers 20 - 0x00, 0x00, // Unused - 0x07, // NameSize + 0x00, 0x00, // TLSPort + 0x07, // NameSize 'S', 'e', 'r', 'v', 'e', 'r', '2', // Name - 0x0C, // DescriptionSize + 0x0C, // DescriptionSize 'F', 'i', 'r', 's', 't', ' ', 'b', 'a', 't', 'c', 'h', '2', // Description // Second ServerInfoHeader (next batch) 0x00, 0x01, // MsgType (1) @@ -240,10 +240,10 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 3, // IP address 0x1F, 0x92, // Port 8082 0x00, 0x1E, // NumUsers 30 - 0x00, 0x00, // Unused - 0x07, // NameSize + 0x00, 0x00, // TLSPort + 0x07, // NameSize 'S', 'e', 'r', 'v', 'e', 'r', '3', // Name - 0x0D, // DescriptionSize + 0x0D, // DescriptionSize 'S', 'e', 'c', 'o', 'n', 'd', ' ', 'b', 'a', 't', 'c', 'h', '1', // Description }), writeBuffer: &bytes.Buffer{}, @@ -254,7 +254,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 1}, Port: [2]byte{0x1F, 0x90}, NumUsers: [2]byte{0x00, 0x0A}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 7, Name: []byte("Server1"), DescriptionSize: 12, @@ -264,7 +264,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 2}, Port: [2]byte{0x1F, 0x91}, NumUsers: [2]byte{0x00, 0x14}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 7, Name: []byte("Server2"), DescriptionSize: 12, @@ -274,7 +274,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 3}, Port: [2]byte{0x1F, 0x92}, NumUsers: [2]byte{0x00, 0x1E}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 7, Name: []byte("Server3"), DescriptionSize: 13, @@ -298,20 +298,20 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 1, // IP 0x15, 0x7c, // Port 5500 0x00, 0x01, // NumUsers 1 - 0x00, 0x00, // Unused - 0x01, // NameSize - 'A', // Name - 0x01, // DescriptionSize - '1', // Description + 0x00, 0x00, // TLSPort + 0x01, // NameSize + 'A', // Name + 0x01, // DescriptionSize + '1', // Description // ServerRecord 2 192, 168, 1, 2, // IP 0x15, 0x7c, // Port 5500 0x00, 0x02, // NumUsers 2 - 0x00, 0x00, // Unused - 0x01, // NameSize - 'B', // Name - 0x01, // DescriptionSize - '2', // Description + 0x00, 0x00, // TLSPort + 0x01, // NameSize + 'B', // Name + 0x01, // DescriptionSize + '2', // Description // Second ServerInfoHeader 0x00, 0x01, // MsgType (1) 0x00, 0x0A, // MsgDataSize @@ -321,11 +321,11 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 3, // IP 0x15, 0x7c, // Port 5500 0x00, 0x03, // NumUsers 3 - 0x00, 0x00, // Unused - 0x01, // NameSize - 'C', // Name - 0x01, // DescriptionSize - '3', // Description + 0x00, 0x00, // TLSPort + 0x01, // NameSize + 'C', // Name + 0x01, // DescriptionSize + '3', // Description // Third ServerInfoHeader 0x00, 0x01, // MsgType (1) 0x00, 0x0A, // MsgDataSize @@ -335,11 +335,11 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 4, // IP 0x15, 0x7c, // Port 5500 0x00, 0x04, // NumUsers 4 - 0x00, 0x00, // Unused - 0x01, // NameSize - 'D', // Name - 0x01, // DescriptionSize - '4', // Description + 0x00, 0x00, // TLSPort + 0x01, // NameSize + 'D', // Name + 0x01, // DescriptionSize + '4', // Description }), writeBuffer: &bytes.Buffer{}, }, @@ -349,7 +349,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 1}, Port: [2]byte{0x15, 0x7c}, NumUsers: [2]byte{0x00, 0x01}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 1, Name: []byte("A"), DescriptionSize: 1, @@ -359,7 +359,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 2}, Port: [2]byte{0x15, 0x7c}, NumUsers: [2]byte{0x00, 0x02}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 1, Name: []byte("B"), DescriptionSize: 1, @@ -369,7 +369,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 3}, Port: [2]byte{0x15, 0x7c}, NumUsers: [2]byte{0x00, 0x03}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 1, Name: []byte("C"), DescriptionSize: 1, @@ -379,7 +379,7 @@ func TestGetListing(t *testing.T) { IPAddr: [4]byte{192, 168, 1, 4}, Port: [2]byte{0x15, 0x7c}, NumUsers: [2]byte{0x00, 0x04}, - Unused: [2]byte{0x00, 0x00}, + TLSPort: [2]byte{0x00, 0x00}, NameSize: 1, Name: []byte("D"), DescriptionSize: 1, @@ -403,11 +403,11 @@ func TestGetListing(t *testing.T) { 192, 168, 1, 1, // IP 0x15, 0x7c, // Port 5500 0x00, 0x01, // NumUsers 1 - 0x00, 0x00, // Unused - 0x01, // NameSize - 'A', // Name - 0x01, // DescriptionSize - '1', // Description + 0x00, 0x00, // TLSPort + 0x01, // NameSize + 'A', // Name + 0x01, // DescriptionSize + '1', // Description // Incomplete second ServerInfoHeader 0x00, 0x01, // MsgType only }), |