addrmgr: Always use a 50% chance between tried and new entries.
This change was suggested as Countermeasure 2 in Eclipse Attacks on Bitcoin's Peer-to-Peer Network, Ethan Heilman, Alison Kendler, Aviv Zohar, Sharon Goldberg. ePrint Archive Report 2015/263. March 2015. This mimics Bitcoin Core commit c6a63ceeb4956933588995bcf01dc3095aaeb1fc
This commit is contained in:
parent
320ecea6a0
commit
0eef96e1c8
3 changed files with 9 additions and 26 deletions
|
@ -12,7 +12,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -741,7 +740,7 @@ func NetAddressKey(na *wire.NetAddress) string {
|
||||||
// random one from the possible addresses with preference given to ones that
|
// random one from the possible addresses with preference given to ones that
|
||||||
// have not been used recently and should not pick 'close' addresses
|
// have not been used recently and should not pick 'close' addresses
|
||||||
// consecutively.
|
// consecutively.
|
||||||
func (a *AddrManager) GetAddress(class string, newBias int) *KnownAddress {
|
func (a *AddrManager) GetAddress(class string) *KnownAddress {
|
||||||
// Protect concurrent access.
|
// Protect concurrent access.
|
||||||
a.mtx.Lock()
|
a.mtx.Lock()
|
||||||
defer a.mtx.Unlock()
|
defer a.mtx.Unlock()
|
||||||
|
@ -750,20 +749,8 @@ func (a *AddrManager) GetAddress(class string, newBias int) *KnownAddress {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if newBias > 100 {
|
// Use a 50% chance for choosing between tried and new table entries.
|
||||||
newBias = 100
|
if a.nTried > 0 && (a.nNew == 0 || a.rand.Intn(2) == 0) {
|
||||||
}
|
|
||||||
if newBias < 0 {
|
|
||||||
newBias = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bias between new and tried addresses.
|
|
||||||
triedCorrelation := math.Sqrt(float64(a.nTried)) *
|
|
||||||
(100.0 - float64(newBias))
|
|
||||||
newCorrelation := math.Sqrt(float64(a.nNew)) * float64(newBias)
|
|
||||||
|
|
||||||
if ((newCorrelation + triedCorrelation) * a.rand.Float64()) <
|
|
||||||
triedCorrelation {
|
|
||||||
// Tried entry.
|
// Tried entry.
|
||||||
large := 1 << 30
|
large := 1 << 30
|
||||||
factor := 1.0
|
factor := 1.0
|
||||||
|
|
|
@ -221,7 +221,7 @@ func TestAttempt(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Adding address failed: %v", err)
|
t.Fatalf("Adding address failed: %v", err)
|
||||||
}
|
}
|
||||||
ka := n.GetAddress("any", 100)
|
ka := n.GetAddress("any")
|
||||||
|
|
||||||
if !ka.LastAttempt().IsZero() {
|
if !ka.LastAttempt().IsZero() {
|
||||||
t.Errorf("Address should not have attempts, but does")
|
t.Errorf("Address should not have attempts, but does")
|
||||||
|
@ -243,7 +243,7 @@ func TestConnected(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Adding address failed: %v", err)
|
t.Fatalf("Adding address failed: %v", err)
|
||||||
}
|
}
|
||||||
ka := n.GetAddress("any", 100)
|
ka := n.GetAddress("any")
|
||||||
na := ka.NetAddress()
|
na := ka.NetAddress()
|
||||||
na.Timestamp = time.Now().Add(time.Hour * -1) // make it an hour ago
|
na.Timestamp = time.Now().Add(time.Hour * -1) // make it an hour ago
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ func TestGetAddress(t *testing.T) {
|
||||||
n := addrmgr.New("testgetaddress", lookupFunc)
|
n := addrmgr.New("testgetaddress", lookupFunc)
|
||||||
|
|
||||||
// Get an address from an empty set (should error)
|
// Get an address from an empty set (should error)
|
||||||
if rv := n.GetAddress("any", 10); rv != nil {
|
if rv := n.GetAddress("any"); rv != nil {
|
||||||
t.Errorf("GetAddress failed: got: %v want: %v\n", rv, nil)
|
t.Errorf("GetAddress failed: got: %v want: %v\n", rv, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ func TestGetAddress(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Adding address failed: %v", err)
|
t.Fatalf("Adding address failed: %v", err)
|
||||||
}
|
}
|
||||||
ka := n.GetAddress("any", 120) // 100 bias is max, but shouldn't error
|
ka := n.GetAddress("any")
|
||||||
if ka == nil {
|
if ka == nil {
|
||||||
t.Fatalf("Did not get an address where there is one in the pool")
|
t.Fatalf("Did not get an address where there is one in the pool")
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,7 @@ func TestGetAddress(t *testing.T) {
|
||||||
|
|
||||||
// Mark this as a good address and get it
|
// Mark this as a good address and get it
|
||||||
n.Good(ka.NetAddress())
|
n.Good(ka.NetAddress())
|
||||||
ka = n.GetAddress("any", -10) // 0 bias is min, but shouldn't error
|
ka = n.GetAddress("any")
|
||||||
if ka == nil {
|
if ka == nil {
|
||||||
t.Fatalf("Did not get an address where there is one in the pool")
|
t.Fatalf("Did not get an address where there is one in the pool")
|
||||||
}
|
}
|
||||||
|
|
|
@ -695,15 +695,11 @@ out:
|
||||||
tries := 0
|
tries := 0
|
||||||
for state.NeedMoreOutbound() &&
|
for state.NeedMoreOutbound() &&
|
||||||
atomic.LoadInt32(&s.shutdown) == 0 {
|
atomic.LoadInt32(&s.shutdown) == 0 {
|
||||||
// We bias like bitcoind does, 10 for no outgoing
|
|
||||||
// up to 90 (8) for the selection of new vs tried
|
|
||||||
//addresses.
|
|
||||||
|
|
||||||
nPeers := state.OutboundCount()
|
nPeers := state.OutboundCount()
|
||||||
if nPeers > 8 {
|
if nPeers > 8 {
|
||||||
nPeers = 8
|
nPeers = 8
|
||||||
}
|
}
|
||||||
addr := s.addrManager.GetAddress("any", 10+nPeers*10)
|
addr := s.addrManager.GetAddress("any")
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue