From 0eef96e1c8c0dc1323d5f1d69f7874f21f4bc3ed Mon Sep 17 00:00:00 2001 From: David Hill Date: Mon, 6 Apr 2015 12:13:00 -0400 Subject: [PATCH] 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 --- addrmgr/addrmanager.go | 19 +++---------------- addrmgr/addrmanager_test.go | 10 +++++----- server.go | 6 +----- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index dd1734c1..318fd6d8 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -12,7 +12,6 @@ import ( "encoding/json" "fmt" "io" - "math" "math/rand" "net" "os" @@ -741,7 +740,7 @@ func NetAddressKey(na *wire.NetAddress) string { // random one from the possible addresses with preference given to ones that // have not been used recently and should not pick 'close' addresses // consecutively. -func (a *AddrManager) GetAddress(class string, newBias int) *KnownAddress { +func (a *AddrManager) GetAddress(class string) *KnownAddress { // Protect concurrent access. a.mtx.Lock() defer a.mtx.Unlock() @@ -750,20 +749,8 @@ func (a *AddrManager) GetAddress(class string, newBias int) *KnownAddress { return nil } - if newBias > 100 { - newBias = 100 - } - 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 { + // Use a 50% chance for choosing between tried and new table entries. + if a.nTried > 0 && (a.nNew == 0 || a.rand.Intn(2) == 0) { // Tried entry. large := 1 << 30 factor := 1.0 diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 28262ea9..7e1d2384 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -221,7 +221,7 @@ func TestAttempt(t *testing.T) { if err != nil { t.Fatalf("Adding address failed: %v", err) } - ka := n.GetAddress("any", 100) + ka := n.GetAddress("any") if !ka.LastAttempt().IsZero() { t.Errorf("Address should not have attempts, but does") @@ -243,7 +243,7 @@ func TestConnected(t *testing.T) { if err != nil { t.Fatalf("Adding address failed: %v", err) } - ka := n.GetAddress("any", 100) + ka := n.GetAddress("any") na := ka.NetAddress() 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) // 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) } @@ -343,7 +343,7 @@ func TestGetAddress(t *testing.T) { if err != nil { 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 { 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 n.Good(ka.NetAddress()) - ka = n.GetAddress("any", -10) // 0 bias is min, but shouldn't error + ka = n.GetAddress("any") if ka == nil { t.Fatalf("Did not get an address where there is one in the pool") } diff --git a/server.go b/server.go index 9a17c60e..160c9c6f 100644 --- a/server.go +++ b/server.go @@ -695,15 +695,11 @@ out: tries := 0 for state.NeedMoreOutbound() && 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() if nPeers > 8 { nPeers = 8 } - addr := s.addrManager.GetAddress("any", 10+nPeers*10) + addr := s.addrManager.GetAddress("any") if addr == nil { break }