client.go | 1 + peer-impl.go | 3 +++ peerconn.go | 4 ++++ torrent.go | 6 +++--- webseed-peer.go | 7 +++++-- diff --git a/client.go b/client.go index 4986424cd9d730f1e394b6038d3f920ac3b85bbe..ad20ef2be2c7ca4c36330147b5a46732943885b1 100644 --- a/client.go +++ b/client.go @@ -1505,6 +1505,7 @@ for _, t := range cl.torrents { t.iterPeers(func(p *Peer) { if p.remoteIp().Equal(ip) { t.logger.Levelf(log.Warning, "dropping peer %v with banned ip %v", p, ip) + // Should this be a close? p.drop() } }) diff --git a/peer-impl.go b/peer-impl.go index e29fb43967cb255086dc3fa73dead6b077749df4..1b9cf978205506a598fbfbad1812a31cf5cafb40 100644 --- a/peer-impl.go +++ b/peer-impl.go @@ -20,7 +20,10 @@ _request(Request) bool connectionFlags() string onClose() onGotInfo(*metainfo.Info) + // Drop connection. This may be a no-op if there is no connection. drop() + // Rebuke the peer + ban() String() string connStatusString() string diff --git a/peerconn.go b/peerconn.go index ed77f44442f6ce36aae35dc75e99d12e97c51a39..280a82ae411d1c085bf845dc3b9eb4fe84298f80 100644 --- a/peerconn.go +++ b/peerconn.go @@ -1595,6 +1595,10 @@ func (cn *PeerConn) drop() { cn.t.dropConnection(cn) } +func (cn *PeerConn) ban() { + cn.t.cl.banPeerIP(cn.remoteIp()) +} + func (cn *Peer) netGoodPiecesDirtied() int64 { return cn._stats.PiecesDirtiedGood.Int64() - cn._stats.PiecesDirtiedBad.Int64() } diff --git a/torrent.go b/torrent.go index d6ff2dbcd04d3f2f42ed05a69596d0b7f18d99aa..bbe57f6194c330aebd1c30f062bcf514a0f9e27a 100644 --- a/torrent.go +++ b/torrent.go @@ -2049,9 +2049,8 @@ // Turns out it's still useful to ban peers like this because if there's only a // single peer for a piece, and we never progress that piece to completion, we // will never smart-ban them. Discovered in // https://github.com/anacrolix/torrent/issues/715. - t.logger.Levelf(log.Warning, "banning %v for being sole dirtier of piece %v after failed piece check", c.remoteIp(), piece) - t.cl.banPeerIP(c.remoteIp()) - c.drop() + t.logger.Levelf(log.Warning, "banning %v for being sole dirtier of piece %v after failed piece check", c, piece) + c.ban() } } } @@ -2156,6 +2155,7 @@ "peer remote ip does not match its bannable addr [peer=%v, remote ip=%v, bannable addr=%v]", p, remoteIp, p.bannableAddr) } if _, ok := t.cl.badPeerIPs[netipAddr]; ok { + // Should this be a close? p.drop() log.Printf("dropped %v for banned remote IP %v", p, netipAddr) } diff --git a/webseed-peer.go b/webseed-peer.go index 9b1cba2233ec82f05d09a94b4a5177d3d592b138..0cdf4cacd4950300d27b2c4625fc92d10229f712 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -114,9 +114,12 @@ func (ws *webseedPeer) connectionFlags() string { return "WS" } -// TODO: This is called when banning peers. Perhaps we want to be able to ban webseeds too. We could -// return bool if this is even possible, and if it isn't, skip to the next drop candidate. +// Maybe this should drop all existing connections, or something like that. func (ws *webseedPeer) drop() {} + +func (cn *webseedPeer) ban() { + cn.peer.close() +} func (ws *webseedPeer) handleUpdateRequests() { // Because this is synchronous, webseed peers seem to get first dibs on newly prioritized