]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Drop connections that contributed to pieces that failed to hash
authorMatt Joiner <anacrolix@gmail.com>
Mon, 3 Aug 2015 15:12:09 +0000 (01:12 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 3 Aug 2015 15:12:09 +0000 (01:12 +1000)
There are peers out there that seem to intentionally spam bad data, and the same pieces will often fail continuously. This really puts a bee in their bonnet.

client.go
connection.go
dht/dht.go

index 13b67cfae2dedd3a7a169f63b58ef1dedb953817..f5a52449b3d0ac5760c0d94bc6d605d911ca4439 100644 (file)
--- a/client.go
+++ b/client.go
@@ -2527,6 +2527,10 @@ func (me *Client) downloadedChunk(t *torrent, c *connection, msg *pp.Message) er
                }
                tr.Stop("write chunk")
        }()
+       if c.peerTouchedPieces == nil {
+               c.peerTouchedPieces = make(map[int]struct{})
+       }
+       c.peerTouchedPieces[int(req.Index)] = struct{}{}
 
        // log.Println("got chunk", req)
        piece.Event.Broadcast()
@@ -2562,6 +2566,16 @@ func (me *Client) pieceHashed(t *torrent, piece pp.Integer, correct bool) {
                } else {
                        log.Printf("%s: piece %d failed hash", t, piece)
                        pieceHashedNotCorrect.Add(1)
+                       var touched []*connection
+                       for _, c := range t.Conns {
+                               if _, ok := c.peerTouchedPieces[int(piece)]; ok {
+                                       touched = append(touched, c)
+                               }
+                       }
+                       log.Printf("dropping %d conns that touched piece", len(touched))
+                       for _, c := range touched {
+                               me.dropConnection(t, c)
+                       }
                }
        }
        p.EverHashed = true
index ba0d124a8f85077dc1b1b1262c94450c6c49a735..85df7eb47039228c6144fd0043c2859d8578c26f 100644 (file)
@@ -74,6 +74,8 @@ type connection struct {
        // related messages yet.
        PeerPieces []bool
        peerHasAll bool
+       // Pieces we've accepted chunks for from the peer.
+       peerTouchedPieces map[int]struct{}
 
        PeerMaxRequests  int // Maximum pending requests the peer allows.
        PeerExtensionIDs map[string]byte
@@ -257,8 +259,9 @@ func (cn *connection) WriteStatus(w io.Writer, t *torrent) {
                eventAgeString(cn.completedHandshake),
                eventAgeString(cn.lastUsefulChunkReceived))
        fmt.Fprintf(w,
-               "    %s completed, good chunks: %d/%d-%d reqq: %d-%d, flags: %s\n",
+               "    %s completed, %d pieces touched, good chunks: %d/%d-%d reqq: %d-%d, flags: %s\n",
                cn.completedString(t),
+               len(cn.peerTouchedPieces),
                cn.UsefulChunksReceived,
                cn.UnwantedChunksReceived+cn.UsefulChunksReceived,
                cn.chunksSent,
index e269350f24ad662fe43a868c601aeb68a0bbdd00..599522f80a44f8f47a483b5c2a1198703a66c080 100644 (file)
@@ -587,6 +587,10 @@ func (s *Server) SetIPBlockList(list *iplist.IPList) {
        s.ipBlockList = list
 }
 
+func (s *Server) IPBlocklist() *iplist.IPList {
+       return s.ipBlockList
+}
+
 func (s *Server) init() (err error) {
        err = s.setDefaults()
        if err != nil {