keksvpn/pkg/ipfunc/ipfunc.go
2022-02-28 16:17:42 +01:00

79 lines
No EOL
1.2 KiB
Go

package ipfunc
import (
"errors"
"fmt"
"net"
"sync"
)
type IPSubnet struct {
freeIPs []string
mux sync.Mutex
}
func NewIPSubnet(network string) (IPSubnet, error) {
i := IPSubnet{}
ip, ipnet, err := net.ParseCIDR(network)
if err != nil {
return IPSubnet{}, fmt.Errorf("Cant create IPSubnet, input ip cant pase: %w", err)
}
var ips []string
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
lenIPs := len(ips)
switch {
case lenIPs < 2:
i.freeIPs = ips
default:
i.freeIPs = ips[1 : len(ips)-1]
}
return i, nil
}
func (i *IPSubnet) GetNextFreeIP() (string, error) {
if len(i.freeIPs) == 0 {
return "", errors.New("No free IP")
}
i.mux.Lock()
defer i.mux.Unlock()
rip := i.freeIPs[0]
i.remove(rip)
return rip, nil
}
func (i *IPSubnet) remove (ip string) {
var newips []string
for _, oneIp := range i.freeIPs {
if oneIp != ip {
newips = append(newips, oneIp)
}
}
i.freeIPs = newips
}
func (i *IPSubnet)Remove(ip string) {
i.mux.Lock()
defer i.mux.Unlock()
i.remove(ip)
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}