From 68e3b9f666b72f0313c4e58dd7bee90b7d9246c0 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Tue, 4 Aug 2015 00:31:53 +1000 Subject: [PATCH] dht: Block bad nodes, start by banning those that send port=0 --- client.go | 2 +- dht/announce.go | 14 ++++++++++++++ dht/dht.go | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/client.go b/client.go index 465f1062..dc5b66fd 100644 --- a/client.go +++ b/client.go @@ -226,7 +226,7 @@ func (cl *Client) WriteStatus(_w io.Writer) { fmt.Fprintf(w, "Peer ID: %+q\n", cl.peerID) if cl.dHT != nil { dhtStats := cl.dHT.Stats() - fmt.Fprintf(w, "DHT nodes: %d (%d good)\n", dhtStats.Nodes, dhtStats.GoodNodes) + fmt.Fprintf(w, "DHT nodes: %d (%d good, %d banned)\n", dhtStats.Nodes, dhtStats.GoodNodes, dhtStats.BadNodes) fmt.Fprintf(w, "DHT Server ID: %x\n", cl.dHT.ID()) fmt.Fprintf(w, "DHT port: %d\n", addrPort(cl.dHT.Addr())) fmt.Fprintf(w, "DHT announces: %d\n", dhtStats.ConfirmedAnnounces) diff --git a/dht/announce.go b/dht/announce.go index 75a9558e..3b9dc32f 100644 --- a/dht/announce.go +++ b/dht/announce.go @@ -108,6 +108,12 @@ func (me *Announce) gotNodeAddr(addr dHTAddr) { if me.server.ipBlocked(addr.UDPAddr().IP) { return } + me.server.mu.Lock() + if me.server.badNodes.Test([]byte(addr.String())) { + me.server.mu.Unlock() + return + } + me.server.mu.Unlock() me.contact(addr) } @@ -162,6 +168,14 @@ func (me *Announce) getPeers(addr dHTAddr) error { me.mu.Unlock() if vs := m.Values(); vs != nil { + for _, cp := range vs { + if cp.Port == 0 { + me.server.mu.Lock() + me.server.badNode(addr) + me.server.mu.Unlock() + return + } + } nodeInfo := NodeInfo{ Addr: t.remoteAddr, } diff --git a/dht/dht.go b/dht/dht.go index ed544f60..5db6adb4 100644 --- a/dht/dht.go +++ b/dht/dht.go @@ -22,6 +22,7 @@ import ( "github.com/anacrolix/missinggo" "github.com/anacrolix/sync" + "github.com/tylertreat/BoomFilters" "github.com/anacrolix/torrent/bencode" "github.com/anacrolix/torrent/iplist" @@ -50,6 +51,7 @@ type Server struct { closed chan struct{} passive bool // Don't respond to queries. ipBlockList *iplist.IPList + badNodes *boom.BloomFilter numConfirmedAnnounces int bootstrapNodes []string @@ -81,6 +83,8 @@ type ServerStats struct { OutstandingTransactions int // Individual announce_peer requests that got a success response. ConfirmedAnnounces int + // Nodes that have been blocked. + BadNodes uint } // Returns statistics for the server. @@ -95,6 +99,7 @@ func (s *Server) Stats() (ss ServerStats) { ss.Nodes = len(s.nodes) ss.OutstandingTransactions = len(s.transactions) ss.ConfirmedAnnounces = s.numConfirmedAnnounces + ss.BadNodes = s.badNodes.Count() return } @@ -121,6 +126,7 @@ func NewServer(c *ServerConfig) (s *Server, err error) { s = &Server{ config: *c, ipBlockList: c.IPBlocklist, + badNodes: boom.NewBloomFilter(1000, 0.1), } if c.Conn != nil { s.socket = c.Conn @@ -790,6 +796,9 @@ func (s *Server) getNode(addr dHTAddr, id string) (n *node) { if !s.config.NoSecurity && !n.IsSecure() { return } + if s.badNodes.Test([]byte(addrStr)) { + return + } s.nodes[addrStr] = n return } @@ -1214,3 +1223,8 @@ func (s *Server) closestNodes(k int, target nodeID, filter func(*node) bool) []* } return ret } + +func (me *Server) badNode(addr dHTAddr) { + me.badNodes.Add([]byte(addr.String())) + delete(me.nodes, addr.String()) +} -- 2.48.1