// Announce announces using UDP format func (u UDPTracker) Announce(query url.Values, file data.FileRecord) []byte { // Create UDP announce response announce := udp.AnnounceResponse{ Action: 1, TransID: u.TransID, Interval: uint32(common.Static.Config.Interval), Leechers: uint32(file.Leechers()), Seeders: uint32(file.Seeders()), } // Convert to UDP byte buffer announceBuf, err := announce.MarshalBinary() if err != nil { log.Println(err.Error()) return u.Error("Could not create UDP announce response") } // Numwant numwant, err := strconv.Atoi(query.Get("numwant")) if err != nil { numwant = 50 } // Add compact peer list res := bytes.NewBuffer(announceBuf) err = binary.Write(res, binary.BigEndian, file.PeerList(query.Get("ip"), numwant)) if err != nil { log.Println(err.Error()) return u.Error("Could not create UDP announce response") } return res.Bytes() }
// Announce announces using HTTP format func (h HTTPTracker) Announce(query url.Values, file data.FileRecord) []byte { // Generate response struct announce := AnnounceResponse{ Complete: file.Seeders(), Incomplete: file.Leechers(), Interval: common.Static.Config.Interval, MinInterval: common.Static.Config.Interval / 2, } // Check for numwant parameter, return up to that number of peers // Default is 50 per protocol numwant := 50 if query.Get("numwant") != "" { // Verify numwant is an integer num, err := strconv.Atoi(query.Get("numwant")) if err == nil { numwant = num } } // Marshal struct into bencode buf := bytes.NewBuffer(make([]byte, 0)) if err := bencode.Marshal(buf, announce); err != nil { log.Println(err.Error()) return h.Error("Tracker error: failed to create announce response") } // Generate compact peer list of length numwant, exclude this user peers := file.PeerList(query.Get("ip"), numwant) // Because the bencode marshaler does not handle compact, binary peer list conversion, // we handle it manually here. // Get initial buffer, chop off 3 bytes: "0:e", append the actual list length with new colon out := buf.Bytes() out = append(out[0:len(out)-3], []byte(strconv.Itoa(len(peers))+":")...) // Append peers list, terminate with an "e" out = append(append(out, peers...), byte('e')) // Return final announce message return out }