From 54339a30e34aae7872f55fcb8abc2e69a14f6cea Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Tue, 4 Aug 2015 01:12:09 +1000 Subject: [PATCH] Drop connections that contributed to pieces that failed to hash 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 | 14 ++++++++++++++ connection.go | 5 ++++- dht/dht.go | 4 ++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 13b67cfa..f5a52449 100644 --- 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 diff --git a/connection.go b/connection.go index ba0d124a..85df7eb4 100644 --- a/connection.go +++ b/connection.go @@ -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, diff --git a/dht/dht.go b/dht/dht.go index e269350f..599522f8 100644 --- a/dht/dht.go +++ b/dht/dht.go @@ -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 { -- 2.48.1