From: Matt Joiner Date: Mon, 3 Aug 2015 15:12:09 +0000 (+1000) Subject: Drop connections that contributed to pieces that failed to hash X-Git-Tag: v1.0.0~1089 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=54339a30e34aae7872f55fcb8abc2e69a14f6cea;p=btrtrc.git 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. --- 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 {