udp: Implement scrapes
This commit is contained in:
parent
be5720dadd
commit
9526df74ad
2 changed files with 59 additions and 10 deletions
|
@ -22,6 +22,7 @@ var (
|
||||||
errMalformedPacket = errors.New("malformed packet")
|
errMalformedPacket = errors.New("malformed packet")
|
||||||
errMalformedIP = errors.New("malformed IP address")
|
errMalformedIP = errors.New("malformed IP address")
|
||||||
errMalformedEvent = errors.New("malformed event ID")
|
errMalformedEvent = errors.New("malformed event ID")
|
||||||
|
errBadConnectionID = errors.New("bad connection ID")
|
||||||
)
|
)
|
||||||
|
|
||||||
func writeHeader(response []byte, action uint32, transactionID []byte) {
|
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]
|
transactionID := packet[12:16]
|
||||||
generatedConnID := GenerateConnectionID(addr.IP)
|
generatedConnID := GenerateConnectionID(addr.IP)
|
||||||
|
|
||||||
writer := &Writer{transactionID: transactionID}
|
writer := &Writer{
|
||||||
|
buf: new(bytes.Buffer),
|
||||||
|
|
||||||
|
connectionID: connID,
|
||||||
|
transactionID: transactionID,
|
||||||
|
}
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -65,22 +71,34 @@ func (s *Server) handlePacket(packet []byte, addr *net.UDPAddr) (response []byte
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Announce request.
|
// Announce request.
|
||||||
writer.buf = new(bytes.Buffer)
|
if !bytes.Equal(connID, generatedConnID) {
|
||||||
ann, err := s.newAnnounce(packet, addr.IP)
|
writer.WriteError(errBadConnectionID)
|
||||||
|
} else {
|
||||||
|
ann, err := s.newAnnounce(packet, addr.IP)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = s.tracker.HandleAnnounce(ann, writer)
|
err = s.tracker.HandleAnnounce(ann, writer)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleTorrentError(err, writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTorrentError(err, writer)
|
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
// Scrape request.
|
// Scrape request.
|
||||||
writer.buf = new(bytes.Buffer)
|
if !bytes.Equal(connID, generatedConnID) {
|
||||||
// handleTorrentError(s.tracker.HandleScrape(scrape, writer), writer)
|
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()
|
response = writer.buf.Bytes()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -132,3 +150,26 @@ func (s *Server) newAnnounce(packet []byte, ip net.IP) (*models.Announce, error)
|
||||||
Uploaded: uploaded,
|
Uploaded: uploaded,
|
||||||
}, nil
|
}, 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
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
type Writer struct {
|
type Writer struct {
|
||||||
buf *bytes.Buffer
|
buf *bytes.Buffer
|
||||||
|
|
||||||
|
connectionID []byte
|
||||||
transactionID []byte
|
transactionID []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +41,13 @@ func (w *Writer) WriteAnnounce(res *models.AnnounceResponse) error {
|
||||||
|
|
||||||
func (w *Writer) WriteScrape(res *models.ScrapeResponse) error {
|
func (w *Writer) WriteScrape(res *models.ScrapeResponse) error {
|
||||||
w.writeHeader(2)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue