Feature: support fakeip
This commit is contained in:
50
component/fakeip/pool.go
Normal file
50
component/fakeip/pool.go
Normal file
@ -0,0 +1,50 @@
|
||||
package fakeip
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
// Pool is a implementation about fake ip generator without storage
|
||||
type Pool struct {
|
||||
max uint32
|
||||
min uint32
|
||||
offset uint32
|
||||
}
|
||||
|
||||
// Get return a new fake ip
|
||||
func (p *Pool) Get() net.IP {
|
||||
ip := uintToIP(p.min + p.offset)
|
||||
p.offset = (p.offset + 1) % (p.max - p.min)
|
||||
return ip
|
||||
}
|
||||
|
||||
func ipToUint(ip net.IP) uint32 {
|
||||
v := uint32(ip[0]) << 24
|
||||
v += uint32(ip[1]) << 16
|
||||
v += uint32(ip[2]) << 8
|
||||
v += uint32(ip[3])
|
||||
return v
|
||||
}
|
||||
|
||||
func uintToIP(v uint32) net.IP {
|
||||
return net.IPv4(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
|
||||
}
|
||||
|
||||
// New return Pool instance
|
||||
func New(ipnet *net.IPNet) (*Pool, error) {
|
||||
min := ipToUint(ipnet.IP) + 1
|
||||
|
||||
ones, bits := ipnet.Mask.Size()
|
||||
total := 1<<uint(bits-ones) - 2
|
||||
|
||||
if total <= 0 {
|
||||
return nil, errors.New("ipnet don't have valid ip")
|
||||
}
|
||||
|
||||
max := min + uint32(total)
|
||||
return &Pool{
|
||||
min: min,
|
||||
max: max,
|
||||
}, nil
|
||||
}
|
44
component/fakeip/pool_test.go
Normal file
44
component/fakeip/pool_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
package fakeip
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPool_Basic(t *testing.T) {
|
||||
_, ipnet, _ := net.ParseCIDR("192.168.0.1/30")
|
||||
pool, _ := New(ipnet)
|
||||
|
||||
first := pool.Get()
|
||||
last := pool.Get()
|
||||
|
||||
if !first.Equal(net.IP{192, 168, 0, 1}) {
|
||||
t.Error("should get right first ip, instead of", first.String())
|
||||
}
|
||||
|
||||
if !last.Equal(net.IP{192, 168, 0, 2}) {
|
||||
t.Error("should get right last ip, instead of", first.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPool_Cycle(t *testing.T) {
|
||||
_, ipnet, _ := net.ParseCIDR("192.168.0.1/30")
|
||||
pool, _ := New(ipnet)
|
||||
|
||||
first := pool.Get()
|
||||
pool.Get()
|
||||
same := pool.Get()
|
||||
|
||||
if !first.Equal(same) {
|
||||
t.Error("should return same ip", first.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPool_Error(t *testing.T) {
|
||||
_, ipnet, _ := net.ParseCIDR("192.168.0.1/31")
|
||||
_, err := New(ipnet)
|
||||
|
||||
if err == nil {
|
||||
t.Error("should return err")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user