Soft limit CIDR range for IPv6 network to 288230376151711744 devices (#1344)

That should be enough for most of users (c).

Closes #1340
This commit is contained in:
Andrew Dryga
2023-01-19 19:16:16 -06:00
committed by GitHub
parent 03100df545
commit 48a3621aed
3 changed files with 49 additions and 1 deletions

View File

@@ -145,7 +145,7 @@ defmodule FzHttp.Devices.Device do
end
defp put_default_ip(changeset, field) do
cidr_string = FzHttp.Config.fetch_env!(:fz_http, :"wireguard_#{field}_network")
cidr_string = wireguard_network(field)
{:ok, cidr_inet} = EctoNetwork.INET.cast(cidr_string)
cidr = CIDR.parse(cidr_string)
offset = Enum.random(2..(cidr.hosts - 2))
@@ -162,6 +162,16 @@ defmodule FzHttp.Devices.Device do
end
end
defp wireguard_network(field) do
cidr_string = FzHttp.Config.fetch_env!(:fz_http, :"wireguard_#{field}_network")
[inet, network] = String.split(cidr_string, "/")
network = String.to_integer(network)
"#{inet}/#{limit_cidr_range(field, network)}"
end
defp limit_cidr_range(:ipv4, network), do: network
defp limit_cidr_range(:ipv6, network), do: max(network, 70)
defp ipv4_address do
FzHttp.Config.fetch_env!(:fz_http, :wireguard_ipv4_address)
|> EctoNetwork.INET.cast()

View File

@@ -112,6 +112,38 @@ defmodule FzHttp.Devices.Device.QueryTest do
assert Repo.one(queryable) == %Postgrex.INET{address: {64_768, 0, 0, 0, 0, 3, 3, 4}}
end
test "selects available IPv6 at end of CIDR range" do
cidr = string_to_inet("fd00::/106")
gateway_ip = string_to_inet("fd00::3:3:3")
offset = 4_194_304
queryable = next_available_address(cidr, offset, [gateway_ip])
assert Repo.one(queryable) == %Postgrex.INET{address: {64_768, 0, 0, 0, 0, 0, 63, 65_535}}
end
test "works when offset is out of IPv6 CIDR range" do
cidr = string_to_inet("fd00::/106")
gateway_ip = string_to_inet("fd00::3:3:3")
offset = 4_194_305
queryable = next_available_address(cidr, offset, [gateway_ip])
assert Repo.one(queryable) == %Postgrex.INET{address: {64_768, 0, 0, 0, 0, 0, 64, 0}}
end
test "works when netmask allows a large number of devices" do
cidr = string_to_inet("fd00::/70")
gateway_ip = string_to_inet("fd00::3:3:3")
offset = 9_223_372_036_854_775_807
queryable = next_available_address(cidr, offset, [gateway_ip])
assert Repo.one(queryable) == %Postgrex.INET{
address: {64_768, 0, 0, 0, 32_767, 65_535, 65_535, 65_534}
}
end
test "selects nothing when IPv6 CIDR range is exhausted" do
cidr = string_to_inet("fd00::3:2:0/126")
gateway_ip = string_to_inet("fd00::3:2:1")

View File

@@ -82,6 +82,12 @@ defmodule FzHttp.DevicesTest do
refute is_nil(device.ipv6)
end
test "soft limit max network range for IPv6", %{device: device} do
FzHttp.Config.put_env(:wireguard_ipv6_network, "fd00::/20")
attrs = %{@device_attrs | ipv4: nil, ipv6: nil, user_id: device.user_id}
assert {:ok, _device} = Devices.create_device(attrs)
end
test "returns error when device IP can't be assigned due to CIDR pool exhaustion", %{
device: device
} do