]> Sergey Matveev's repositories - btrtrc.git/commitdiff
dht: Block bad nodes, start by banning those that send port=0
authorMatt Joiner <anacrolix@gmail.com>
Mon, 3 Aug 2015 14:31:53 +0000 (00:31 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Mon, 3 Aug 2015 14:31:53 +0000 (00:31 +1000)
client.go
dht/announce.go
dht/dht.go

index 465f10629d82698a3a9e7d2679266537ddd20c2e..dc5b66fd921b1ad7340a08e8a0fe7c995b9312f0 100644 (file)
--- 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)
index 75a9558e643779cafc4986faa547de335ba02c7e..3b9dc32f3e0fad94eaedf3d5900f5acf4d6b16d1 100644 (file)
@@ -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,
                        }
index ed544f6066163216b9bca3497cf78682f76c96e7..5db6adb4c236d3e44811d2d29b46b6ef29fecd0e 100644 (file)
@@ -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())
+}