connection.go | 24 +++++++++++++++++++++++- misc.go | 9 +++++++++ diff --git a/connection.go b/connection.go index 70afb2a85b27701045ae10f67ebd363b3c53b5c0..3ad80b5b244f11527cd57d656ee9f78159d95e96 100644 --- a/connection.go +++ b/connection.go @@ -824,13 +824,34 @@ } return } +func (c *connection) fastEnabled() bool { + return c.PeerExtensionBytes.SupportsFast() && c.t.cl.extensionBytes.SupportsFast() +} + +// Returns true if we were able to reject the request. +func (c *connection) reject(r request) bool { + if !c.fastEnabled() { + return false + } + c.deleteRequest(r) + c.Post(r.ToMsg(pp.Reject)) + return true +} + func (c *connection) onReadRequest(r request) error { requestedChunkLengths.Add(strconv.FormatUint(r.Length.Uint64(), 10), 1) + if r.Begin+r.Length > c.t.pieceLength(int(r.Index)) { + return errors.New("bad request") + } + if _, ok := c.PeerRequests[r]; ok { + return nil + } if c.Choked { + c.reject(r) return nil } if len(c.PeerRequests) >= maxRequests { - // TODO: Should we drop them or Choke them instead? + c.reject(r) return nil } if !c.t.havePiece(r.Index.Int()) { @@ -1254,6 +1275,7 @@ return false } delete(c.requests, r) c.t.pendingRequests[r]-- + c.updateRequests() return true } diff --git a/misc.go b/misc.go index 58221661049b348c382a611a0a615af0bf90f8ea..f3b38bf3666440ce3124d69b033829caf7df85c0 100644 --- a/misc.go +++ b/misc.go @@ -17,6 +17,15 @@ Index pp.Integer chunkSpec } +func (r request) ToMsg(mt pp.MessageType) pp.Message { + return pp.Message{ + Type: mt, + Index: r.Index, + Begin: r.Begin, + Length: r.Length, + } +} + func newRequest(index, begin, length pp.Integer) request { return request{index, chunkSpec{begin, length}} }