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)
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)
}
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,
}
"github.com/anacrolix/missinggo"
"github.com/anacrolix/sync"
+ "github.com/tylertreat/BoomFilters"
"github.com/anacrolix/torrent/bencode"
"github.com/anacrolix/torrent/iplist"
closed chan struct{}
passive bool // Don't respond to queries.
ipBlockList *iplist.IPList
+ badNodes *boom.BloomFilter
numConfirmedAnnounces int
bootstrapNodes []string
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.
ss.Nodes = len(s.nodes)
ss.OutstandingTransactions = len(s.transactions)
ss.ConfirmedAnnounces = s.numConfirmedAnnounces
+ ss.BadNodes = s.badNodes.Count()
return
}
s = &Server{
config: *c,
ipBlockList: c.IPBlocklist,
+ badNodes: boom.NewBloomFilter(1000, 0.1),
}
if c.Conn != nil {
s.socket = c.Conn
if !s.config.NoSecurity && !n.IsSecure() {
return
}
+ if s.badNodes.Test([]byte(addrStr)) {
+ return
+ }
s.nodes[addrStr] = n
return
}
}
return ret
}
+
+func (me *Server) badNode(addr dHTAddr) {
+ me.badNodes.Add([]byte(addr.String()))
+ delete(me.nodes, addr.String())
+}