From 1f4b943454cd21d914397dc18cfcb0d566b3ddf1 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Fri, 17 Jul 2015 11:34:30 +0100 Subject: [PATCH] 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