dnsseed,zcash: occasionally retry blacklisted addresses
This commit is contained in:
parent
bba9f4436e
commit
e57eebd627
|
@ -1,6 +1,7 @@
|
|||
package dnsseed
|
||||
|
||||
import (
|
||||
crypto_rand "crypto/rand"
|
||||
"net"
|
||||
"net/url"
|
||||
"time"
|
||||
|
@ -73,10 +74,18 @@ func setup(c *caddy.Controller) error {
|
|||
// Start the update timer
|
||||
go func() {
|
||||
log.Infof("Starting update timer. Will crawl every %.0f minutes.", updateInterval.Minutes())
|
||||
randByte := []byte{0}
|
||||
for {
|
||||
select {
|
||||
case <-time.After(updateInterval):
|
||||
runCrawl(seeder)
|
||||
crypto_rand.Read(randByte[:])
|
||||
if randByte[0] >= byte(192) {
|
||||
// About 25% of the time, retry the blacklist.
|
||||
// This stops us from losing peers forever due to
|
||||
// temporary downtime.
|
||||
seeder.RetryBlacklist()
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
|
|
@ -104,6 +104,7 @@ func (bk *AddressBook) Remove(s PeerKey) {
|
|||
}
|
||||
}
|
||||
|
||||
// Blacklist adds an address to the blacklist so we won't try to connect to it again.
|
||||
func (bk *AddressBook) Blacklist(s PeerKey) {
|
||||
bk.addrState.Lock()
|
||||
defer bk.addrState.Unlock()
|
||||
|
@ -122,6 +123,16 @@ func (bk *AddressBook) Blacklist(s PeerKey) {
|
|||
}
|
||||
}
|
||||
|
||||
// Redeem removes an address from the blacklist.
|
||||
func (bk *AddressBook) Redeem(s PeerKey) {
|
||||
bk.addrState.Lock()
|
||||
defer bk.addrState.Unlock()
|
||||
|
||||
if _, ok := bk.blacklist[s]; ok {
|
||||
delete(bk.blacklist, s)
|
||||
}
|
||||
}
|
||||
|
||||
// Touch updates the last-seen timestamp if the peer is in the valid address book or does nothing if not.
|
||||
func (bk *AddressBook) Touch(s PeerKey) {
|
||||
bk.addrState.Lock()
|
||||
|
|
|
@ -426,6 +426,48 @@ func (s *Seeder) RefreshAddresses(disconnect bool) {
|
|||
s.logger.Printf("RefreshAddresses() finished.")
|
||||
}
|
||||
|
||||
// RetryBlacklist checks if the addresses in our blacklist are usable again.
|
||||
// If the trial connection succeeds, they're removed from the blacklist.
|
||||
func (s *Seeder) RetryBlacklist() {
|
||||
s.logger.Printf("Giving the blacklist another chance")
|
||||
|
||||
var blacklistQueue chan *Address
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// XXX lil awkward to allocate a channel whose size we can't determine without a lock here
|
||||
s.addrBook.enqueueAddrs(&blacklistQueue)
|
||||
|
||||
for i := 0; i < crawlerGoroutineCount; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
for len(blacklistQueue) > 0 {
|
||||
// Pull the next address off the queue
|
||||
next := <-blacklistQueue
|
||||
na := next.netaddr
|
||||
|
||||
ipString := na.IP.String()
|
||||
portString := strconv.Itoa(int(na.Port))
|
||||
|
||||
err := s.Connect(ipString, portString)
|
||||
|
||||
if err != nil {
|
||||
// Connection failed. Peer remains blacklisted.
|
||||
continue
|
||||
}
|
||||
|
||||
s.DisconnectPeer(next.asPeerKey())
|
||||
|
||||
// This would deadlock if enqueueAddrs still held the RLock.
|
||||
s.addrBook.Redeem(next.asPeerKey())
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
s.logger.Printf("RetryBlacklist() finished.")
|
||||
}
|
||||
|
||||
// WaitForAddresses waits for n addresses to be confirmed and available in the address book.
|
||||
func (s *Seeder) WaitForAddresses(n int, timeout time.Duration) error {
|
||||
done := make(chan struct{})
|
||||
|
@ -462,3 +504,8 @@ func (s *Seeder) GetPeerCount() int {
|
|||
func (s *Seeder) testBlacklist(pk PeerKey) {
|
||||
s.addrBook.Blacklist(pk)
|
||||
}
|
||||
|
||||
// testRedeen adds a peer to the blacklist directly, for testing.
|
||||
func (s *Seeder) testRedeem(pk PeerKey) {
|
||||
s.addrBook.Redeem(pk)
|
||||
}
|
||||
|
|
|
@ -231,4 +231,10 @@ func TestBlacklist(t *testing.T) {
|
|||
if err != ErrBlacklistedPeer {
|
||||
t.Errorf("Blacklist did not prevent connection")
|
||||
}
|
||||
|
||||
regSeeder.testRedeem(PeerKey("127.0.0.1:12345"))
|
||||
err = regSeeder.Connect("127.0.0.1", "12345")
|
||||
if err != nil {
|
||||
t.Errorf("Redeem didn't allow reconnecting")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue