dht: Limit the size of peer discovery backlog
This commit is contained in:
parent
a081ad63d9
commit
fa501ed06a
|
@ -156,7 +156,7 @@ func (n *Node) DefinitelyGood() bool {
|
||||||
if len(n.id) != 20 {
|
if len(n.id) != 20 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// No reason to think ill of them if they've never responded.
|
// No reason to think ill of them if they've never been queried.
|
||||||
if n.lastSentQuery.IsZero() {
|
if n.lastSentQuery.IsZero() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,10 @@ type peerDiscovery struct {
|
||||||
infoHash string
|
infoHash string
|
||||||
}
|
}
|
||||||
|
|
||||||
const parallelQueries = 100
|
const (
|
||||||
|
parallelQueries = 100
|
||||||
|
backlogMaxLen = 10000
|
||||||
|
)
|
||||||
|
|
||||||
func (me *peerDiscovery) Close() {
|
func (me *peerDiscovery) Close() {
|
||||||
me.peerStream.Close()
|
me.peerStream.Close()
|
||||||
|
@ -43,12 +46,29 @@ func (s *Server) GetPeers(infoHash string) (*peerStream, error) {
|
||||||
peerStream: &peerStream{
|
peerStream: &peerStream{
|
||||||
Values: make(chan peerStreamValue),
|
Values: make(chan peerStreamValue),
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
|
values: make(chan peerStreamValue),
|
||||||
},
|
},
|
||||||
triedAddrs: make(map[string]struct{}, 500),
|
triedAddrs: make(map[string]struct{}, 500),
|
||||||
backlog: make(map[string]net.Addr, parallelQueries),
|
backlog: make(map[string]net.Addr, parallelQueries),
|
||||||
server: s,
|
server: s,
|
||||||
infoHash: infoHash,
|
infoHash: infoHash,
|
||||||
}
|
}
|
||||||
|
// Function ferries from values to Values until discovery is halted.
|
||||||
|
go func() {
|
||||||
|
defer close(disc.Values)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case psv := <-disc.values:
|
||||||
|
select {
|
||||||
|
case disc.Values <- psv:
|
||||||
|
case <-disc.stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-disc.stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
disc.mu.Lock()
|
disc.mu.Lock()
|
||||||
for _, addr := range startAddrs {
|
for _, addr := range startAddrs {
|
||||||
disc.contact(addr)
|
disc.contact(addr)
|
||||||
|
@ -72,7 +92,9 @@ func (me *peerDiscovery) gotNodeAddr(addr net.Addr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if me.pending >= parallelQueries {
|
if me.pending >= parallelQueries {
|
||||||
me.backlog[addr.String()] = addr
|
if len(me.backlog) < backlogMaxLen {
|
||||||
|
me.backlog[addr.String()] = addr
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
me.contact(addr)
|
me.contact(addr)
|
||||||
}
|
}
|
||||||
|
@ -89,7 +111,6 @@ func (me *peerDiscovery) contact(addr net.Addr) {
|
||||||
|
|
||||||
func (me *peerDiscovery) transactionClosed() {
|
func (me *peerDiscovery) transactionClosed() {
|
||||||
me.pending--
|
me.pending--
|
||||||
// log.Printf("pending: %d", me.pending)
|
|
||||||
for key, addr := range me.backlog {
|
for key, addr := range me.backlog {
|
||||||
if me.pending >= parallelQueries {
|
if me.pending >= parallelQueries {
|
||||||
break
|
break
|
||||||
|
@ -140,7 +161,7 @@ func (me *peerDiscovery) getPeers(addr net.Addr) error {
|
||||||
}()
|
}()
|
||||||
copy(nodeInfo.ID[:], id)
|
copy(nodeInfo.ID[:], id)
|
||||||
select {
|
select {
|
||||||
case me.peerStream.Values <- peerStreamValue{
|
case me.peerStream.values <- peerStreamValue{
|
||||||
Peers: vs,
|
Peers: vs,
|
||||||
NodeInfo: nodeInfo,
|
NodeInfo: nodeInfo,
|
||||||
}:
|
}:
|
||||||
|
@ -157,10 +178,6 @@ func (me *peerDiscovery) getPeers(addr net.Addr) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (me *peerDiscovery) streamValue(psv peerStreamValue) {
|
|
||||||
me.peerStream.Values <- psv
|
|
||||||
}
|
|
||||||
|
|
||||||
type peerStreamValue struct {
|
type peerStreamValue struct {
|
||||||
Peers []util.CompactPeer // Peers given in get_peers response.
|
Peers []util.CompactPeer // Peers given in get_peers response.
|
||||||
NodeInfo // The node that gave the response.
|
NodeInfo // The node that gave the response.
|
||||||
|
@ -169,6 +186,8 @@ type peerStreamValue struct {
|
||||||
type peerStream struct {
|
type peerStream struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
Values chan peerStreamValue
|
Values chan peerStreamValue
|
||||||
|
// Inner chan is set to nil when on close.
|
||||||
|
values chan peerStreamValue
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +198,5 @@ func (ps *peerStream) Close() {
|
||||||
case <-ps.stop:
|
case <-ps.stop:
|
||||||
default:
|
default:
|
||||||
close(ps.stop)
|
close(ps.stop)
|
||||||
close(ps.Values)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue