Prevent non-active peers from announcing events

This commit is contained in:
Justin Li 2014-07-23 00:30:11 -04:00
parent 8625c4b3c4
commit ba1ad7f5bf
2 changed files with 21 additions and 4 deletions

View file

@ -68,12 +68,12 @@ func (tkr *Tracker) HandleAnnounce(ann *models.Announce, w Writer) error {
peer := models.NewPeer(ann, user, torrent) peer := models.NewPeer(ann, user, torrent)
created, err := updateSwarm(conn, ann, peer, torrent) created, err := updateSwarm(conn, w, ann, peer, torrent)
if err != nil { if err != nil {
return err return err
} }
snatched, err := handleEvent(conn, ann, peer, user, torrent) snatched, err := handleEvent(conn, w, ann, peer, user, torrent)
if err != nil { if err != nil {
return err return err
} }
@ -95,7 +95,7 @@ func (tkr *Tracker) HandleAnnounce(ann *models.Announce, w Writer) error {
} }
// updateSwarm handles the changes to a torrent's swarm given an announce. // updateSwarm handles the changes to a torrent's swarm given an announce.
func updateSwarm(c Conn, ann *models.Announce, p *models.Peer, t *models.Torrent) (created bool, err error) { func updateSwarm(c Conn, w Writer, ann *models.Announce, p *models.Peer, t *models.Torrent) (created bool, err error) {
c.TouchTorrent(t.Infohash) c.TouchTorrent(t.Infohash)
switch { switch {
@ -114,6 +114,12 @@ func updateSwarm(c Conn, ann *models.Announce, p *models.Peer, t *models.Torrent
t.Leechers[p.ID] = *p t.Leechers[p.ID] = *p
default: default:
if ann.Event != "" {
err = models.ErrBadRequest
w.WriteError(err)
return
}
if ann.Left == 0 { if ann.Left == 0 {
err = c.PutSeeder(t.Infohash, p) err = c.PutSeeder(t.Infohash, p)
if err != nil { if err != nil {
@ -138,7 +144,7 @@ func updateSwarm(c Conn, ann *models.Announce, p *models.Peer, t *models.Torrent
// handleEvent checks to see whether an announce has an event and if it does, // handleEvent checks to see whether an announce has an event and if it does,
// properly handles that event. // properly handles that event.
func handleEvent(c Conn, ann *models.Announce, p *models.Peer, u *models.User, t *models.Torrent) (snatched bool, err error) { func handleEvent(c Conn, w Writer, ann *models.Announce, p *models.Peer, u *models.User, t *models.Torrent) (snatched bool, err error) {
switch { switch {
case ann.Event == "stopped" || ann.Event == "paused": case ann.Event == "stopped" || ann.Event == "paused":
if t.InSeederPool(p) { if t.InSeederPool(p) {
@ -156,6 +162,9 @@ func handleEvent(c Conn, ann *models.Announce, p *models.Peer, u *models.User, t
} }
delete(t.Leechers, p.ID) delete(t.Leechers, p.ID)
stats.RecordPeerEvent(stats.DeletedLeech, p.IPv6()) stats.RecordPeerEvent(stats.DeletedLeech, p.IPv6())
} else {
err = models.ErrBadRequest
w.WriteError(err)
} }
case ann.Event == "completed": case ann.Event == "completed":
@ -175,6 +184,9 @@ func handleEvent(c Conn, ann *models.Announce, p *models.Peer, u *models.User, t
if t.InLeecherPool(p) { if t.InLeecherPool(p) {
err = leecherFinished(c, t.Infohash, p) err = leecherFinished(c, t.Infohash, p)
} else {
err = models.ErrBadRequest
w.WriteError(err)
} }
snatched = true snatched = true

View file

@ -16,6 +16,11 @@ var (
// ErrMalformedRequest is returned when a request does not contain the // ErrMalformedRequest is returned when a request does not contain the
// required parameters needed to create a model. // required parameters needed to create a model.
ErrMalformedRequest = errors.New("malformed request") ErrMalformedRequest = errors.New("malformed request")
// ErrBadRequest is returned when a request is invalid in the peer's
// current state. For example, announcing a "completed" event while
// not a leecher or a "stopped" event while not active.
ErrBadRequest = errors.New("bad request")
) )
// Peer is a participant in a swarm. // Peer is a participant in a swarm.