"github.com/anacrolix/torrent/tracker"
)
+// I could move a lot of these counters to their own file, but I suspect they
+// may be attached to a Client someday.
var (
unwantedChunksReceived = expvar.NewInt("chunksReceivedUnwanted")
unexpectedChunksReceived = expvar.NewInt("chunksReceivedUnexpected")
supportedExtensionMessages = expvar.NewMap("supportedExtensionMessages")
postedMessageTypes = expvar.NewMap("postedMessageTypes")
postedKeepalives = expvar.NewInt("postedKeepalives")
+ // Requests received for pieces we don't have.
+ requestsReceivedForMissingPieces = expvar.NewInt("requestsReceivedForMissingPieces")
)
const (
err := me.sendChunk(t, c, r)
if err != nil {
log.Printf("error sending chunk %+v to peer: %s", r, err)
+ // If we failed to send a chunk, choke the peer to ensure they
+ // flush all their requests. We've probably dropped a piece,
+ // but there's no way to communicate this to the peer. If they
+ // ask for it again, we'll kick them to allow us to send them
+ // an updated bitfield.
+ break another
}
delete(c.PeerRequests, r)
goto another
func (me *Client) sendChunk(t *torrent, c *connection, r request) error {
// Count the chunk being sent, even if it isn't.
- c.chunksSent++
b := make([]byte, r.Length)
p := t.Info.Piece(int(r.Index))
n, err := t.readAt(b, p.Offset()+int64(r.Begin))
Begin: r.Begin,
Piece: b,
})
+ c.chunksSent++
uploadChunksPosted.Add(1)
c.lastChunkSent = time.Now()
return nil
err = errors.New("peer sent request but isn't interested")
break
}
+ if !t.havePiece(msg.Index.Int()) {
+ // This isn't necessarily them screwing up. We can drop pieces
+ // from our storage, and can't communicate this to peers
+ // except by reconnecting.
+ requestsReceivedForMissingPieces.Add(1)
+ err = errors.New("peer requested piece we don't have")
+ break
+ }
if c.PeerRequests == nil {
c.PeerRequests = make(map[request]struct{}, maxRequests)
}