udp: Implement scrapes

This commit is contained in:
Justin Li 2015-02-20 12:35:31 -05:00
parent be5720dadd
commit 9526df74ad
2 changed files with 59 additions and 10 deletions

View file

@ -22,6 +22,7 @@ var (
errMalformedPacket = errors.New("malformed packet")
errMalformedIP = errors.New("malformed IP address")
errMalformedEvent = errors.New("malformed event ID")
errBadConnectionID = errors.New("bad connection ID")
)
func writeHeader(response []byte, action uint32, transactionID []byte) {
@ -50,7 +51,12 @@ func (s *Server) handlePacket(packet []byte, addr *net.UDPAddr) (response []byte
transactionID := packet[12:16]
generatedConnID := GenerateConnectionID(addr.IP)
writer := &Writer{transactionID: transactionID}
writer := &Writer{
buf: new(bytes.Buffer),
connectionID: connID,
transactionID: transactionID,
}
switch action {
case 0:
@ -65,22 +71,34 @@ func (s *Server) handlePacket(packet []byte, addr *net.UDPAddr) (response []byte
case 1:
// Announce request.
writer.buf = new(bytes.Buffer)
ann, err := s.newAnnounce(packet, addr.IP)
if !bytes.Equal(connID, generatedConnID) {
writer.WriteError(errBadConnectionID)
} else {
ann, err := s.newAnnounce(packet, addr.IP)
if err == nil {
err = s.tracker.HandleAnnounce(ann, writer)
if err == nil {
err = s.tracker.HandleAnnounce(ann, writer)
}
handleTorrentError(err, writer)
}
handleTorrentError(err, writer)
case 2:
// Scrape request.
writer.buf = new(bytes.Buffer)
// handleTorrentError(s.tracker.HandleScrape(scrape, writer), writer)
if !bytes.Equal(connID, generatedConnID) {
writer.WriteError(errBadConnectionID)
} else {
scrape, err := s.newScrape(packet)
if err == nil {
err = s.tracker.HandleScrape(scrape, writer)
}
handleTorrentError(err, writer)
}
}
if writer.buf != nil {
if writer.buf.Len() > 0 {
response = writer.buf.Bytes()
}
return
@ -132,3 +150,26 @@ func (s *Server) newAnnounce(packet []byte, ip net.IP) (*models.Announce, error)
Uploaded: uploaded,
}, nil
}
func (s *Server) newScrape(packet []byte) (*models.Scrape, error) {
if len(packet) < 16 {
return nil, errMalformedPacket
}
var infohashes []string
packet = packet[16:]
if len(packet)%20 != 0 {
return nil, errMalformedPacket
}
for len(packet) >= 20 {
infohash := packet[:20]
infohashes = append(infohashes, string(infohash))
}
return &models.Scrape{
Config: s.config,
Infohashes: infohashes,
}, nil
}

View file

@ -14,6 +14,7 @@ import (
type Writer struct {
buf *bytes.Buffer
connectionID []byte
transactionID []byte
}
@ -40,6 +41,13 @@ func (w *Writer) WriteAnnounce(res *models.AnnounceResponse) error {
func (w *Writer) WriteScrape(res *models.ScrapeResponse) error {
w.writeHeader(2)
for _, torrent := range res.Files {
binary.Write(w.buf, binary.BigEndian, uint32(torrent.Seeders.Len()))
binary.Write(w.buf, binary.BigEndian, uint32(torrent.Snatches))
binary.Write(w.buf, binary.BigEndian, uint32(torrent.Leechers.Len()))
}
return nil
}