"github.com/anacrolix/libtorgo/bencode"
)
+const maxNodes = 10000
+
// Uniquely identifies a transaction to us.
type transactionKey struct {
RemoteAddr string // host:port
s.mu.Lock()
defer s.mu.Unlock()
for _, n := range s.nodes {
- if n.Good() {
+ if n.DefinitelyGood() {
ss.NumGoodNodes++
}
}
return
}
-func (n *Node) Good() bool {
+func (n *Node) DefinitelyGood() bool {
if len(n.id) != 20 {
return false
}
if n.lastSentQuery.Before(n.lastGotResponse) {
return true
}
- if time.Now().Sub(n.lastSentQuery) >= 2*time.Minute {
- return false
- }
return true
}
}
func (t *transaction) timeout() {
+ go func() {
+ t.s.mu.Lock()
+ defer t.s.mu.Unlock()
+ t.s.nodeTimedOut(t.remoteAddr)
+ }()
t.close()
}
if t.closing() {
return
}
+ t.queryPacket = nil
close(t.Response)
close(t.done)
t.timer.Stop()
if t.onResponse != nil {
t.onResponse(m)
}
+ t.queryPacket = nil
select {
case t.Response <- m:
default:
return
}
}
- log.Printf("%s: received bad krpc message: %s: %q", s, err, b)
+ log.Printf("%s: received bad krpc message from %s: %s: %q", s, addr, err, b)
}()
return
}
n = &Node{
addr: addr,
}
- s.nodes[addr.String()] = n
+ if len(s.nodes) < maxNodes {
+ s.nodes[addr.String()] = n
+ }
}
return
}
+func (s *Server) nodeTimedOut(addr dHTAddr) {
+ node, ok := s.nodes[addr.String()]
+ if !ok {
+ return
+ }
+ if node.DefinitelyGood() {
+ return
+ }
+ if len(s.nodes) < maxNodes {
+ return
+ }
+ delete(s.nodes, addr.String())
+}
func (s *Server) writeToNode(b []byte, node dHTAddr) (err error) {
if list := s.ipBlockList; list != nil {
s.mu.Lock()
defer s.mu.Unlock()
for _, node := range s.closestNodes(160, infoHash, func(n *Node) bool {
- return n.Good() && n.announceToken != ""
+ return n.announceToken != ""
}) {
err = s.announcePeer(node.addr, infoHash, port, node.announceToken, impliedPort)
if err != nil {
func (s *Server) numGoodNodes() (num int) {
for _, n := range s.nodes {
- if n.Good() {
+ if n.DefinitelyGood() {
num++
}
}
// }
func (s *Server) closestGoodNodes(k int, targetID string) []*Node {
- return s.closestNodes(k, targetID, func(n *Node) bool { return n.Good() })
+ return s.closestNodes(k, targetID, func(n *Node) bool { return n.DefinitelyGood() })
}
func (s *Server) closestNodes(k int, targetID string, filter func(*Node) bool) []*Node {