]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add Have and Bitfield connection methods
authorMatt Joiner <anacrolix@gmail.com>
Mon, 4 Jan 2016 11:37:49 +0000 (22:37 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 4 Jan 2016 11:37:49 +0000 (22:37 +1100)
client.go
connection.go

index 0f7daccb88cfef241adf6eb58c30c5f3c23e933a..8b53a7fd8690f2fc81fb8654051fee71bbe55a8c 100644 (file)
--- 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)
index 0edda653c6420321fefe40ce31de6fa99849d39d..8f601d5efb811c20f63666503932361ce3e22845 100644 (file)
@@ -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
+}