From d68664d6c8f213a6f79e84e290a2292e5f0aa55f Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Sat, 29 Nov 2014 20:33:17 -0600
Subject: [PATCH] Some changes to block list handling

---
 client.go | 37 +++++++++++++++++++++++++++----------
 1 file changed, 27 insertions(+), 10 deletions(-)

diff --git a/client.go b/client.go
index 2da4d5b4..b3eb7d99 100644
--- a/client.go
+++ b/client.go
@@ -63,6 +63,7 @@ var (
 	unsuccessfulDials           = expvar.NewInt("unsuccessfulDials")
 	successfulDials             = expvar.NewInt("successfulDials")
 	acceptedConns               = expvar.NewInt("acceptedConns")
+	inboundConnsBlocked         = expvar.NewInt("inboundConnsBlocked")
 )
 
 const (
@@ -146,6 +147,9 @@ func (me *Client) SetIPBlockList(list *iplist.IPList) {
 	me.mu.Lock()
 	defer me.mu.Unlock()
 	me.ipBlockList = list
+	if me.dHT != nil {
+		me.dHT.SetIPBlockList(list)
+	}
 }
 
 func (me *Client) PeerID() string {
@@ -427,15 +431,12 @@ func (me *Client) Stop() {
 	me.mu.Unlock()
 }
 
-func (cl *Client) ipBlocked(ip net.IP) bool {
+func (cl *Client) ipBlockRange(ip net.IP) (r *iplist.Range) {
 	if cl.ipBlockList == nil {
-		return false
-	}
-	if r := cl.ipBlockList.Lookup(ip); r != nil {
-		log.Printf("IP blocked: %s in range %s-%s: %s", ip, r.First, r.Last, r.Description)
-		return true
+		return
 	}
-	return false
+	r = cl.ipBlockList.Lookup(ip)
+	return
 }
 
 func (cl *Client) acceptConnections(l net.Listener, utp bool) {
@@ -457,9 +458,11 @@ func (cl *Client) acceptConnections(l net.Listener, utp bool) {
 		}
 		acceptedConns.Add(1)
 		cl.mu.RLock()
-		blocked := cl.ipBlocked(AddrIP(conn.RemoteAddr()))
+		blockRange := cl.ipBlockRange(AddrIP(conn.RemoteAddr()))
 		cl.mu.RUnlock()
-		if blocked {
+		if blockRange != nil {
+			inboundConnsBlocked.Add(1)
+			log.Printf("inbound connection from %s blocked by %s", conn.RemoteAddr(), blockRange)
 			continue
 		}
 		go func() {
@@ -529,7 +532,8 @@ func (me *Client) initiateConn(peer Peer, t *torrent) {
 		duplicateConnsAvoided.Add(1)
 		return
 	}
-	if me.ipBlocked(peer.IP) {
+	if r := me.ipBlockRange(peer.IP); r != nil {
+		log.Printf("outbound connect to %s blocked by IP blocklist rule %s", peer.IP, r)
 		return
 	}
 	dialTimeout := reducedDialTimeout(nominalDialTimeout, me.halfOpenLimit, len(t.Peers))
@@ -1275,6 +1279,19 @@ func (me *Client) AddPeers(infoHash InfoHash, peers []Peer) error {
 	if t == nil {
 		return errors.New("no such torrent")
 	}
+	blocked := 0
+	for i, p := range peers {
+		if me.ipBlockRange(p.IP) == nil {
+			continue
+		}
+		peers[i] = peers[len(peers)-1]
+		peers = peers[:len(peers)-1]
+		i--
+		blocked++
+	}
+	if blocked != 0 {
+		log.Printf("IP blocklist screened %d peers from being added", blocked)
+	}
 	t.AddPeers(peers)
 	me.openNewConns(t)
 	return nil
-- 
2.51.0