Do not assume IPv4 during address generation

This commit is contained in:
Csaba Sarkadi 2021-10-31 16:05:08 +01:00
parent b6d0c4f2aa
commit 46cdce00af
2 changed files with 15 additions and 19 deletions

View file

@ -141,36 +141,32 @@ func (h *Headscale) getAvailableIP() (*netaddr.IP, error) {
return nil, err return nil, err
} }
ipPrefixNetworkAddress, ipPrefixBroadcastAddress := func() (netaddr.IP, netaddr.IP) {
ipRange := ipPrefix.Range()
return ipRange.From(), ipRange.To()
}()
// Get the first IP in our prefix // Get the first IP in our prefix
ip := ipPrefix.IP() ip := ipPrefixNetworkAddress.Next()
for { for {
if !ipPrefix.Contains(ip) { if !ipPrefix.Contains(ip) {
return nil, errCouldNotAllocateIP return nil, errCouldNotAllocateIP
} }
// Some OS (including Linux) does not like when IPs ends with 0 or 255, which switch {
// is typically called network or broadcast. Lets avoid them and continue case ip.Compare(ipPrefixBroadcastAddress) == 0:
// to look when we get one of those traditionally reserved IPs. fallthrough
ipRaw := ip.As4() case containsIPs(usedIps, ip):
if ipRaw[3] == 0 || ipRaw[3] == 255 { fallthrough
case ip.IsZero() || ip.IsLoopback():
ip = ip.Next() ip = ip.Next()
continue continue
}
if ip.IsZero() && default:
ip.IsLoopback() {
ip = ip.Next()
continue
}
if !containsIPs(usedIps, ip) {
return &ip, nil return &ip, nil
} }
ip = ip.Next()
} }
} }

View file

@ -93,7 +93,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) {
c.Assert(ips[0], check.Equals, netaddr.MustParseIP("10.27.0.1")) c.Assert(ips[0], check.Equals, netaddr.MustParseIP("10.27.0.1"))
c.Assert(ips[9], check.Equals, netaddr.MustParseIP("10.27.0.10")) c.Assert(ips[9], check.Equals, netaddr.MustParseIP("10.27.0.10"))
c.Assert(ips[300], check.Equals, netaddr.MustParseIP("10.27.1.47")) c.Assert(ips[300], check.Equals, netaddr.MustParseIP("10.27.1.45"))
// Check that we can read back the IPs // Check that we can read back the IPs
machine1, err := app.GetMachineByID(1) machine1, err := app.GetMachineByID(1)
@ -112,7 +112,7 @@ func (s *Suite) TestGetMultiIp(c *check.C) {
netaddr.MustParseIP("10.27.0.50").String(), netaddr.MustParseIP("10.27.0.50").String(),
) )
expectedNextIP := netaddr.MustParseIP("10.27.1.97") expectedNextIP := netaddr.MustParseIP("10.27.1.95")
nextIP, err := app.getAvailableIP() nextIP, err := app.getAvailableIP()
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)