From f4d6e028d47215150826b794caebb8aee5bed59e Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 17 Jul 2015 11:33:29 +0100 Subject: [PATCH 1/4] Simplify --- ipam/allocator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipam/allocator.go b/ipam/allocator.go index 8137cb33..4e47cf11 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -64,7 +64,7 @@ func NewAllocator(ourName router.PeerName, ourUID router.PeerUID, ourNickname st return &Allocator{ ourName: ourName, universe: universe, - ring: ring.New(universe.Start, address.Add(universe.Start, universe.Size()), ourName), + ring: ring.New(universe.Start, universe.End, ourName), owned: make(map[string][]address.Address), paxos: paxos.NewNode(ourName, ourUID, quorum), nicknames: map[router.PeerName]string{ourName: ourNickname}, From 1f4b943454cd21d914397dc18cfcb0d566b3ddf1 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 17 Jul 2015 11:34:30 +0100 Subject: [PATCH 2/4] More helpful error message when --ip-alloc-range mismatched --- ipam/allocator.go | 4 ++++ ipam/ring/ring.go | 4 ++++ net/address/address.go | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/ipam/allocator.go b/ipam/allocator.go index 4e47cf11..2960168f 100644 --- a/ipam/allocator.go +++ b/ipam/allocator.go @@ -613,6 +613,10 @@ func (alloc *Allocator) update(sender router.PeerName, msg []byte) error { // shouldn't get updates for a empty Ring. But tolerate // them just in case. if data.Ring != nil { + if data.Ring.Range() != alloc.universe { + return fmt.Errorf("Incompatible IP allocation range %s; ours is %s", + data.Ring.Range().AsCIDRString(), alloc.universe.AsCIDRString()) + } err = alloc.ring.Merge(*data.Ring) if !alloc.ring.Empty() { alloc.pruneNicknames() diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 11d53126..4adea6ae 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -92,6 +92,10 @@ func New(start, end address.Address, peer router.PeerName) *Ring { return ring } +func (r *Ring) Range() address.Range { + return address.Range{Start: r.Start, End: r.End} +} + // Returns the distance between two tokens on this ring, dealing // with ranges which cross the origin func (r *Ring) distance(start, end address.Address) address.Offset { diff --git a/net/address/address.go b/net/address/address.go index f3faf138..b5ffb265 100644 --- a/net/address/address.go +++ b/net/address/address.go @@ -23,6 +23,17 @@ func (r Range) String() string { return fmt.Sprintf("[%s-%s)", r.Sta func (r Range) Overlaps(or Range) bool { return !(r.Start >= or.End || r.End <= or.Start) } func (r Range) Contains(addr Address) bool { return addr >= r.Start && addr < r.End } +func (r Range) AsCIDRString() string { + prefixLen := 32 + for size := r.Size(); size > 1; size = size / 2 { + if size%2 != 0 { // Size not a power of two; cannot be expressed as a CIDR. + return r.String() + } + prefixLen-- + } + return CIDR{Start: r.Start, PrefixLen: prefixLen}.String() +} + type CIDR struct { Start Address PrefixLen int From 9b2c5b8466002329fc4c401428d31cb5e10f3b5e Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 17 Jul 2015 11:56:25 +0100 Subject: [PATCH 3/4] Improve description of merge error --- ipam/ring/ring.go | 22 +++++++++++----------- ipam/ring/ring_test.go | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 4adea6ae..9faf016a 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -33,16 +33,16 @@ func (r *Ring) assertInvariants() { // Errors returned by Merge var ( - ErrNotSorted = errors.New("Ring not sorted") - ErrTokenRepeated = errors.New("Token appears twice in ring") - ErrTokenOutOfRange = errors.New("Token is out of range") - ErrDifferentSubnets = errors.New("IP Allocator with different subnet detected") - ErrNewerVersion = errors.New("Received new version for entry I own!") - ErrInvalidEntry = errors.New("Received invalid state update!") - ErrEntryInMyRange = errors.New("Received new entry in my range!") - ErrNoFreeSpace = errors.New("No free space found!") - ErrInvalidTimeout = errors.New("dt must be greater than 0") - ErrNotFound = errors.New("No entries for peer found") + ErrNotSorted = errors.New("Ring not sorted") + ErrTokenRepeated = errors.New("Token appears twice in ring") + ErrTokenOutOfRange = errors.New("Token is out of range") + ErrDifferentRange = errors.New("Received range differs from ours!") + ErrNewerVersion = errors.New("Received new version for entry I own!") + ErrInvalidEntry = errors.New("Received invalid state update!") + ErrEntryInMyRange = errors.New("Received new entry in my range!") + ErrNoFreeSpace = errors.New("No free space found!") + ErrInvalidTimeout = errors.New("dt must be greater than 0") + ErrNotFound = errors.New("No entries for peer found") ) func (r *Ring) checkInvariants() error { @@ -191,7 +191,7 @@ func (r *Ring) Merge(gossip Ring) error { } if r.Start != gossip.Start || r.End != gossip.End { - return ErrDifferentSubnets + return ErrDifferentRange } // Now merge their ring with yours, in a temporary ring. diff --git a/ipam/ring/ring_test.go b/ipam/ring/ring_test.go index e29c3a5e..c9ab789b 100644 --- a/ipam/ring/ring_test.go +++ b/ipam/ring/ring_test.go @@ -212,7 +212,7 @@ func TestMergeErrors(t *testing.T) { // Should Merge two rings for different ranges ring2 = New(start, middle, peer2name) ring2.Entries = []*entry{} - require.True(t, ring1.Merge(*ring2) == ErrDifferentSubnets, "Expected ErrDifferentSubnets") + require.True(t, ring1.Merge(*ring2) == ErrDifferentRange, "Expected ErrDifferentRange") // Cannot Merge newer version of entry I own ring2 = New(start, end, peer2name) From 2dbf83889b7677e2d72830fe37e619c2ebc37e8f Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 17 Jul 2015 12:19:54 +0100 Subject: [PATCH 4/4] Remove unused error messages --- ipam/ring/ring.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/ipam/ring/ring.go b/ipam/ring/ring.go index 9faf016a..6021efcc 100644 --- a/ipam/ring/ring.go +++ b/ipam/ring/ring.go @@ -40,8 +40,6 @@ var ( ErrNewerVersion = errors.New("Received new version for entry I own!") ErrInvalidEntry = errors.New("Received invalid state update!") ErrEntryInMyRange = errors.New("Received new entry in my range!") - ErrNoFreeSpace = errors.New("No free space found!") - ErrInvalidTimeout = errors.New("dt must be greater than 0") ErrNotFound = errors.New("No entries for peer found") )