diff options
| author | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2021-07-28 18:21:52 -0700 |
|---|---|---|
| committer | Jeff Halter <868228+jhalter@users.noreply.github.com> | 2021-07-28 14:21:52 -0700 |
| commit | 22c599abc18895f73e96095f35b71cf3357d41b4 (patch) | |
| tree | 482ef57d386c955692ea43c43e4655b3c3763499 /tracker.go | |
| parent | 71c56068adca18f76ebee86355f000a3e51d3127 (diff) | |
Move code to hotline dir
Diffstat (limited to 'tracker.go')
| -rw-r--r-- | tracker.go | 198 |
1 files changed, 0 insertions, 198 deletions
diff --git a/tracker.go b/tracker.go deleted file mode 100644 index 97ca108..0000000 --- a/tracker.go +++ /dev/null @@ -1,198 +0,0 @@ -package hotline - -import ( - "bytes" - "encoding/binary" - "fmt" - "github.com/jhalter/mobius/concat" - "net" - "strconv" - "time" -) - -type TrackerRegistration struct { - Port []byte // Server’s listening UDP port number TODO: wat? - UserCount int // Number of users connected to this particular server - PassID []byte // Random number generated by the server - Name string // Server’s name - Description string // Description of the server -} - -func (tr *TrackerRegistration) Payload() []byte { - userCount := make([]byte, 2) - binary.BigEndian.PutUint16(userCount, uint16(tr.UserCount)) - - return concat.Slices( - []byte{0x00, 0x01}, - tr.Port, - userCount, - []byte{0x00, 0x00}, - tr.PassID, - []byte{uint8(len(tr.Name))}, - []byte(tr.Name), - []byte{uint8(len(tr.Description))}, - []byte(tr.Description), - ) -} - -func register(tracker string, tr TrackerRegistration) error { - conn, err := net.Dial("udp", tracker) - if err != nil { - return err - } - - if _, err := conn.Write(tr.Payload()); err != nil { - return err - } - - return nil -} - -type ServerListing struct { -} - -const trackerTimeout = 5 * time.Second - -// All string values use 8-bit ASCII character set encoding. -// Client Interface with Tracker -// After establishing a connection with tracker, the following information is sent: -// Description Size Data Note -// Magic number 4 ‘HTRK’ -// Version 2 1 or 2 Old protocol (1) or new (2) - -// Reply received from the tracker starts with a header: -// - -type TrackerHeader struct { - Protocol [4]byte // "HTRK" 0x4854524B - Version [2]byte // Old protocol (1) or new (2) -} - -//Message type 2 1 Sending list of servers -//Message data size 2 Remaining size of this request -//Number of servers 2 Number of servers in the server list -//Number of servers 2 Same as previous field -type ServerInfoHeader struct { - MsgType [2]byte // always has value of 1 - MsgDataSize [2]byte // Remaining size of request - SrvCount [2]byte // Number of servers in the server list - SrvCountDup [2]byte // Same as previous field ¯\_(ツ)_/¯ -} - -type ServerRecord struct { - IPAddr []byte - Port []byte - NumUsers []byte // Number of users connected to this particular server - Unused []byte - NameSize byte // Length of name string - Name []byte // Server’s name - DescriptionSize byte - Description []byte -} - -func GetListing(addr string) ([]ServerRecord, error) { - conn, err := net.DialTimeout("tcp", addr, trackerTimeout) - if err != nil { - return nil, err - } - //spew.Dump(conn) - _, err = conn.Write( - []byte{ - 0x48, 0x54, 0x52, 0x4B, // HTRK - 0x00, 0x01, // Version - }, - ) - if err != nil { - return nil, err - } - - totalRead := 0 - - buf := make([]byte, 4096) // handshakes are always 12 bytes in length - var readLen int - if readLen, err = conn.Read(buf); err != nil { - return nil, err - } - totalRead += readLen - - var th TrackerHeader - if err := binary.Read(bytes.NewReader(buf[:6]), binary.BigEndian, &th); err != nil { - return nil, err - } - - var info ServerInfoHeader - if err := binary.Read(bytes.NewReader(buf[6:14]), binary.BigEndian, &info); err != nil { - return nil, err - } - - payloadSize := int(binary.BigEndian.Uint16(info.MsgDataSize[:])) - - if totalRead < payloadSize { - for { - //fmt.Printf("totalRead: %v", totalRead) - //fmt.Printf("readLen: %v Payload size: %v, Server count: %x\n", readLen, payloadSize, info.SrvCount) - - if readLen, err = conn.Read(buf); err != nil { - return nil, err - } - totalRead += readLen - if totalRead >= payloadSize { - break - } - } - } - //fmt.Println("passed read") - totalSrv := int(binary.BigEndian.Uint16(info.SrvCount[:])) - - //fmt.Printf("readLen: %v Payload size: %v, Server count: %x\n", readLen, payloadSize, info.SrvCount) - srvBuf := buf[14:totalRead] - - totalRead += readLen - - var servers []ServerRecord - for { - var srv ServerRecord - n, _ := srv.Read(srvBuf) - servers = append(servers, srv) - - srvBuf = srvBuf[n:] - // fmt.Printf("srvBuf len: %v\n", len(srvBuf)) - if len(servers) == totalSrv { - return servers, nil - } - - if len(srvBuf) == 0 { - if readLen, err = conn.Read(buf); err != nil { - return nil, err - } - srvBuf = buf[8:readLen] - } - } - - return servers, nil -} - -func (s *ServerRecord) Read(b []byte) (n int, err error) { - s.IPAddr = b[0:4] - s.Port = b[4:6] - s.NumUsers = b[6:8] - s.NameSize = b[10] - nameLen := int(b[10]) - s.Name = b[11 : 11+nameLen] - s.DescriptionSize = b[11+nameLen] - s.Description = b[12+nameLen : 12+nameLen+int(s.DescriptionSize)] - - return 12 + nameLen + int(s.DescriptionSize), nil -} - -func (s *ServerRecord) PortInt() int { - data := binary.BigEndian.Uint16(s.Port) - return int(data) -} - -func (s *ServerRecord) Addr() string { - return fmt.Sprintf("%s:%s", - net.IP(s.IPAddr), - strconv.Itoa(int(binary.BigEndian.Uint16(s.Port))), - ) -} |