From 3c446086af9e3525a171739893b87cf28e5dd72b Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 4 Jan 2016 22:37:49 +1100 Subject: [PATCH] Add Have and Bitfield connection methods --- client.go | 12 ++---------- connection.go | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/client.go b/client.go index 0f7daccb..8b53a7fd 100644 --- a/client.go +++ b/client.go @@ -1226,10 +1226,7 @@ func (me *Client) sendInitialMessages(conn *connection, torrent *torrent) { }) } if torrent.haveAnyPieces() { - conn.Post(pp.Message{ - Type: pp.Bitfield, - Bitfield: torrent.bitfield(), - }) + conn.Bitfield(torrent.bitfield()) } else if me.extensionBytes.SupportsFast() && conn.PeerExtensionBytes.SupportsFast() { conn.Post(pp.Message{ Type: pp.HaveNone, @@ -2660,7 +2657,6 @@ func (me *Client) pieceHashed(t *torrent, piece int, correct bool) { me.pieceChanged(t, int(piece)) } -// TODO: Check this isn't called more than once for each piece being correct. func (me *Client) pieceChanged(t *torrent, piece int) { correct := t.pieceComplete(piece) p := &t.Pieces[piece] @@ -2684,11 +2680,7 @@ func (me *Client) pieceChanged(t *torrent, piece int) { } for _, conn := range t.Conns { if correct { - conn.Post(pp.Message{ - Type: pp.Have, - Index: pp.Integer(piece), - }) - // TODO: Cancel requests for this piece. + conn.Have(piece) for r := range conn.Requests { if int(r.Index) == piece { conn.Cancel(r) diff --git a/connection.go b/connection.go index 0edda653..8f601d5e 100644 --- a/connection.go +++ b/connection.go @@ -64,6 +64,7 @@ type connection struct { // Indexed by metadata piece, set to true if posted and pending a // response. metadataRequests []bool + sentHaves []bool // Stuff controlled by the remote peer. PeerID [20]byte @@ -551,3 +552,28 @@ func (conn *connection) writeOptimizer(keepAliveDelay time.Duration) { } } } + +func (cn *connection) Have(piece int) { + for piece >= len(cn.sentHaves) { + cn.sentHaves = append(cn.sentHaves, false) + } + if cn.sentHaves[piece] { + return + } + cn.Post(pp.Message{ + Type: pp.Have, + Index: pp.Integer(piece), + }) + cn.sentHaves[piece] = true +} + +func (cn *connection) Bitfield(haves []bool) { + if len(cn.sentHaves) != nil { + panic("bitfield must be first have-related message sent") + } + cn.Post(pp.Message{ + Type: pp.Bitfield, + Bitfield: haves, + }) + cn.sentHaves = haves +} -- 2.48.1